From 204b46525871805754bf6ef6974efbeafc818aaa Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:38:32 -0600 Subject: [PATCH 01/98] More tool compat (#2292) --- .../railcraft/api/items/IToolCrowbar.java | 78 +++++++++++++++++++ .../mrtjp/projectred/api/IScrewdriver.java | 11 +++ src/main/java/gregtech/api/GTValues.java | 4 +- .../gregtech/api/items/toolitem/IGTTool.java | 50 +++++++++++- 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 src/api/java/mods/railcraft/api/items/IToolCrowbar.java create mode 100644 src/api/java/mrtjp/projectred/api/IScrewdriver.java diff --git a/src/api/java/mods/railcraft/api/items/IToolCrowbar.java b/src/api/java/mods/railcraft/api/items/IToolCrowbar.java new file mode 100644 index 00000000000..7b8006b5ec2 --- /dev/null +++ b/src/api/java/mods/railcraft/api/items/IToolCrowbar.java @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------------ + Copyright (c) CovertJaguar, 2011-2020 + + This work (the API) is licensed under the "MIT" License, + see LICENSE.md for details. + -----------------------------------------------------------------------------*/ +package mods.railcraft.api.items; + +import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; + +/** + * @author CovertJaguar + */ +public interface IToolCrowbar { + String ORE_TAG = "toolCrowbar"; + + /** + * Controls non-rotational interactions with blocks. Crowbar specific stuff. + *

+ * Rotational interaction is handled by the Block.rotateBlock() function, + * which should be called from the Item.onUseFirst() function of your tool. + * + * @param player the player + * @param crowbar the crowbar + * @param pos the block @return true if can whack a block + */ + boolean canWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos); + + /** + * Callback to do damage to the item. + * + * @param player the player + * @param crowbar the crowbar + * @param pos the block + */ + void onWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos); + + /** + * Controls whether you can link a cart. + * + * @param player the player + * @param crowbar the crowbar + * @param cart the cart @return true if can link a cart + */ + boolean canLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart); + + /** + * Callback to do damage. + * + * @param player the player + * @param crowbar the crowbar + * @param cart the cart + */ + void onLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart); + + /** + * Controls whether you can boost a cart. + * + * @param player the player + * @param crowbar the crowbar + * @param cart the cart @return true if can boost a cart + */ + boolean canBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart); + + /** + * Callback to do damage, boosting a cart usually does more damage than + * normal usage. + * + * @param player the player + * @param crowbar the crowbar + * @param cart the cart + */ + void onBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart); +} diff --git a/src/api/java/mrtjp/projectred/api/IScrewdriver.java b/src/api/java/mrtjp/projectred/api/IScrewdriver.java new file mode 100644 index 00000000000..a6298fecefd --- /dev/null +++ b/src/api/java/mrtjp/projectred/api/IScrewdriver.java @@ -0,0 +1,11 @@ +package mrtjp.projectred.api; + +import net.minecraft.item.ItemStack; +import net.minecraft.entity.player.EntityPlayer; + +public interface IScrewdriver { + + boolean canUse(EntityPlayer player, ItemStack stack); + + void damageScrewdriver(EntityPlayer player, ItemStack stack); // Damage the item on usage +} diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index fa0f424854a..ef4a1730829 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -155,7 +155,9 @@ public class GTValues { MODID_ET = "extratrees", MODID_GENETICS = "genetics", MODID_BOP = "biomesoplenty", - MODID_TCON = "tconstruct"; + MODID_TCON = "tconstruct", + MODID_PROJRED_CORE = "projectred-core", + MODID_RC = "railcraft"; private static Boolean isClient; diff --git a/src/main/java/gregtech/api/items/toolitem/IGTTool.java b/src/main/java/gregtech/api/items/toolitem/IGTTool.java index 300c36f537e..4c3ba369341 100644 --- a/src/main/java/gregtech/api/items/toolitem/IGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/IGTTool.java @@ -40,6 +40,7 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.item.EntityMinecart; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.EntityEquipmentSlot; @@ -68,6 +69,8 @@ import forestry.api.arboriculture.IToolGrafter; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import mods.railcraft.api.items.IToolCrowbar; +import mrtjp.projectred.api.IScrewdriver; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -91,10 +94,12 @@ @Optional.Interface(modid = GTValues.MODID_COFH, iface = "cofh.api.item.IToolHammer"), @Optional.Interface(modid = GTValues.MODID_EIO, iface = "crazypants.enderio.api.tool.ITool"), @Optional.Interface(modid = GTValues.MODID_FR, iface = "forestry.api.arboriculture.IToolGrafter"), + @Optional.Interface(modid = GTValues.MODID_PROJRED_CORE, iface = "mrtjp.projectred.api.IScrewdriver"), + @Optional.Interface(modid = GTValues.MODID_RC, iface = "mods.railcraft.api.items.IToolCrowbar"), @Optional.Interface(modid = GTValues.MODID_ECORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") }) public interface IGTTool extends ItemUIFactory, IAEWrench, IToolWrench, IToolHammer, ITool, IToolGrafter, - IOverlayRenderAware { + IOverlayRenderAware, IScrewdriver, IToolCrowbar { /** * @return the modid of the tool @@ -1042,4 +1047,47 @@ default float getSaplingModifier(ItemStack stack, World world, EntityPlayer play default void renderItemOverlayIntoGUI(@NotNull ItemStack stack, int xPosition, int yPosition) { ToolChargeBarRenderer.renderBarsTool(this, stack, xPosition, yPosition); } + + // IScrewdriver + @Override + default boolean canUse(EntityPlayer player, ItemStack stack) { + return get().getToolClasses(stack).contains(ToolClasses.SCREWDRIVER); + } + + @Override + default void damageScrewdriver(EntityPlayer player, ItemStack stack) { + damageItem(stack, player); + } + + // IToolCrowbar + + @Override + default boolean canWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos) { + return get().getToolClasses(crowbar).contains(ToolClasses.CROWBAR); + } + + @Override + default void onWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos) { + damageItem(crowbar, player); + } + + @Override + default boolean canLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart) { + return get().getToolClasses(crowbar).contains(ToolClasses.CROWBAR); + } + + @Override + default void onLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart) { + damageItem(crowbar, player); + } + + @Override + default boolean canBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart) { + return get().getToolClasses(crowbar).contains(ToolClasses.CROWBAR); + } + + @Override + default void onBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart) { + damageItem(crowbar, player); + } } From fccc57fadc61c608fcbe078c4728ac3c64d79c98 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:08:03 -0600 Subject: [PATCH 02/98] Fix silicon bee crash (#2299) --- .../gregtech/integration/forestry/bees/GTBeeDefinition.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 827eb307c28..97fed7a25c3 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -587,7 +587,8 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, TOLERATES_RAIN, true); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Loader.isModLoaded(GTValues.MODID_MB) && Loader.isModLoaded(GTValues.MODID_APPENG)) { + // MB Skystone bee is only registered if AE2 is also active dis.registerMutation(IRON, ForestryUtil.getSpecies(GTValues.MODID_MB, "AESkystone"), 17); } else { dis.registerMutation(IRON, BeeDefinition.IMPERIAL, 17); From 98e81843244df0183cc12dda702db347b01ba286 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:23:26 -0600 Subject: [PATCH 03/98] Fix using MV muffler in EBF JEI preview (#2298) --- .../common/metatileentities/MetaTileEntities.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index d35d77f79d8..c346ac65e23 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -267,7 +267,7 @@ public class MetaTileEntities { // UHV public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, // ZPM, UV - public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV]; // LV-UV + public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV + 1]; // LV-UV public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; public static final MetaTileEntityQuantumChest[] QUANTUM_CHEST = new MetaTileEntityQuantumChest[10]; public static final MetaTileEntityQuantumTank[] QUANTUM_TANK = new MetaTileEntityQuantumTank[10]; @@ -1137,12 +1137,13 @@ public static void init() { CLEANING_MAINTENANCE_HATCH = registerMetaTileEntity(1401, new MetaTileEntityCleaningMaintenanceHatch(gregtechId("maintenance_hatch_cleanroom_auto"))); - // Muffler Hatches, IDs 1657- - for (int i = 0; i < MUFFLER_HATCH.length; i++) { - String voltageName = GTValues.VN[i + 1].toLowerCase(); - MUFFLER_HATCH[i] = new MetaTileEntityMufflerHatch(gregtechId("muffler_hatch." + voltageName), i + 1); + // Muffler Hatches, IDs 1657-1664 + for (int i = 0; i < MUFFLER_HATCH.length - 1; i++) { + int tier = i + 1; + String voltageName = GTValues.VN[tier].toLowerCase(); + MUFFLER_HATCH[tier] = new MetaTileEntityMufflerHatch(gregtechId("muffler_hatch." + voltageName), tier); - registerMetaTileEntity(1657 + i, MUFFLER_HATCH[i]); + registerMetaTileEntity(1657 + i, MUFFLER_HATCH[tier]); } CLIPBOARD_TILE = registerMetaTileEntity(1666, new MetaTileEntityClipboard(gregtechId("clipboard"))); From cd4c040b2d4a52da73324c9ffa146eff11fd2598 Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:26:12 -0700 Subject: [PATCH 04/98] Allow specifying NBT matching on Research ItemStacks (#2294) --- .../builders/AssemblyLineRecipeBuilder.java | 28 ++++++++++++++++ .../builders/ResearchRecipeBuilder.java | 16 +++++++-- .../api/util/AssemblyLineManager.java | 33 ++++++++++++++++--- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java index 2d9d5006c1b..9ddc9d6851b 100644 --- a/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java @@ -155,6 +155,7 @@ public static class ResearchRecipeEntry { private final String researchId; private final ItemStack researchStack; private final ItemStack dataStack; + private final boolean ignoreNBT; private final int duration; private final int EUt; private final int CWUt; @@ -166,6 +167,9 @@ public static class ResearchRecipeEntry { * @param duration the duration of the recipe * @param EUt the EUt of the recipe * @param CWUt how much computation per tick this recipe needs if in Research Station + *

+ * By default, will ignore NBT on researchStack input. If NBT matching is desired, see + * {@link #ResearchRecipeEntry(String, ItemStack, ItemStack, boolean, int, int, int)} */ public ResearchRecipeEntry(@NotNull String researchId, @NotNull ItemStack researchStack, @NotNull ItemStack dataStack, int duration, int EUt, int CWUt) { @@ -175,6 +179,26 @@ public ResearchRecipeEntry(@NotNull String researchId, @NotNull ItemStack resear this.duration = duration; this.EUt = EUt; this.CWUt = CWUt; + this.ignoreNBT = true; + } + + /** + * @param researchId the id of the research to store + * @param researchStack the stack to scan for research + * @param dataStack the stack to contain the data + * @param duration the duration of the recipe + * @param EUt the EUt of the recipe + * @param CWUt how much computation per tick this recipe needs if in Research Station + */ + public ResearchRecipeEntry(@NotNull String researchId, @NotNull ItemStack researchStack, + @NotNull ItemStack dataStack, boolean ignoreNBT, int duration, int EUt, int CWUt) { + this.researchId = researchId; + this.researchStack = researchStack; + this.dataStack = dataStack; + this.ignoreNBT = ignoreNBT; + this.duration = duration; + this.EUt = EUt; + this.CWUt = CWUt; } @NotNull @@ -192,6 +216,10 @@ public ItemStack getDataStack() { return dataStack; } + public boolean getIgnoreNBT() { + return ignoreNBT; + } + public int getDuration() { return duration; } diff --git a/src/main/java/gregtech/api/recipes/builders/ResearchRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/ResearchRecipeBuilder.java index bbbda50d520..b20da993e70 100644 --- a/src/main/java/gregtech/api/recipes/builders/ResearchRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/ResearchRecipeBuilder.java @@ -15,12 +15,22 @@ public abstract class ResearchRecipeBuilder> protected ItemStack researchStack; protected ItemStack dataStack; + protected boolean ignoreNBT; protected String researchId; protected int eut; public T researchStack(@NotNull ItemStack researchStack) { if (!researchStack.isEmpty()) { this.researchStack = researchStack; + this.ignoreNBT = true; + } + return (T) this; + } + + public T researchStack(@NotNull ItemStack researchStack, boolean ignoreNBT) { + if (!researchStack.isEmpty()) { + this.researchStack = researchStack; + this.ignoreNBT = ignoreNBT; } return (T) this; } @@ -99,7 +109,8 @@ protected AssemblyLineRecipeBuilder.ResearchRecipeEntry build() { validateResearchItem(); if (duration <= 0) duration = DEFAULT_SCANNER_DURATION; if (eut <= 0) eut = DEFAULT_SCANNER_EUT; - return new AssemblyLineRecipeBuilder.ResearchRecipeEntry(researchId, researchStack, dataStack, duration, + return new AssemblyLineRecipeBuilder.ResearchRecipeEntry(researchId, researchStack, dataStack, ignoreNBT, + duration, eut, 0); } } @@ -148,7 +159,8 @@ protected AssemblyLineRecipeBuilder.ResearchRecipeEntry build() { int duration = totalCWU; if (eut <= 0) eut = DEFAULT_STATION_EUT; - return new AssemblyLineRecipeBuilder.ResearchRecipeEntry(researchId, researchStack, dataStack, duration, + return new AssemblyLineRecipeBuilder.ResearchRecipeEntry(researchId, researchStack, dataStack, ignoreNBT, + duration, eut, cwut); } } diff --git a/src/main/java/gregtech/api/util/AssemblyLineManager.java b/src/main/java/gregtech/api/util/AssemblyLineManager.java index f4f577996b2..a2652acfa84 100644 --- a/src/main/java/gregtech/api/util/AssemblyLineManager.java +++ b/src/main/java/gregtech/api/util/AssemblyLineManager.java @@ -121,33 +121,56 @@ public static void createDefaultResearchRecipe(@NotNull AssemblyLineRecipeBuilde for (AssemblyLineRecipeBuilder.ResearchRecipeEntry entry : builder.getRecipeEntries()) { createDefaultResearchRecipe(entry.getResearchId(), entry.getResearchStack(), entry.getDataStack(), + entry.getIgnoreNBT(), entry.getDuration(), entry.getEUt(), entry.getCWUt()); } } + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void createDefaultResearchRecipe(@NotNull String researchId, @NotNull ItemStack researchItem, @NotNull ItemStack dataItem, int duration, int EUt, int CWUt) { + createDefaultResearchRecipe(researchId, researchItem, dataItem, true, duration, EUt, CWUt); + } + + public static void createDefaultResearchRecipe(@NotNull String researchId, @NotNull ItemStack researchItem, + @NotNull ItemStack dataItem, boolean ignoreNBT, int duration, + int EUt, int CWUt) { if (!ConfigHolder.machines.enableResearch) return; NBTTagCompound compound = GTUtility.getOrCreateNbtCompound(dataItem); writeResearchToNBT(compound, researchId); if (CWUt > 0) { - RecipeMaps.RESEARCH_STATION_RECIPES.recipeBuilder() + RecipeBuilder researchBuilder = RecipeMaps.RESEARCH_STATION_RECIPES.recipeBuilder() .inputNBT(dataItem.getItem(), 1, dataItem.getMetadata(), NBTMatcher.ANY, NBTCondition.ANY) - .inputs(researchItem) .outputs(dataItem) .EUt(EUt) .CWUt(CWUt) - .totalCWU(duration) - .buildAndRegister(); + .totalCWU(duration); + + if (ignoreNBT) { + researchBuilder.inputNBT(researchItem.getItem(), 1, researchItem.getMetadata(), NBTMatcher.ANY, + NBTCondition.ANY); + } else { + researchBuilder.inputs(researchItem); + } + + researchBuilder.buildAndRegister(); } else { RecipeBuilder builder = RecipeMaps.SCANNER_RECIPES.recipeBuilder() .inputNBT(dataItem.getItem(), 1, dataItem.getMetadata(), NBTMatcher.ANY, NBTCondition.ANY) - .inputs(researchItem) .outputs(dataItem) .duration(duration) .EUt(EUt); + + if (ignoreNBT) { + builder.inputNBT(researchItem.getItem(), 1, researchItem.getMetadata(), NBTMatcher.ANY, + NBTCondition.ANY); + } else { + builder.inputs(researchItem); + } + builder.applyProperty(ScanProperty.getInstance(), true); builder.buildAndRegister(); } From e9a8ddde6ff6dfc9ecd2ae255257142af6323f09 Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:27:14 -0700 Subject: [PATCH 05/98] Attempt to clarify tooltip (#2300) --- src/main/resources/assets/gregtech/lang/en_us.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index f34849c4bdd..5ab44b85d32 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5557,7 +5557,7 @@ gregtech.multiblock.pattern.error.batteries=§cMust have at least one non-empty gregtech.multiblock.pattern.error.filters=§cAll filters must be the same§r gregtech.multiblock.pattern.clear_amount_1=§6Must have a clear 1x1x1 space in front§r gregtech.multiblock.pattern.clear_amount_3=§6Must have a clear 3x3x1 space in front§r -gregtech.multiblock.pattern.single=§6Only this block can be used§r +gregtech.multiblock.pattern.single=§6Only this block type can be used§r gregtech.multiblock.pattern.location_end=§cVery End§r gregtech.multiblock.pattern.replaceable_air=Replaceable by Air From 673be5badd82555719718b3e4b9661a2a646e73b Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:42:46 -0600 Subject: [PATCH 06/98] Chisel module (#2290) --- dependencies.gradle | 1 + src/main/java/gregtech/api/GTValues.java | 3 +- .../api/unification/ore/OrePrefix.java | 1 + .../integration/chisel/ChiselModule.java | 119 ++++++++++++++++++ .../gregtech/loaders/OreDictionaryLoader.java | 2 + .../gregtech/modules/GregTechModules.java | 1 + 6 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/main/java/gregtech/integration/chisel/ChiselModule.java diff --git a/dependencies.gradle b/dependencies.gradle index a1254cf48a9..db9bf2304c2 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -44,6 +44,7 @@ dependencies { compileOnlyApi rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 compileOnlyApi rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 compileOnlyApi rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 + compileOnlyApi rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index ef4a1730829..7a1b5d34f4f 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -157,7 +157,8 @@ public class GTValues { MODID_BOP = "biomesoplenty", MODID_TCON = "tconstruct", MODID_PROJRED_CORE = "projectred-core", - MODID_RC = "railcraft"; + MODID_RC = "railcraft", + MODID_CHISEL = "chisel"; private static Boolean isClient; diff --git a/src/main/java/gregtech/api/unification/ore/OrePrefix.java b/src/main/java/gregtech/api/unification/ore/OrePrefix.java index 64eb11cd7fa..30239988324 100644 --- a/src/main/java/gregtech/api/unification/ore/OrePrefix.java +++ b/src/main/java/gregtech/api/unification/ore/OrePrefix.java @@ -467,6 +467,7 @@ public static void init() { block.modifyMaterialAmount(Materials.Glowstone, 4); block.modifyMaterialAmount(Materials.NetherQuartz, 4); + block.modifyMaterialAmount(Materials.CertusQuartz, 4); block.modifyMaterialAmount(Materials.Brick, 4); block.modifyMaterialAmount(Materials.Clay, 4); block.modifyMaterialAmount(Materials.Glass, 1); diff --git a/src/main/java/gregtech/integration/chisel/ChiselModule.java b/src/main/java/gregtech/integration/chisel/ChiselModule.java new file mode 100644 index 00000000000..c6dc3cafe05 --- /dev/null +++ b/src/main/java/gregtech/integration/chisel/ChiselModule.java @@ -0,0 +1,119 @@ +package gregtech.integration.chisel; + +import gregtech.api.GTValues; +import gregtech.api.block.VariantBlock; +import gregtech.api.modules.GregTechModule; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.Materials; +import gregtech.common.blocks.BlockColored; +import gregtech.common.blocks.BlockCompressed; +import gregtech.common.blocks.BlockWarningSign; +import gregtech.common.blocks.BlockWarningSign1; +import gregtech.common.blocks.MetaBlocks; +import gregtech.common.blocks.StoneVariantBlock; +import gregtech.common.blocks.StoneVariantBlock.StoneType; +import gregtech.common.blocks.StoneVariantBlock.StoneVariant; +import gregtech.common.blocks.wood.BlockGregPlanks; +import gregtech.integration.IntegrationSubmodule; +import gregtech.modules.GregTechModules; + +import net.minecraft.block.Block; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IStringSerializable; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLInterModComms; + +import team.chisel.common.carving.Carving; + +import java.util.Objects; + +@GregTechModule( + moduleID = GregTechModules.MODULE_CHISEL, + containerID = GTValues.MODID, + modDependencies = GTValues.MODID_CHISEL, + name = "GregTech Chisel Integration", + description = "Chisel Integration Module") +public class ChiselModule extends IntegrationSubmodule { + + @Override + public void init(FMLInitializationEvent event) { + // GT custom groups + addVariations("gt_warning_sign", MetaBlocks.WARNING_SIGN, BlockWarningSign.SignType.values()); + addVariations("gt_warning_sign", MetaBlocks.WARNING_SIGN_1, BlockWarningSign1.SignType.values()); + addVariations("gt_studs", MetaBlocks.STUDS); + addVariations("gt_metal_sheet", MetaBlocks.METAL_SHEET); + addVariations("gt_large_metal_sheet", MetaBlocks.LARGE_METAL_SHEET); + for (EnumDyeColor color : EnumDyeColor.values()) { + Block lamp = MetaBlocks.LAMPS.get(color); + Block lampBorderless = MetaBlocks.BORDERLESS_LAMPS.get(color); + String group = "gt_lamp_" + color.getName().toLowerCase(); + for (int i = 0; i < 8; i++) { + addVariation(group, lamp, i); + addVariation(group, lampBorderless, i); + } + } + + // Chisel shared groups + addVariations("marble", StoneType.MARBLE, false); + addVariations("basalt", StoneType.BASALT, false); + addVariations("black_granite", StoneType.BLACK_GRANITE, false); + addVariations("red_granite", StoneType.RED_GRANITE, false); + addVariations("light_concrete", StoneType.CONCRETE_LIGHT, true); + addVariations("dark_concrete", StoneType.CONCRETE_DARK, true); + + // Mod-dependent groups + if (doesGroupExist("treated_wood")) { // IE Treated Wood group + addVariations("treated_wood", MetaBlocks.PLANKS, BlockGregPlanks.BlockType.TREATED_PLANK); + } + if (doesGroupExist("certus")) { // AE2 Certus Quartz group + addVariation("certus", Materials.CertusQuartz); + } + } + + @SafeVarargs + private & IStringSerializable, T extends VariantBlock> void addVariations(String group, + T block, + U... variants) { + if (variants != null) { + for (U variant : variants) { + addVariation(group, block, block.getMetaFromState(block.getState(variant))); + } + } + } + + private void addVariations(String group, BlockColored block) { + for (EnumDyeColor color : EnumDyeColor.values()) { + addVariation(group, block, color.getMetadata()); + } + } + + private void addVariations(String group, StoneType type, boolean enableCobbles) { + for (StoneVariantBlock.StoneVariant variant : StoneVariant.values()) { + if (!enableCobbles && (variant == StoneVariant.COBBLE || variant == StoneVariant.COBBLE_MOSSY)) { + continue; + } + StoneVariantBlock block = MetaBlocks.STONE_BLOCKS.get(variant); + int meta = block.getMetaFromState(block.getState(type)); + addVariation(group, block, meta); + } + } + + private void addVariation(String group, Material material) { + BlockCompressed block = MetaBlocks.COMPRESSED.get(material); + int meta = block.getMetaFromState(block.getBlock(material)); + addVariation(group, block, meta); + } + + private void addVariation(String group, Block block, int meta) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setString("group", group); + tag.setString("block", Objects.requireNonNull(block.getRegistryName()).toString()); + tag.setInteger("meta", meta); + FMLInterModComms.sendMessage(GTValues.MODID_CHISEL, "add_variation", tag); + } + + private boolean doesGroupExist(String group) { + return Carving.chisel.getGroup(group) != null; + } +} diff --git a/src/main/java/gregtech/loaders/OreDictionaryLoader.java b/src/main/java/gregtech/loaders/OreDictionaryLoader.java index b05fba4609b..a902983af39 100644 --- a/src/main/java/gregtech/loaders/OreDictionaryLoader.java +++ b/src/main/java/gregtech/loaders/OreDictionaryLoader.java @@ -25,12 +25,14 @@ public class OreDictionaryLoader { public static final String OREDICT_FUEL_COKE = "fuelCoke"; public static final String OREDICT_BLOCK_FUEL_COKE = "blockFuelCoke"; + public static final String OREDICT_BLOCK_COAL_COKE = "blockCoalCoke"; public static void init() { GTLog.logger.info("Registering OreDict entries."); OreDictionary.registerOre(OREDICT_FUEL_COKE, OreDictUnifier.get(OrePrefix.gem, Materials.Coke)); OreDictionary.registerOre(OREDICT_BLOCK_FUEL_COKE, OreDictUnifier.get(OrePrefix.block, Materials.Coke)); + OreDictionary.registerOre(OREDICT_BLOCK_COAL_COKE, OreDictUnifier.get(OrePrefix.block, Materials.Coke)); OreDictionary.registerOre("crystalCertusQuartz", OreDictUnifier.get(OrePrefix.gem, Materials.CertusQuartz)); OreDictUnifier.registerOre(new ItemStack(Blocks.CLAY), OrePrefix.block, Materials.Clay); diff --git a/src/main/java/gregtech/modules/GregTechModules.java b/src/main/java/gregtech/modules/GregTechModules.java index 9c07e90db26..96ad33664b9 100644 --- a/src/main/java/gregtech/modules/GregTechModules.java +++ b/src/main/java/gregtech/modules/GregTechModules.java @@ -17,6 +17,7 @@ public class GregTechModules implements IModuleContainer { public static final String MODULE_HWYLA = "hwyla_integration"; public static final String MODULE_BAUBLES = "baubles_integration"; public static final String MODULE_FR = "fr_integration"; + public static final String MODULE_CHISEL = "chisel_integration"; @Override public String getID() { From 2fb6af970a2ef3206a5b5199b7e9cf14bdda543a Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:12:42 -0600 Subject: [PATCH 07/98] Fix pipe restrictor render on bottom face (#2302) --- src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java index 841d230d0f5..632bdad8f2b 100644 --- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java +++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java @@ -100,7 +100,7 @@ public static void initializeRestrictor(TextureMap map) { static { FACE_BORDER_MAP.put(EnumFacing.DOWN, - borderMap(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST)); + borderMap(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.EAST)); FACE_BORDER_MAP.put(EnumFacing.UP, borderMap(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.EAST)); FACE_BORDER_MAP.put(EnumFacing.NORTH, From 7112238820d67c1e9f52b22070ce56be799dcf1e Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:15:58 -0600 Subject: [PATCH 08/98] Fix battery slot charge flickering (#2305) --- .../api/capability/impl/EnergyContainerHandler.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java b/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java index 81972c3f5d7..37688a4deec 100644 --- a/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java +++ b/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java @@ -157,16 +157,16 @@ private boolean handleElectricItem(IElectricItem electricItem) { // Check if the item is a battery (or similar), and if we can receive some amount of energy if (electricItem.canProvideChargeExternally() && getEnergyCanBeInserted() > 0) { - // Drain from the battery if we are below half energy capacity, and if the tier matches - if (chargePercent <= 0.5 && chargeTier == machineTier) { + // Drain from the battery if we are below 1/3rd energy capacity, and if the tier matches + if (chargePercent <= 0.33 && chargeTier == machineTier) { long dischargedBy = electricItem.discharge(getEnergyCanBeInserted(), machineTier, false, true, false); addEnergy(dischargedBy); return dischargedBy > 0L; } } - // Else, check if we have above 50% power - if (chargePercent > 0.5) { + // Else, check if we have above 2/3rds charge + if (chargePercent > 0.66) { long chargedBy = electricItem.charge(getEnergyStored(), chargeTier, false, false); removeEnergy(chargedBy); return chargedBy > 0; @@ -178,7 +178,7 @@ private boolean handleForgeEnergyItem(IEnergyStorage energyStorage) { int machineTier = GTUtility.getTierByVoltage(Math.max(getInputVoltage(), getOutputVoltage())); double chargePercent = getEnergyStored() / (getEnergyCapacity() * 1.0); - if (chargePercent > 0.5) { + if (chargePercent > 0.66) { // 2/3rds full long chargedBy = FeCompat.insertEu(energyStorage, GTValues.V[machineTier]); removeEnergy(chargedBy); return chargedBy > 0; From 318e6eafda3a813144c68df7a222ca731ecdbbb7 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:21:29 -0600 Subject: [PATCH 09/98] Tweak muffler effect API (#2286) --- .../multiblock/MultiblockWithDisplayBase.java | 7 ++- .../particle/VanillaParticleEffects.java | 63 ++++++++++--------- .../MetaTileEntityMufflerHatch.java | 10 ++- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java index a94c78ccdff..55723ef456d 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java @@ -275,7 +275,7 @@ public boolean isMufflerFaceFree() { } /** - * @deprecated Use {@link gregtech.client.particle.VanillaParticleEffects#MUFFLER_SMOKE} instead. + * @deprecated Override {@link #getMufflerParticle()} instead. */ @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @Deprecated @@ -284,6 +284,11 @@ public void runMufflerEffect(float xPos, float yPos, float zPos, float xSpd, flo getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, xPos, yPos, zPos, xSpd, ySpd, zSpd); } + @SideOnly(Side.CLIENT) + public @NotNull EnumParticleTypes getMufflerParticle() { + return EnumParticleTypes.SMOKE_LARGE; + } + /** * Sets the recovery items of this multiblock * diff --git a/src/main/java/gregtech/client/particle/VanillaParticleEffects.java b/src/main/java/gregtech/client/particle/VanillaParticleEffects.java index 2765d3945d9..ddfa0592369 100644 --- a/src/main/java/gregtech/client/particle/VanillaParticleEffects.java +++ b/src/main/java/gregtech/client/particle/VanillaParticleEffects.java @@ -26,35 +26,6 @@ public enum VanillaParticleEffects implements IMachineParticleEffect { mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x, y, z, 0, 0, 0); }), - MUFFLER_SMOKE(mte -> { - if (mte.getWorld() == null || mte.getPos() == null) return; - - BlockPos pos = mte.getPos(); - EnumFacing facing = mte.getFrontFacing(); - float xPos = facing.getXOffset() * 0.76F + pos.getX() + 0.25F; - float yPos = facing.getYOffset() * 0.76F + pos.getY() + 0.25F; - float zPos = facing.getZOffset() * 0.76F + pos.getZ() + 0.25F; - - float ySpd = facing.getYOffset() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); - float xSpd; - float zSpd; - - if (facing.getYOffset() == -1) { - float temp = GTValues.RNG.nextFloat() * 2 * (float) Math.PI; - xSpd = (float) Math.sin(temp) * 0.1F; - zSpd = (float) Math.cos(temp) * 0.1F; - } else { - xSpd = facing.getXOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); - zSpd = facing.getZOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); - } - - xPos += GTValues.RNG.nextFloat() * 0.5F; - yPos += GTValues.RNG.nextFloat() * 0.5F; - zPos += GTValues.RNG.nextFloat() * 0.5F; - - mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, xPos, yPos, zPos, xSpd, ySpd, zSpd); - }), - PBF_SMOKE(mte -> { if (mte.getWorld() == null || mte.getPos() == null) return; @@ -167,12 +138,12 @@ public void runEffect(@NotNull MetaTileEntity metaTileEntity) { } @SideOnly(Side.CLIENT) - public static void defaultFrontEffect(MetaTileEntity mte, EnumParticleTypes... particles) { + public static void defaultFrontEffect(@NotNull MetaTileEntity mte, EnumParticleTypes... particles) { defaultFrontEffect(mte, 0.0F, particles); } @SideOnly(Side.CLIENT) - public static void defaultFrontEffect(MetaTileEntity mte, float yOffset, EnumParticleTypes... particles) { + public static void defaultFrontEffect(@NotNull MetaTileEntity mte, float yOffset, EnumParticleTypes... particles) { if (particles == null || particles.length == 0) return; if (mte.getWorld() == null || mte.getPos() == null) return; @@ -201,4 +172,34 @@ public static void defaultFrontEffect(MetaTileEntity mte, float yOffset, EnumPar mte.getWorld().spawnParticle(particle, x, y, z, 0, 0, 0); } } + + @SideOnly(Side.CLIENT) + public static void mufflerEffect(@NotNull MetaTileEntity mte, @NotNull EnumParticleTypes particle) { + if (mte.getWorld() == null || mte.getPos() == null) return; + + BlockPos pos = mte.getPos(); + EnumFacing facing = mte.getFrontFacing(); + float xPos = facing.getXOffset() * 0.76F + pos.getX() + 0.25F; + float yPos = facing.getYOffset() * 0.76F + pos.getY() + 0.25F; + float zPos = facing.getZOffset() * 0.76F + pos.getZ() + 0.25F; + + float ySpd = facing.getYOffset() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); + float xSpd; + float zSpd; + + if (facing.getYOffset() == -1) { + float temp = GTValues.RNG.nextFloat() * 2 * (float) Math.PI; + xSpd = (float) Math.sin(temp) * 0.1F; + zSpd = (float) Math.cos(temp) * 0.1F; + } else { + xSpd = facing.getXOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); + zSpd = facing.getZOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); + } + + xPos += GTValues.RNG.nextFloat() * 0.5F; + yPos += GTValues.RNG.nextFloat() * 0.5F; + zPos += GTValues.RNG.nextFloat() * 0.5F; + + mte.getWorld().spawnParticle(particle, xPos, yPos, zPos, xSpd, ySpd, zSpd); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java index 4b3e75a4c2c..5bc07d2e793 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java @@ -11,6 +11,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; @@ -69,7 +70,7 @@ public void update() { if (getWorld().isRemote && getController() instanceof MultiblockWithDisplayBase controller && controller.isActive()) { - VanillaParticleEffects.MUFFLER_SMOKE.runEffect(this); + VanillaParticleEffects.mufflerEffect(this, controller.getMufflerParticle()); } } @@ -112,12 +113,15 @@ private boolean checkFrontFaceFree() { return blockState.getBlock().isAir(blockState, getWorld(), frontPos) || GTUtility.isBlockSnow(blockState); } - /** @deprecated Use {@link VanillaParticleEffects#MUFFLER_SMOKE} instead. */ + /** @deprecated No longer needed. Multiblock controller sets the particle type. */ @Deprecated @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @SideOnly(Side.CLIENT) public void pollutionParticles() { - VanillaParticleEffects.MUFFLER_SMOKE.runEffect(this); + MultiblockControllerBase controller = getController(); + if (controller instanceof MultiblockWithDisplayBase displayBase) { + VanillaParticleEffects.mufflerEffect(this, displayBase.getMufflerParticle()); + } } @Override From 2b989a3337e24506fc47d3ebdb1f66eafb10ac41 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Fri, 15 Dec 2023 21:22:02 -0500 Subject: [PATCH 10/98] log incomplete packet reads in NetworkHandler (#2288) --- .../core/network/internal/NetworkHandler.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/core/network/internal/NetworkHandler.java b/src/main/java/gregtech/core/network/internal/NetworkHandler.java index 60849c35415..3d6769891f9 100644 --- a/src/main/java/gregtech/core/network/internal/NetworkHandler.java +++ b/src/main/java/gregtech/core/network/internal/NetworkHandler.java @@ -7,6 +7,7 @@ import gregtech.api.network.INetworkHandler; import gregtech.api.network.IPacket; import gregtech.api.network.IServerExecutor; +import gregtech.api.util.GTLog; import gregtech.core.CoreModule; import net.minecraft.client.network.NetHandlerPlayClient; @@ -26,8 +27,11 @@ import net.minecraftforge.fml.relauncher.SideOnly; import io.netty.buffer.Unpooled; +import org.jetbrains.annotations.NotNull; -public class NetworkHandler implements INetworkHandler { +import java.lang.reflect.InvocationTargetException; + +public final class NetworkHandler implements INetworkHandler { private static final NetworkHandler INSTANCE = new NetworkHandler(); @@ -106,7 +110,7 @@ public void sendToServer(IPacket packet) { @SubscribeEvent @SideOnly(Side.CLIENT) - public void onClientPacket(FMLNetworkEvent.ClientCustomPacketEvent event) throws Exception { + public void onClientPacket(FMLNetworkEvent.@NotNull ClientCustomPacketEvent event) throws Exception { IPacket packet = toGTPacket(event.getPacket()); if (IClientExecutor.class.isAssignableFrom(packet.getClass())) { IClientExecutor executor = (IClientExecutor) packet; @@ -121,7 +125,7 @@ public void onClientPacket(FMLNetworkEvent.ClientCustomPacketEvent event) throws } @SubscribeEvent - public void onServerPacket(FMLNetworkEvent.ServerCustomPacketEvent event) throws Exception { + public void onServerPacket(FMLNetworkEvent.@NotNull ServerCustomPacketEvent event) throws Exception { IPacket packet = toGTPacket(event.getPacket()); if (IServerExecutor.class.isAssignableFrom(packet.getClass())) { IServerExecutor executor = (IServerExecutor) packet; @@ -135,17 +139,27 @@ public void onServerPacket(FMLNetworkEvent.ServerCustomPacketEvent event) throws } } - private FMLProxyPacket toFMLPacket(IPacket packet) { + private @NotNull FMLProxyPacket toFMLPacket(@NotNull IPacket packet) { PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); buf.writeVarInt(packetHandler.getPacketId(packet.getClass())); packet.encode(buf); return new FMLProxyPacket(buf, GTValues.MODID); } - private IPacket toGTPacket(FMLProxyPacket proxyPacket) throws Exception { + private @NotNull IPacket toGTPacket(@NotNull FMLProxyPacket proxyPacket) throws NoSuchMethodException, + InvocationTargetException, + InstantiationException, + IllegalAccessException { PacketBuffer payload = (PacketBuffer) proxyPacket.payload(); - IPacket packet = packetHandler.getPacketClass(payload.readVarInt()).newInstance(); + var clazz = packetHandler.getPacketClass(payload.readVarInt()); + IPacket packet = clazz.getConstructor().newInstance(); packet.decode(payload); + + if (payload.readableBytes() != 0) { + GTLog.logger.error( + "NetworkHandler failed to finish reading packet with class {} and {} bytes remaining", + clazz.getName(), payload.readableBytes()); + } return packet; } } From 90820e63faa996f012027ad25404d914ec25509f Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:32:41 -0600 Subject: [PATCH 11/98] Fusion rebalancing (#2252) --- .../capability/impl/AbstractRecipeLogic.java | 3 +- .../impl/MultiblockRecipeLogic.java | 2 +- .../FusionEUToStartProperty.java | 19 ++++++---- .../material/materials/ElementMaterials.java | 2 ++ .../java/gregtech/common/CommonProxy.java | 6 ++-- .../electric/MetaTileEntityFusionReactor.java | 14 ++++++++ .../gregtech/loaders/recipe/FuelRecipes.java | 14 ++++++++ .../gregtech/loaders/recipe/FusionLoader.java | 36 ++++++++++++++----- 8 files changed, 75 insertions(+), 21 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index a241b32b3a0..cc2ce878aee 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -651,8 +651,7 @@ protected int[] calculateOverclock(@NotNull Recipe recipe) { * @param recipe the recipe to overclock * @return an int array of {OverclockedEUt, OverclockedDuration} */ - @NotNull - protected int[] performOverclocking(@NotNull Recipe recipe) { + protected int @NotNull [] performOverclocking(@NotNull Recipe recipe) { int[] values = { recipe.getEUt(), recipe.getDuration(), getNumberOfOCs(recipe.getEUt()) }; modifyOverclockPre(values, recipe.getRecipePropertyStorage()); diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index 3917d4a7bda..1ebb3e73c82 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -282,7 +282,7 @@ protected boolean prepareRecipeDistinct(Recipe recipe) { } @Override - protected void modifyOverclockPre(@NotNull int[] values, @NotNull IRecipePropertyStorage storage) { + protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipePropertyStorage storage) { super.modifyOverclockPre(values, storage); // apply maintenance bonuses diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java index 12fd90e7748..60188d8cd5f 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java @@ -6,6 +6,7 @@ import net.minecraft.client.resources.I18n; import org.apache.commons.lang3.Validate; +import org.apache.commons.lang3.tuple.Pair; import java.util.Map; import java.util.TreeMap; @@ -14,7 +15,7 @@ public class FusionEUToStartProperty extends RecipeProperty { public static final String KEY = "eu_to_start"; - private static final TreeMap registeredFusionTiers = new TreeMap<>(); + private static final TreeMap> registeredFusionTiers = new TreeMap<>(); private static FusionEUToStartProperty INSTANCE; @@ -33,23 +34,29 @@ public static FusionEUToStartProperty getInstance() { @Override public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.eu_to_start", - TextFormattingUtil.formatLongToCompactString(castValue(value))) + getFusionTier(castValue(value)), x, y, + TextFormattingUtil.formatLongToCompactString(castValue(value))) + getFusionTierName(castValue(value)), + x, y, color); } - private static String getFusionTier(Long eu) { - Map.Entry mapEntry = registeredFusionTiers.ceilingEntry(eu); + private static String getFusionTierName(Long eu) { + Map.Entry> mapEntry = registeredFusionTiers.ceilingEntry(eu); if (mapEntry == null) { throw new IllegalArgumentException("Value is above registered maximum EU values"); } - return String.format(" %s", mapEntry.getValue()); + return String.format(" %s", mapEntry.getValue().getRight()); + } + + public static int getFusionTier(Long eu) { + Map.Entry> mapEntry = registeredFusionTiers.ceilingEntry(eu); + return mapEntry == null ? 0 : mapEntry.getValue().getLeft(); } public static void registerFusionTier(int tier, String shortName) { Validate.notNull(shortName); long maxEU = 16 * 10000000L * (long) Math.pow(2, tier - 6); - registeredFusionTiers.put(maxEU, shortName); + registeredFusionTiers.put(maxEU, Pair.of(tier, shortName)); } } diff --git a/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java b/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java index 37c745dc5c5..8d4af1f4fa7 100644 --- a/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java @@ -42,6 +42,7 @@ public static void register() { Americium = new Material.Builder(3, gregtechId("americium")) .ingot(3) .liquid(new FluidBuilder().temperature(1449)) + .plasma() .color(0x287869).iconSet(METALLIC) .flags(EXT_METAL, GENERATE_FOIL, GENERATE_FINE_WIRE, GENERATE_DOUBLE_PLATE) .element(Elements.Am) @@ -814,6 +815,7 @@ public static void register() { Tin = new Material.Builder(112, gregtechId("tin")) .ingot(1) .liquid(new FluidBuilder().temperature(505)) + .plasma() .ore() .color(0xDCDCDC) .flags(EXT2_METAL, MORTAR_GRINDABLE, GENERATE_ROTOR, GENERATE_SPRING, GENERATE_SPRING_SMALL, diff --git a/src/main/java/gregtech/common/CommonProxy.java b/src/main/java/gregtech/common/CommonProxy.java index 7cac0f93204..f8a956e201b 100644 --- a/src/main/java/gregtech/common/CommonProxy.java +++ b/src/main/java/gregtech/common/CommonProxy.java @@ -297,9 +297,9 @@ public static void initComponents(RegistryEvent.Register event) { @SubscribeEvent public static void registerRecipes(RegistryEvent.Register event) { // Registers Fusion tiers for the FusionEUToStartProperty - FusionEUToStartProperty.registerFusionTier(6, "(MK1)"); - FusionEUToStartProperty.registerFusionTier(7, "(MK2)"); - FusionEUToStartProperty.registerFusionTier(8, "(MK3)"); + FusionEUToStartProperty.registerFusionTier(GTValues.LuV, "(MK1)"); + FusionEUToStartProperty.registerFusionTier(GTValues.ZPM, "(MK2)"); + FusionEUToStartProperty.registerFusionTier(GTValues.UV, "(MK3)"); // Register data stick copying custom scanner logic AssemblyLineManager.registerScannerLogic(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java index 8e667bedfcb..90b8b70886c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java @@ -30,6 +30,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.recipeproperties.FusionEUToStartProperty; +import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; @@ -630,6 +631,19 @@ public boolean checkRecipe(@NotNull Recipe recipe) { return true; } + @Override + protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipePropertyStorage storage) { + super.modifyOverclockPre(values, storage); + + // Limit the number of OCs to the difference in fusion reactor MK. + // I.e., a MK2 reactor can overclock a MK1 recipe once, and a + // MK3 reactor can overclock a MK2 recipe once, or a MK1 recipe twice. + long euToStart = storage.getRecipePropertyValue(FusionEUToStartProperty.getInstance(), 0L); + int fusionTier = FusionEUToStartProperty.getFusionTier(euToStart); + if (fusionTier != 0) fusionTier -= MetaTileEntityFusionReactor.this.tier; + values[2] = Math.min(fusionTier, values[2]); + } + @NotNull @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/loaders/recipe/FuelRecipes.java b/src/main/java/gregtech/loaders/recipe/FuelRecipes.java index 94da5ecb799..740521e8657 100644 --- a/src/main/java/gregtech/loaders/recipe/FuelRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/FuelRecipes.java @@ -291,6 +291,13 @@ public static void registerFuels() { RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Iron.getPlasma(1)) .fluidOutputs(Iron.getFluid(1)) + .duration(112) + .EUt((int) V[EV]) + .buildAndRegister(); + + RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() + .fluidInputs(Tin.getPlasma(1)) + .fluidOutputs(Tin.getFluid(1)) .duration(128) .EUt((int) V[EV]) .buildAndRegister(); @@ -301,5 +308,12 @@ public static void registerFuels() { .duration(192) .EUt((int) V[EV]) .buildAndRegister(); + + RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() + .fluidInputs(Americium.getPlasma(1)) + .fluidOutputs(Americium.getFluid(1)) + .duration(320) + .EUt((int) V[EV]) + .buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/FusionLoader.java b/src/main/java/gregtech/loaders/recipe/FusionLoader.java index f5ec3a7b861..49515136876 100644 --- a/src/main/java/gregtech/loaders/recipe/FusionLoader.java +++ b/src/main/java/gregtech/loaders/recipe/FusionLoader.java @@ -38,16 +38,16 @@ public static void init() { RecipeMaps.FUSION_RECIPES.recipeBuilder() .fluidInputs(Materials.Silicon.getFluid(16)) .fluidInputs(Materials.Magnesium.getFluid(16)) - .fluidOutputs(Materials.Iron.getPlasma(16)) + .fluidOutputs(Materials.Iron.getPlasma(144)) .duration(32) .EUt(VA[IV]) - .EUToStart(360_000_000) + .EUToStart(300_000_000) .buildAndRegister(); RecipeMaps.FUSION_RECIPES.recipeBuilder() .fluidInputs(Materials.Potassium.getFluid(16)) .fluidInputs(Materials.Fluorine.getFluid(125)) - .fluidOutputs(Materials.Nickel.getPlasma(16)) + .fluidOutputs(Materials.Nickel.getPlasma(144)) .duration(16) .EUt(VA[LuV]) .EUToStart(480_000_000) @@ -62,6 +62,24 @@ public static void init() { .EUToStart(180_000_000) .buildAndRegister(); + RecipeMaps.FUSION_RECIPES.recipeBuilder() + .fluidInputs(Materials.Plutonium241.getFluid(144)) + .fluidInputs(Materials.Hydrogen.getFluid(2000)) + .fluidOutputs(Materials.Americium.getPlasma(144)) + .duration(64) + .EUt(98304) + .EUToStart(500_000_000) + .buildAndRegister(); + + RecipeMaps.FUSION_RECIPES.recipeBuilder() + .fluidInputs(Materials.Silver.getFluid(144)) + .fluidInputs(Materials.Helium3.getFluid(375)) + .fluidOutputs(Materials.Tin.getPlasma(144)) + .duration(16) + .EUt(49152) + .EUToStart(280_000_000) + .buildAndRegister(); + RecipeMaps.FUSION_RECIPES.recipeBuilder() .fluidInputs(Materials.Neodymium.getFluid(16)) .fluidInputs(Materials.Hydrogen.getFluid(375)) @@ -72,9 +90,9 @@ public static void init() { .buildAndRegister(); RecipeMaps.FUSION_RECIPES.recipeBuilder() - .fluidInputs(Materials.Lutetium.getFluid(32)) - .fluidInputs(Materials.Chrome.getFluid(32)) - .fluidOutputs(Materials.Americium.getFluid(32)) + .fluidInputs(Materials.Lutetium.getFluid(16)) + .fluidInputs(Materials.Chrome.getFluid(16)) + .fluidOutputs(Materials.Americium.getFluid(16)) .duration(64) .EUt(49152) .EUToStart(200_000_000) @@ -147,16 +165,16 @@ public static void init() { .fluidInputs(Materials.Gallium.getFluid(16)) .fluidInputs(Materials.Radon.getFluid(125)) .fluidOutputs(Materials.Duranium.getFluid(16)) - .duration(64) + .duration(32) .EUt(16384) .EUToStart(140_000_000) .buildAndRegister(); RecipeMaps.FUSION_RECIPES.recipeBuilder() - .fluidInputs(Materials.Titanium.getFluid(32)) + .fluidInputs(Materials.Titanium.getFluid(48)) .fluidInputs(Materials.Duranium.getFluid(32)) .fluidOutputs(Materials.Tritanium.getFluid(16)) - .duration(64) + .duration(16) .EUt(VA[LuV]) .EUToStart(200_000_000) .buildAndRegister(); From d17b3392b5f679cd14886f0c79819b5d6d09ceef Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 17 Dec 2023 03:07:07 -0600 Subject: [PATCH 12/98] Fix plasma temp NPE for plasma-only materials (#2306) --- .../java/gregtech/api/fluids/FluidBuilder.java | 2 +- .../gregtech/api/fluids/store/FluidStorage.java | 15 +++++++++------ .../api/fluids/store/FluidStorageKey.java | 17 +++++++++++++++++ .../api/fluids/store/FluidStorageKeys.java | 2 +- .../loaders/recipe/RecyclingRecipes.java | 10 +++++++--- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/fluids/FluidBuilder.java b/src/main/java/gregtech/api/fluids/FluidBuilder.java index 757369b75ae..f7a75111cc4 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -428,7 +428,7 @@ private void determineTemperature(@Nullable Material material) { } case GAS -> ROOM_TEMPERATURE; case PLASMA -> { - if (material.hasFluid()) { + if (material.hasFluid() && material.getFluid() != null) { yield BASE_PLASMA_TEMPERATURE + material.getFluid().getTemperature(); } yield BASE_PLASMA_TEMPERATURE; diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorage.java b/src/main/java/gregtech/api/fluids/store/FluidStorage.java index f9a232b0d27..fe7505423d0 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorage.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorage.java @@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Comparator; import java.util.Map; public final class FluidStorage { @@ -69,12 +70,14 @@ public void registerFluids(@NotNull Material material) { enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); } - for (var entry : toRegister.entrySet()) { - Fluid fluid = entry.getValue().build(material.getModid(), material, entry.getKey()); - if (!storeNoOverwrites(entry.getKey(), fluid)) { - GTLog.logger.error("{} already has an associated fluid for material {}", material); - } - } + toRegister.entrySet().stream() + .sorted(Comparator.comparingInt(e -> -e.getKey().getRegistrationPriority())) + .forEach(entry -> { + Fluid fluid = entry.getValue().build(material.getModid(), material, entry.getKey()); + if (!storeNoOverwrites(entry.getKey(), fluid)) { + GTLog.logger.error("{} already has an associated fluid for material {}", material); + } + }); toRegister = null; registered = true; } diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java b/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java index 01f44dcc8da..7b58514aa35 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java @@ -24,6 +24,7 @@ public final class FluidStorageKey { private final Function translationKeyFunction; private final int hashCode; private final FluidState defaultFluidState; + private final int registrationPriority; public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, @NotNull UnaryOperator<@NotNull String> registryNameOperator, @@ -35,12 +36,20 @@ public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull Mate @NotNull UnaryOperator<@NotNull String> registryNameOperator, @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction, @Nullable FluidState defaultFluidState) { + this(resourceLocation, iconType, registryNameOperator, translationKeyFunction, defaultFluidState, 0); + } + + public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, + @NotNull UnaryOperator<@NotNull String> registryNameOperator, + @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction, + @Nullable FluidState defaultFluidState, int registrationPriority) { this.resourceLocation = resourceLocation; this.iconType = iconType; this.registryNameOperator = registryNameOperator; this.translationKeyFunction = translationKeyFunction; this.hashCode = resourceLocation.hashCode(); this.defaultFluidState = defaultFluidState; + this.registrationPriority = registrationPriority; if (keys.containsKey(resourceLocation)) { throw new IllegalArgumentException("Cannot create duplicate keys"); } @@ -81,6 +90,14 @@ public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull Mate return defaultFluidState; } + /** + * @return The registration priority for this fluid type, determining the build order for fluids. + * Useful for when your fluid building requires some properties from previous fluids. + */ + public int getRegistrationPriority() { + return registrationPriority; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java b/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java index 10407e03b03..3b9a6be51e8 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java @@ -33,7 +33,7 @@ public final class FluidStorageKeys { public static final FluidStorageKey PLASMA = new FluidStorageKey(gregtechId("plasma"), MaterialIconType.plasma, s -> "plasma." + s, m -> "gregtech.fluid.plasma", - FluidState.PLASMA); + FluidState.PLASMA, -1); private FluidStorageKeys() {} } diff --git a/src/main/java/gregtech/loaders/recipe/RecyclingRecipes.java b/src/main/java/gregtech/loaders/recipe/RecyclingRecipes.java index e4cbbab3310..ba4223d289f 100644 --- a/src/main/java/gregtech/loaders/recipe/RecyclingRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/RecyclingRecipes.java @@ -140,7 +140,10 @@ private static void registerExtractorRecycling(ItemStack input, List ms.material.hasProperty(PropertyKey.FLUID)).findFirst() - .orElse(null); + MaterialStack fluidMs = materials.stream() + .filter(ms -> ms.material.hasProperty(PropertyKey.FLUID) && ms.material.getFluid() != null) + .findFirst().orElse(null); if (fluidMs == null) return; // Find the next MaterialStack, which will be the Item output. From 510be94e3b0590ba73b2c56b13c30d5c7b6ed08b Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 17 Dec 2023 13:50:57 -0600 Subject: [PATCH 13/98] Port to MUI 2.4 (#2281) --- dependencies.gradle | 6 +- .../java/gregtech/api/cover/CoverWithUI.java | 14 +- .../gregtech/api/items/gui/ItemUIFactory.java | 9 +- .../api/metatileentity/MetaTileEntity.java | 13 +- .../java/gregtech/api/mui/GTGuiTextures.java | 30 ++-- .../java/gregtech/api/mui/GTGuiTheme.java | 72 ++++++--- src/main/java/gregtech/api/mui/GTGuis.java | 139 ++++++------------ .../api/mui/factory/CoverGuiFactory.java | 79 ++++++++++ .../api/mui/factory/MetaItemGuiFactory.java | 56 +++++++ .../mui/factory/MetaTileEntityGuiFactory.java | 63 ++++++++ .../mui/widget/GhostCircuitSlotWidget.java | 3 +- .../gregtech/common/covers/CoverStorage.java | 5 +- .../items/behaviors/IntCircuitBehaviour.java | 17 ++- .../multiblockpart/MetaTileEntityItemBus.java | 49 +++--- .../MetaTileEntitySteamItemBus.java | 5 +- .../storage/MetaTileEntityCrate.java | 5 +- src/main/java/gregtech/core/CoreModule.java | 2 + .../resources/assets/gregtech/lang/en_us.lang | 2 +- .../textures/gui/base/background_popup.png | Bin 0 -> 536 bytes 19 files changed, 373 insertions(+), 196 deletions(-) create mode 100644 src/main/java/gregtech/api/mui/factory/CoverGuiFactory.java create mode 100644 src/main/java/gregtech/api/mui/factory/MetaItemGuiFactory.java create mode 100644 src/main/java/gregtech/api/mui/factory/MetaTileEntityGuiFactory.java create mode 100644 src/main/resources/assets/gregtech/textures/gui/base/background_popup.png diff --git a/dependencies.gradle b/dependencies.gradle index db9bf2304c2..82ef07ce6a8 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -25,16 +25,14 @@ dependencies { // the CCL deobf jar uses very old MCP mappings, making it error at runtime in runClient/runServer // therefore we manually deobf the regular jar implementation rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848") // CCL 3.2.3.358 - implementation "curse.maven:modularui-624243:4856895-deobf-4856896-sources-4856897" // MUI 2.3.1 + implementation("com.cleanroommc:modularui:2.4.1") { transitive = false } // Soft Dependencies // Can change any of these from compileOnlyApi -> implementation to test them in-game. implementation "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684" implementation rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - implementation ("com.cleanroommc:groovyscript:0.7.1") { - transitive = false - } + implementation("com.cleanroommc:groovyscript:0.7.1") { transitive = false } implementation rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 compileOnlyApi rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 diff --git a/src/main/java/gregtech/api/cover/CoverWithUI.java b/src/main/java/gregtech/api/cover/CoverWithUI.java index a504a7484d0..10ab6f243dd 100644 --- a/src/main/java/gregtech/api/cover/CoverWithUI.java +++ b/src/main/java/gregtech/api/cover/CoverWithUI.java @@ -3,8 +3,8 @@ import gregtech.api.gui.IUIHolder; import gregtech.api.gui.ModularUI; import gregtech.api.mui.GTGuiTheme; -import gregtech.api.mui.GTGuis; import gregtech.api.mui.GregTechGuiScreen; +import gregtech.api.mui.factory.CoverGuiFactory; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -12,13 +12,13 @@ import net.minecraftforge.fml.relauncher.SideOnly; import com.cleanroommc.modularui.api.IGuiHolder; -import com.cleanroommc.modularui.manager.GuiCreationContext; +import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import org.jetbrains.annotations.ApiStatus; -public interface CoverWithUI extends Cover, IUIHolder, IGuiHolder { +public interface CoverWithUI extends Cover, IUIHolder, IGuiHolder { @ApiStatus.Experimental default boolean usesMui2() { @@ -27,8 +27,7 @@ default boolean usesMui2() { default void openUI(EntityPlayerMP player) { if (usesMui2()) { - GTGuis.getCoverUiInfo(getAttachedSide()) - .open(player, getCoverableView().getWorld(), getCoverableView().getPos()); + CoverGuiFactory.open(player, this); } else { CoverUIFactory.INSTANCE.openUI(this, player); } @@ -42,7 +41,7 @@ default ModularUI createUI(EntityPlayer player) { @ApiStatus.NonExtendable @SideOnly(Side.CLIENT) @Override - default ModularScreen createScreen(GuiCreationContext creationContext, ModularPanel mainPanel) { + default ModularScreen createScreen(SidedPosGuiData guiData, ModularPanel mainPanel) { return new GregTechGuiScreen(mainPanel, getUITheme()); } @@ -51,8 +50,7 @@ default GTGuiTheme getUITheme() { } @Override - default ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, - boolean isClient) { + default ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { return null; } diff --git a/src/main/java/gregtech/api/items/gui/ItemUIFactory.java b/src/main/java/gregtech/api/items/gui/ItemUIFactory.java index 998bca5dec7..abff0448370 100644 --- a/src/main/java/gregtech/api/items/gui/ItemUIFactory.java +++ b/src/main/java/gregtech/api/items/gui/ItemUIFactory.java @@ -10,13 +10,13 @@ import net.minecraftforge.fml.relauncher.SideOnly; import com.cleanroommc.modularui.api.IGuiHolder; -import com.cleanroommc.modularui.manager.GuiCreationContext; +import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import org.jetbrains.annotations.ApiStatus; -public interface ItemUIFactory extends IItemComponent, IGuiHolder { +public interface ItemUIFactory extends IItemComponent, IGuiHolder { /** * Creates new UI basing on given holder. Holder contains information @@ -30,7 +30,7 @@ default ModularUI createUI(PlayerInventoryHolder holder, EntityPlayer entityPlay @ApiStatus.NonExtendable @SideOnly(Side.CLIENT) @Override - default ModularScreen createScreen(GuiCreationContext creationContext, ModularPanel mainPanel) { + default ModularScreen createScreen(HandGuiData creationContext, ModularPanel mainPanel) { return new GregTechGuiScreen(mainPanel, getUITheme()); } @@ -39,8 +39,7 @@ default GTGuiTheme getUITheme() { } @Override - default ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, - boolean isClient) { + default ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager) { return null; } } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index aa223d66de7..659460902b0 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -16,8 +16,8 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.interfaces.ISyncedTileEntity; import gregtech.api.mui.GTGuiTheme; -import gregtech.api.mui.GTGuis; import gregtech.api.mui.GregTechGuiScreen; +import gregtech.api.mui.factory.MetaTileEntityGuiFactory; import gregtech.api.recipes.RecipeMap; import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; @@ -70,7 +70,7 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.IGuiHolder; -import com.cleanroommc.modularui.manager.GuiCreationContext; +import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; import com.cleanroommc.modularui.value.sync.GuiSyncManager; @@ -90,7 +90,7 @@ import static gregtech.api.capability.GregtechDataCodes.*; -public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, IVoidable, IGuiHolder { +public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, IVoidable, IGuiHolder { public static final IndexedCuboid6 FULL_CUBE_COLLISION = new IndexedCuboid6(null, Cuboid6.full); @@ -437,7 +437,7 @@ public boolean usesMui2() { @SideOnly(Side.CLIENT) @Override - public final ModularScreen createScreen(GuiCreationContext creationContext, ModularPanel mainPanel) { + public final ModularScreen createScreen(PosGuiData posGuiData, ModularPanel mainPanel) { return new GregTechGuiScreen(mainPanel, getUITheme()); } @@ -446,8 +446,7 @@ public GTGuiTheme getUITheme() { } @Override - public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, - boolean isClient) { + public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { return null; } @@ -469,7 +468,7 @@ public boolean onRightClick(EntityPlayer playerIn, EnumHand hand, EnumFacing fac if (!playerIn.isSneaking() && openGUIOnRightClick()) { if (getWorld() != null && !getWorld().isRemote) { if (usesMui2()) { - GTGuis.MTE.open(playerIn, getWorld(), getPos()); + MetaTileEntityGuiFactory.open(playerIn, this); } else { MetaTileEntityUIFactory.INSTANCE.openUI(getHolder(), (EntityPlayerMP) playerIn); } diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index 434c90e9ce3..d632bf3f8e6 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -52,7 +52,15 @@ public static class IDs { .location(GTValues.MODID, "textures/gui/base/background.png") .imageSize(176, 166) .adaptable(3) - .registerAsBackground(IDs.STANDARD_BACKGROUND, true) + .name(IDs.STANDARD_BACKGROUND) + .canApplyTheme() + .build(); + + public static final UITexture BACKGROUND_POPUP = UITexture.builder() + .location(GTValues.MODID, "textures/gui/base/background_popup.png") + .imageSize(195, 136) + .adaptable(4) + .canApplyTheme() .build(); // todo BORDERED/BOXED backgrounds will not be ported, if possible @@ -61,14 +69,14 @@ public static class IDs { .location(GTValues.MODID, "textures/gui/base/background_bronze.png") .imageSize(176, 166) .adaptable(3) - .registerAsBackground(IDs.BRONZE_BACKGROUND) + .name(IDs.BRONZE_BACKGROUND) .build(); public static final UITexture BACKGROUND_STEEL = UITexture.builder() .location(GTValues.MODID, "textures/gui/base/background_steel.png") .imageSize(176, 166) .adaptable(3) - .registerAsBackground(IDs.STEEL_BACKGROUND) + .name(IDs.STEEL_BACKGROUND) .build(); // todo move to textures/gui/base @@ -76,7 +84,7 @@ public static class IDs { .location(GTValues.MODID, "textures/gui/primitive/primitive_background.png") .imageSize(176, 166) .adaptable(3) - .registerAsBackground(IDs.PRIMITIVE_BACKGROUND) + .name(IDs.PRIMITIVE_BACKGROUND) .build(); // todo clipboard backgrounds, may deserve some redoing @@ -108,21 +116,22 @@ public static class IDs { .location(GTValues.MODID, "textures/gui/base/slot.png") .imageSize(18, 18) .adaptable(1) - .registerAsBackground(IDs.STANDARD_SLOT, true) + .name(IDs.STANDARD_SLOT) + .canApplyTheme() .build(); public static final UITexture SLOT_BRONZE = new UITexture.Builder() .location(GTValues.MODID, "textures/gui/base/slot_bronze.png") .imageSize(18, 18) .adaptable(1) - .registerAsBackground(IDs.BRONZE_SLOT) + .name(IDs.BRONZE_SLOT) .build(); public static final UITexture SLOT_STEEL = new UITexture.Builder() .location(GTValues.MODID, "textures/gui/base/slot_steel.png") .imageSize(18, 18) .adaptable(1) - .registerAsBackground(IDs.STEEL_SLOT) + .name(IDs.STEEL_SLOT) .build(); // todo move to textures/gui/base @@ -130,14 +139,15 @@ public static class IDs { .location(GTValues.MODID, "textures/gui/primitive/primitive_slot.png") .imageSize(18, 18) .adaptable(1) - .registerAsBackground(IDs.PRIMITIVE_SLOT) + .name(IDs.PRIMITIVE_SLOT) .build(); public static final UITexture FLUID_SLOT = new UITexture.Builder() .location(GTValues.MODID, "textures/gui/base/fluid_slot.png") .imageSize(18, 18) .adaptable(1) - .registerAsBackground(IDs.STANDARD_FLUID_SLOT, true) + .name(IDs.STANDARD_FLUID_SLOT) + .canApplyTheme() .build(); // todo bronze/steel/primitive fluid slots? @@ -253,7 +263,7 @@ public static class IDs { .location(GTValues.MODID, "textures/gui/widget/button.png") .imageSize(18, 18) .adaptable(1) - .registerAsIcon(IDs.STANDARD_BUTTON) + .name(IDs.STANDARD_BUTTON) .canApplyTheme() .build(); diff --git a/src/main/java/gregtech/api/mui/GTGuiTheme.java b/src/main/java/gregtech/api/mui/GTGuiTheme.java index c23754eea94..eb1c301aca2 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTheme.java +++ b/src/main/java/gregtech/api/mui/GTGuiTheme.java @@ -6,6 +6,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import com.cleanroommc.modularui.api.IThemeApi; +import com.cleanroommc.modularui.screen.Tooltip; import com.cleanroommc.modularui.theme.ReloadThemeEvent; import com.cleanroommc.modularui.utils.JsonBuilder; @@ -17,27 +18,30 @@ public class GTGuiTheme { private static final List THEMES = new ArrayList<>(); - public static final GTGuiTheme STANDARD = new Builder("gregtech_standard") + public static final GTGuiTheme STANDARD = templateBuilder("gregtech_standard") .panel(GTGuiTextures.IDs.STANDARD_BACKGROUND) .itemSlot(GTGuiTextures.IDs.STANDARD_SLOT) .fluidSlot(GTGuiTextures.IDs.STANDARD_FLUID_SLOT) .color(ConfigHolder.client.defaultUIColor) + .button(GTGuiTextures.IDs.STANDARD_BUTTON) .toggleButton(GTGuiTextures.IDs.STANDARD_BUTTON, GTGuiTextures.IDs.STANDARD_SLOT, ConfigHolder.client.defaultUIColor) .build(); - public static final GTGuiTheme BRONZE = new Builder("gregtech_bronze") + // TODO Cover theme to utilize the GT5u-like button textures vs the standard ones + + public static final GTGuiTheme BRONZE = templateBuilder("gregtech_bronze") .panel(GTGuiTextures.IDs.BRONZE_BACKGROUND) .itemSlot(GTGuiTextures.IDs.BRONZE_SLOT) .build(); - public static final GTGuiTheme STEEL = new Builder("gregtech_steel") + public static final GTGuiTheme STEEL = templateBuilder("gregtech_steel") .panel(GTGuiTextures.IDs.STEEL_BACKGROUND) .itemSlot(GTGuiTextures.IDs.STEEL_SLOT) .build(); - public static final GTGuiTheme PRIMITIVE = new Builder("gregtech_primitive") + public static final GTGuiTheme PRIMITIVE = templateBuilder("gregtech_primitive") .panel(GTGuiTextures.IDs.PRIMITIVE_BACKGROUND) .itemSlot(GTGuiTextures.IDs.PRIMITIVE_SLOT) .build(); @@ -77,6 +81,14 @@ public static void onReloadThemes(ReloadThemeEvent.Pre event) { THEMES.forEach(GTGuiTheme::buildJson); } + public static Builder templateBuilder(String themeId) { + Builder builder = new Builder(themeId); + builder.openCloseAnimation(0); + builder.tooltipPos(Tooltip.Pos.NEXT_TO_MOUSE); + builder.smoothProgressBar(true); + return builder; + } + public static class Builder { private final GTGuiTheme theme; @@ -110,6 +122,28 @@ public Builder globalHoverBackground(String hoverBackgroundId) { return this; } + /** + * Set the window open/close animation speed. Overrides global cfg. + * + * @param rate the rate in frames to play the open/close animation over, or 0 for no animation + */ + public Builder openCloseAnimation(int rate) { + theme.elementBuilder.add(b -> b.add("openCloseAnimation", rate)); + return this; + } + + /** Set whether progress bars should animate smoothly. Overrides global cfg. */ + public Builder smoothProgressBar(boolean smoothBar) { + theme.elementBuilder.add(b -> b.add("smoothProgressBar", smoothBar)); + return this; + } + + /** Set the tooltip pos for this theme. Overrides global cfg. */ + public Builder tooltipPos(Tooltip.Pos tooltipPos) { + theme.elementBuilder.add(b -> b.add("tooltipPos", tooltipPos.name())); + return this; + } + /** Set a global UI coloration for this theme. */ public Builder color(int color) { theme.elementBuilder.add(b -> b.add("color", color)); @@ -130,8 +164,6 @@ public Builder textShadow() { /** * Set a custom panel (background texture) for UIs with this theme. - * This ID must correspond with a {@link com.cleanroommc.modularui.drawable.UITexture} that is - * registered using {@link com.cleanroommc.modularui.drawable.GuiTextures#registerBackground}! */ public Builder panel(String panelId) { theme.elementBuilder.add(b -> b @@ -144,28 +176,36 @@ public Builder panel(String panelId) { /** * Set a custom button texture for UIs with this theme. - * This ID must correspond with a {@link com.cleanroommc.modularui.drawable.UITexture} that is - * registered using {@link com.cleanroommc.modularui.drawable.GuiTextures#registerIcon}! */ public Builder button(String buttonId) { - return button(buttonId, 0xFFFFFFFF, false); + return button(buttonId, buttonId, 0xFFFFFFFF, false); + } + + /** + * Set a custom button texture for UIs with this theme. + * + * @param buttonId The ID of the button texture + * @param hoverId The ID of the button texture while hovering over the button with your mouse + */ + public Builder button(String buttonId, String hoverId) { + return button(buttonId, hoverId, 0xFFFFFFFF, false); } /** * Set a custom button texture for UIs with this theme. - * This ID must correspond with a {@link com.cleanroommc.modularui.drawable.UITexture} that is - * registered using {@link com.cleanroommc.modularui.drawable.GuiTextures#registerIcon}! * * @param buttonId The ID of the button texture + * @param hoverId The ID of the button texture while hovering over the button with your mouse * @param textColor The color of text overlaid on this button * @param textShadow If text overlaid on this button should have a text shadow */ - public Builder button(String buttonId, int textColor, boolean textShadow) { + public Builder button(String buttonId, String hoverId, int textColor, boolean textShadow) { theme.elementBuilder.add(b -> b .add("button", new JsonBuilder() .add("background", new JsonBuilder() .add("type", "texture") .add("id", buttonId)) + .add("hoverBackground", hoverId) .add("textColor", textColor) .add("textShadow", textShadow))); return this; @@ -173,8 +213,6 @@ public Builder button(String buttonId, int textColor, boolean textShadow) { /** * Set a custom item slot texture for UIs with this theme. - * This ID must correspond with a {@link com.cleanroommc.modularui.drawable.UITexture} that is - * registered using {@link com.cleanroommc.modularui.drawable.GuiTextures#registerIcon}! */ public Builder itemSlot(String itemSlotId) { return itemSlot(itemSlotId, 0x60FFFFFF); @@ -182,8 +220,6 @@ public Builder itemSlot(String itemSlotId) { /** * Set a custom item slot texture for UIs with this theme. - * This ID must correspond with a {@link com.cleanroommc.modularui.drawable.UITexture} that is - * registered using {@link com.cleanroommc.modularui.drawable.GuiTextures#registerIcon}! * * @param itemSlotId The ID of the item slot texture * @param hoverColor The color of the tooltip hover box for this widget @@ -200,8 +236,6 @@ public Builder itemSlot(String itemSlotId, int hoverColor) { /** * Set a custom fluid slot texture for UIs with this theme. - * This ID must correspond with a {@link com.cleanroommc.modularui.drawable.UITexture} that is - * registered using {@link com.cleanroommc.modularui.drawable.GuiTextures#registerIcon}! */ public Builder fluidSlot(String fluidSlotId) { return fluidSlot(fluidSlotId, 0x60FFFFFF); @@ -209,8 +243,6 @@ public Builder fluidSlot(String fluidSlotId) { /** * Set a custom fluid slot texture for UIs with this theme. - * This ID must correspond with a {@link com.cleanroommc.modularui.drawable.UITexture} that is - * registered using {@link com.cleanroommc.modularui.drawable.GuiTextures#registerIcon}! * * @param fluidSlotId The ID of the fluid slot texture * @param hoverColor The color of the tooltip hover box for this widget diff --git a/src/main/java/gregtech/api/mui/GTGuis.java b/src/main/java/gregtech/api/mui/GTGuis.java index 35893a3908e..d60b66088c7 100644 --- a/src/main/java/gregtech/api/mui/GTGuis.java +++ b/src/main/java/gregtech/api/mui/GTGuis.java @@ -1,77 +1,28 @@ package gregtech.api.mui; -import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.cover.Cover; -import gregtech.api.cover.CoverHolder; -import gregtech.api.cover.CoverWithUI; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.util.GTUtility; +import gregtech.api.mui.factory.CoverGuiFactory; +import gregtech.api.mui.factory.MetaItemGuiFactory; +import gregtech.api.mui.factory.MetaTileEntityGuiFactory; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import com.cleanroommc.modularui.api.IGuiHolder; -import com.cleanroommc.modularui.manager.GuiInfo; +import com.cleanroommc.modularui.factory.GuiManager; import com.cleanroommc.modularui.screen.ModularPanel; - -import java.util.EnumMap; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; public class GTGuis { - private static final EnumMap COVERS = new EnumMap<>(EnumFacing.class); - - public static final GuiInfo MTE = GuiInfo.builder() - .clientGui((context, mainPanel) -> { - MetaTileEntity mte = GTUtility.getMetaTileEntity(context.getWorld(), context.getBlockPos()); - if (mte != null) { - return mte.createScreen(context, mainPanel); - } - throw new UnsupportedOperationException(); - }) - .commonGui((context, syncHandler) -> { - MetaTileEntity mte = GTUtility.getMetaTileEntity(context.getWorld(), context.getBlockPos()); - if (mte != null) { - return mte.buildUI(context, syncHandler, context.getWorld().isRemote); - } - throw new UnsupportedOperationException(); - }) - .build(); - - public static final GuiInfo PLAYER_META_ITEM_MAIN_HAND = GuiInfo.builder() - .clientGui((context, mainPanel) -> { - ItemStack itemStack = context.getMainHandItem(); - return getGuiHolder(itemStack).createScreen(context.with(EnumHand.MAIN_HAND), mainPanel); - - }) - .commonGui((context, guiSyncHandler) -> { - ItemStack itemStack = context.getMainHandItem(); - return getGuiHolder(itemStack).buildUI(context.with(EnumHand.MAIN_HAND), guiSyncHandler, - context.getWorld().isRemote); - }) - .build(); - - public static final GuiInfo PLAYER_META_ITEM_OFF_HAND = GuiInfo.builder() - .clientGui((context, mainPanel) -> { - ItemStack itemStack = context.getOffHandItem(); - return getGuiHolder(itemStack).createScreen(context.with(EnumHand.OFF_HAND), mainPanel); - - }) - .commonGui((context, guiSyncHandler) -> { - ItemStack itemStack = context.getOffHandItem(); - return getGuiHolder(itemStack).buildUI(context.with(EnumHand.OFF_HAND), guiSyncHandler, - context.getWorld().isRemote); - }) - .build(); - - public static GuiInfo getMetaItemUiInfo(EnumHand hand) { - return hand == EnumHand.MAIN_HAND ? PLAYER_META_ITEM_MAIN_HAND : PLAYER_META_ITEM_OFF_HAND; - } - - public static GuiInfo getCoverUiInfo(EnumFacing facing) { - return COVERS.get(facing); + @ApiStatus.Internal + public static void registerFactories() { + GuiManager.registerFactory(MetaTileEntityGuiFactory.INSTANCE); + GuiManager.registerFactory(MetaItemGuiFactory.INSTANCE); + GuiManager.registerFactory(CoverGuiFactory.INSTANCE); } public static ModularPanel createPanel(String name, int width, int height) { @@ -92,44 +43,40 @@ public static ModularPanel createPanel(ItemStack stack, int width, int height) { return createPanel(valueItem.unlocalizedName, width, height); } - static { - for (EnumFacing facing : EnumFacing.values()) { - COVERS.put(facing, makeCoverUiInfo(facing)); - } + public static ModularPanel createPopupPanel(String name, int width, int height) { + return createPopupPanel(name, width, height, false, false); } - private static GuiInfo makeCoverUiInfo(EnumFacing facing) { - return GuiInfo.builder() - .clientGui((context, mainPanel) -> { - TileEntity te = context.getTileEntity(); - if (te == null) throw new IllegalStateException(); - CoverHolder coverHolder = te.getCapability(GregtechTileCapabilities.CAPABILITY_COVER_HOLDER, - facing); - if (coverHolder == null) throw new IllegalStateException(); - Cover cover = coverHolder.getCoverAtSide(facing); - if (!(cover instanceof CoverWithUI)) throw new IllegalStateException(); - return ((CoverWithUI) cover).createScreen(context, mainPanel); - }) - .commonGui((context, syncHandler) -> { - TileEntity te = context.getTileEntity(); - if (te == null) throw new IllegalStateException(); - CoverHolder coverHolder = te.getCapability(GregtechTileCapabilities.CAPABILITY_COVER_HOLDER, - facing); - if (coverHolder == null) throw new IllegalStateException(); - Cover cover = coverHolder.getCoverAtSide(facing); - if (!(cover instanceof CoverWithUI)) throw new IllegalStateException(); - return ((CoverWithUI) cover).buildUI(context, syncHandler, context.getWorld().isRemote); - }) - .build(); + public static ModularPanel createPopupPanel(String name, int width, int height, boolean disableBelow, + boolean closeOnOutsideClick) { + return new PopupPanel(name, width, height, disableBelow, closeOnOutsideClick); } - private static IGuiHolder getGuiHolder(ItemStack stack) { - if (stack.getItem() instanceof MetaItem) { - MetaItem.MetaValueItem valueItem = ((MetaItem) stack.getItem()).getItem(stack); - if (valueItem != null && valueItem.getUIManager() != null) { - return valueItem.getUIManager(); - } + private static class PopupPanel extends ModularPanel { + + private final boolean disableBelow; + private final boolean closeOnOutsideClick; + + public PopupPanel(@NotNull String name, int width, int height, boolean disableBelow, + boolean closeOnOutsideClick) { + super(name); + flex().startDefaultMode(); + flex().size(width, height).align(Alignment.Center); + flex().endDefaultMode(); + background(GTGuiTextures.BACKGROUND_POPUP); + child(ButtonWidget.panelCloseButton().top(5).right(5)); + this.disableBelow = disableBelow; + this.closeOnOutsideClick = closeOnOutsideClick; + } + + @Override + public boolean disablePanelsBelow() { + return disableBelow; + } + + @Override + public boolean closeOnOutOfBoundsClick() { + return closeOnOutsideClick; } - throw new IllegalStateException(); } } diff --git a/src/main/java/gregtech/api/mui/factory/CoverGuiFactory.java b/src/main/java/gregtech/api/mui/factory/CoverGuiFactory.java new file mode 100644 index 00000000000..918aad93833 --- /dev/null +++ b/src/main/java/gregtech/api/mui/factory/CoverGuiFactory.java @@ -0,0 +1,79 @@ +package gregtech.api.mui.factory; + +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.cover.Cover; +import gregtech.api.cover.CoverHolder; +import gregtech.api.cover.CoverWithUI; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; + +import com.cleanroommc.modularui.api.IGuiHolder; +import com.cleanroommc.modularui.factory.AbstractUIFactory; +import com.cleanroommc.modularui.factory.GuiManager; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class CoverGuiFactory extends AbstractUIFactory { + + public static final CoverGuiFactory INSTANCE = new CoverGuiFactory(); + + private CoverGuiFactory() { + super("gregtech:cover"); + } + + public static > void open(EntityPlayer player, T cover) { + Objects.requireNonNull(player); + Objects.requireNonNull(cover); + if (!cover.getCoverableView().isValid()) { + throw new IllegalArgumentException("Can't open Cover GUI on invalid cover holder!"); + } + if (player.world != cover.getWorld()) { + throw new IllegalArgumentException("Cover must be in same dimension as the player!"); + } + BlockPos pos = cover.getPos(); + SidedPosGuiData data = new SidedPosGuiData(player, pos.getX(), pos.getY(), pos.getZ(), cover.getAttachedSide()); + GuiManager.open(INSTANCE, data, (EntityPlayerMP) player); + } + + @Override + public @NotNull IGuiHolder getGuiHolder(SidedPosGuiData data) { + TileEntity te = data.getTileEntity(); + if (te == null) { + throw new IllegalStateException("Could not get gui for null TileEntity!"); + } + CoverHolder coverHolder = te.getCapability(GregtechTileCapabilities.CAPABILITY_COVER_HOLDER, data.getSide()); + if (coverHolder == null) { + throw new IllegalStateException("Could not get CoverHolder for found TileEntity!"); + } + Cover cover = coverHolder.getCoverAtSide(data.getSide()); + if (cover == null) { + throw new IllegalStateException("Could not find cover at side " + data.getSide() + + " for found CoverHolder!"); + } + if (!(cover instanceof CoverWithUI coverWithUI)) { + throw new IllegalStateException("Cover at side " + data.getSide() + " is not a gui holder!"); + } + return coverWithUI; + } + + @Override + public void writeGuiData(SidedPosGuiData guiData, PacketBuffer buffer) { + buffer.writeVarInt(guiData.getX()); + buffer.writeVarInt(guiData.getY()); + buffer.writeVarInt(guiData.getZ()); + buffer.writeByte(guiData.getSide().getIndex()); + } + + @Override + public @NotNull SidedPosGuiData readGuiData(EntityPlayer player, PacketBuffer buffer) { + return new SidedPosGuiData(player, buffer.readVarInt(), buffer.readVarInt(), buffer.readVarInt(), + EnumFacing.VALUES[buffer.readByte()]); + } +} diff --git a/src/main/java/gregtech/api/mui/factory/MetaItemGuiFactory.java b/src/main/java/gregtech/api/mui/factory/MetaItemGuiFactory.java new file mode 100644 index 00000000000..7fea957a5a1 --- /dev/null +++ b/src/main/java/gregtech/api/mui/factory/MetaItemGuiFactory.java @@ -0,0 +1,56 @@ +package gregtech.api.mui.factory; + +import gregtech.api.items.metaitem.MetaItem; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumHand; + +import com.cleanroommc.modularui.api.IGuiHolder; +import com.cleanroommc.modularui.factory.AbstractUIFactory; +import com.cleanroommc.modularui.factory.GuiManager; +import com.cleanroommc.modularui.factory.HandGuiData; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class MetaItemGuiFactory extends AbstractUIFactory { + + public static final MetaItemGuiFactory INSTANCE = new MetaItemGuiFactory(); + + private MetaItemGuiFactory() { + super("gregtech:meta_item"); + } + + public static void open(EntityPlayer player, EnumHand hand) { + Objects.requireNonNull(player); + Objects.requireNonNull(hand); + HandGuiData guiData = new HandGuiData(player, hand); + GuiManager.open(INSTANCE, guiData, (EntityPlayerMP) player); + } + + @Override + public @NotNull IGuiHolder getGuiHolder(HandGuiData data) { + ItemStack stack = data.getUsedItemStack(); + if (!(stack.getItem() instanceof MetaItemmetaItem)) { + throw new IllegalArgumentException("Found item is not a valid MetaItem!"); + } + MetaItem.MetaValueItem valueItem = metaItem.getItem(stack); + if (valueItem == null || valueItem.getUIManager() == null) { + throw new IllegalArgumentException("Found MetaItem is not a gui holder!"); + } + return valueItem.getUIManager(); + } + + @Override + public void writeGuiData(HandGuiData guiData, PacketBuffer buffer) { + buffer.writeByte(guiData.getHand().ordinal()); + } + + @Override + public @NotNull HandGuiData readGuiData(EntityPlayer player, PacketBuffer buffer) { + return new HandGuiData(player, EnumHand.values()[buffer.readByte()]); + } +} diff --git a/src/main/java/gregtech/api/mui/factory/MetaTileEntityGuiFactory.java b/src/main/java/gregtech/api/mui/factory/MetaTileEntityGuiFactory.java new file mode 100644 index 00000000000..0363476a987 --- /dev/null +++ b/src/main/java/gregtech/api/mui/factory/MetaTileEntityGuiFactory.java @@ -0,0 +1,63 @@ +package gregtech.api.mui.factory; + +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; + +import com.cleanroommc.modularui.api.IGuiHolder; +import com.cleanroommc.modularui.factory.AbstractUIFactory; +import com.cleanroommc.modularui.factory.GuiManager; +import com.cleanroommc.modularui.factory.PosGuiData; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class MetaTileEntityGuiFactory extends AbstractUIFactory { + + public static final MetaTileEntityGuiFactory INSTANCE = new MetaTileEntityGuiFactory(); + + private MetaTileEntityGuiFactory() { + super("gregtech:mte"); + } + + public static > void open(EntityPlayer player, T mte) { + Objects.requireNonNull(player); + Objects.requireNonNull(mte); + if (!mte.isValid()) { + throw new IllegalArgumentException("Can't open invalid MetaTileEntity GUI!"); + } + if (player.world != mte.getWorld()) { + throw new IllegalArgumentException("MetaTileEntity must be in same dimension as the player!"); + } + BlockPos pos = mte.getPos(); + PosGuiData data = new PosGuiData(player, pos.getX(), pos.getY(), pos.getZ()); + GuiManager.open(INSTANCE, data, (EntityPlayerMP) player); + } + + @Override + public @NotNull IGuiHolder getGuiHolder(PosGuiData data) { + TileEntity te = data.getTileEntity(); + if (te instanceof IGregTechTileEntity gtte) { + MetaTileEntity mte = gtte.getMetaTileEntity(); + return Objects.requireNonNull(castGuiHolder(mte), "Found MetaTileEntity is not a gui holder!"); + } + throw new IllegalStateException("Found TileEntity is not a MetaTileEntity!"); + } + + @Override + public void writeGuiData(PosGuiData guiData, PacketBuffer buffer) { + buffer.writeVarInt(guiData.getX()); + buffer.writeVarInt(guiData.getY()); + buffer.writeVarInt(guiData.getZ()); + } + + @Override + public @NotNull PosGuiData readGuiData(EntityPlayer player, PacketBuffer buffer) { + return new PosGuiData(player, buffer.readVarInt(), buffer.readVarInt(), buffer.readVarInt()); + } +} diff --git a/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java b/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java index bab12d1013b..bd848099117 100644 --- a/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java +++ b/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java @@ -114,6 +114,7 @@ private void createSelectorPanel() { .size(18) .background(GTGuiTextures.SLOT, new ItemDrawable( IntCircuitIngredient.getIntegratedCircuit(index)).asIcon()) + .disableHoverBackground() .onMousePressed(mouseButton -> { getSyncHandler().syncToServer(SYNC_CIRCUIT_INDEX, buf -> buf.writeShort(index)); circuitPreview.setItem(IntCircuitIngredient.getIntegratedCircuit(index)); @@ -122,7 +123,7 @@ private void createSelectorPanel() { } } - getPanel().getScreen().openPanel(GTGuis.createPanel("circuit_selector", 176, 120) + getPanel().getScreen().openPanel(GTGuis.createPopupPanel("circuit_selector", 176, 120) .child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) .child(circuitPreview.asIcon().size(16).asWidget() .size(18) diff --git a/src/main/java/gregtech/common/covers/CoverStorage.java b/src/main/java/gregtech/common/covers/CoverStorage.java index a91caa74cb2..a63fe3cbd56 100644 --- a/src/main/java/gregtech/common/covers/CoverStorage.java +++ b/src/main/java/gregtech/common/covers/CoverStorage.java @@ -24,7 +24,7 @@ import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.manager.GuiCreationContext; +import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; @@ -88,8 +88,7 @@ public boolean usesMui2() { } @Override - public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, - boolean isClient) { + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { guiSyncManager.registerSlotGroup("item_inv", this.storageHandler.getSlots()); int rowSize = this.storageHandler.getSlots(); diff --git a/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java b/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java index 82a492eaa7b..2be3dcbc766 100644 --- a/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java @@ -7,6 +7,7 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; +import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.util.GTUtility; @@ -21,7 +22,7 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.drawable.ItemDrawable; -import com.cleanroommc.modularui.manager.GuiCreationContext; +import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.InteractionSyncHandler; @@ -57,23 +58,22 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { ItemStack heldItem = player.getHeldItem(hand); if (!world.isRemote) { - GTGuis.getMetaItemUiInfo(hand).open(player); + MetaItemGuiFactory.open(player, hand); } return ActionResult.newResult(EnumActionResult.SUCCESS, heldItem); } @Override - public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, - boolean isClient) { - ItemDrawable circuitPreview = new ItemDrawable(guiCreationContext.getUsedItemStack()); + public ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager) { + ItemDrawable circuitPreview = new ItemDrawable(guiData.getUsedItemStack()); for (int i = 0; i <= 32; i++) { int finalI = i; guiSyncManager.syncValue("config", i, new InteractionSyncHandler() .setOnMousePressed(b -> { ItemStack item = IntCircuitIngredient.getIntegratedCircuit(finalI); - item.setCount(guiCreationContext.getUsedItemStack().getCount()); + item.setCount(guiData.getUsedItemStack().getCount()); circuitPreview.setItem(item); - guiCreationContext.getPlayer().setHeldItem(guiCreationContext.getUsedHand(), item); + guiData.getPlayer().setHeldItem(guiData.getHand(), item); })); } @@ -87,10 +87,11 @@ public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManage .size(18) .background(GTGuiTextures.SLOT, new ItemDrawable(IntCircuitIngredient.getIntegratedCircuit(index)).asIcon().size(16)) + .disableHoverBackground() .syncHandler("config", index)); } } - return GTGuis.createPanel(guiCreationContext.getUsedItemStack(), 176, 120) + return GTGuis.createPanel(guiData.getUsedItemStack(), 176, 120) .child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) .child(circuitPreview.asIcon().size(16).asWidget() .size(18) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java index 2b5ffaddc4d..ce42375b680 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -37,7 +37,7 @@ import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.manager.GuiCreationContext; +import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; @@ -265,8 +265,7 @@ public boolean usesMui2() { } @Override - public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, - boolean isClient) { + public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { int rowSize = (int) Math.sqrt(getInventorySize()); guiSyncManager.registerSlotGroup("item_inv", rowSize); @@ -294,28 +293,6 @@ public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManage boolean hasGhostCircuit = hasGhostCircuitInventory() && this.circuitInventory != null; - ToggleButton workingButton = new ToggleButton(); - workingButton.value( - new BoolValue.Dynamic(workingStateValue::getBoolValue, val -> { - workingStateValue.setBoolValue(val); - workingButton.markTooltipDirty(); - })) - .overlay(GTGuiTextures.BUTTON_ITEM_OUTPUT) - .tooltipBuilder(t -> t.addLine(workingStateValue.getBoolValue() ? - IKey.lang("gregtech.gui.item_auto_output.tooltip.enabled") : - IKey.lang("gregtech.gui.item_auto_output.tooltip.disabled"))); - - ToggleButton collapseButton = new ToggleButton(); - collapseButton.value( - new BoolValue.Dynamic(collapseStateValue::getBoolValue, val -> { - collapseStateValue.setBoolValue(val); - collapseButton.markTooltipDirty(); - })) - .overlay(GTGuiTextures.BUTTON_AUTO_COLLAPSE) - .tooltipBuilder(t -> t.addLine(collapseStateValue.getBoolValue() ? - IKey.lang("gregtech.gui.item_auto_collapse.tooltip.enabled") : - IKey.lang("gregtech.gui.item_auto_collapse.tooltip.disabled"))); - return GTGuis.createPanel(this, backgroundWidth, backgroundHeight) .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) @@ -329,8 +306,26 @@ public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManage .pos(backgroundWidth - 7 - 18, backgroundHeight - 18 * 4 - 7 - 5) .width(18).height(18 * 4 + 5) .child(GTGuiTextures.getLogo().asWidget().size(17).top(18 * 3 + 5)) - .child(workingButton.top(18 * 2)) - .child(collapseButton.top(18)) + .child(new ToggleButton() + .top(18 * 2) + .value(new BoolValue.Dynamic(workingStateValue::getBoolValue, + workingStateValue::setBoolValue)) + .overlay(GTGuiTextures.BUTTON_ITEM_OUTPUT) + .disableHoverBackground() + .tooltipBuilder(t -> t.setAutoUpdate(true) + .addLine(workingStateValue.getBoolValue() ? + IKey.lang("gregtech.gui.item_auto_output.tooltip.enabled") : + IKey.lang("gregtech.gui.item_auto_output.tooltip.disabled")))) + .child(new ToggleButton() + .top(18) + .value(new BoolValue.Dynamic(collapseStateValue::getBoolValue, + collapseStateValue::setBoolValue)) + .overlay(GTGuiTextures.BUTTON_AUTO_COLLAPSE) + .disableHoverBackground() + .tooltipBuilder(t -> t.setAutoUpdate(true) + .addLine(collapseStateValue.getBoolValue() ? + IKey.lang("gregtech.gui.item_auto_collapse.tooltip.enabled") : + IKey.lang("gregtech.gui.item_auto_collapse.tooltip.disabled")))) .childIf(hasGhostCircuit, new GhostCircuitSlotWidget() .slot(SyncHandlers.itemSlot(circuitInventory, 0)) .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) diff --git a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java index acc41bc21c1..97f855406e2 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java @@ -24,7 +24,7 @@ import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.manager.GuiCreationContext; +import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; @@ -86,8 +86,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } @Override - public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, - boolean isClient) { + public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { guiSyncManager.registerSlotGroup("item_inv", 2); List> widgets = new ArrayList<>(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java index a3680aadfd1..44859246953 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java @@ -33,7 +33,7 @@ import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.manager.GuiCreationContext; +import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; @@ -146,8 +146,7 @@ public boolean usesMui2() { } @Override - public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, - boolean isClient) { + public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { guiSyncManager.registerSlotGroup("item_inv", rowSize); int rows = inventorySize / rowSize; diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 56c1196049e..1d2dc88a4ec 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -15,6 +15,7 @@ import gregtech.api.modules.IGregTechModule; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuiTheme; +import gregtech.api.mui.GTGuis; import gregtech.api.recipes.ModHandler; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.recipeproperties.TemperatureProperty; @@ -131,6 +132,7 @@ public void preInit(FMLPreInitializationEvent event) { GTSoundEvents.register(); /* MUI Initialization */ + GTGuis.registerFactories(); GTGuiTextures.init(); GTGuiTheme.registerThemes(); diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 5ab44b85d32..b70165a7af4 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -531,7 +531,7 @@ metaitem.tool.datamodule.name=Data Module metaitem.tool.datamodule.tooltip=Storage for Incredibly Complex Data/n§cCan only be read by a Data Bank metaitem.circuit.integrated.name=Programmed Circuit metaitem.circuit.integrated.tooltip=Use to open configuration GUI/n/nShift-Right-Click on a machine/nwith a circuit slot to set it to/nthis circuit's value./n -metaitem.circuit.integrated.gui=Programmed Circuit Configuration +metaitem.circuit.integrated.gui=Circuit Configuration metaitem.circuit.integrated.jei_description=JEI is only showing recipes for the given configuration.\n\nYou can select a configuration in the Programmed Circuit configuration tab. item.glass.lens=Glass Lens (White) diff --git a/src/main/resources/assets/gregtech/textures/gui/base/background_popup.png b/src/main/resources/assets/gregtech/textures/gui/base/background_popup.png new file mode 100644 index 0000000000000000000000000000000000000000..f77849e8f7b08a50479030c9b5b5c28975f01da8 GIT binary patch literal 536 zcmeAS@N?(olHy`uVBq!ia0vp^hk>|*gAGVVJ&0!oQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nd!r97I;J!GcfQ0b@3f$Jf6QI1t=&{;u=vBoS#-wo>-L1P>`6JSE84fTB2a0 zXQ*eI;vNCChOyJr#WAEJ?(OA+yv+s-ERM65q~7u>*fY_=leNNcR{z`O<-6aoa{sz{ zI_GHbetY2=uW#h+l|5d_z3B1ILeAAUzW+@wDd>K9Ke@ul(BTM!AhQdPz$gP-AQb#+ zE9gyp^IRy*NNR@WnZLCx{^tMw`8?S7o^{QWJKOd$_S}18X8EHL62JYD@<);T3K F0RT|Kk?Q~e literal 0 HcmV?d00001 From 5e73960b6814ed400fb975a2b86e4b169561d2b6 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 17 Dec 2023 17:20:01 -0600 Subject: [PATCH 14/98] UI theme cleanups --- .../java/gregtech/api/mui/GTGuiTextures.java | 7 +- .../java/gregtech/api/mui/GTGuiTheme.java | 110 +++++++++++++++--- .../multiblockpart/MetaTileEntityItemBus.java | 4 +- 3 files changed, 98 insertions(+), 23 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index d632bf3f8e6..d1f432c6c07 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -4,6 +4,7 @@ import com.cleanroommc.modularui.drawable.UITexture; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; /** * GT MUI textures.
@@ -454,7 +455,11 @@ private static UITexture progressBar(String path, int width, int height, boolean } // todo steam logos? multi indicator blinking logos? - public static UITexture getLogo() { + public static @NotNull UITexture getLogo(GTGuiTheme theme) { + if (theme != null) { + UITexture logo = theme.getLogo(); + if (logo != null) return logo; + } return GTValues.XMAS.get() ? GREGTECH_LOGO_XMAS : GREGTECH_LOGO; } } diff --git a/src/main/java/gregtech/api/mui/GTGuiTheme.java b/src/main/java/gregtech/api/mui/GTGuiTheme.java index eb1c301aca2..c3f80b09943 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTheme.java +++ b/src/main/java/gregtech/api/mui/GTGuiTheme.java @@ -5,14 +5,18 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import com.cleanroommc.modularui.api.ITheme; import com.cleanroommc.modularui.api.IThemeApi; +import com.cleanroommc.modularui.drawable.UITexture; import com.cleanroommc.modularui.screen.Tooltip; import com.cleanroommc.modularui.theme.ReloadThemeEvent; import com.cleanroommc.modularui.utils.JsonBuilder; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +import java.util.function.Supplier; public class GTGuiTheme { @@ -24,7 +28,7 @@ public class GTGuiTheme { .fluidSlot(GTGuiTextures.IDs.STANDARD_FLUID_SLOT) .color(ConfigHolder.client.defaultUIColor) .button(GTGuiTextures.IDs.STANDARD_BUTTON) - .toggleButton(GTGuiTextures.IDs.STANDARD_BUTTON, + .simpleToggleButton(GTGuiTextures.IDs.STANDARD_BUTTON, GTGuiTextures.IDs.STANDARD_SLOT, ConfigHolder.client.defaultUIColor) .build(); @@ -51,6 +55,8 @@ public class GTGuiTheme { private final List> elementBuilder; private final JsonBuilder jsonBuilder; + private Supplier logo; + private GTGuiTheme(String themeId) { this.themeId = themeId; this.jsonBuilder = new JsonBuilder(); @@ -62,6 +68,15 @@ public String getId() { return themeId; } + public ITheme getMuiTheme() { + return IThemeApi.get().getTheme(themeId); + } + + public @Nullable UITexture getLogo() { + if (logo == null) return null; + return logo.get(); + } + private void register() { buildJson(); IThemeApi.get().registerTheme(themeId, jsonBuilder); @@ -278,33 +293,90 @@ public Builder textField(int textColor, int markedColor) { return this; } - public Builder toggleButton(String toggleButtonId, String selectedBackgroundId) { - return toggleButton(toggleButtonId, selectedBackgroundId, 0xFFFFFFFF, true); - } - - public Builder toggleButton(String toggleButtonId, String selectedBackgroundId, int selectedColor) { - return toggleButton(toggleButtonId, selectedBackgroundId, 0xFFFFFFFF, true, null, selectedColor); - } - - public Builder toggleButton(String toggleButtonId, String selectedBackgroundId, int textColor, - boolean textShadow) { - return toggleButton(toggleButtonId, selectedBackgroundId, textColor, textShadow, null, 0xFFBBBBBB); + /** + * Set the theme options for a ToggleButton widget. + * + * @param backgroundId The main background for the unpressed button + * @param hoverBackgroundId The on-hover background for the unpressed button + * @param selectedBackgroundId The main background for the pressed button + * @param selectedHoverBackgroundId The on-hover background for the pressed button + * @param selectedColor The color to apply to the pressed button + */ + public Builder toggleButton(String backgroundId, String hoverBackgroundId, + String selectedBackgroundId, String selectedHoverBackgroundId, int selectedColor) { + return toggleButton( + backgroundId, hoverBackgroundId, + selectedBackgroundId, selectedHoverBackgroundId, + selectedColor, 0xFFBBBBBB, false); } - public Builder toggleButton(String toggleButtonId, String selectedBackgroundId, int textColor, - boolean textShadow, String selectedHoverBackgroundId, int selectedColor) { + /** + * Set the theme options for a ToggleButton widget. + * + * @param backgroundId The main background for the unpressed button + * @param hoverBackgroundId The on-hover background for the unpressed button + * @param selectedBackgroundId The main background for the pressed button + * @param selectedHoverBackgroundId The on-hover background for the pressed button + * @param selectedColor The color to apply to the pressed button + * @param textColor The color for text overlaid on this button + * @param textShadow Whether to apply text shadow to text overlaid on this button + */ + public Builder toggleButton(String backgroundId, String hoverBackgroundId, + String selectedBackgroundId, String selectedHoverBackgroundId, + int selectedColor, int textColor, boolean textShadow) { theme.elementBuilder.add(b -> b .add("toggleButton", new JsonBuilder() .add("background", new JsonBuilder() .add("type", "texture") - .add("id", toggleButtonId)) - .add("textColor", textColor) - .add("textShadow", textShadow) + .add("id", backgroundId)) + .add("hoverBackground", new JsonBuilder() + .add("type", "texture") + .add("id", hoverBackgroundId)) .add("selectedBackground", new JsonBuilder() .add("type", "texture") .add("id", selectedBackgroundId)) - .add("selectedHoverBackground", selectedHoverBackgroundId) - .add("selectedColor", selectedColor))); + .add("selectedHoverBackground", new JsonBuilder() + .add("type", "texture") + .add("id", selectedHoverBackgroundId)) + .add("selectedColor", selectedColor) + .add("textColor", textColor) + .add("textShadow", textShadow))); + return this; + } + + /** + * Simple toggle button configuration for when you want a button with no texture changes on hover. + * + * @param backgroundId The unselected background texture + * @param selectedBackgroundId The selected background texture + * @param selectedColor The background color when the button is selected + */ + public Builder simpleToggleButton(String backgroundId, String selectedBackgroundId, int selectedColor) { + return simpleToggleButton(backgroundId, selectedBackgroundId, selectedColor, 0xFFBBBBBB, false); + } + + /** + * Simple toggle button configuration for when you want a button with no texture changes on hover. + * + * @param backgroundId The unselected background texture + * @param selectedBackgroundId The selected background texture + * @param selectedColor The background color when the button is selected + * @param textColor The color for text overlaid on this button + * @param textShadow Whether to apply text shadow to text overlaid on this button + */ + public Builder simpleToggleButton(String backgroundId, String selectedBackgroundId, int selectedColor, + int textColor, boolean textShadow) { + return toggleButton( + backgroundId, backgroundId, + selectedBackgroundId, selectedBackgroundId, + selectedColor, textColor, textShadow); + } + + /** + * Set a logo supplier for this theme. + */ + public Builder logo(Supplier logo) { + theme.logo = logo; return this; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java index ce42375b680..949f47b77ca 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -305,13 +305,12 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .child(new Column() .pos(backgroundWidth - 7 - 18, backgroundHeight - 18 * 4 - 7 - 5) .width(18).height(18 * 4 + 5) - .child(GTGuiTextures.getLogo().asWidget().size(17).top(18 * 3 + 5)) + .child(GTGuiTextures.getLogo(getUITheme()).asWidget().size(17).top(18 * 3 + 5)) .child(new ToggleButton() .top(18 * 2) .value(new BoolValue.Dynamic(workingStateValue::getBoolValue, workingStateValue::setBoolValue)) .overlay(GTGuiTextures.BUTTON_ITEM_OUTPUT) - .disableHoverBackground() .tooltipBuilder(t -> t.setAutoUpdate(true) .addLine(workingStateValue.getBoolValue() ? IKey.lang("gregtech.gui.item_auto_output.tooltip.enabled") : @@ -321,7 +320,6 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .value(new BoolValue.Dynamic(collapseStateValue::getBoolValue, collapseStateValue::setBoolValue)) .overlay(GTGuiTextures.BUTTON_AUTO_COLLAPSE) - .disableHoverBackground() .tooltipBuilder(t -> t.setAutoUpdate(true) .addLine(collapseStateValue.getBoolValue() ? IKey.lang("gregtech.gui.item_auto_collapse.tooltip.enabled") : From d87677651d874d224ebddfbda5c2e8cc0fc14c31 Mon Sep 17 00:00:00 2001 From: Tictim Date: Mon, 18 Dec 2023 09:42:38 +0900 Subject: [PATCH 15/98] Ore Dictionary Filter Update (#2296) --- src/main/java/gregtech/GregTechMod.java | 15 +- .../java/gregtech/api/gui/GuiTextures.java | 4 + .../gregtech/api/util/oreglob/OreGlob.java | 127 ++++++++++++--- .../api/util/oreglob/OreGlobCompiler.java | 10 ++ .../filter/OreDictionaryItemFilter.java | 146 ++++++++++++++---- .../filter/oreglob/impl/OreGlobMessages.java | 13 ++ .../filter/oreglob/impl/OreGlobParser.java | 44 +++--- .../widget/orefilter/OreFilterTestSlot.java | 63 ++++---- src/main/java/gregtech/core/CoreModule.java | 4 + .../resources/assets/gregtech/lang/en_us.lang | 6 +- .../ore_filter/button_case_sensitive.png | Bin 0 -> 339 bytes .../widget/ore_filter/button_match_all.png | Bin 0 -> 386 bytes .../java/gregtech/api/util/OreGlobTest.java | 17 +- 13 files changed, 322 insertions(+), 127 deletions(-) create mode 100644 src/main/java/gregtech/api/util/oreglob/OreGlobCompiler.java create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/ore_filter/button_case_sensitive.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/ore_filter/button_match_all.png diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index aa770c26ed6..f76989a97d5 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -3,9 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.modules.ModuleContainerRegistryEvent; -import gregtech.api.util.oreglob.OreGlob; import gregtech.client.utils.BloomEffectUtil; -import gregtech.common.covers.filter.oreglob.impl.OreGlobParser; import gregtech.modules.GregTechModules; import gregtech.modules.ModuleManager; @@ -15,7 +13,17 @@ import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.event.*; +import net.minecraftforge.fml.common.event.FMLConstructionEvent; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLInterModComms; +import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent; +import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent; +import net.minecraftforge.fml.common.event.FMLServerStartedEvent; +import net.minecraftforge.fml.common.event.FMLServerStartingEvent; +import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; +import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; @Mod(modid = GTValues.MODID, name = "GregTech", @@ -44,7 +52,6 @@ public GregTechMod() { public void onConstruction(FMLConstructionEvent event) { moduleManager = ModuleManager.getInstance(); GregTechAPI.moduleManager = moduleManager; - OreGlob.setCompiler(input -> new OreGlobParser(input).compile()); moduleManager.registerContainer(new GregTechModules()); MinecraftForge.EVENT_BUS.post(new ModuleContainerRegistryEvent()); moduleManager.setup(event.getASMHarvestedData(), Loader.instance().getConfigDir()); diff --git a/src/main/java/gregtech/api/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index fb073716142..e85bffcfe97 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -435,6 +435,10 @@ public class GuiTextures { .fullImage("textures/items/metaitems/cover.controller.png"); // Ore Filter + public static final TextureArea ORE_FILTER_BUTTON_CASE_SENSITIVE = TextureArea + .fullImage("textures/gui/widget/ore_filter/button_case_sensitive.png"); + public static final TextureArea ORE_FILTER_BUTTON_MATCH_ALL = TextureArea + .fullImage("textures/gui/widget/ore_filter/button_match_all.png"); public static final TextureArea ORE_FILTER_INFO = TextureArea.fullImage("textures/gui/widget/ore_filter/info.png"); public static final TextureArea ORE_FILTER_SUCCESS = TextureArea .fullImage("textures/gui/widget/ore_filter/success.png"); diff --git a/src/main/java/gregtech/api/util/oreglob/OreGlob.java b/src/main/java/gregtech/api/util/oreglob/OreGlob.java index 072e4959eeb..a560fcae1bf 100644 --- a/src/main/java/gregtech/api/util/oreglob/OreGlob.java +++ b/src/main/java/gregtech/api/util/oreglob/OreGlob.java @@ -7,21 +7,19 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import java.util.Collection; import java.util.List; -import java.util.Set; -import java.util.function.Function; /** * Glob-like string matcher language designed for ore dictionary matching. *

- * An OreGlob instance provides two functions: the ability to match strings, - * and the ability to translate expression structure into user-friendly text - * explanations. The text can be either a plaintext, or a text formatted by standard + * An OreGlob instance provides two functions: the ability to match strings, and the ability to translate expression + * structure into user-friendly text explanations. The text can be either a plaintext, or a text formatted by standard * Minecraft text format. */ public abstract class OreGlob { - private static Function compiler; + private static OreGlobCompiler compiler; /** * Tries to compile the string expression into OreGlob instance. @@ -29,15 +27,31 @@ public abstract class OreGlob { * @param expression OreGlob expression * @return Compilation result * @throws IllegalStateException If compiler is not provided yet + * @deprecated use {@link #compile(String, boolean)} */ @NotNull + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static OreGlobCompileResult compile(@NotNull String expression) { + return compile(expression, true); + } + + /** + * Tries to compile the string expression into OreGlob instance. + * + * @param expression OreGlob expression + * @param ignoreCase Whether the resulting OreGlob instance should do case-insensitive matches + * @return Compilation result + * @throws IllegalStateException If compiler is not provided yet + */ + @NotNull + public static OreGlobCompileResult compile(@NotNull String expression, boolean ignoreCase) { if (compiler == null) throw new IllegalStateException("Compiler unavailable"); - return compiler.apply(expression); + return compiler.compile(expression, ignoreCase); } @ApiStatus.Internal - public static void setCompiler(@NotNull Function compiler) { + public static void setCompiler(@NotNull OreGlobCompiler compiler) { OreGlob.compiler = compiler; } @@ -60,30 +74,97 @@ public static void setCompiler(@NotNull Function c public abstract boolean matches(@NotNull String input); /** - * Tries to match each ore dictionary entries associated with given item. - * If any of them matches, {@code true} is returned. *

- * For items not associated with any ore dictionary entries, this method returns - * {@code true} if this instance matches empty string instead. + * Tries to match each ore dictionary entries associated with given item. If any of them matches, {@code true} is + * returned. + *

+ *

+ * For items not associated with any ore dictionary entries, this method returns {@code true} if this instance + * matches empty string instead. + *

* * @param stack Item input * @return Whether this instance matches the input + * @deprecated use {@link #matchesAll(ItemStack)} or {@link #matchesAny(ItemStack)} */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public final boolean matches(@NotNull ItemStack stack) { - Set oreDicts = OreDictUnifier.getOreDictionaryNames(stack); - if (oreDicts.isEmpty()) { - return matches(""); - } else { - for (String oreDict : oreDicts) { - if (matches(oreDict)) return true; - } - return false; - } + return matchesAny(stack); + } + + /** + *

+ * Tries to match each ore dictionary entries associated with given item. If any of them matches, {@code true} is + * returned. + *

+ *

+ * For items not associated with any ore dictionary entries, this method returns {@code true} if this instance + * matches empty string instead. + *

+ * + * @param stack Item input + * @return Whether this instance matches the input + */ + public final boolean matchesAny(@NotNull ItemStack stack) { + return matchesAny(OreDictUnifier.getOreDictionaryNames(stack), true); + } + + /** + *

+ * Tries to match each ore dictionary entries associated with given item. If all of them matches, {@code true} is + * returned. + *

+ *

+ * For items not associated with any ore dictionary entries, this method returns {@code true} if this instance + * matches empty string instead. + *

+ * + * @param stack Item input + * @return Whether this instance matches the input + */ + public final boolean matchesAll(@NotNull ItemStack stack) { + return matchesAll(OreDictUnifier.getOreDictionaryNames(stack), true); + } + + /** + *

+ * Tries to match each input. If any of them matches, {@code true} is returned. + *

+ * + * @param inputs Collection of input strings + * @param specialEmptyMatch If {@code true}, this method will match an empty string ({@code ""}) if the input + * collection is empty. If {@code true}, this method will return {@code false} in such + * scenario. + * @return Whether this instance matches the input + */ + public final boolean matchesAny(@NotNull Collection inputs, boolean specialEmptyMatch) { + if (specialEmptyMatch && inputs.isEmpty()) return matches(""); + for (String input : inputs) if (matches(input)) return true; + return false; + } + + /** + *

+ * Tries to match each input. If all of them matches, {@code true} is returned. Note that this method does not have + * special case for empty inputs. + *

+ * + * @param inputs Collection of input strings + * @param specialEmptyMatch If {@code true}, this method will match an empty string ({@code ""}) if the input + * collection is empty. If {@code true}, this method will return {@code true} in such + * scenario. + * @return Whether this instance matches the input + */ + public final boolean matchesAll(@NotNull Collection inputs, boolean specialEmptyMatch) { + if (specialEmptyMatch && inputs.isEmpty()) return matches(""); + for (String input : inputs) if (!matches(input)) return false; + return true; } /** - * Visualize this instance with standard Minecraft text formatting. Two spaces (' ') will - * be used as indentation. + * Visualize this instance with standard Minecraft text formatting. Two spaces ({@code ' '}) will be used as + * indentation. * * @return Formatted visualization * @see OreGlob#toFormattedString(String) diff --git a/src/main/java/gregtech/api/util/oreglob/OreGlobCompiler.java b/src/main/java/gregtech/api/util/oreglob/OreGlobCompiler.java new file mode 100644 index 00000000000..d66fb7785a0 --- /dev/null +++ b/src/main/java/gregtech/api/util/oreglob/OreGlobCompiler.java @@ -0,0 +1,10 @@ +package gregtech.api.util.oreglob; + +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface OreGlobCompiler { + + @NotNull + OreGlobCompileResult compile(@NotNull String expression, boolean ignoreCase); +} diff --git a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java index 95cc2f172e0..1db9a6087e3 100644 --- a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java @@ -2,12 +2,15 @@ import gregtech.api.gui.GuiTextures; import gregtech.api.gui.Widget; +import gregtech.api.gui.resources.TextureArea; import gregtech.api.gui.widgets.DrawableWidget; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.ItemVariantMap; import gregtech.api.unification.stack.MultiItemVariantMap; import gregtech.api.unification.stack.SingleItemVariantMap; +import gregtech.api.util.function.BooleanConsumer; import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.oreglob.OreGlobCompileResult; import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; @@ -18,55 +21,90 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.text.TextFormatting; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.Set; +import java.util.function.BooleanSupplier; import java.util.function.Consumer; public class OreDictionaryItemFilter extends ItemFilter { + private final Map> matchCache = new Object2ObjectOpenHashMap<>(); + private final SingleItemVariantMap noOreDictMatch = new SingleItemVariantMap<>(); + protected String expression = ""; + private OreGlob glob = ImpossibleOreGlob.getInstance(); private boolean error; - private final Map> matchCache = new Object2ObjectOpenHashMap<>(); - private final SingleItemVariantMap noOreDictMatch = new SingleItemVariantMap<>(); + private boolean caseSensitive; + /** + * {@code false} requires any of the entry to be match in order for the match to be success, {@code true} requires + * all entries to match + */ + private boolean matchAll; + @NotNull public String getExpression() { return expression; } + @NotNull + public OreGlob getGlob() { + return this.glob; + } + + protected void recompile(@Nullable Consumer<@Nullable OreGlobCompileResult> callback) { + clearCache(); + String expr = this.expression; + if (!expr.isEmpty()) { + OreGlobCompileResult result = OreGlob.compile(expr, !this.caseSensitive); + this.glob = result.getInstance(); + this.error = result.hasError(); + if (callback != null) callback.accept(result); + } else { + this.glob = ImpossibleOreGlob.getInstance(); + this.error = true; + if (callback != null) callback.accept(null); + } + } + + protected void clearCache() { + this.matchCache.clear(); + this.noOreDictMatch.clear(); + } + @Override public void initUI(Consumer widgetGroup) { ItemOreFilterTestSlot[] testSlot = new ItemOreFilterTestSlot[5]; for (int i = 0; i < testSlot.length; i++) { - testSlot[i] = new ItemOreFilterTestSlot(20 + 22 * i, 0); - widgetGroup.accept(testSlot[i]); + ItemOreFilterTestSlot slot = new ItemOreFilterTestSlot(20 + 22 * i, 0); + slot.setGlob(getGlob()); + slot.setMatchAll(this.matchAll); + widgetGroup.accept(slot); + testSlot[i] = slot; } OreGlobCompileStatusWidget compilationStatus = new OreGlobCompileStatusWidget(10, 10); + + Consumer<@Nullable OreGlobCompileResult> compileCallback = result -> { + compilationStatus.setCompileResult(result); + for (ItemOreFilterTestSlot slot : testSlot) { + slot.setGlob(getGlob()); + } + }; + HighlightedTextField textField = new HighlightedTextField(14, 26, 152, 14, () -> this.expression, s -> { if (s.equals(this.expression)) return; this.expression = s; - if (!s.isEmpty()) { - OreGlobCompileResult result = OreGlob.compile(s); - this.glob = result.getInstance(); - this.error = result.hasError(); - compilationStatus.setCompileResult(result); - } else { - this.glob = ImpossibleOreGlob.getInstance(); - this.error = true; - compilationStatus.setCompileResult(null); - } - this.matchCache.clear(); - this.noOreDictMatch.clear(); markDirty(); - for (ItemOreFilterTestSlot slot : testSlot) { - slot.setGlob(this.error ? null : this.glob); - } + recompile(compileCallback); }); compilationStatus.setTextField(textField); @@ -91,7 +129,7 @@ public void initUI(Consumer widgetGroup) { case '*', '?' -> h.format(i, TextFormatting.GREEN); case '!' -> h.format(i, TextFormatting.RED); case '\\' -> h.format(i++, TextFormatting.YELLOW); - case '$' -> { + case '$' -> { // TODO: remove this switch case in 2.9 h.format(i, TextFormatting.DARK_GREEN); for (; i < t.length(); i++) { switch (t.charAt(i)) { @@ -114,6 +152,25 @@ public void initUI(Consumer widgetGroup) { h.format(i + 1, TextFormatting.RESET); } }).setMaxLength(64)); + widgetGroup.accept(new ForcedInitialSyncImageCycleButtonWidget(130, 38, 18, 18, + GuiTextures.ORE_FILTER_BUTTON_CASE_SENSITIVE, () -> this.caseSensitive, caseSensitive -> { + if (this.caseSensitive == caseSensitive) return; + this.caseSensitive = caseSensitive; + markDirty(); + recompile(compileCallback); + }).setTooltipHoverString( + i -> "cover.ore_dictionary_filter.button.case_sensitive." + (i == 0 ? "disabled" : "enabled"))); + widgetGroup.accept(new ForcedInitialSyncImageCycleButtonWidget(148, 38, 18, 18, + GuiTextures.ORE_FILTER_BUTTON_MATCH_ALL, () -> this.matchAll, matchAll -> { + if (this.matchAll == matchAll) return; + this.matchAll = matchAll; + markDirty(); + clearCache(); + for (ItemOreFilterTestSlot slot : testSlot) { + slot.setMatchAll(matchAll); + } + }).setTooltipHoverString( + i -> "cover.ore_dictionary_filter.button.match_all." + (i == 0 ? "disabled" : "enabled"))); } @Override @@ -122,7 +179,7 @@ public Object matchItemStack(ItemStack itemStack) { "wtf is this system?? i can put any non null object here and it i will work??? $arch" : null; } - public boolean matchesItemStack(ItemStack itemStack) { + public boolean matchesItemStack(@NotNull ItemStack itemStack) { if (this.error) return false; Item item = itemStack.getItem(); ItemVariantMap> oreDictEntry = OreDictUnifier.getOreDictionaryEntry(item); @@ -160,7 +217,7 @@ public boolean matchesItemStack(ItemStack itemStack) { } this.matchCache.put(item, cacheEntry); } - boolean matches = this.glob.matches(itemStack); + boolean matches = this.matchAll ? this.glob.matchesAll(itemStack) : this.glob.matchesAny(itemStack); cacheEntry.put(itemStack, matches); return matches; } @@ -181,20 +238,43 @@ public int getTotalOccupiedHeight() { } @Override - public void writeToNBT(NBTTagCompound tagCompound) { - tagCompound.setString("OreDictionaryFilter", expression); + public void writeToNBT(NBTTagCompound tag) { + tag.setString("OreDictionaryFilter", expression); + if (this.caseSensitive) tag.setBoolean("caseSensitive", true); + if (this.matchAll) tag.setBoolean("matchAll", true); } @Override - public void readFromNBT(NBTTagCompound tagCompound) { - this.expression = tagCompound.getString("OreDictionaryFilter"); - if (!this.expression.isEmpty()) { - OreGlobCompileResult result = OreGlob.compile(this.expression); - this.glob = result.getInstance(); - this.error = result.hasError(); - } else { - this.glob = ImpossibleOreGlob.getInstance(); - this.error = true; + public void readFromNBT(NBTTagCompound tag) { + this.expression = tag.getString("OreDictionaryFilter"); + this.caseSensitive = tag.getBoolean("caseSensitive"); + this.matchAll = tag.getBoolean("matchAll"); + recompile(null); + } + + public static class ForcedInitialSyncImageCycleButtonWidget extends ImageCycleButtonWidget { + + private final BooleanConsumer updater; + + public ForcedInitialSyncImageCycleButtonWidget(int xPosition, int yPosition, int width, int height, + TextureArea buttonTexture, BooleanSupplier supplier, + BooleanConsumer updater) { + super(xPosition, yPosition, width, height, buttonTexture, supplier, updater); + this.currentOption = 0; + this.updater = updater; + } + + @Override + public void readUpdateInfo(int id, PacketBuffer buffer) { + if (id == 1) { + int currentOptionCache = this.currentOption; + super.readUpdateInfo(id, buffer); + if (this.currentOption != currentOptionCache) { + this.updater.apply(currentOption >= 1); // call updater to apply necessary state changes + } + } else { + super.readUpdateInfo(id, buffer); + } } } } diff --git a/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobMessages.java b/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobMessages.java index 6b3da3ca6fd..d0c2d44e7df 100644 --- a/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobMessages.java +++ b/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobMessages.java @@ -2,6 +2,8 @@ import gregtech.api.util.LocalizationUtils; +import org.jetbrains.annotations.ApiStatus; + import java.util.Locale; interface OreGlobMessages { @@ -102,21 +104,32 @@ static String compileErrorUnexpectedTokenAfterEOF(String token) { return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "unexpected_token_after_eof", token); } + // compilation flags are expected to be removed in future release + + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") static String compileErrorUnexpectedCompilationFlag() { // Compilation flags in the middle of expression return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "unexpected_compilation_flag"); } + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") static String compileErrorEmptyCompilationFlag() { // No compilation flags given return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "empty_compilation_flag"); } + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") static String compileErrorUnknownCompilationFlag(String flag) { // Unknown compilation flag '%s' return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "unknown_compilation_flag", flag); } + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") static String compileErrorRedundantCompilationFlag(String flag) { // Compilation flag '%s' written twice return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "redundant_compilation_flag", flag); diff --git a/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobParser.java b/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobParser.java index 0bc564d69db..b4cec035040 100644 --- a/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobParser.java +++ b/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobParser.java @@ -5,6 +5,7 @@ import gregtech.common.covers.filter.oreglob.node.OreGlobNode; import gregtech.common.covers.filter.oreglob.node.OreGlobNodes; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -14,7 +15,7 @@ /** * Top-down parser for oreGlob expression. - * + * *
  * oreGlob = [ FLAG ], [ or ], EOF
  *
@@ -47,8 +48,7 @@ public final class OreGlobParser {
 
     private boolean error;
 
-    private boolean caseSensitive;
-
+    private boolean ignoreCase;
     private int inputIndex;
 
     private TokenType tokenType;
@@ -56,8 +56,9 @@ public final class OreGlobParser {
     @Nullable
     private String tokenLiteralValue;
 
-    public OreGlobParser(String input) {
+    public OreGlobParser(String input, boolean ignoreCase) {
         this.input = input;
+        this.ignoreCase = ignoreCase;
     }
 
     // Get codepoint at current position and incr index
@@ -68,6 +69,7 @@ private int readNextChar() {
         return input.codePointAt(i);
     }
 
+    @SuppressWarnings("deprecation")
     private void advance() {
         boolean first = this.inputIndex == 0;
         while (true) {
@@ -84,7 +86,7 @@ private void advance() {
                 case '^' -> setCurrentToken(XOR, start, 1);
                 case '*' -> setCurrentToken(ANY, start, 1);
                 case '?' -> setCurrentToken(ANY_CHAR, start, 1);
-                case '$' -> {
+                case '$' -> { // TODO: remove this switch case in 2.9
                     if (!first) {
                         error(OreGlobMessages.compileErrorUnexpectedCompilationFlag(), start, 1);
                     }
@@ -145,8 +147,10 @@ private String gatherLiteralValue() {
         }
     }
 
+    @Deprecated
+    @SuppressWarnings("DeprecatedIsStillUsed")
+    @ApiStatus.ScheduledForRemoval(inVersion = "2.9")
     private void gatherFlags(boolean add) {
-        boolean flagsAdded = false;
         while (true) {
             int i = this.inputIndex;
             int c = readNextChar();
@@ -156,39 +160,27 @@ private void gatherFlags(boolean add) {
                     if (c == CHAR_EOF) {
                         error(OreGlobMessages.compileErrorEOFAfterEscape(), i, 1);
                     } else if (add) {
-                        addFlag(c, i);
-                        flagsAdded = true;
+                        addFlag(c);
                         continue;
                     }
                 }
                 case ' ', '\t', '\n', '\r', CHAR_EOF -> {}
                 default -> {
                     if (add) {
-                        addFlag(c, i);
-                        flagsAdded = true;
+                        addFlag(c);
                     }
                     continue;
                 }
             }
-            if (!flagsAdded && add) {
-                error(OreGlobMessages.compileErrorEmptyCompilationFlag(), i, 1);
-            }
+            warn("Compilation flags ('$') are scheduled to be removed in future releases.");
             return;
         }
     }
 
-    private void addFlag(int flag, int index) {
-        switch (flag) {
-            case 'c', 'C' -> {
-                if (this.caseSensitive) {
-                    warn(OreGlobMessages.compileErrorRedundantCompilationFlag("c"), index, 1);
-                } else {
-                    this.caseSensitive = true;
-                }
-            }
-            default -> warn(OreGlobMessages.compileErrorUnknownCompilationFlag(
-                    new StringBuilder().appendCodePoint(flag).toString()), index, 1);
-        }
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval(inVersion = "2.9")
+    private void addFlag(int flag) {
+        if (flag == 'c' || flag == 'C') this.ignoreCase = false;
     }
 
     private boolean advanceIf(TokenType type) {
@@ -296,7 +288,7 @@ private OreGlobNode primary() {
         return switch (tokenType) {
             case LITERAL -> {
                 if (tokenLiteralValue != null) {
-                    OreGlobNode result = OreGlobNodes.match(tokenLiteralValue, !this.caseSensitive);
+                    OreGlobNode result = OreGlobNodes.match(tokenLiteralValue, this.ignoreCase);
                     advance();
                     yield result;
                 } else { // likely caused by program error, not user issue
diff --git a/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java b/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java
index 6bde8f6cb5b..fd81e80bcd7 100644
--- a/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java
+++ b/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java
@@ -23,7 +23,6 @@
 
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -32,6 +31,9 @@
  */
 public abstract class OreFilterTestSlot extends WidgetGroup {
 
+    private final ImageWidget match;
+    private final ImageWidget noMatch;
+
     @Nullable
     private OreGlob glob;
     private boolean expectedResult = true;
@@ -48,8 +50,7 @@ public abstract class OreFilterTestSlot extends WidgetGroup {
 
     private boolean initialized = false;
 
-    private final ImageWidget match;
-    private final ImageWidget noMatch;
+    private boolean matchAll;
 
     public OreFilterTestSlot(int xPosition, int yPosition) {
         super(xPosition, yPosition, 18, 18);
@@ -86,30 +87,42 @@ public OreFilterTestSlot onMatchChange(@Nullable BooleanConsumer onMatchChange)
     }
 
     public void setGlob(@Nullable OreGlob glob) {
+        if (this.glob == glob) return;
         this.glob = glob;
         updatePreview();
     }
 
+    public void setMatchAll(boolean matchAll) {
+        if (this.matchAll == matchAll) return;
+        this.matchAll = matchAll;
+        updatePreview();
+    }
+
     protected void updatePreview() {
         if (!this.initialized) return;
         Set oreDicts = getTestCandidates();
         if (oreDicts != null) {
-            boolean success;
             OreGlob glob = this.glob;
             if (oreDicts.isEmpty()) {
                 // no oredict entries
-                this.testResult = Object2BooleanMaps.singleton("", success = glob != null && glob.matches(""));
+                this.testResult = Object2BooleanMaps.singleton("", glob != null && glob.matches(""));
                 this.matchType = MatchType.NO_ORE_DICT_MATCH;
             } else {
                 this.testResult = new Object2BooleanAVLTreeMap<>();
-                success = false;
                 for (String oreDict : oreDicts) {
                     boolean matches = glob != null && glob.matches(oreDict);
                     this.testResult.put(oreDict, matches);
-                    success |= matches;
                 }
                 this.matchType = MatchType.ORE_DICT_MATCH;
             }
+            boolean success = this.matchAll;
+            for (var e : testResult.object2BooleanEntrySet()) {
+                boolean result = e.getBooleanValue();
+                if (result == !this.matchAll) {
+                    success = !this.matchAll;
+                    break;
+                }
+            }
             updateAndNotifyMatchSuccess(this.expectedResult == success);
             this.match.setVisible(this.expectedResult == success);
             this.noMatch.setVisible(this.expectedResult != success);
@@ -131,9 +144,8 @@ private void updateAndNotifyMatchSuccess(boolean newValue) {
     }
 
     /**
-     * Get each test candidate for current state of test slot. An empty collection indicates that the
-     * match is for items without any ore dictionary entry. A {@code null} value indicates that the
-     * input state is invalid or empty.
+     * Get each test candidate for current state of test slot. An empty collection indicates that the match is for items
+     * without any ore dictionary entry. A {@code null} value indicates that the input state is invalid or empty.
      *
      * @return each test candidate for current state of test slot
      */
@@ -168,26 +180,17 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender
     @Override
     public void drawInForeground(int mouseX, int mouseY) {
         if (isActive() && isMouseOverElement(mouseX, mouseY)) {
-            List list;
-            switch (this.matchType) {
-                case NO_ORE_DICT_MATCH:
-                    list = Collections.singletonList(I18n.format(this.matchSuccess ?
-                            "cover.ore_dictionary_filter.test_slot.no_oredict.matches" :
-                            "cover.ore_dictionary_filter.test_slot.no_oredict.matches_not"));
-                    break;
-                case ORE_DICT_MATCH:
-                    list = this.testResult.object2BooleanEntrySet().stream().map(
-                            e -> I18n.format(e.getBooleanValue() ?
-                                    "cover.ore_dictionary_filter.test_slot.matches" :
-                                    "cover.ore_dictionary_filter.test_slot.matches_not", e.getKey()))
-                            .collect(Collectors.toList());
-                    break;
-                case INVALID:
-                default:
-                    list = Arrays.asList(LocalizationUtils.formatLines("cover.ore_dictionary_filter.test_slot.info"));
-                    break;
-            }
-            drawHoveringText(ItemStack.EMPTY, list, 300, mouseX, mouseY);
+            drawHoveringText(ItemStack.EMPTY, switch (this.matchType) {
+                case NO_ORE_DICT_MATCH -> Collections.singletonList(I18n.format(this.matchSuccess ?
+                        "cover.ore_dictionary_filter.test_slot.no_oredict.matches" :
+                        "cover.ore_dictionary_filter.test_slot.no_oredict.matches_not"));
+                case ORE_DICT_MATCH -> this.testResult.object2BooleanEntrySet().stream().map(
+                        e -> I18n.format(e.getBooleanValue() ?
+                                "cover.ore_dictionary_filter.test_slot.matches" :
+                                "cover.ore_dictionary_filter.test_slot.matches_not", e.getKey()))
+                        .collect(Collectors.toList());
+                default -> Arrays.asList(LocalizationUtils.formatLines("cover.ore_dictionary_filter.test_slot.info"));
+            }, 300, mouseX, mouseY);
         }
     }
 
diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java
index 1d2dc88a4ec..46eeb3e8335 100644
--- a/src/main/java/gregtech/core/CoreModule.java
+++ b/src/main/java/gregtech/core/CoreModule.java
@@ -28,6 +28,7 @@
 import gregtech.api.util.CapesRegistry;
 import gregtech.api.util.VirtualTankRegistry;
 import gregtech.api.util.input.KeyBind;
+import gregtech.api.util.oreglob.OreGlob;
 import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinHandler;
 import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinSaveData;
 import gregtech.api.worldgen.config.WorldGenRegistry;
@@ -43,6 +44,7 @@
 import gregtech.common.command.worldgen.CommandWorldgen;
 import gregtech.common.covers.CoverBehaviors;
 import gregtech.common.covers.filter.FilterTypeRegistry;
+import gregtech.common.covers.filter.oreglob.impl.OreGlobParser;
 import gregtech.common.items.MetaItems;
 import gregtech.common.items.ToolItems;
 import gregtech.common.metatileentities.MetaTileEntities;
@@ -114,6 +116,8 @@ public CoreModule() {
         // must be set here because of GroovyScript compat
         // trying to read this before the pre-init stage
         GregTechAPI.materialManager = MaterialRegistryManager.getInstance();
+
+        OreGlob.setCompiler((expr, ignoreCase) -> new OreGlobParser(expr, ignoreCase).compile());
     }
 
     @NotNull
diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang
index b70165a7af4..f4525a2dc5c 100644
--- a/src/main/resources/assets/gregtech/lang/en_us.lang
+++ b/src/main/resources/assets/gregtech/lang/en_us.lang
@@ -1175,7 +1175,7 @@ cover.filter.blacklist.disabled=Whitelist
 cover.filter.blacklist.enabled=Blacklist
 
 cover.ore_dictionary_filter.title=Ore Dictionary Filter
-cover.ore_dictionary_filter.info=§bAccepts complex expressions/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r for grouping/n§6*§r for wildcard (i.e. 0 or more characters)/n§6?§r for any 1 character/n§6()§r for matching empty entry (including items with no ore dictionary)/n§6$c§r at the start of expression for case-sensitive match/n§bExample:/n§6dust*Gold | (plate* & !*Double*)/nWill match all gold dusts of all sizes or all plates, but not double plates
+cover.ore_dictionary_filter.info=§bAccepts complex expressions/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r for grouping/n§6*§r for wildcard (i.e. 0 or more characters)/n§6?§r for any 1 character/n§6()§r for matching empty entry (including items with no ore dictionary)/n§bExample:/n§6dust*Gold | (plate* & !*Double*)/nWill match all gold dusts of all sizes or all plates, but not double plates
 cover.ore_dictionary_filter.test_slot.info=Insert a item to test if it matches the filter expression
 cover.ore_dictionary_filter.test_slot.matches=§a* %s
 cover.ore_dictionary_filter.test_slot.matches_not=§c* %s
@@ -1186,6 +1186,10 @@ cover.ore_dictionary_filter.status.err_warn=§c%s error(s) and %s warning(s)
 cover.ore_dictionary_filter.status.warn=§7%s warning(s)
 cover.ore_dictionary_filter.status.no_issues=§aNo issues
 cover.ore_dictionary_filter.status.explain=Ore filter explanation:
+cover.ore_dictionary_filter.button.case_sensitive.disabled=Case insensitive match
+cover.ore_dictionary_filter.button.case_sensitive.enabled=Case sensitive match
+cover.ore_dictionary_filter.button.match_all.disabled=Match any one of ore dictionary entries
+cover.ore_dictionary_filter.button.match_all.enabled=Match all ore dictionary entries
 
 cover.ore_dictionary_filter.preview.next=... followed by 
 cover.ore_dictionary_filter.preview.match='%s'
diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/ore_filter/button_case_sensitive.png b/src/main/resources/assets/gregtech/textures/gui/widget/ore_filter/button_case_sensitive.png
new file mode 100644
index 0000000000000000000000000000000000000000..6615e156d4f5b3426199403f095230d8d89c9eb0
GIT binary patch
literal 339
zcmV-Z0j&OsP)Px$4M{{nR7i>KmB9_eAPhx6Rc@W5t27HRKo-c=Lm;FcvOos#0-Ysu;)8WBqE$I^{%>fVz?ebJz=;W
zG50H+bM20tbC~L?DZIciY#9hIQF<<}~dTko`mR%qwFZ@LRj=C?a!+SqEl
zBao@uVho4~Q=_X*V>^jpF$N>_c2WcdCnph1kMUa|08b}lHR3KKB2rs5?L#j9*GiCB
l{|>1qP#yg{Px$JV``BR7i>Kls!(vKoEt$l|q4X19~@{0}&43jwTmKK{JOKS)#}VIKUhrL7anz
zJ~xO`Pz;5=mjAsZLZZm4tljbR`@HrG?(STuq9|Czi%Vo?r4hib2u~sOhIUoplWIM)
zbLXVmnhWmkF_D=~J~_|x)=Zw~{Y1@;IkO?vMjtoA-Tkt)dH6g6@bImzneICL0__(10Wq5dlD}ncC>2%5(SB%<4qV8%2c2S9pIJ
zNR)!H-Y=1ru--3uTOI2(qi9i0L{%L%fipfx5$TzjS=;DbnHh_sC}#iq6oqR;0@sF|
zik&iZZOBsHa*Nk3qq&BR`U-(ege|ZcN|b`3s$?RinfrMS8PT>t=3XXhl-xAh0OF=f
gwyEAx)c(OreGlobCompileResult.class) {
 
             @Override

From 3fb84d6cdcbfed053de43cb7179f4207e9a49a3f Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Sun, 17 Dec 2023 19:42:55 -0500
Subject: [PATCH 16/98] invalidate pipenet routepaths on chunk unload (#2303)

---
 .../metatileentity/NeighborCacheTileEntityBase.java  | 11 +++++++++++
 src/main/java/gregtech/api/pipenet/PipeNet.java      | 12 +++++++++++-
 .../api/pipenet/tile/TileEntityPipeBase.java         | 12 ++++++++++++
 .../common/pipelike/cable/net/EnergyNet.java         | 10 +++++++++-
 .../common/pipelike/cable/tile/TileEntityCable.java  |  8 +++++++-
 .../common/pipelike/itempipe/net/ItemPipeNet.java    | 11 ++++++++++-
 .../pipelike/itempipe/tile/TileEntityItemPipe.java   |  6 ++++++
 .../common/pipelike/laser/net/LaserPipeNet.java      |  5 +++++
 .../pipelike/laser/tile/TileEntityLaserPipe.java     |  6 ++++++
 .../common/pipelike/optical/net/OpticalPipeNet.java  |  5 +++++
 .../pipelike/optical/tile/TileEntityOpticalPipe.java |  6 ++++++
 11 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/src/main/java/gregtech/api/metatileentity/NeighborCacheTileEntityBase.java b/src/main/java/gregtech/api/metatileentity/NeighborCacheTileEntityBase.java
index 473b950d63c..97200ab8518 100644
--- a/src/main/java/gregtech/api/metatileentity/NeighborCacheTileEntityBase.java
+++ b/src/main/java/gregtech/api/metatileentity/NeighborCacheTileEntityBase.java
@@ -7,6 +7,7 @@
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.World;
 
+import org.jetbrains.annotations.MustBeInvokedByOverriders;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -28,24 +29,34 @@ protected void invalidateNeighbors() {
         }
     }
 
+    @MustBeInvokedByOverriders
     @Override
     public void setWorld(@NotNull World worldIn) {
         super.setWorld(worldIn);
         invalidateNeighbors();
     }
 
+    @MustBeInvokedByOverriders
     @Override
     public void setPos(@NotNull BlockPos posIn) {
         super.setPos(posIn);
         invalidateNeighbors();
     }
 
+    @MustBeInvokedByOverriders
     @Override
     public void invalidate() {
         super.invalidate();
         invalidateNeighbors();
     }
 
+    @MustBeInvokedByOverriders
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        invalidateNeighbors();
+    }
+
     @Override
     public @Nullable TileEntity getNeighbor(@NotNull EnumFacing facing) {
         if (world == null || pos == null) return null;
diff --git a/src/main/java/gregtech/api/pipenet/PipeNet.java b/src/main/java/gregtech/api/pipenet/PipeNet.java
index 384d15134a1..536b2a23b81 100644
--- a/src/main/java/gregtech/api/pipenet/PipeNet.java
+++ b/src/main/java/gregtech/api/pipenet/PipeNet.java
@@ -15,8 +15,13 @@
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 
-import java.util.*;
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 public abstract class PipeNet implements INBTSerializable {
 
@@ -63,6 +68,11 @@ public void onPipeConnectionsUpdate() {}
 
     public void onNeighbourUpdate(BlockPos fromPos) {}
 
+    /**
+     * Is called when any Pipe TE in the PipeNet is unloaded
+     */
+    public void onChunkUnload() {}
+
     public Map> getAllNodes() {
         return unmodifiableNodeByBlockPos;
     }
diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
index a2d593bb206..b1ec074d9d6 100644
--- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
+++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
@@ -26,6 +26,7 @@
 import net.minecraftforge.common.capabilities.Capability;
 import net.minecraftforge.common.util.Constants.NBT;
 
+import org.jetbrains.annotations.MustBeInvokedByOverriders;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -539,6 +540,17 @@ public boolean shouldRefresh(@NotNull World world, @NotNull BlockPos pos, IBlock
         return oldState.getBlock() != newSate.getBlock();
     }
 
+    @MustBeInvokedByOverriders
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        WorldPipeNet worldPipeNet = getPipeBlock().getWorldPipeNet(getWorld());
+        PipeNet net = worldPipeNet.getNetFromPos(pos);
+        if (net != null) {
+            net.onChunkUnload();
+        }
+    }
+
     public void doExplosion(float explosionPower) {
         getWorld().setBlockToAir(getPos());
         if (!getWorld().isRemote) {
diff --git a/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java b/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java
index 8d6f7110cb1..a56fb565600 100644
--- a/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java
+++ b/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java
@@ -11,7 +11,10 @@
 
 import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
 
 public class EnergyNet extends PipeNet {
 
@@ -67,6 +70,11 @@ public void onPipeConnectionsUpdate() {
         NET_DATA.clear();
     }
 
+    @Override
+    public void onChunkUnload() {
+        NET_DATA.clear();
+    }
+
     @Override
     protected void transferNodeData(Map> transferredNodes,
                                     PipeNet parentNet) {
diff --git a/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java b/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java
index d54d160e525..befdf615466 100644
--- a/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java
+++ b/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java
@@ -258,7 +258,7 @@ public  T getCapabilityInternal(Capability capability, @Nullable EnumFacin
         if (capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER) {
             if (world.isRemote)
                 return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER.cast(clientCapability);
-            if (handlers.size() == 0)
+            if (handlers.isEmpty())
                 initHandlers();
             checkNetwork();
             return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER.cast(handlers.getOrDefault(facing, defaultHandler));
@@ -293,6 +293,12 @@ private EnergyNet getEnergyNet() {
         return currentEnergyNet;
     }
 
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        this.handlers.clear();
+    }
+
     @Override
     public int getDefaultPaintingColor() {
         return 0x404040;
diff --git a/src/main/java/gregtech/common/pipelike/itempipe/net/ItemPipeNet.java b/src/main/java/gregtech/common/pipelike/itempipe/net/ItemPipeNet.java
index 25e6534b0f4..c836119c344 100644
--- a/src/main/java/gregtech/common/pipelike/itempipe/net/ItemPipeNet.java
+++ b/src/main/java/gregtech/common/pipelike/itempipe/net/ItemPipeNet.java
@@ -9,7 +9,11 @@
 import net.minecraft.util.EnumFacing;
 import net.minecraft.util.math.BlockPos;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class ItemPipeNet extends PipeNet {
 
@@ -43,6 +47,11 @@ public void onPipeConnectionsUpdate() {
         NET_DATA.clear();
     }
 
+    @Override
+    public void onChunkUnload() {
+        NET_DATA.clear();
+    }
+
     @Override
     protected void transferNodeData(Map> transferredNodes,
                                     PipeNet parentNet) {
diff --git a/src/main/java/gregtech/common/pipelike/itempipe/tile/TileEntityItemPipe.java b/src/main/java/gregtech/common/pipelike/itempipe/tile/TileEntityItemPipe.java
index 5880f375964..80b5e233b92 100644
--- a/src/main/java/gregtech/common/pipelike/itempipe/tile/TileEntityItemPipe.java
+++ b/src/main/java/gregtech/common/pipelike/itempipe/tile/TileEntityItemPipe.java
@@ -153,4 +153,10 @@ public int getTransferredItems() {
         updateTransferredState();
         return this.transferredItems;
     }
+
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        this.handlers.clear();
+    }
 }
diff --git a/src/main/java/gregtech/common/pipelike/laser/net/LaserPipeNet.java b/src/main/java/gregtech/common/pipelike/laser/net/LaserPipeNet.java
index 02781ae8ce8..67aef2810ac 100644
--- a/src/main/java/gregtech/common/pipelike/laser/net/LaserPipeNet.java
+++ b/src/main/java/gregtech/common/pipelike/laser/net/LaserPipeNet.java
@@ -46,6 +46,11 @@ public void onPipeConnectionsUpdate() {
         netData.clear();
     }
 
+    @Override
+    public void onChunkUnload() {
+        netData.clear();
+    }
+
     @Override
     protected void transferNodeData(Map> transferredNodes,
                                     PipeNet parentNet) {
diff --git a/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java b/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java
index 6a11c0503a4..759fa494152 100644
--- a/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java
+++ b/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java
@@ -224,6 +224,12 @@ public void readFromNBT(@NotNull NBTTagCompound compound) {
         }
     }
 
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        this.handlers.clear();
+    }
+
     private static class DefaultLaserContainer implements ILaserContainer {
 
         @Override
diff --git a/src/main/java/gregtech/common/pipelike/optical/net/OpticalPipeNet.java b/src/main/java/gregtech/common/pipelike/optical/net/OpticalPipeNet.java
index 18f2edd36ca..fceabc6aae6 100644
--- a/src/main/java/gregtech/common/pipelike/optical/net/OpticalPipeNet.java
+++ b/src/main/java/gregtech/common/pipelike/optical/net/OpticalPipeNet.java
@@ -47,6 +47,11 @@ public void onPipeConnectionsUpdate() {
         NET_DATA.clear();
     }
 
+    @Override
+    public void onChunkUnload() {
+        NET_DATA.clear();
+    }
+
     @Override
     protected void transferNodeData(Map> transferredNodes,
                                     PipeNet parentNet) {
diff --git a/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java b/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java
index adf7f995ae1..43efe04cb56 100644
--- a/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java
+++ b/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java
@@ -194,6 +194,12 @@ public void receiveCustomData(int discriminator, PacketBuffer buf) {
         }
     }
 
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        this.handlers.clear();
+    }
+
     private static class DefaultDataHandler implements IDataAccessHatch {
 
         @Override

From a51c424037ee062edc693ffb30bd140287fccd54 Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 17 Dec 2023 18:43:12 -0600
Subject: [PATCH 17/98] Allow electrolyzing more hydrocarbons (#2258)

---
 .../materials/OrganicChemistryMaterials.java  |   6 +-
 .../recipe/chemistry/SeparationRecipes.java   | 124 ++++++++++++------
 2 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java b/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java
index f47c7cc0a42..de2bdf4a703 100644
--- a/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java
+++ b/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java
@@ -194,7 +194,6 @@ public static void register() {
         Chloromethane = new Material.Builder(1024, gregtechId("chloromethane"))
                 .gas()
                 .color(0xC82CA0)
-                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 1, Hydrogen, 3, Chlorine, 1)
                 .build();
 
@@ -221,12 +220,14 @@ public static void register() {
         Propene = new Material.Builder(1028, gregtechId("propene"))
                 .gas()
                 .color(0xFFDD55)
+                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 3, Hydrogen, 6)
                 .build();
 
         Ethane = new Material.Builder(1029, gregtechId("ethane"))
                 .gas()
                 .color(0xC8C8FF)
+                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 2, Hydrogen, 6)
                 .build();
 
@@ -268,7 +269,6 @@ public static void register() {
         Ethenone = new Material.Builder(1035, gregtechId("ethenone"))
                 .fluid()
                 .color(0x141446)
-                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 2, Hydrogen, 2, Oxygen, 1)
                 .build();
 
@@ -331,7 +331,6 @@ public static void register() {
         AceticAcid = new Material.Builder(1044, gregtechId("acetic_acid"))
                 .liquid(new FluidBuilder().attribute(FluidAttributes.ACID))
                 .color(0xC8B4A0)
-                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 2, Hydrogen, 4, Oxygen, 2)
                 .build();
 
@@ -373,7 +372,6 @@ public static void register() {
         Acetone = new Material.Builder(1050, gregtechId("acetone"))
                 .fluid()
                 .color(0xAFAFAF)
-                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 3, Hydrogen, 6, Oxygen, 1)
                 .build();
 
diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java
index 3d51fc11124..fc433308a0d 100644
--- a/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java
+++ b/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java
@@ -369,44 +369,6 @@ public static void init() {
                 .output(dust, Carbon, 4)
                 .duration(100).EUt(60).buildAndRegister();
 
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(AceticAcid.getFluid(2000))
-                .fluidOutputs(Ethane.getFluid(1000))
-                .fluidOutputs(CarbonDioxide.getFluid(2000))
-                .fluidOutputs(Hydrogen.getFluid(2000))
-                .duration(512).EUt(60).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Chloromethane.getFluid(2000))
-                .fluidOutputs(Ethane.getFluid(1000))
-                .fluidOutputs(Chlorine.getFluid(2000))
-                .duration(400).EUt(60).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Acetone.getFluid(2000))
-                .output(dust, Carbon, 3)
-                .fluidOutputs(Propane.getFluid(1000))
-                .fluidOutputs(Water.getFluid(2000))
-                .duration(480).EUt(60).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Butane.getFluid(1000))
-                .fluidOutputs(Butene.getFluid(1000))
-                .fluidOutputs(Hydrogen.getFluid(2000))
-                .duration(240).EUt(VA[MV]).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Butene.getFluid(1000))
-                .fluidOutputs(Butadiene.getFluid(1000))
-                .fluidOutputs(Hydrogen.getFluid(2000))
-                .duration(240).EUt(VA[MV]).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Propane.getFluid(1000))
-                .fluidOutputs(Propene.getFluid(1000))
-                .fluidOutputs(Hydrogen.getFluid(2000))
-                .duration(640).EUt(VA[MV]).buildAndRegister();
-
         ELECTROLYZER_RECIPES.recipeBuilder()
                 .input(dust, Diamond)
                 .output(dust, Carbon, 64)
@@ -470,6 +432,92 @@ public static void init() {
                 .fluidOutputs(Chlorine.getFluid(1000))
                 .duration(288).EUt(60).buildAndRegister();
 
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Propane.getFluid(1000))
+                .output(dust, Carbon, 3)
+                .fluidOutputs(Hydrogen.getFluid(8000))
+                .duration(176).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Butene.getFluid(1000))
+                .output(dust, Carbon, 4)
+                .fluidOutputs(Hydrogen.getFluid(8000))
+                .duration(192).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Butane.getFluid(1000))
+                .output(dust, Carbon, 4)
+                .fluidOutputs(Hydrogen.getFluid(10000))
+                .duration(224).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Styrene.getFluid(1000))
+                .output(dust, Carbon, 8)
+                .fluidOutputs(Hydrogen.getFluid(8000))
+                .duration(384).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Butadiene.getFluid(1000))
+                .output(dust, Carbon, 4)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .duration(240).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Phenol.getFluid(1000))
+                .output(dust, Carbon, 6)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .fluidOutputs(Oxygen.getFluid(1000))
+                .duration(312).EUt(90).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Ethylene.getFluid(1000))
+                .output(dust, Carbon, 2)
+                .fluidOutputs(Hydrogen.getFluid(4000))
+                .duration(96).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Benzene.getFluid(1000))
+                .output(dust, Carbon, 6)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .duration(288).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Ethanol.getFluid(1000))
+                .output(dust, Carbon, 2)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .fluidOutputs(Oxygen.getFluid(1000))
+                .duration(144).EUt(90).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Toluene.getFluid(1000))
+                .output(dust, Carbon, 7)
+                .fluidOutputs(Hydrogen.getFluid(8000))
+                .duration(360).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Dimethylbenzene.getFluid(1000))
+                .output(dust, Carbon, 8)
+                .fluidOutputs(Hydrogen.getFluid(10000))
+                .duration(432).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Octane.getFluid(1000))
+                .output(dust, Carbon, 8)
+                .fluidOutputs(Hydrogen.getFluid(18000))
+                .duration(624).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Propene.getFluid(1000))
+                .output(dust, Carbon, 3)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .duration(144).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Ethane.getFluid(1000))
+                .output(dust, Carbon, 2)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .duration(128).EUt(60).buildAndRegister();
+
         // Thermal Centrifuge
         THERMAL_CENTRIFUGE_RECIPES.recipeBuilder()
                 .inputs(new ItemStack(Blocks.COBBLESTONE, 1, GTValues.W))

From e54bb80402211e073bcac50dcd6d42bc6b42a30e Mon Sep 17 00:00:00 2001
From: serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 17 Dec 2023 18:44:43 -0600
Subject: [PATCH 18/98] 2.8.4

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index e213ae3b547..cc4a87789c5 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,7 +7,7 @@ modGroup = gregtech
 
 # Version of your mod.
 # This field can be left empty if you want your mod's version to be determined by the latest git tag instead.
-modVersion = 2.8.3-beta
+modVersion = 2.8.4-beta
 
 # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version)
 includeMCVersionJar = true

From 0bd52347f97a60fa2eb434ca3613093cc11e20a4 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Sun, 17 Dec 2023 21:46:25 -0500
Subject: [PATCH 19/98] only access worldpipenet on server (#2310)

---
 .../gregtech/api/pipenet/WorldPipeNet.java    | 21 +++++++++++++++----
 .../api/pipenet/tile/TileEntityPipeBase.java  | 10 +++++----
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/main/java/gregtech/api/pipenet/WorldPipeNet.java b/src/main/java/gregtech/api/pipenet/WorldPipeNet.java
index 23860461888..03211cc377c 100644
--- a/src/main/java/gregtech/api/pipenet/WorldPipeNet.java
+++ b/src/main/java/gregtech/api/pipenet/WorldPipeNet.java
@@ -1,5 +1,7 @@
 package gregtech.api.pipenet;
 
+import gregtech.api.util.GTLog;
+
 import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.nbt.NBTTagList;
 import net.minecraft.util.EnumFacing;
@@ -12,7 +14,11 @@
 import org.jetbrains.annotations.NotNull;
 
 import java.lang.ref.WeakReference;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public abstract class WorldPipeNet> extends WorldSavedData {
 
@@ -35,9 +41,16 @@ protected void setWorldAndInit(World world) {
         }
     }
 
-    public static String getDataID(final String baseID, final World world) {
-        if (world == null || world.isRemote)
-            throw new RuntimeException("WorldPipeNet should only be created on the server!");
+    public static @NotNull String getDataID(@NotNull final String baseID, @NotNull final World world) {
+        // noinspection ConstantValue
+        if (world == null || world.isRemote) {
+            GTLog.logger.error("WorldPipeNet should only be created on the server!", new Throwable());
+            // noinspection ConstantValue
+            if (world == null) {
+                return baseID;
+            }
+        }
+
         int dimension = world.provider.getDimension();
         return dimension == 0 ? baseID : baseID + '.' + dimension;
     }
diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
index b1ec074d9d6..84897a022e8 100644
--- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
+++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
@@ -544,10 +544,12 @@ public boolean shouldRefresh(@NotNull World world, @NotNull BlockPos pos, IBlock
     @Override
     public void onChunkUnload() {
         super.onChunkUnload();
-        WorldPipeNet worldPipeNet = getPipeBlock().getWorldPipeNet(getWorld());
-        PipeNet net = worldPipeNet.getNetFromPos(pos);
-        if (net != null) {
-            net.onChunkUnload();
+        if (!world.isRemote) {
+            WorldPipeNet worldPipeNet = getPipeBlock().getWorldPipeNet(getWorld());
+            PipeNet net = worldPipeNet.getNetFromPos(pos);
+            if (net != null) {
+                net.onChunkUnload();
+            }
         }
     }
 

From c4060fa6d3ea8c0d6b8ed9f9719cfbd841261312 Mon Sep 17 00:00:00 2001
From: serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 17 Dec 2023 20:46:51 -0600
Subject: [PATCH 20/98] 2.8.5

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index cc4a87789c5..8cc69185de4 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,7 +7,7 @@ modGroup = gregtech
 
 # Version of your mod.
 # This field can be left empty if you want your mod's version to be determined by the latest git tag instead.
-modVersion = 2.8.4-beta
+modVersion = 2.8.5-beta
 
 # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version)
 includeMCVersionJar = true

From 8a2ca325be08cc6dc6c506db76b1c470716d2c19 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Thu, 28 Dec 2023 19:49:43 -0500
Subject: [PATCH 21/98] update GHA workflows (#2270)

---
 .github/actions/build_setup/action.yml        | 30 +++++++
 .github/workflows/format_java.yml             | 29 +++++++
 .github/workflows/manage_pr_labels.yml        | 39 +++++++++
 .github/workflows/pr_artifact.yml             | 77 ----------------
 .github/workflows/pr_labels.yml               | 35 --------
 .github/workflows/pr_testing.yml              | 60 -------------
 .github/workflows/publish.yml                 | 87 -------------------
 .github/workflows/publish_project.yml         | 58 +++++++++++++
 .github/workflows/test_java.yml               | 31 +++++++
 .github/workflows/update_buildscript.yml      | 45 ++++------
 .github/workflows/update_gradle_cache.yml     | 39 ++++-----
 .github/workflows/validate_gradle_wrapper.yml |  7 +-
 12 files changed, 222 insertions(+), 315 deletions(-)
 create mode 100644 .github/actions/build_setup/action.yml
 create mode 100644 .github/workflows/format_java.yml
 create mode 100644 .github/workflows/manage_pr_labels.yml
 delete mode 100644 .github/workflows/pr_artifact.yml
 delete mode 100644 .github/workflows/pr_labels.yml
 delete mode 100644 .github/workflows/pr_testing.yml
 delete mode 100644 .github/workflows/publish.yml
 create mode 100644 .github/workflows/publish_project.yml
 create mode 100644 .github/workflows/test_java.yml

diff --git a/.github/actions/build_setup/action.yml b/.github/actions/build_setup/action.yml
new file mode 100644
index 00000000000..7409143dc18
--- /dev/null
+++ b/.github/actions/build_setup/action.yml
@@ -0,0 +1,30 @@
+name: Build Setup
+description: Setup for standard Java builds
+
+inputs:
+  update-cache:
+    description: If cache should be updated
+    required: false
+    default: false
+
+runs:
+  using: 'composite'
+
+  steps:
+  - name: Set up JDK 17
+    uses: actions/setup-java@v4
+    with:
+      distribution: zulu
+      java-version: 17
+
+  - name: Setup Gradle
+    uses: gradle/gradle-build-action@v2
+    with:
+      cache-write-only: ${{ inputs.update-cache }}
+      generate-job-summary: false
+      gradle-home-cache-includes: |
+        caches
+        caches/retro_futura_gradle
+        notifications
+        jdks
+        wrapper
diff --git a/.github/workflows/format_java.yml b/.github/workflows/format_java.yml
new file mode 100644
index 00000000000..e4537200c13
--- /dev/null
+++ b/.github/workflows/format_java.yml
@@ -0,0 +1,29 @@
+# Runs formatting requirements
+name: Java Formatting
+
+on:
+  push:
+    branches:
+      - master
+    paths: ['src/main/java/**', 'src/test/**']
+  pull_request:
+    paths: ['src/main/java/**', 'src/test/**']
+
+concurrency:
+  group: checks-${{ github.head_ref || github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  formatting:
+    name: Formatting
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout Repository
+        uses: actions/checkout@v4
+
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
+
+      - name: Run Spotless Formatting Check with Gradle
+        run: ./gradlew spotlessCheck --warning-mode all --build-cache
diff --git a/.github/workflows/manage_pr_labels.yml b/.github/workflows/manage_pr_labels.yml
new file mode 100644
index 00000000000..7dcddd620b4
--- /dev/null
+++ b/.github/workflows/manage_pr_labels.yml
@@ -0,0 +1,39 @@
+# Manages labels on PRs before allowing merging
+name: Pull Request Labels
+
+on:
+  pull_request:
+    types:
+      - opened
+      - labeled
+      - unlabeled
+      - synchronize
+
+# if a second commit is pushed quickly after the first, cancel the first one's build
+concurrency:
+  group: pr-labels-${{ github.head_ref }}
+  cancel-in-progress: true
+
+jobs:
+  Labels:
+    runs-on: ubuntu-latest
+
+    permissions:
+      pull-requests: read # needed to utilize required-labels
+
+    steps:
+      - name: Check for Merge-Blocking Labels # blocks merge if present
+        uses: mheap/github-action-required-labels@v5
+        with:
+          mode: exactly
+          count: 0
+          labels: 'status: do not merge'
+          exit_type: failure
+
+      - name: Check for Required Labels # require at least one of these labels
+        uses: mheap/github-action-required-labels@v5
+        with:
+          mode: minimum
+          count: 1
+          labels: 'type: feature, type: bug, type: refactor, type: translation, ignore changelog'
+          exit_type: failure
diff --git a/.github/workflows/pr_artifact.yml b/.github/workflows/pr_artifact.yml
deleted file mode 100644
index 54187e2e326..00000000000
--- a/.github/workflows/pr_artifact.yml
+++ /dev/null
@@ -1,77 +0,0 @@
-# Creates a built artifact jar for apropriately labeled Pull Requests
-name: PR Artifact
-
-on:
-  pull_request:
-    types: 
-      - labeled
-      - synchronize
-
-# if a second commit is pushed quickly after the first, cancel the first one's build
-concurrency:
-  group: build-artifact-${{github.head_ref}}
-  cancel-in-progress: true
-
-env:
-  ARTIFACT_NAME: 'gregtech-dev'
-  NOTIFICATION_BODY: |
-    This Pull Request has automatic artifact deployment enabled. Download the latest build [here](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}), and extract the contents.
-
-jobs:
-  Build_Artifact:
-    if: contains(github.event.pull_request.labels.*.name, format('deployment{0} artifact', ':'))
-    runs-on: ubuntu-latest
-
-    permissions: 
-      pull-requests: write # needed to make a comment
-      contents: read # needed to checkout the repo if defining other permissions
-
-    steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v3
-
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
-
-      - name: Build Project
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'build --build-cache --no-daemon ' # disable daemon since only one gradle operation will happen
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-
-      - name: Determine Artifact Name
-        id: artifact_name
-        run: |
-          FILE=(build/libs/*)
-          echo "artifact_name=${FILE[0]}" >> $GITHUB_OUTPUT
-
-      - name: Publish Artifact
-        uses: actions/upload-artifact@v3
-        with:
-          name: "${{env.ARTIFACT_NAME}}-${{github.head_ref}}-${{github.sha}}"
-          path: "${{steps.artifact_name.outputs.artifact_name}}"
-          if-no-files-found: error
-
-      - name: Find Existing Comment
-        uses: peter-evans/find-comment@v2
-        id: find-existing
-        with:
-          issue-number: ${{github.event.pull_request.number}}
-          comment-author: 'github-actions[bot]'
-          body-includes: 'Download the latest build [here]'
-
-      - name: Create or Update Artifact Publish Notification
-        uses: peter-evans/create-or-update-comment@v2
-        with:
-          issue-number: ${{github.event.pull_request.number}}
-          comment-id: ${{steps.find-existing.outputs.comment-id}}
-          edit-mode: replace
-          body: ${{env.NOTIFICATION_BODY}}
diff --git a/.github/workflows/pr_labels.yml b/.github/workflows/pr_labels.yml
deleted file mode 100644
index a47b267ec3c..00000000000
--- a/.github/workflows/pr_labels.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-# Manages labels on PRs before allowing merging
-name: PR labels
-
-on:
-  pull_request:
-    types: [opened, labeled, unlabeled, synchronize]
-
-# if a second commit is pushed quickly after the first, cancel the first one's build
-concurrency:
-  group: pr-labels-${{github.head_ref}}
-  cancel-in-progress: true
-
-jobs:
-  Labels:
-    runs-on: ubuntu-latest
-
-    permissions: 
-      pull-requests: read # needed to utilize required-labels
-
-    steps:
-      - name: Merge-Blocking Labels # blocks merge if present
-        uses: mheap/github-action-required-labels@v3
-        with:
-          mode: exactly
-          count: 0
-          labels: "status: do not merge"
-          exit_type: failure
-      
-      - name: Required Changelog Labels # require at least one of these labels
-        uses: mheap/github-action-required-labels@v3
-        with:
-          mode: minimum
-          count: 1
-          labels: "type: feature, type: bug, type: refactor, type: translation, ignore changelog"
-          exit_type: failure
diff --git a/.github/workflows/pr_testing.yml b/.github/workflows/pr_testing.yml
deleted file mode 100644
index 7761d2a8555..00000000000
--- a/.github/workflows/pr_testing.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# Runs tests and other checks on Pull Requests
-name: PR Testing
-
-on:
-  pull_request:
-    branches:
-      - master
-
-# if a second commit is pushed quickly after the first, cancel the first one's build
-concurrency:
-  group: pr-testing-${{github.head_ref}}
-  cancel-in-progress: true
-
-jobs:
-  Test:
-    runs-on: ubuntu-latest
-
-    steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v3
-
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
-
-      - name: Run Tests
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'test --build-cache --no-daemon' # disable daemon since only one gradle operation will happen
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-
-  Formatting:
-    runs-on: ubuntu-latest
-
-    steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v3
-
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
-
-      - name: Run Spotless
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'spotlessCheck --build-cache'
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
deleted file mode 100644
index df5366133a1..00000000000
--- a/.github/workflows/publish.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-# Publishes built jars to distribution platforms
-name: Publish
-
-on:
-  push:
-    tags:
-      - 'v[0-9]+.[0-9]+.[0-9]+' # any semver tag, e.g. v1.2.3
-
-env:
-  # link to the changelog with a format code for the version
-  CHANGELOG_LOCATION: "Changelog is available [here](https://github.com/${{github.repository}}/releases/tag/${{github.ref_name}})"
-  # type of release
-  RELEASE_TYPE: "beta"
-
-jobs:
-  Publish:
-    runs-on: ubuntu-latest
-
-    permissions: 
-      contents: write # needed to create GitHub releases
-
-    steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v3
-      
-      - name: Check for Duplicate Tags
-        run: |
-          if git rev-parse -q --verify "refs/tags/${{ github.ref }}" >/dev/null; then
-            echo "Tag already exists. A version bump is required."
-            exit 1
-          fi
-
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
-      
-      - name: Build Project
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'build --build-cache --daemon' # use the daemon here so the rest of the process is faster
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-      
-      - name: Publish to GitHub
-        uses: softprops/action-gh-release@v1
-        with:
-          files: "build/libs/*.jar"
-          generate_release_notes: true
-          fail_on_unmatched_files: true
-
-      - name: Publish to Curseforge
-        uses: gradle/gradle-build-action@v2
-        env:
-          CURSEFORGE_API_KEY: "${{secrets.CURSEFORGE_API_KEY}}"
-          CURSEFORGE_PROJECT_ID: "${{secrets.CURSEFORGE_PROJECT_ID}}"
-          CHANGELOG_LOCATION: "${{env.CHANGELOG_LOCATION}}"
-          RELEASE_TYPE: "${{env.RELEASE_TYPE}}"
-        with:
-          arguments: 'curseforge --daemon'
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-
-      - name: Publish to Modrinth
-        uses: gradle/gradle-build-action@v2
-        env:
-          MODRINTH_API_KEY: "${{secrets.MODRINTH_API_KEY}}"
-          MODRINTH_PROJECT_ID: "${{secrets.MODRINTH_PROJECT_ID}}"
-          CHANGELOG_LOCATION: "${{env.CHANGELOG_LOCATION}}"
-          RELEASE_TYPE: "${{env.RELEASE_TYPE}}"
-        with:
-          arguments: 'modrinth --daemon'
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml
new file mode 100644
index 00000000000..2172ac6806e
--- /dev/null
+++ b/.github/workflows/publish_project.yml
@@ -0,0 +1,58 @@
+# Publishes the project to GitHub Releases, CurseForge, and Modrinth
+name: Publish Project
+
+on:
+  push:
+    tags:
+      - 'v[0-9]+.[0-9]+.[0-9]+' # any SemVer tag, e.g. v1.2.3
+
+env:
+  # link to the changelog with a format code for the version
+  CHANGELOG_LOCATION: "Changelog is available [here](https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }})"
+  # type of release
+  RELEASE_TYPE: 'beta'
+
+concurrency:
+  group: publish-${{ github.head_ref || github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  publish:
+    name: Publish
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: write # needed to create GitHub releases
+
+    steps:
+      - name: Checkout Repository
+        uses: actions/checkout@v4
+
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
+
+      - name: Build Project
+        run: ./gradlew build --warning-mode all --build-cache
+
+      - name: Publish to GitHub
+        uses: softprops/action-gh-release@v1
+        with:
+          files: "build/libs/*.jar"
+          generate_release_notes: true
+          fail_on_unmatched_files: true
+
+      - name: Publish to Curseforge
+        env:
+          CURSEFORGE_API_KEY: "${{ secrets.CURSEFORGE_API_KEY }}"
+          CURSEFORGE_PROJECT_ID: "${{ secrets.CURSEFORGE_PROJECT_ID }}"
+          CHANGELOG_LOCATION: "${{ env.CHANGELOG_LOCATION }}"
+          RELEASE_TYPE: "${{ env.RELEASE_TYPE }}"
+        run: ./gradlew curseforge --warning-mode all --build-cache
+
+      - name: Publish to Modrinth
+        env:
+          MODRINTH_API_KEY: "${{ secrets.MODRINTH_API_KEY }}"
+          MODRINTH_PROJECT_ID: "${{ secrets.MODRINTH_PROJECT_ID }}"
+          CHANGELOG_LOCATION: "${{ env.CHANGELOG_LOCATION }}"
+          RELEASE_TYPE: "${{ env.RELEASE_TYPE }}"
+        run: ./gradlew modrinth --warning-mode all --build-cache
diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml
new file mode 100644
index 00000000000..4840c9fa34d
--- /dev/null
+++ b/.github/workflows/test_java.yml
@@ -0,0 +1,31 @@
+# Runs tests
+name: Java Tests
+
+on:
+  push:
+    branches:
+      - master
+    paths: ['src/main/java/**', 'src/test/**', 'src/api/java/**', 'gradle/**', '**.gradle', 'gradle.properties',
+            'gradlew**', 'src/main/resources/*_at.cfg']
+  pull_request:
+    paths: ['src/main/java/**', 'src/test/**', 'src/api/java/**', 'gradle/**', '**.gradle', 'gradle.properties',
+            'gradlew**', 'src/main/resources/*_at.cfg']
+
+concurrency:
+  group: checks-${{ github.head_ref || github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  test:
+    name: Tests
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout Repository
+        uses: actions/checkout@v4
+
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
+
+      - name: Run Tests with Gradle
+        run: ./gradlew test --warning-mode all --build-cache
diff --git a/.github/workflows/update_buildscript.yml b/.github/workflows/update_buildscript.yml
index f8107f648d5..45fa46819d2 100644
--- a/.github/workflows/update_buildscript.yml
+++ b/.github/workflows/update_buildscript.yml
@@ -1,41 +1,33 @@
 # Checks daily to see if the buildscript is in need of an update
-name: Buildscript Updating
+name: Update Buildscript
 
 on:
   workflow_dispatch:
   schedule:
-    - cron: "0 0 * * *" # "min hr day month year", so run once per day
+    - cron: '0 0 * * *' # "min hr day month year", so run once per day
 
 jobs:
   buildscript-update:
     runs-on: ubuntu-latest
+
     # Avoid running this workflow on forks
     if: github.repository == 'GregTechCEu/GregTech'
+
     permissions:
       contents: write
       pull-requests: write
+
     steps:
-      - name: Checkout
-        uses: actions/checkout@v3
+      - name: Checkout Repository
+        uses: actions/checkout@v4
 
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
 
-      - name: Run script updater
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'updateBuildScript'
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
+      - name: Run Buildscript Updater
+        run: ./gradlew updateBuildScript --warning-mode all --build-cache
 
-      - name: Get new script version
+      - name: Get New Buildscript Version
         id: version-check
         run: |
           new_version=$(head -1 build.gradle | sed -r 's|//version: (.*)|\1|g')
@@ -43,7 +35,7 @@ jobs:
 
       - name: Create Pull Request
         id: create-pull-request
-        uses: peter-evans/create-pull-request@v4
+        uses: peter-evans/create-pull-request@v5
         env:
           GITHUB_TOKEN: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }}
         with:
@@ -56,11 +48,8 @@ jobs:
           body: This pull request is created by the buildscript-update workflow
           labels: ignore changelog
 
-      - name: Enable pull request auto-merge
-        id: pull-request-auto-merge
+      - name: Enable Pull-Request Auto-Merge
         if: steps.create-pull-request.outputs.pull-request-operation == 'created'
-        uses: peter-evans/enable-pull-request-automerge@v3
-        with:
-          token: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }}
-          pull-request-number: ${{ steps.create-pull-request.outputs.pull-request-number }}
-          merge-method: squash
+        run: gh pr merge --squash --auto "${{ steps.create-pull-request.outputs.pull-request-number }}"
+        env:
+          GH_TOKEN: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }}
diff --git a/.github/workflows/update_gradle_cache.yml b/.github/workflows/update_gradle_cache.yml
index 9853000d7ac..ba93b16779a 100644
--- a/.github/workflows/update_gradle_cache.yml
+++ b/.github/workflows/update_gradle_cache.yml
@@ -1,39 +1,30 @@
-# Updates the Gradle Cache when relevant files change
+# Updates the Gradle Cache when necessary
 name: Update Gradle Cache
 
 on:
-  workflow_dispatch:
   push:
     branches:
       - master
-    paths:
-      - "gradle**" # covers gradle folder, gradle.properties, gradlew
-      - "build.gradle*"
-      - "settings.gradle*"
-      - "src/main/resources/*_at.cfg" # access transformers
+    paths: ['gradle/**', '**.gradle', 'gradle.properties', 'gradlew**', 'src/main/resources/*_at.cfg']
+  workflow_dispatch:
+
+concurrency:
+  group: gradle-cache-${{ github.ref }}
+  cancel-in-progress: true
 
 jobs:
-  Update_Cache:
+  update-cache:
+    name: Update Grade Cache
     runs-on: ubuntu-latest
 
     steps:
       - name: Checkout Repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
-      - name: Setup Java
-        uses: actions/setup-java@v3
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
         with:
-          distribution: 'zulu'
-          java-version: '17'
+          update-cache: true
 
-      - name: Update Cache
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'test --build-cache --no-daemon' # disable daemon since only one gradle operation will happen
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-          cache-write-only: true
+      - name: Build Project with Gradle
+        run: ./gradlew assemble --warning-mode all --build-cache
diff --git a/.github/workflows/validate_gradle_wrapper.yml b/.github/workflows/validate_gradle_wrapper.yml
index 6f7a9d4cbe9..591e487d7d5 100644
--- a/.github/workflows/validate_gradle_wrapper.yml
+++ b/.github/workflows/validate_gradle_wrapper.yml
@@ -1,4 +1,4 @@
-# Validates the integrity of the Gradle wrapper
+# Validates the integrity of the Gradle Wrapper
 name: Validate Gradle Wrapper
 
 on:
@@ -13,9 +13,8 @@ on:
     paths:
       - 'gradle/**'
 
-# if a second commit is pushed quickly after the first, cancel the first one's build
 concurrency:
-  group: gradle-wrapper-validation-${{github.head_ref}}
+  group: gradle-wrapper-validation-${{ github.head_ref || github.ref }}
   cancel-in-progress: true
 
 jobs:
@@ -24,7 +23,7 @@ jobs:
 
     steps:
       - name: Checkout Repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Validate Gradle Wrapper
         uses: gradle/wrapper-validation-action@v1

From 3ff51be2b7f6b210826acd38942ff94dd31ee772 Mon Sep 17 00:00:00 2001
From: ALongStringOfNumbers
 <31759736+ALongStringOfNumbers@users.noreply.github.com>
Date: Thu, 28 Dec 2023 18:30:01 -0700
Subject: [PATCH 22/98] Fix a couple incomplete recieveCustomData calls (#2322)

---
 .../electric/MetaTileEntityCleanroom.java     | 32 ++++++++++++++++---
 .../MetaTileEntityMultiFluidHatch.java        |  8 +++++
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java
index b9fd8ebf60c..0c34ab575ec 100644
--- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java
+++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java
@@ -1,15 +1,31 @@
 package gregtech.common.metatileentities.multi.electric;
 
 import gregtech.api.GTValues;
-import gregtech.api.capability.*;
+import gregtech.api.capability.GregtechDataCodes;
+import gregtech.api.capability.GregtechTileCapabilities;
+import gregtech.api.capability.IEnergyContainer;
+import gregtech.api.capability.IMufflerHatch;
+import gregtech.api.capability.IWorkable;
 import gregtech.api.capability.impl.CleanroomLogic;
 import gregtech.api.capability.impl.EnergyContainerList;
 import gregtech.api.metatileentity.IDataInfoProvider;
 import gregtech.api.metatileentity.MetaTileEntity;
 import gregtech.api.metatileentity.SimpleGeneratorMetaTileEntity;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
-import gregtech.api.metatileentity.multiblock.*;
-import gregtech.api.pattern.*;
+import gregtech.api.metatileentity.multiblock.CleanroomType;
+import gregtech.api.metatileentity.multiblock.FuelMultiblockController;
+import gregtech.api.metatileentity.multiblock.ICleanroomProvider;
+import gregtech.api.metatileentity.multiblock.ICleanroomReceiver;
+import gregtech.api.metatileentity.multiblock.IMultiblockPart;
+import gregtech.api.metatileentity.multiblock.MultiblockAbility;
+import gregtech.api.metatileentity.multiblock.MultiblockDisplayText;
+import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase;
+import gregtech.api.pattern.BlockPattern;
+import gregtech.api.pattern.FactoryBlockPattern;
+import gregtech.api.pattern.MultiblockShapeInfo;
+import gregtech.api.pattern.PatternMatchContext;
+import gregtech.api.pattern.PatternStringError;
+import gregtech.api.pattern.TraceabilityPredicate;
 import gregtech.api.util.BlockInfo;
 import gregtech.api.util.GTUtility;
 import gregtech.api.util.TextComponentUtil;
@@ -61,7 +77,13 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
 
 public class MetaTileEntityCleanroom extends MultiblockWithDisplayBase
                                      implements ICleanroomProvider, IWorkable, IDataInfoProvider {
@@ -643,6 +665,8 @@ public void receiveCustomData(int dataId, PacketBuffer buf) {
         if (dataId == GregtechDataCodes.UPDATE_STRUCTURE_SIZE) {
             this.lDist = buf.readInt();
             this.rDist = buf.readInt();
+            this.bDist = buf.readInt();
+            this.fDist = buf.readInt();
             this.hDist = buf.readInt();
         } else if (dataId == GregtechDataCodes.WORKABLE_ACTIVE) {
             this.cleanroomLogic.setActive(buf.readBoolean());
diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java
index cf77abc3bb6..cf053eb8500 100644
--- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java
+++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java
@@ -122,6 +122,14 @@ public void receiveInitialSyncData(PacketBuffer buf) {
         this.workingEnabled = buf.readBoolean();
     }
 
+    @Override
+    public void receiveCustomData(int dataId, PacketBuffer buf) {
+        super.receiveCustomData(dataId, buf);
+        if (dataId == GregtechDataCodes.WORKING_ENABLED) {
+            this.workingEnabled = buf.readBoolean();
+        }
+    }
+
     @Override
     public NBTTagCompound writeToNBT(NBTTagCompound data) {
         super.writeToNBT(data);

From 3d3d97d4ee43135e7b8cd42c03713294d291ea7e Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+techlord22@users.noreply.github.com>
Date: Thu, 28 Dec 2023 20:32:04 -0500
Subject: [PATCH 23/98] fix test and formatting action concurrency groups

---
 .github/workflows/format_java.yml | 2 +-
 .github/workflows/test_java.yml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/format_java.yml b/.github/workflows/format_java.yml
index e4537200c13..e8d233df439 100644
--- a/.github/workflows/format_java.yml
+++ b/.github/workflows/format_java.yml
@@ -10,7 +10,7 @@ on:
     paths: ['src/main/java/**', 'src/test/**']
 
 concurrency:
-  group: checks-${{ github.head_ref || github.ref }}
+  group: formatting-${{ github.head_ref || github.ref }}
   cancel-in-progress: true
 
 jobs:
diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml
index 4840c9fa34d..11bc42e8067 100644
--- a/.github/workflows/test_java.yml
+++ b/.github/workflows/test_java.yml
@@ -12,7 +12,7 @@ on:
             'gradlew**', 'src/main/resources/*_at.cfg']
 
 concurrency:
-  group: checks-${{ github.head_ref || github.ref }}
+  group: tests-${{ github.head_ref || github.ref }}
   cancel-in-progress: true
 
 jobs:

From a4d15ffe85a5feb2605ef3cce7ffec0bd12da4fb Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Thu, 28 Dec 2023 19:40:27 -0600
Subject: [PATCH 24/98] Add some GT items to ExtraBees alveary mutator (#2315)

---
 .../integration/forestry/ForestryModule.java  | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/main/java/gregtech/integration/forestry/ForestryModule.java b/src/main/java/gregtech/integration/forestry/ForestryModule.java
index edd4080c33b..de316640666 100644
--- a/src/main/java/gregtech/integration/forestry/ForestryModule.java
+++ b/src/main/java/gregtech/integration/forestry/ForestryModule.java
@@ -7,12 +7,14 @@
 import gregtech.api.items.toolitem.ItemGTTool;
 import gregtech.api.modules.GregTechModule;
 import gregtech.api.recipes.machines.RecipeMapScanner;
+import gregtech.api.unification.OreDictUnifier;
 import gregtech.api.unification.material.Material;
 import gregtech.api.unification.material.Materials;
 import gregtech.api.unification.material.event.MaterialEvent;
 import gregtech.api.unification.material.info.MaterialFlags;
 import gregtech.api.unification.material.properties.OreProperty;
 import gregtech.api.unification.material.properties.PropertyKey;
+import gregtech.api.unification.ore.OrePrefix;
 import gregtech.common.items.ToolItems;
 import gregtech.integration.IntegrationModule;
 import gregtech.integration.IntegrationSubmodule;
@@ -25,6 +27,7 @@
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
 import net.minecraft.item.crafting.IRecipe;
 import net.minecraftforge.client.event.ModelRegistryEvent;
 import net.minecraftforge.event.RegistryEvent;
@@ -41,6 +44,8 @@
 import forestry.core.items.IColoredItem;
 import org.jetbrains.annotations.NotNull;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
 
@@ -160,6 +165,10 @@ public void init(FMLInitializationEvent event) {
             }
         }
 
+        if (Loader.isModLoaded(GTValues.MODID_EB)) {
+            registerAlvearyMutators();
+        }
+
         if (event.getSide() == Side.CLIENT) {
             if (ForestryUtil.apicultureEnabled()) {
                 if (ForestryConfig.enableGTBees) {
@@ -344,4 +353,31 @@ private static void createOreProperty(Material material, Material... byproducts)
         material.setProperty(PropertyKey.ORE, property);
         material.addFlags(MaterialFlags.DISABLE_ORE_BLOCK);
     }
+
+    private static void registerAlvearyMutators() {
+        try {
+            Class mutationHandler = Class.forName("binnie.extrabees.utils.AlvearyMutationHandler");
+            Method method = mutationHandler.getDeclaredMethod("addMutationItem", ItemStack.class, float.class);
+
+            registerAlvearyMutator(method, Materials.Uranium238, 2.0f);
+            registerAlvearyMutator(method, Materials.Uranium235, 4.0f);
+            registerAlvearyMutator(method, Materials.Plutonium241, 6.0f);
+            registerAlvearyMutator(method, Materials.Plutonium239, 8.0f);
+            registerAlvearyMutator(method, Materials.NaquadahEnriched, 10.0f);
+            registerAlvearyMutator(method, Materials.Naquadria, 15.0f);
+        } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
+            IntegrationModule.logger.error("Could not register GT Alveary mutators!");
+        }
+    }
+
+    private static void registerAlvearyMutator(Method method, Material material, float chance) {
+        try {
+            ItemStack stack = OreDictUnifier.get(OrePrefix.dust, material);
+            if (stack != ItemStack.EMPTY) {
+                method.invoke(null, stack, chance);
+            }
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            IntegrationModule.logger.error("Could not register GT Alveary mutators!");
+        }
+    }
 }

From 3d1c1670b67d46dfbe02e7669a95baa8a2fbb621 Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Thu, 28 Dec 2023 19:40:47 -0600
Subject: [PATCH 25/98] Update build script version to 1702805890 (#2309)

Co-authored-by: DStrand1 
Co-authored-by: alongstringofnumbers 
---
 build.gradle      | 6 ++++--
 gradle.properties | 4 +++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/build.gradle b/build.gradle
index 29b2ba602bf..913152a71c5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,4 @@
-//version: 1702244235
+//version: 1702805890
 /*
  * DO NOT CHANGE THIS FILE!
  * Also, you may replace this file at any time if there is an update available.
@@ -72,6 +72,7 @@ propertyDefaultIfUnset("usesShadowedDependencies", false)
 propertyDefaultIfUnset("minimizeShadowedDependencies", true)
 propertyDefaultIfUnset("relocateShadowedDependencies", true)
 propertyDefaultIfUnset("separateRunDirectories", false)
+propertyDefaultIfUnset("versionDisplayFormat", '$MOD_NAME \u2212 $VERSION')
 propertyDefaultIfUnsetWithEnvVar("modrinthProjectId", "", "MODRINTH_PROJECT_ID")
 propertyDefaultIfUnset("modrinthRelations", "")
 propertyDefaultIfUnsetWithEnvVar("curseForgeProjectId", "", "CURSEFORGE_PROJECT_ID")
@@ -889,7 +890,7 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
             def changelogFile = getChangelog()
             def changelogRaw = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
 
-            mainFile.displayName = "${modName}: ${modVersion}"
+            mainFile.displayName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion)
             mainFile.releaseType = getReleaseType()
             mainFile.changelog = changelogRaw
             mainFile.changelogType = 'markdown'
@@ -929,6 +930,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
     modrinth {
         token = modrinthApiKey.getOrElse('debug_token')
         projectId = modrinthProjectId
+        versionName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion)
         changelog = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
         versionType = getReleaseType()
         versionNumber = modVersion
diff --git a/gradle.properties b/gradle.properties
index 8cc69185de4..2408eee2147 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -90,7 +90,9 @@ relocateShadowedDependencies = true
 # Separate run directories into "run/client" for runClient task, and "run/server" for runServer task.
 # Useful for debugging a server and client simultaneously. If not enabled, it will be in the standard location "run/"
 separateRunDirectories = false
-
+# The display name format of versions published to Curse and Modrinth. $MOD_NAME and $VERSION are available variables.
+# Default: $MOD_NAME \u2212 $VERSION. \u2212 is the minus character which looks much better than the hyphen minus on Curse.
+versionDisplayFormat=$MOD_NAME: $VERSION
 
 # Publishing to modrinth requires you to set the MODRINTH_API_KEY environment variable to your current modrinth API token.
 

From b271dfa7755cbac6bdc505d678844fd8d422022a Mon Sep 17 00:00:00 2001
From: ALongStringOfNumbers
 <31759736+ALongStringOfNumbers@users.noreply.github.com>
Date: Fri, 29 Dec 2023 10:26:30 -0700
Subject: [PATCH 26/98] Change order of item in Research Station JEI page
 (#2325)

---
 .../java/gregtech/api/recipes/ui/impl/ResearchStationUI.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/gregtech/api/recipes/ui/impl/ResearchStationUI.java b/src/main/java/gregtech/api/recipes/ui/impl/ResearchStationUI.java
index 917fc953dab..a0485997884 100644
--- a/src/main/java/gregtech/api/recipes/ui/impl/ResearchStationUI.java
+++ b/src/main/java/gregtech/api/recipes/ui/impl/ResearchStationUI.java
@@ -39,11 +39,11 @@ public ModularUI.Builder createJeiUITemplate(IItemHandlerModifiable importItems,
                         GuiTextures.PROGRESS_BAR_RESEARCH_STATION_1, ProgressWidget.MoveType.HORIZONTAL))
                 .widget(new ProgressWidget(pairedSuppliers.getRight(), 119, 32, 10, 18,
                         GuiTextures.PROGRESS_BAR_RESEARCH_STATION_2, ProgressWidget.MoveType.VERTICAL_DOWNWARDS))
-                .widget(new SlotWidget(importItems, 0, 115, 50, true, true)
+                .widget(new SlotWidget(exportItems, 0, 115, 50, true, true)
                         .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.DATA_ORB_OVERLAY))
                 .widget(new SlotWidget(importItems, 1, 43, 21, true, true)
                         .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.SCANNER_OVERLAY))
-                .widget(new SlotWidget(exportItems, 0, 97, 21, true, true)
+                .widget(new SlotWidget(importItems, 0, 97, 21, true, true)
                         .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.RESEARCH_STATION_OVERLAY));
     }
 }

From e8e3c702c2e01ab75b0213de9cf267b2bf23b9d6 Mon Sep 17 00:00:00 2001
From: "Josiah \"Rebase\" Roberts"
 <37082009+josiah-roberts@users.noreply.github.com>
Date: Fri, 29 Dec 2023 12:19:22 -0600
Subject: [PATCH 27/98] Fix large turbine recipe selection (#2324)

---
 .../LargeTurbineWorkableHandler.java          | 68 +++++++++++++++++--
 1 file changed, 62 insertions(+), 6 deletions(-)

diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java
index 482d6c710b5..db414ae4da7 100644
--- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java
+++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java
@@ -1,6 +1,7 @@
 package gregtech.common.metatileentities.multi.electric.generator;
 
 import gregtech.api.GTValues;
+import gregtech.api.capability.IMultipleTankHandler;
 import gregtech.api.capability.IRotorHolder;
 import gregtech.api.capability.impl.MultiblockFuelRecipeLogic;
 import gregtech.api.metatileentity.multiblock.FuelMultiblockController;
@@ -8,13 +9,20 @@
 import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController;
 import gregtech.api.recipes.Recipe;
 import gregtech.api.recipes.RecipeBuilder;
+import gregtech.api.recipes.RecipeMap;
+import gregtech.api.util.GTUtility;
 
+import net.minecraft.item.ItemStack;
 import net.minecraft.util.math.MathHelper;
 import net.minecraftforge.fluids.FluidStack;
 import net.minecraftforge.fluids.IFluidTank;
 import net.minecraftforge.fluids.capability.IFluidHandler;
+import net.minecraftforge.items.IItemHandlerModifiable;
+
+import org.jetbrains.annotations.Nullable;
 
 import java.util.List;
+import java.util.stream.Collectors;
 
 public class LargeTurbineWorkableHandler extends MultiblockFuelRecipeLogic {
 
@@ -42,7 +50,9 @@ protected void updateRecipeProgress() {
     public FluidStack getInputFluidStack() {
         // Previous Recipe is always null on first world load, so try to acquire a new recipe
         if (previousRecipe == null) {
-            Recipe recipe = findRecipe(Integer.MAX_VALUE, getInputInventory(), getInputTank());
+            // previousRecipe is set whenever a valid recipe is found
+            // if it's not set, find *any* recipe we have at least the base (non-parallel) inputs for
+            Recipe recipe = super.findRecipe(Integer.MAX_VALUE, getInputInventory(), getInputTank());
 
             return recipe == null ? null : getInputTank().drain(
                     new FluidStack(recipe.getFluidInputs().get(0).getInputFluidStack().getFluid(), Integer.MAX_VALUE),
@@ -73,6 +83,53 @@ protected long boostProduction(long production) {
         return 0;
     }
 
+    private int getParallel(Recipe recipe, double totalHolderEfficiencyCoefficient, int turbineMaxVoltage) {
+        return MathHelper.ceil((turbineMaxVoltage - this.excessVoltage) /
+                (Math.abs(recipe.getEUt()) * totalHolderEfficiencyCoefficient));
+    }
+
+    private boolean canDoRecipeWithParallel(Recipe recipe) {
+        IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder();
+        if (rotorHolder == null || !rotorHolder.hasRotor())
+            return false;
+        double totalHolderEfficiencyCoefficient = rotorHolder.getTotalEfficiency() / 100.0;
+        int turbineMaxVoltage = (int) getMaxVoltage();
+        int parallel = getParallel(recipe, totalHolderEfficiencyCoefficient, turbineMaxVoltage);
+
+        FluidStack recipeFluidStack = recipe.getFluidInputs().get(0).getInputFluidStack();
+
+        // Intentionally not using this.getInputFluidStack because that is locked to the previous recipe
+        FluidStack inputFluid = getInputTank().drain(
+                new FluidStack(recipeFluidStack.getFluid(), Integer.MAX_VALUE),
+                false);
+        return inputFluid != null && inputFluid.amount >= recipeFluidStack.amount * parallel;
+    }
+
+    @Override
+    protected boolean checkPreviousRecipe() {
+        return super.checkPreviousRecipe() && canDoRecipeWithParallel(this.previousRecipe);
+    }
+
+    @Override
+    protected @Nullable Recipe findRecipe(long maxVoltage, IItemHandlerModifiable inputs,
+                                          IMultipleTankHandler fluidInputs) {
+        RecipeMap map = getRecipeMap();
+        if (map == null || !isRecipeMapValid(map)) {
+            return null;
+        }
+
+        final List items = GTUtility.itemHandlerToList(inputs).stream().filter(s -> !s.isEmpty()).collect(
+                Collectors.toList());
+        final List fluids = GTUtility.fluidHandlerToList(fluidInputs).stream()
+                .filter(f -> f != null && f.amount != 0)
+                .collect(Collectors.toList());
+
+        return map.find(items, fluids, recipe -> {
+            if (recipe.getEUt() > maxVoltage) return false;
+            return recipe.matches(false, inputs, fluidInputs) && this.canDoRecipeWithParallel(recipe);
+        });
+    }
+
     @Override
     protected boolean prepareRecipe(Recipe recipe) {
         IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder();
@@ -83,13 +140,12 @@ protected boolean prepareRecipe(Recipe recipe) {
         FluidStack recipeFluidStack = recipe.getFluidInputs().get(0).getInputFluidStack();
         int parallel = 0;
 
-        if (excessVoltage >= turbineMaxVoltage) {
-            excessVoltage -= turbineMaxVoltage;
+        if (this.excessVoltage >= turbineMaxVoltage) {
+            this.excessVoltage -= turbineMaxVoltage;
         } else {
             double holderEfficiency = rotorHolder.getTotalEfficiency() / 100.0;
             // get the amount of parallel required to match the desired output voltage
-            parallel = MathHelper.ceil((turbineMaxVoltage - excessVoltage) /
-                    (Math.abs(recipe.getEUt()) * holderEfficiency));
+            parallel = getParallel(recipe, holderEfficiency, turbineMaxVoltage);
 
             // Null check fluid here, since it can return null on first join into world or first form
             FluidStack inputFluid = getInputFluidStack();
@@ -98,7 +154,7 @@ protected boolean prepareRecipe(Recipe recipe) {
             }
 
             // this is necessary to prevent over-consumption of fuel
-            excessVoltage += (int) (parallel * Math.abs(recipe.getEUt()) * holderEfficiency - turbineMaxVoltage);
+            this.excessVoltage += (int) (parallel * Math.abs(recipe.getEUt()) * holderEfficiency - turbineMaxVoltage);
         }
 
         // rebuild the recipe and adjust voltage to match the turbine

From dec3f76e5fe11df8cfb6e1aca73431af577c89bc Mon Sep 17 00:00:00 2001
From: "Josiah \"Rebase\" Roberts"
 <37082009+josiah-roberts@users.noreply.github.com>
Date: Fri, 29 Dec 2023 12:53:58 -0600
Subject: [PATCH 28/98] Use locale formatting where possible in WAILA and The
 One Probe (#2327)

---
 .../hwyla/provider/ConverterDataProvider.java       | 11 +++++++----
 .../hwyla/provider/DiodeDataProvider.java           |  7 +++++--
 .../hwyla/provider/PrimitivePumpDataProvider.java   |  4 +++-
 .../hwyla/provider/RecipeLogicDataProvider.java     |  5 +++--
 .../hwyla/provider/SteamBoilerDataProvider.java     |  4 +++-
 .../hwyla/provider/TransformerDataProvider.java     |  5 +++--
 .../theoneprobe/provider/ConverterInfoProvider.java | 13 +++++++++----
 .../theoneprobe/provider/CoverInfoProvider.java     |  5 +++--
 .../provider/ElectricContainerInfoProvider.java     |  5 +++--
 .../provider/LaserContainerInfoProvider.java        |  6 ++++--
 .../provider/PrimitivePumpInfoProvider.java         |  5 ++++-
 .../provider/RecipeLogicInfoProvider.java           |  7 +++++--
 .../provider/SteamBoilerInfoProvider.java           |  4 +++-
 .../provider/TransformerInfoProvider.java           |  5 +++--
 .../theoneprobe/provider/WorkableInfoProvider.java  |  6 ++++--
 15 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/src/main/java/gregtech/integration/hwyla/provider/ConverterDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/ConverterDataProvider.java
index 341334681c7..593832936cc 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/ConverterDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/ConverterDataProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.capability.FeCompat;
 import gregtech.api.capability.GregtechCapabilities;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.converter.ConverterTrait;
 
 import net.minecraft.client.resources.I18n;
@@ -67,19 +68,21 @@ protected NBTTagCompound getNBTData(ConverterTrait capability, NBTTagCompound ta
                 tooltip.add(I18n.format("gregtech.top.convert_fe"));
                 if (accessor.getSide() == frontFacing) {
                     tooltip.add(I18n.format("gregtech.top.transform_output") + " " + voltageName +
-                            TextFormatting.RESET + " (" + amperage + "A)");
+                            TextFormatting.RESET + " (" + TextFormattingUtil.formatNumbers(amperage) + "A)");
                 } else {
                     tooltip.add(I18n.format("gregtech.top.transform_input") + " " +
-                            FeCompat.toFe(voltage * amperage, FeCompat.ratio(true)) + " FE");
+                            TextFormattingUtil.formatNumbers(FeCompat.toFe(voltage * amperage, FeCompat.ratio(true))) +
+                            " FE");
                 }
             } else {
                 tooltip.add(I18n.format("gregtech.top.convert_eu"));
                 if (accessor.getSide() == frontFacing) {
                     tooltip.add(I18n.format("gregtech.top.transform_output") + " " +
-                            FeCompat.toFe(voltage * amperage, FeCompat.ratio(false)) + " FE");
+                            TextFormattingUtil.formatNumbers(FeCompat.toFe(voltage * amperage, FeCompat.ratio(false))) +
+                            " FE");
                 } else {
                     tooltip.add(I18n.format("gregtech.top.transform_input") + " " + voltageName + TextFormatting.RESET +
-                            " (" + amperage + "A)");
+                            " (" + TextFormattingUtil.formatNumbers(amperage) + "A)");
                 }
             }
         }
diff --git a/src/main/java/gregtech/integration/hwyla/provider/DiodeDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/DiodeDataProvider.java
index 1000a11ff55..69e38bfaad7 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/DiodeDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/DiodeDataProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.capability.IEnergyContainer;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.electric.MetaTileEntityDiode;
 
 import net.minecraft.client.resources.I18n;
@@ -59,9 +60,11 @@ protected NBTTagCompound getNBTData(IEnergyContainer capability, NBTTagCompound
             final EnumFacing frontFacing = EnumFacing.byIndex(tag.getInteger("FrontFacing"));
 
             if (accessor.getSide() == frontFacing) { // output side
-                tooltip.add(I18n.format("gregtech.top.transform_output") + " " + outputAmperage + " A");
+                tooltip.add(I18n.format("gregtech.top.transform_output") + " " +
+                        TextFormattingUtil.formatNumbers(outputAmperage) + " A");
             } else {
-                tooltip.add(I18n.format("gregtech.top.transform_input") + " " + inputAmperage + " A");
+                tooltip.add(I18n.format("gregtech.top.transform_input") + " " +
+                        TextFormattingUtil.formatNumbers(inputAmperage) + " A");
             }
         }
         return tooltip;
diff --git a/src/main/java/gregtech/integration/hwyla/provider/PrimitivePumpDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/PrimitivePumpDataProvider.java
index 4af2e2f8915..3598647818f 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/PrimitivePumpDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/PrimitivePumpDataProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.metatileentity.multiblock.IPrimitivePump;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.client.resources.I18n;
 import net.minecraft.entity.player.EntityPlayerMP;
@@ -58,7 +59,8 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
         if (accessor.getNBTData().hasKey("gregtech.IPrimitivePump")) {
             NBTTagCompound tag = accessor.getNBTData().getCompoundTag("gregtech.IPrimitivePump");
             int production = tag.getInteger("Production");
-            tooltip.add(I18n.format("gregtech.top.primitive_pump_production") + " " + TextFormatting.AQUA + production +
+            tooltip.add(I18n.format("gregtech.top.primitive_pump_production") + " " + TextFormatting.AQUA +
+                    TextFormattingUtil.formatNumbers(production) +
                     TextFormatting.RESET + " L/s");
         }
         return tooltip;
diff --git a/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java
index f1a2a6b5a4c..655dd57aa20 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java
@@ -9,6 +9,7 @@
 import gregtech.api.metatileentity.multiblock.RecipeMapSteamMultiblockController;
 import gregtech.api.unification.material.Materials;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler;
 
 import net.minecraft.client.resources.I18n;
@@ -72,7 +73,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
                     MetaTileEntity mte = gtte.getMetaTileEntity();
                     if (mte instanceof SteamMetaTileEntity || mte instanceof MetaTileEntityLargeBoiler ||
                             mte instanceof RecipeMapSteamMultiblockController) {
-                        endText = ": " + absEUt + TextFormatting.RESET + " L/t " +
+                        endText = ": " + TextFormattingUtil.formatNumbers(absEUt) + TextFormatting.RESET + " L/t " +
                                 I18n.format(Materials.Steam.getUnlocalizedName());
                     }
                     AbstractRecipeLogic arl = mte.getRecipeLogic();
@@ -81,7 +82,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
                     }
                 }
                 if (endText == null) {
-                    endText = ": " + absEUt + TextFormatting.RESET + " EU/t (" +
+                    endText = ": " + TextFormattingUtil.formatNumbers(absEUt) + TextFormatting.RESET + " EU/t (" +
                             GTValues.VNF[GTUtility.getTierByVoltage(absEUt)] + TextFormatting.RESET + ")";
                 }
 
diff --git a/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java
index 85a3f738ca0..0baaab2927f 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.unification.material.Materials;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.steam.boiler.SteamBoiler;
 
 import net.minecraft.client.resources.I18n;
@@ -65,7 +66,8 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
 
                 // Creating steam
                 if (steamRate > 0 && hasWater) {
-                    tooltip.add(I18n.format("gregtech.top.energy_production") + ": " + (steamRate / 10) + " L/t " +
+                    tooltip.add(I18n.format("gregtech.top.energy_production") + ": " +
+                            TextFormattingUtil.formatNumbers(steamRate / 10) + " L/t " +
                             I18n.format(Materials.Steam.getUnlocalizedName()));
                 }
 
diff --git a/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java
index 49da30bf2da..e54792f8139 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.capability.IEnergyContainer;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.electric.MetaTileEntityTransformer;
 
 import net.minecraft.client.resources.I18n;
@@ -82,7 +83,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
                     .append(GTValues.VNF[GTUtility.getTierByVoltage(inputVoltage)])
                     .append(TextFormatting.RESET)
                     .append(" (")
-                    .append(inputAmperage)
+                    .append(TextFormattingUtil.formatNumbers(inputAmperage))
                     .append("A)");
 
             StringBuilder output = new StringBuilder()
@@ -90,7 +91,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
                     .append(GTValues.VNF[GTUtility.getTierByVoltage(outputVoltage)])
                     .append(TextFormatting.RESET)
                     .append(" (")
-                    .append(outputAmperage)
+                    .append(TextFormattingUtil.formatNumbers(outputAmperage))
                     .append("A)");
 
             // Step Up/Step Down line
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java
index 4a635e9058a..2ef4b0e3e05 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java
@@ -5,6 +5,7 @@
 import gregtech.api.capability.GregtechCapabilities;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.converter.ConverterTrait;
 
 import net.minecraft.entity.player.EntityPlayer;
@@ -45,18 +46,22 @@ protected void addProbeInfo(@NotNull ConverterTrait capability, @NotNull IProbeI
         if (capability.isFeToEu()) {
             if (data.getSideHit() == facing) {
                 probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_output*} " + voltageN +
-                        TextFormatting.GREEN + " (" + amperage + "A)");
+                        TextFormatting.GREEN + " (" + TextFormattingUtil.formatNumbers(amperage) + "A)");
             } else {
                 probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_input*} " + TextFormatting.RED +
-                        FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(true)) + " FE");
+                        TextFormattingUtil.formatNumbers(
+                                FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(true))) +
+                        " FE");
             }
         } else {
             if (data.getSideHit() == facing) {
                 probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_output*} " + TextFormatting.RED +
-                        FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(false)) + " FE");
+                        TextFormattingUtil.formatNumbers(
+                                FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(false))) +
+                        " FE");
             } else {
                 probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_input*} " + voltageN +
-                        TextFormatting.GREEN + " (" + amperage + "A)");
+                        TextFormatting.GREEN + " (" + TextFormattingUtil.formatNumbers(amperage) + "A)");
             }
         }
     }
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java
index 645e6774d3b..6656fcc9d7e 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java
@@ -204,7 +204,8 @@ private static void transferRateText(@NotNull IProbeInfo probeInfo, @NotNull IIO
     private static void transferModeText(@NotNull IProbeInfo probeInfo, @NotNull TransferMode mode,
                                          @NotNull String rateUnit, int rate, boolean hasFilter) {
         String text = TextStyleClass.OK + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC;
-        if (!hasFilter && mode != TransferMode.TRANSFER_ANY) text += TextStyleClass.LABEL + " " + rate + rateUnit;
+        if (!hasFilter && mode != TransferMode.TRANSFER_ANY)
+            text += TextStyleClass.LABEL + " " + TextFormattingUtil.formatNumbers(rate) + rateUnit;
         probeInfo.text(text);
     }
 
@@ -220,7 +221,7 @@ private static void transferModeText(@NotNull IProbeInfo probeInfo, @NotNull Tra
     private static void voidingText(@NotNull IProbeInfo probeInfo, @NotNull VoidingMode mode, @NotNull String unit,
                                     int amount, boolean hasFilter) {
         String text = TextFormatting.RED + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC;
-        if (mode != VoidingMode.VOID_ANY && !hasFilter) text += " " + amount + unit;
+        if (mode != VoidingMode.VOID_ANY && !hasFilter) text += " " + TextFormattingUtil.formatNumbers(amount) + unit;
         probeInfo.text(text);
     }
 
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java
index 7252ebbca23..4b2e970d7c6 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.capability.GregtechCapabilities;
 import gregtech.api.capability.IEnergyContainer;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.tileentity.TileEntity;
@@ -36,9 +37,9 @@ protected void addProbeInfo(@NotNull IEnergyContainer capability, @NotNull IProb
         long maxStorage = capability.getEnergyCapacity();
         if (maxStorage == 0) return; // do not add empty max storage progress bar
         probeInfo.progress(capability.getEnergyStored(), maxStorage, probeInfo.defaultProgressStyle()
-                .suffix(" / " + maxStorage + " EU")
+                .suffix(" / " + TextFormattingUtil.formatNumbers(maxStorage) + " EU")
                 .filledColor(0xFFEEE600)
                 .alternateFilledColor(0xFFEEE600)
-                .borderColor(0xFF555555));
+                .borderColor(0xFF555555).numberFormat(mcjty.theoneprobe.api.NumberFormat.COMMAS));
     }
 }
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java
index d75c6a7c8eb..404bf223680 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.capability.GregtechTileCapabilities;
 import gregtech.api.capability.ILaserContainer;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.tileentity.TileEntity;
@@ -10,6 +11,7 @@
 
 import mcjty.theoneprobe.api.IProbeHitData;
 import mcjty.theoneprobe.api.IProbeInfo;
+import mcjty.theoneprobe.api.NumberFormat;
 import org.jetbrains.annotations.NotNull;
 
 public class LaserContainerInfoProvider extends CapabilityInfoProvider {
@@ -31,10 +33,10 @@ protected void addProbeInfo(ILaserContainer capability, IProbeInfo probeInfo, En
         long maxStorage = capability.getEnergyCapacity();
         if (maxStorage == 0) return; // do not add empty max storage progress bar
         probeInfo.progress(capability.getEnergyStored(), maxStorage, probeInfo.defaultProgressStyle()
-                .suffix(" / " + maxStorage + " EU")
+                .suffix(" / " + TextFormattingUtil.formatNumbers(maxStorage) + " EU")
                 .filledColor(0xFFEEE600)
                 .alternateFilledColor(0xFFEEE600)
-                .borderColor(0xFF555555));
+                .borderColor(0xFF555555).numberFormat(NumberFormat.COMMAS));
     }
 
     @Override
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java
index ea20f8be8a8..3c7d3d79004 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.metatileentity.MetaTileEntity;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.metatileentity.multiblock.IPrimitivePump;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.entity.player.EntityPlayer;
@@ -32,7 +33,9 @@ public void addProbeInfo(@NotNull ProbeMode mode, @NotNull IProbeInfo probeInfo,
             if (metaTileEntity instanceof IPrimitivePump) {
                 probeInfo.text(
                         TextStyleClass.INFO + "{*gregtech.top.primitive_pump_production*} " + TextFormatting.AQUA +
-                                ((IPrimitivePump) metaTileEntity).getFluidProduction() + TextFormatting.RESET + " L/s");
+                                TextFormattingUtil
+                                        .formatNumbers(((IPrimitivePump) metaTileEntity).getFluidProduction()) +
+                                TextFormatting.RESET + " L/s");
             }
         }
     }
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java
index 8ea1a0ac3c7..3a60fab7db6 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java
@@ -10,6 +10,7 @@
 import gregtech.api.metatileentity.multiblock.RecipeMapSteamMultiblockController;
 import gregtech.api.unification.material.Materials;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler;
 
 import net.minecraft.entity.player.EntityPlayer;
@@ -53,14 +54,16 @@ protected void addProbeInfo(@NotNull AbstractRecipeLogic capability, @NotNull IP
                 MetaTileEntity mte = gtTileEntity.getMetaTileEntity();
                 if (mte instanceof SteamMetaTileEntity || mte instanceof MetaTileEntityLargeBoiler ||
                         mte instanceof RecipeMapSteamMultiblockController) {
-                    text = TextFormatting.AQUA.toString() + absEUt + TextStyleClass.INFO + " L/t {*" +
+                    text = TextFormatting.AQUA.toString() + TextFormattingUtil.formatNumbers(absEUt) +
+                            TextStyleClass.INFO + " L/t {*" +
                             Materials.Steam.getUnlocalizedName() + "*}";
                 }
             }
             if (text == null) {
                 // Default behavior, if this TE is not a steam machine (or somehow not instanceof
                 // IGregTechTileEntity...)
-                text = TextFormatting.RED.toString() + absEUt + TextStyleClass.INFO + " EU/t" + TextFormatting.GREEN +
+                text = TextFormatting.RED.toString() + TextFormattingUtil.formatNumbers(absEUt) + TextStyleClass.INFO +
+                        " EU/t" + TextFormatting.GREEN +
                         " (" + GTValues.VNF[GTUtility.getTierByVoltage(absEUt)] + TextFormatting.GREEN + ")";
             }
 
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java
index 4ccdc7125d0..248d0fc1d02 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.metatileentity.MetaTileEntity;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.unification.material.Materials;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.steam.boiler.SteamBoiler;
 
 import net.minecraft.block.state.IBlockState;
@@ -36,7 +37,8 @@ public void addProbeInfo(ProbeMode mode, IProbeInfo probeInfo, EntityPlayer play
                         // Creating steam
                         if (steamOutput > 0 && boiler.hasWater()) {
                             probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_production*} " +
-                                    TextFormatting.AQUA + (steamOutput / 10) + TextStyleClass.INFO + " L/t" + " {*" +
+                                    TextFormatting.AQUA + TextFormattingUtil.formatNumbers(steamOutput / 10) +
+                                    TextStyleClass.INFO + " L/t" + " {*" +
                                     Materials.Steam.getUnlocalizedName() + "*}");
                         }
 
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java
index cf77786cc15..0cf94adc4bd 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java
@@ -5,6 +5,7 @@
 import gregtech.api.metatileentity.MetaTileEntity;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.electric.MetaTileEntityTransformer;
 
 import net.minecraft.entity.player.EntityPlayer;
@@ -33,14 +34,14 @@ protected void addProbeInfo(@NotNull IEnergyContainer capability, @NotNull IProb
                         .append(GTValues.VNF[GTUtility.getTierByVoltage(capability.getInputVoltage())])
                         .append(TextFormatting.GREEN)
                         .append(" (")
-                        .append(capability.getInputAmperage())
+                        .append(TextFormattingUtil.formatNumbers(capability.getInputAmperage()))
                         .append("A)");
 
                 StringBuilder output = new StringBuilder()
                         .append(GTValues.VNF[GTUtility.getTierByVoltage(capability.getOutputVoltage())])
                         .append(TextFormatting.GREEN)
                         .append(" (")
-                        .append(capability.getOutputAmperage())
+                        .append(TextFormattingUtil.formatNumbers(capability.getOutputAmperage()))
                         .append("A)");
 
                 // Step Up/Step Down line
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java
index 5d3c500e81e..ac6254aa8b5 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.capability.GregtechTileCapabilities;
 import gregtech.api.capability.IWorkable;
 import gregtech.api.capability.impl.ComputationRecipeLogic;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.tileentity.TileEntity;
@@ -11,6 +12,7 @@
 
 import mcjty.theoneprobe.api.IProbeHitData;
 import mcjty.theoneprobe.api.IProbeInfo;
+import mcjty.theoneprobe.api.NumberFormat;
 import org.jetbrains.annotations.NotNull;
 
 public class WorkableInfoProvider extends CapabilityInfoProvider {
@@ -52,7 +54,7 @@ protected void addProbeInfo(@NotNull IWorkable capability, @NotNull IProbeInfo p
         } else {
             currentProgress = Math.round(currentProgress / 20.0F);
             maxProgress = Math.round(maxProgress / 20.0F);
-            text = " / " + maxProgress + " s";
+            text = " / " + TextFormattingUtil.formatNumbers(maxProgress) + " s";
         }
 
         if (maxProgress > 0) {
@@ -61,7 +63,7 @@ protected void addProbeInfo(@NotNull IWorkable capability, @NotNull IProbeInfo p
                     .suffix(text)
                     .filledColor(color)
                     .alternateFilledColor(color)
-                    .borderColor(0xFF555555));
+                    .borderColor(0xFF555555).numberFormat(NumberFormat.COMMAS));
         }
     }
 }

From 6c2259a3f9e09504f2645a2bb9ebf6bad4473c86 Mon Sep 17 00:00:00 2001
From: "Josiah \"Rebase\" Roberts"
 <37082009+josiah-roberts@users.noreply.github.com>
Date: Sun, 31 Dec 2023 12:52:13 -0600
Subject: [PATCH 29/98] Use EU/t for digital interface (#2329)

---
 .../java/gregtech/common/covers/CoverDigitalInterface.java | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java
index 0a04343acde..7455688d164 100644
--- a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java
+++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java
@@ -16,6 +16,7 @@
 import gregtech.api.metatileentity.multiblock.MultiblockControllerBase;
 import gregtech.api.util.GTLog;
 import gregtech.api.util.Position;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.client.renderer.texture.Textures;
 import gregtech.client.utils.RenderUtil;
 import gregtech.common.terminal.app.prospector.widget.WidgetOreList;
@@ -1046,9 +1047,11 @@ private void renderEnergyMode() {
         }
         RenderUtil.renderLineChart(inputEnergyList, max, -5.5f / 16, 5.5f / 16, 12f / 16, 6f / 16, 0.005f, 0XFF03FF00);
         RenderUtil.renderLineChart(outputEnergyList, max, -5.5f / 16, 5.5f / 16, 12f / 16, 6f / 16, 0.005f, 0XFFFF2F39);
-        RenderUtil.renderText(-5.7f / 16, -2.3f / 16, 0, 1.0f / 270, 0XFF03FF00, "EU I: " + energyInputPerDur + "EU/s",
+        RenderUtil.renderText(-5.7f / 16, -2.3f / 16, 0, 1.0f / 270, 0XFF03FF00,
+                "EU I: " + TextFormattingUtil.formatNumbers(energyInputPerDur / 20) + "EU/t",
                 false);
-        RenderUtil.renderText(-5.7f / 16, -1.6f / 16, 0, 1.0f / 270, 0XFFFF0000, "EU O: " + energyOutputPerDur + "EU/s",
+        RenderUtil.renderText(-5.7f / 16, -1.6f / 16, 0, 1.0f / 270, 0XFFFF0000,
+                "EU O: " + TextFormattingUtil.formatNumbers(energyOutputPerDur / 20) + "EU/t",
                 false);
         // Bandaid fix to prevent overflowing renders when dealing with items that cause long overflow, ie Ultimate
         // Battery

From 79f179c1fec042a46ba440c2dbd8023b1fe9f90d Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 31 Dec 2023 20:14:01 -0600
Subject: [PATCH 30/98] MUI cover skeleton and Machine Controller Cover port
 (#2312)

---
 src/main/java/gregtech/api/cover/Cover.java   |   9 +-
 .../java/gregtech/api/cover/CoverWithUI.java  |  57 ++++-
 .../gregtech/api/cover/CoverableView.java     |   7 +
 .../api/items/behavior/CoverItemBehavior.java |   4 +-
 .../api/metatileentity/MetaTileEntity.java    |   3 +-
 .../java/gregtech/api/mui/GTGuiTextures.java  |  23 +-
 .../java/gregtech/api/mui/GTGuiTheme.java     |  11 +-
 .../tile/PipeCoverableImplementation.java     |   3 +-
 .../common/covers/CoverMachineController.java | 211 ++++++++++++------
 .../resources/assets/gregtech/lang/en_us.lang |  11 +-
 .../textures/gui/widget/button_cross.png      | Bin 0 -> 200 bytes
 .../gui/widget/button_redstone_off.png        | Bin 0 -> 202 bytes
 .../gui/widget/button_redstone_on.png         | Bin 0 -> 225 bytes
 13 files changed, 259 insertions(+), 80 deletions(-)
 create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png
 create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png
 create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png

diff --git a/src/main/java/gregtech/api/cover/Cover.java b/src/main/java/gregtech/api/cover/Cover.java
index 8540d97fc1f..0257544c99a 100644
--- a/src/main/java/gregtech/api/cover/Cover.java
+++ b/src/main/java/gregtech/api/cover/Cover.java
@@ -113,10 +113,13 @@ default long getOffsetTimer() {
 
     /**
      * Called when the cover is first attached on the Server Side.
-     * Do NOT sync custom data to client here. It will overwrite the attach cover packet!
+     * Values set here will automatically be synced to the client, if you
+     * specify them in {@link #writeInitialSyncData}.
+     * 
+     * @apiNote The CoverableView will not have your cover attached to it in this method.
      *
-     * @param coverableView the CoverableView this cover is attached to
-     * @param side          the side this cover is attached to
+     * @param coverableView the CoverableView this cover will be attached to
+     * @param side          the side this cover will be attached to
      * @param player        the player attaching the cover
      * @param itemStack     the item used to place the cover
      */
diff --git a/src/main/java/gregtech/api/cover/CoverWithUI.java b/src/main/java/gregtech/api/cover/CoverWithUI.java
index 10ab6f243dd..f40f2df37bc 100644
--- a/src/main/java/gregtech/api/cover/CoverWithUI.java
+++ b/src/main/java/gregtech/api/cover/CoverWithUI.java
@@ -8,14 +8,22 @@
 
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
 import net.minecraftforge.fml.relauncher.Side;
 import net.minecraftforge.fml.relauncher.SideOnly;
 
 import com.cleanroommc.modularui.api.IGuiHolder;
+import com.cleanroommc.modularui.api.drawable.IKey;
+import com.cleanroommc.modularui.drawable.ItemDrawable;
 import com.cleanroommc.modularui.factory.SidedPosGuiData;
 import com.cleanroommc.modularui.screen.ModularPanel;
 import com.cleanroommc.modularui.screen.ModularScreen;
+import com.cleanroommc.modularui.value.BoolValue;
+import com.cleanroommc.modularui.value.sync.EnumSyncValue;
 import com.cleanroommc.modularui.value.sync.GuiSyncManager;
+import com.cleanroommc.modularui.value.sync.IntSyncValue;
+import com.cleanroommc.modularui.widget.ParentWidget;
+import com.cleanroommc.modularui.widgets.layout.Row;
 import org.jetbrains.annotations.ApiStatus;
 
 public interface CoverWithUI extends Cover, IUIHolder, IGuiHolder {
@@ -46,7 +54,7 @@ default ModularScreen createScreen(SidedPosGuiData guiData, ModularPanel mainPan
     }
 
     default GTGuiTheme getUITheme() {
-        return GTGuiTheme.STANDARD;
+        return GTGuiTheme.COVER;
     }
 
     @Override
@@ -68,4 +76,51 @@ default boolean isRemote() {
     default void markAsDirty() {
         getCoverableView().markDirty();
     }
+
+    /* Helper methods for UI creation with covers that are commonly used */
+
+    /**
+     * The color used for Cover UI titles, and used in {@link #createTitleRow}.
+     */
+    int UI_TITLE_COLOR = 0xFF222222;
+    /**
+     * The color used for Cover UI text. Available for reference, but is
+     * handled automatically by the {@link GTGuiTheme#COVER} theme.
+     */
+    int UI_TEXT_COLOR = 0xFF555555;
+
+    /**
+     * Create the Title bar widget for a Cover.
+     */
+    default Row createTitleRow() {
+        ItemStack item = getDefinition().getDropItemStack();
+        return new Row()
+                .pos(4, 4)
+                .height(16).coverChildrenWidth()
+                .child(new ItemDrawable(getDefinition().getDropItemStack()).asWidget().size(16).marginRight(4))
+                .child(IKey.str(item.getDisplayName()).color(UI_TITLE_COLOR).asWidget().heightRel(1.0f));
+    }
+
+    /**
+     * Create a new settings row for a Cover setting.
+     */
+    default ParentWidget createSettingsRow() {
+        return new ParentWidget<>().height(16).widthRel(1.0f).marginBottom(2);
+    }
+
+    /**
+     * Get a BoolValue for use with toggle buttons which are "linked together,"
+     * meaning only one of them can be pressed at a time.
+     */
+    default > BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) {
+        return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value));
+    }
+
+    /**
+     * Get a BoolValue for use with toggle buttons which are "linked together,"
+     * meaning only one of them can be pressed at a time.
+     */
+    default BoolValue.Dynamic boolValueOf(IntSyncValue syncValue, int value) {
+        return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value));
+    }
 }
diff --git a/src/main/java/gregtech/api/cover/CoverableView.java b/src/main/java/gregtech/api/cover/CoverableView.java
index 0b7d6f33c68..8bebd97b26d 100644
--- a/src/main/java/gregtech/api/cover/CoverableView.java
+++ b/src/main/java/gregtech/api/cover/CoverableView.java
@@ -1,5 +1,6 @@
 package gregtech.api.cover;
 
+import net.minecraft.item.ItemStack;
 import net.minecraft.network.PacketBuffer;
 import net.minecraft.tileentity.TileEntity;
 import net.minecraft.util.EnumFacing;
@@ -87,4 +88,10 @@ default boolean hasCover(@NotNull EnumFacing side) {
     int getInputRedstoneSignal(@NotNull EnumFacing side, boolean ignoreCover);
 
     void writeCoverData(@NotNull Cover cover, int discriminator, @NotNull Consumer<@NotNull PacketBuffer> buf);
+
+    /**
+     * @return an ItemStack representation of the CoverableView, or {@link ItemStack#EMPTY} if not possible.
+     */
+    @NotNull
+    ItemStack getStackForm();
 }
diff --git a/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java b/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java
index 5feda5eac58..826e85d961d 100644
--- a/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java
+++ b/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java
@@ -56,8 +56,10 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, @NotNull World world
 
         ItemStack itemStack = player.getHeldItem(hand);
 
-        coverHolder.addCover(coverSide, cover);
+        // Call onAttachment first so that the cover can set up any
+        // necessary variables needed for the S2C cover sync packet.
         cover.onAttachment(coverHolder, coverSide, player, itemStack);
+        coverHolder.addCover(coverSide, cover);
 
         AdvancementTriggers.FIRST_COVER_PLACE.trigger((EntityPlayerMP) player);
 
diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
index 659460902b0..8b922ffc3f6 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
@@ -834,7 +834,8 @@ public final ItemStack getStackForm(int amount) {
         return new ItemStack(GregTechAPI.MACHINE, amount, metaTileEntityIntId);
     }
 
-    public final ItemStack getStackForm() {
+    @Override
+    public final @NotNull ItemStack getStackForm() {
         return getStackForm(1);
     }
 
diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java
index d1f432c6c07..3c99abaee1e 100644
--- a/src/main/java/gregtech/api/mui/GTGuiTextures.java
+++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java
@@ -19,6 +19,7 @@ public class GTGuiTextures {
     public static class IDs {
 
         public static final String STANDARD_BACKGROUND = "gregtech_standard_bg";
+        public static final String COVER_BACKGROUND = "gregtech_cover_bg";
         public static final String BRONZE_BACKGROUND = "gregtech_bronze_bg";
         public static final String STEEL_BACKGROUND = "gregtech_steel_bg";
         public static final String PRIMITIVE_BACKGROUND = "gregtech_primitive_bg";
@@ -34,9 +35,9 @@ public static class IDs {
     }
 
     // ICONS
-    /** @apiNote You may want {@link GTGuiTextures#getLogo()} instead. */
+    /** @apiNote You may want {@link GTGuiTextures#getLogo} instead. */
     public static final UITexture GREGTECH_LOGO = fullImage("textures/gui/icon/gregtech_logo.png");
-    /** @apiNote You may want {@link GTGuiTextures#getLogo()} instead. */
+    /** @apiNote You may want {@link GTGuiTextures#getLogo} instead. */
     public static final UITexture GREGTECH_LOGO_XMAS = fullImage("textures/gui/icon/gregtech_logo_xmas.png");
     public static final UITexture GREGTECH_LOGO_DARK = fullImage("textures/gui/icon/gregtech_logo_dark.png");
     // todo blinking GT logos
@@ -61,6 +62,7 @@ public static class IDs {
             .location(GTValues.MODID, "textures/gui/base/background_popup.png")
             .imageSize(195, 136)
             .adaptable(4)
+            .name(IDs.COVER_BACKGROUND)
             .canApplyTheme()
             .build();
 
@@ -268,6 +270,19 @@ public static class IDs {
             .canApplyTheme()
             .build();
 
+    public static final UITexture MC_BUTTON = new UITexture.Builder()
+            .location("modularui", "gui/widgets/mc_button.png") // todo
+            .imageSize(16, 32)
+            .uv(0.0f, 0.0f, 1.0f, 0.5f)
+            .adaptable(1)
+            .build();
+
+    public static final UITexture MC_BUTTON_DISABLED = new UITexture.Builder()
+            .location("modularui", "gui/widgets/mc_button_disabled.png") // todo
+            .imageSize(16, 16)
+            .adaptable(1)
+            .build();
+
     // BUTTON OVERLAYS
 
     public static final UITexture BUTTON_ITEM_OUTPUT = fullImage("textures/gui/widget/button_item_output_overlay.png");
@@ -277,6 +292,10 @@ public static class IDs {
             "textures/gui/widget/button_auto_collapse_overlay.png");
     public static final UITexture BUTTON_X = fullImage("textures/gui/widget/button_x_overlay.png", true);
 
+    public static final UITexture BUTTON_CROSS = fullImage("textures/gui/widget/button_cross.png");
+    public static final UITexture BUTTON_REDSTONE_ON = fullImage("textures/gui/widget/button_redstone_on.png");
+    public static final UITexture BUTTON_REDSTONE_OFF = fullImage("textures/gui/widget/button_redstone_off.png");
+
     // PROGRESS BARS
     public static final UITexture PROGRESS_BAR_ARC_FURNACE = progressBar(
             "textures/gui/progress_bar/progress_bar_arc_furnace.png", true);
diff --git a/src/main/java/gregtech/api/mui/GTGuiTheme.java b/src/main/java/gregtech/api/mui/GTGuiTheme.java
index c3f80b09943..fce37223e96 100644
--- a/src/main/java/gregtech/api/mui/GTGuiTheme.java
+++ b/src/main/java/gregtech/api/mui/GTGuiTheme.java
@@ -1,5 +1,6 @@
 package gregtech.api.mui;
 
+import gregtech.api.cover.CoverWithUI;
 import gregtech.common.ConfigHolder;
 
 import net.minecraftforge.common.MinecraftForge;
@@ -33,7 +34,15 @@ public class GTGuiTheme {
                     ConfigHolder.client.defaultUIColor)
             .build();
 
-    // TODO Cover theme to utilize the GT5u-like button textures vs the standard ones
+    public static final GTGuiTheme COVER = templateBuilder("gregtech_cover")
+            .panel(GTGuiTextures.IDs.COVER_BACKGROUND)
+            .itemSlot(GTGuiTextures.IDs.STANDARD_SLOT)
+            .fluidSlot(GTGuiTextures.IDs.STANDARD_FLUID_SLOT)
+            .color(ConfigHolder.client.defaultUIColor)
+            .textColor(CoverWithUI.UI_TEXT_COLOR)
+            .build();
+
+    // TODO Multiblock theme for display texture, logo changes
 
     public static final GTGuiTheme BRONZE = templateBuilder("gregtech_bronze")
             .panel(GTGuiTextures.IDs.BRONZE_BACKGROUND)
diff --git a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java
index 6be552bfc95..df20bd54bfb 100644
--- a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java
+++ b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java
@@ -85,7 +85,8 @@ public final void removeCover(@NotNull EnumFacing side) {
     }
 
     @SuppressWarnings("unchecked")
-    public ItemStack getStackForm() {
+    @Override
+    public @NotNull ItemStack getStackForm() {
         BlockPipe pipeBlock = holder.getPipeBlock();
         return pipeBlock.getDropItem(holder);
     }
diff --git a/src/main/java/gregtech/common/covers/CoverMachineController.java b/src/main/java/gregtech/common/covers/CoverMachineController.java
index 8814da16ca4..423a44fccd3 100644
--- a/src/main/java/gregtech/common/covers/CoverMachineController.java
+++ b/src/main/java/gregtech/common/covers/CoverMachineController.java
@@ -3,23 +3,36 @@
 import gregtech.api.capability.GregtechTileCapabilities;
 import gregtech.api.capability.IControllable;
 import gregtech.api.cover.*;
-import gregtech.api.gui.GuiTextures;
-import gregtech.api.gui.ModularUI;
-import gregtech.api.gui.widgets.*;
+import gregtech.api.mui.GTGuiTextures;
+import gregtech.api.mui.GTGuis;
 import gregtech.client.renderer.texture.Textures;
 
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.PacketBuffer;
 import net.minecraft.util.*;
-import net.minecraftforge.items.ItemStackHandler;
+import net.minecraft.util.text.TextFormatting;
 
 import codechicken.lib.raytracer.CuboidRayTraceResult;
 import codechicken.lib.render.CCRenderState;
 import codechicken.lib.render.pipeline.IVertexOperation;
 import codechicken.lib.vec.Cuboid6;
 import codechicken.lib.vec.Matrix4;
+import com.cleanroommc.modularui.api.drawable.IKey;
+import com.cleanroommc.modularui.drawable.ItemDrawable;
+import com.cleanroommc.modularui.drawable.Rectangle;
+import com.cleanroommc.modularui.factory.SidedPosGuiData;
+import com.cleanroommc.modularui.screen.ModularPanel;
+import com.cleanroommc.modularui.utils.Alignment;
+import com.cleanroommc.modularui.value.BoolValue;
+import com.cleanroommc.modularui.value.sync.BooleanSyncValue;
+import com.cleanroommc.modularui.value.sync.EnumSyncValue;
+import com.cleanroommc.modularui.value.sync.GuiSyncManager;
+import com.cleanroommc.modularui.widget.Widget;
+import com.cleanroommc.modularui.widgets.ToggleButton;
+import com.cleanroommc.modularui.widgets.layout.Column;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -28,23 +41,16 @@
 
 public class CoverMachineController extends CoverBase implements CoverWithUI {
 
-    private int minRedstoneStrength;
     private boolean isInverted;
     private ControllerMode controllerMode;
-    private final ItemStackHandler displayInventory = new ItemStackHandler(1);
 
     public CoverMachineController(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView,
                                   @NotNull EnumFacing attachedSide) {
         super(definition, coverableView, attachedSide);
-        this.minRedstoneStrength = 1;
         this.isInverted = false;
         this.controllerMode = ControllerMode.MACHINE;
     }
 
-    public int getMinRedstoneStrength() {
-        return minRedstoneStrength;
-    }
-
     public ControllerMode getControllerMode() {
         return controllerMode;
     }
@@ -53,12 +59,6 @@ public boolean isInverted() {
         return isInverted;
     }
 
-    public void setMinRedstoneStrength(int minRedstoneStrength) {
-        this.minRedstoneStrength = minRedstoneStrength;
-        updateRedstoneStatus();
-        getCoverableView().markDirty();
-    }
-
     public void setInverted(boolean inverted) {
         isInverted = inverted;
         updateRedstoneStatus();
@@ -69,21 +69,12 @@ public void setControllerMode(ControllerMode controllerMode) {
         resetCurrentControllable();
         this.controllerMode = controllerMode;
         updateRedstoneStatus();
-        updateDisplayInventory();
         getCoverableView().markDirty();
     }
 
-    private void cycleNextControllerMode() {
-        List allowedModes = getAllowedModes(getCoverableView(), getAttachedSide());
-        int nextIndex = allowedModes.indexOf(controllerMode) + 1;
-        if (!allowedModes.isEmpty()) {
-            setControllerMode(allowedModes.get(nextIndex % allowedModes.size()));
-        }
-    }
-
     public List getAllowedModes(@NotNull CoverableView coverable, @NotNull EnumFacing side) {
         List results = new ArrayList<>();
-        for (ControllerMode controllerMode : ControllerMode.values()) {
+        for (ControllerMode controllerMode : ControllerMode.VALUES) {
             IControllable controllable = null;
             if (controllerMode.side == null) {
                 controllable = coverable.getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, side);
@@ -115,21 +106,111 @@ public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing s
     }
 
     @Override
-    public ModularUI createUI(EntityPlayer player) {
-        updateDisplayInventory();
-        return ModularUI.builder(GuiTextures.BACKGROUND, 176, 95)
-                .image(4, 4, 16, 16, GuiTextures.COVER_MACHINE_CONTROLLER)
-                .label(24, 8, "cover.machine_controller.title")
-                .widget(new SliderWidget("cover.machine_controller.redstone", 10, 24, 156, 20, 1.0f, 15.0f,
-                        minRedstoneStrength, it -> setMinRedstoneStrength((int) it)))
-                .widget(new ClickButtonWidget(10, 48, 134, 18, "", data -> cycleNextControllerMode()))
-                .widget(new SimpleTextWidget(77, 58, "", 0xFFFFFF, () -> getControllerMode().getName()).setShadow(true))
-                .widget(new SlotWidget(displayInventory, 0, 148, 48, false, false)
-                        .setBackgroundTexture(GuiTextures.SLOT))
-                .widget(new CycleButtonWidget(48, 70, 80, 18, this::isInverted, this::setInverted,
-                        "cover.machine_controller.normal", "cover.machine_controller.inverted")
-                                .setTooltipHoverString("cover.machine_controller.inverted.description"))
-                .build(this, player);
+    public boolean usesMui2() {
+        return true;
+    }
+
+    @Override
+    public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) {
+        EnumSyncValue controllerModeValue = new EnumSyncValue<>(ControllerMode.class,
+                this::getControllerMode, this::setControllerMode);
+        BooleanSyncValue invertedValue = new BooleanSyncValue(this::isInverted, this::setInverted);
+
+        guiSyncManager.syncValue("controller_mode", controllerModeValue);
+        guiSyncManager.syncValue("inverted", invertedValue);
+
+        return GTGuis.createPanel(this, 176, 112)
+                .child(createTitleRow())
+                .child(new Column()
+                        .widthRel(1.0f).margin(7, 0)
+                        .top(24).coverChildrenHeight()
+
+                        // Inverted mode
+                        .child(createSettingsRow()
+                                .child(new ToggleButton()
+                                        .size(16).left(0)
+                                        .value(new BoolValue.Dynamic(invertedValue::getValue,
+                                                $ -> invertedValue.setValue(true)))
+                                        .overlay(GTGuiTextures.BUTTON_REDSTONE_ON)
+                                        .selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED))
+                                .child(IKey.lang("cover.machine_controller.enable_with_redstone").asWidget()
+                                        .heightRel(1.0f).left(20)))
+                        .child(createSettingsRow()
+                                .child(new ToggleButton()
+                                        .size(16).left(0)
+                                        .value(new BoolValue.Dynamic(() -> !invertedValue.getValue(),
+                                                $ -> invertedValue.setValue(false)))
+                                        .overlay(GTGuiTextures.BUTTON_REDSTONE_OFF)
+                                        .selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED))
+                                .child(IKey.lang("cover.machine_controller.disable_with_redstone").asWidget()
+                                        .heightRel(1.0f).left(20)))
+
+                        // Separating line
+                        .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget()
+                                .height(1).widthRel(0.9f).alignX(0.5f).marginBottom(4).marginTop(4))
+
+                        // Controlling selector
+                        .child(createSettingsRow().height(16 + 2 + 16)
+                                .child(new Column().heightRel(1.0f).coverChildrenWidth()
+                                        .child(IKey.lang("cover.machine_controller.control").asWidget()
+                                                .left(0).height(16).marginBottom(2))
+                                        .child(modeButton(controllerModeValue, ControllerMode.MACHINE).left(0)))
+                                .child(modeColumn(controllerModeValue, ControllerMode.COVER_UP, IKey.str("U"))
+                                        .right(100))
+                                .child(modeColumn(controllerModeValue, ControllerMode.COVER_DOWN, IKey.str("D"))
+                                        .right(80))
+                                .child(modeColumn(controllerModeValue, ControllerMode.COVER_NORTH, IKey.str("N"))
+                                        .right(60))
+                                .child(modeColumn(controllerModeValue, ControllerMode.COVER_SOUTH, IKey.str("S"))
+                                        .right(40))
+                                .child(modeColumn(controllerModeValue, ControllerMode.COVER_EAST, IKey.str("E"))
+                                        .right(20))
+                                .child(modeColumn(controllerModeValue, ControllerMode.COVER_WEST, IKey.str("W"))
+                                        .right(0))));
+    }
+
+    private Column modeColumn(EnumSyncValue syncValue, ControllerMode mode, IKey title) {
+        return new Column().coverChildrenHeight().width(18)
+                .child(title.asWidget().size(16).marginBottom(2).alignment(Alignment.Center))
+                .child(modeButton(syncValue, mode));
+    }
+
+    private Widget modeButton(EnumSyncValue syncValue, ControllerMode mode) {
+        IControllable controllable = getControllable(mode);
+        if (controllable == null) {
+            // Nothing to control, put a placeholder widget
+            // 3 states possible here:
+            IKey detail;
+            if (mode.side == getAttachedSide()) {
+                // our own side, we can't control ourselves
+                detail = IKey.lang("cover.machine_controller.this_cover");
+            } else if (mode.side != null) {
+                // some potential cover that either doesn't exist or isn't controllable
+                detail = IKey.lang("cover.machine_controller.cover_not_controllable");
+            } else {
+                // cover holder is not controllable
+                detail = IKey.lang("cover.machine_controller.machine_not_controllable");
+            }
+
+            return GTGuiTextures.MC_BUTTON.asWidget().size(18)
+                    .overlay(GTGuiTextures.BUTTON_CROSS)
+                    .tooltip(t -> t.addLine(IKey.lang(mode.localeName)).addLine(detail));
+        }
+
+        ItemStack stack;
+        if (mode == ControllerMode.MACHINE) {
+            stack = getCoverableView().getStackForm();
+        } else {
+            // this can't be null because we already checked IControllable, and it was not null
+            // noinspection ConstantConditions
+            stack = getCoverableView().getCoverAtSide(mode.side).getDefinition().getDropItemStack();
+        }
+
+        return new ToggleButton().size(18)
+                .value(boolValueOf(syncValue, mode))
+                .overlay(new ItemDrawable(stack).asIcon().size(16))
+                .tooltip(t -> t.addLine(IKey.lang(mode.localeName))
+                        .addLine(IKey.str(TextFormatting.GRAY + stack.getDisplayName())));
     }
 
     @Override
@@ -163,20 +244,8 @@ public void onRedstoneInputSignalChange(int newSignalStrength) {
         updateRedstoneStatus();
     }
 
-    private void updateDisplayInventory() {
-        EnumFacing controlledSide = getControllerMode().side;
-        ItemStack resultStack = ItemStack.EMPTY;
-        if (controlledSide != null) {
-            Cover cover = getCoverableView().getCoverAtSide(controlledSide);
-            if (cover != null) {
-                resultStack = cover.getDefinition().getDropItemStack();
-            }
-        }
-        this.displayInventory.setStackInSlot(0, resultStack);
-    }
-
-    private @Nullable IControllable getControllable() {
-        EnumFacing side = controllerMode.side;
+    private @Nullable IControllable getControllable(ControllerMode mode) {
+        EnumFacing side = mode.side;
         if (side == null) {
             return getCoverableView().getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE,
                     getAttachedSide());
@@ -190,24 +259,22 @@ private void updateDisplayInventory() {
     }
 
     private void resetCurrentControllable() {
-        IControllable controllable = getControllable();
+        IControllable controllable = getControllable(controllerMode);
         if (controllable != null) {
             controllable.setWorkingEnabled(doesOtherAllowingWork());
         }
     }
 
     private void updateRedstoneStatus() {
-        IControllable controllable = getControllable();
+        IControllable controllable = getControllable(controllerMode);
         if (controllable != null) {
             controllable.setWorkingEnabled(shouldAllowWorking() && doesOtherAllowingWork());
         }
     }
 
     private boolean shouldAllowWorking() {
-        boolean shouldAllowWorking = getCoverableView().getInputRedstoneSignal(getAttachedSide(), true) <
-                minRedstoneStrength;
-        // noinspection SimplifiableConditionalExpression
-        return isInverted ? !shouldAllowWorking : shouldAllowWorking;
+        int inputSignal = getCoverableView().getInputRedstoneSignal(getAttachedSide(), true);
+        return isInverted ? inputSignal > 0 : inputSignal == 0;
     }
 
     private boolean doesOtherAllowingWork() {
@@ -228,7 +295,6 @@ private boolean doesOtherAllowingWork() {
     @Override
     public void writeToNBT(@NotNull NBTTagCompound tagCompound) {
         super.writeToNBT(tagCompound);
-        tagCompound.setInteger("MinRedstoneStrength", minRedstoneStrength);
         tagCompound.setBoolean("Inverted", isInverted);
         tagCompound.setInteger("ControllerMode", controllerMode.ordinal());
     }
@@ -236,9 +302,22 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) {
     @Override
     public void readFromNBT(@NotNull NBTTagCompound tagCompound) {
         super.readFromNBT(tagCompound);
-        this.minRedstoneStrength = tagCompound.getInteger("MinRedstoneStrength");
         this.isInverted = tagCompound.getBoolean("Inverted");
-        this.controllerMode = ControllerMode.values()[tagCompound.getInteger("ControllerMode")];
+        this.controllerMode = ControllerMode.VALUES[tagCompound.getInteger("ControllerMode")];
+    }
+
+    @Override
+    public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) {
+        super.writeInitialSyncData(packetBuffer);
+        packetBuffer.writeBoolean(isInverted);
+        packetBuffer.writeShort(controllerMode.ordinal());
+    }
+
+    @Override
+    public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) {
+        super.readInitialSyncData(packetBuffer);
+        this.isInverted = packetBuffer.readBoolean();
+        this.controllerMode = ControllerMode.VALUES[packetBuffer.readShort()];
     }
 
     public enum ControllerMode implements IStringSerializable {
@@ -254,6 +333,8 @@ public enum ControllerMode implements IStringSerializable {
         public final String localeName;
         public final EnumFacing side;
 
+        public static final ControllerMode[] VALUES = values();
+
         ControllerMode(String localeName, EnumFacing side) {
             this.localeName = localeName;
             this.side = side;
diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang
index f4525a2dc5c..df5124812b5 100644
--- a/src/main/resources/assets/gregtech/lang/en_us.lang
+++ b/src/main/resources/assets/gregtech/lang/en_us.lang
@@ -1304,11 +1304,6 @@ cover.fluid_regulator.transfer_mode.description=§eTransfer Any§r - in this mod
 cover.fluid_regulator.supply_exact=Supply Exact: %s
 cover.fluid_regulator.keep_exact=Keep Exact: %s
 
-cover.machine_controller.title=Machine Controller Settings
-cover.machine_controller.normal=Normal
-cover.machine_controller.inverted=Inverted
-cover.machine_controller.inverted.description=§eNormal§r - in this mode, the cover will require a signal weaker than the set redstone level to run/n§eInverted§r - in this mode, the cover will require a signal stronger than the set redstone level to run
-cover.machine_controller.redstone=Min Redstone Strength: %,d
 cover.machine_controller.mode.machine=Control Machine
 cover.machine_controller.mode.cover_up=Control Cover (Top)
 cover.machine_controller.mode.cover_down=Control Cover (Bottom)
@@ -1316,6 +1311,12 @@ cover.machine_controller.mode.cover_south=Control Cover (South)
 cover.machine_controller.mode.cover_north=Control Cover (North)
 cover.machine_controller.mode.cover_east=Control Cover (East)
 cover.machine_controller.mode.cover_west=Control Cover (West)
+cover.machine_controller.this_cover=§cThis cover
+cover.machine_controller.cover_not_controllable=§cNo controllable cover
+cover.machine_controller.machine_not_controllable=§cMachine not controllable
+cover.machine_controller.control=Control:
+cover.machine_controller.enable_with_redstone=Enable with Redstone
+cover.machine_controller.disable_with_redstone=Disable with Redstone
 
 cover.ender_fluid_link.title=Ender Fluid Link
 cover.ender_fluid_link.iomode.enabled=I/O Enabled
diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png
new file mode 100644
index 0000000000000000000000000000000000000000..863553adbdcc072ea9548cbb88e26b62a3391b29
GIT binary patch
literal 200
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJeoq(2kch*{2@HI
z@X`L-e4Wvt*-S&b(NMA3Gt|C9wju8Vm&Ux)`b@`OuuWc7_raRsZo&-59X!i+9c@0w
zc*LqDO^jcPeSvifYf!=EqmLNN85SOK+iv1e&Mq+fY{s(*jKvJQjv6p?iXMHz*O=J#
xnrW9cL-;o3ZC1-}JaT;8aMA3ch6F3nLFbbGor&06{1E6g22WQ%mvv4FO#mDKNUi_?

literal 0
HcmV?d00001

diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png
new file mode 100644
index 0000000000000000000000000000000000000000..e51d453475577ed0efaad547c2d4bf72877fdb8d
GIT binary patch
literal 202
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJiJmTwArXg@6C_v{Cx}eooYT_!
zzj?#X1_p_K8}Oi(zxWR^Pvc;}!x;E)8&FG#KPyPfEw9BuJ2v(S
pf$do25bw+f5_UVNAz{YAu+Y6H(cxh7KcM3nJYD@<);T3K0RWECN`U|X

literal 0
HcmV?d00001

diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png
new file mode 100644
index 0000000000000000000000000000000000000000..44d6e446b7265c1718359018a88b681f2ad4ceb4
GIT binary patch
literal 225
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ6`n4RArXg@6C_v{H~19XIQ7cj
zNY0Y4A+jPxR%E-g!Ce`n44DsqepVT@HBNlYP}067JEP%a!_y|lVuxhM8}$Na7em<|
zPki3+Y*EL5g`CtioX3>UGwwC@{O@?4rAcI
zZ9wS|f7TxNdCa%G7XNSFu(3}_qTh!7z#@luXFiZHn+yZDHnWD9{M#ixOkNBO$6r0p
UJ
Date: Mon, 1 Jan 2024 06:16:59 +0400
Subject: [PATCH 31/98] Update ru_ru.lang (#2307)

---
 .../resources/assets/gregtech/lang/ru_ru.lang | 266 +++++++++---------
 1 file changed, 136 insertions(+), 130 deletions(-)

diff --git a/src/main/resources/assets/gregtech/lang/ru_ru.lang b/src/main/resources/assets/gregtech/lang/ru_ru.lang
index 6150191749e..ffdafa7a6c6 100644
--- a/src/main/resources/assets/gregtech/lang/ru_ru.lang
+++ b/src/main/resources/assets/gregtech/lang/ru_ru.lang
@@ -42,8 +42,8 @@ gregtech.multiblock.steam.low_steam=Недостаточно пара для р
 gregtech.multiblock.steam.steam_stored=Пар: %s / %s mB
 gregtech.machine.steam_hatch.name=Паровой люк
 gregtech.machine.steam.steam_hatch.tooltip=§eПринимает жидкости: §fПар
-gregtech.machine.steam_import_bus.name=Входной предметный люк (Пар)
-gregtech.machine.steam_export_bus.name=Выходной предметный люк (Пар)
+gregtech.machine.steam_import_bus.name=Паровой входной люк
+gregtech.machine.steam_export_bus.name=Паровой выходной люк
 gregtech.machine.steam_bus.tooltip=Не работает с электрическими многоблочными структурами
 gregtech.machine.steam_oven.name=Паровая мультиплавильня
 gregtech.multiblock.steam_oven.description=Мультиплавильня в паровой эпохе. Требует как минимум 6 бронзовых машинных корпусов. Может использовать только паровые люки. Паровой люк должен находится на нижнем слое и он может быть только один.
@@ -52,7 +52,7 @@ gregtech.multiblock.steam_.duration_modifier=Работает в §f1.5x §7ра
 gregtech.top.working_disabled=Работа остановлена
 gregtech.top.energy_consumption=Использует
 gregtech.top.energy_production=Производит
-gregtech.top.transform_up=§cПовышает§r
+gregtech.top.transform_up=Повышает
 gregtech.top.transform_down=§aПонижает§r
 gregtech.top.transform_input=Вход:
 gregtech.top.transform_output=Выход:
@@ -102,7 +102,7 @@ gregtech.multiblock.extreme_combustion_engine.description=Улучшенный 
 gregtech.multiblock.distillation_tower.description=Ректификационная колонна - представляет собой многоблочную структуру, используемую для перегонки различных типов нефти и некоторых их побочных продуктов.
 gregtech.multiblock.electric_blast_furnace.description=Электрическая доменная печь (ЭДП) - это многоблочная структура, используемая для выплавки сплавов, приготовления металлов и переработки руд. Она необходима для получения высокоуровневых сплавов и металлов, таких как алюминий, нержавеющая сталь и титан, сплав наквада.
 gregtech.multiblock.multi_furnace.description=Мульти-плавильный завод - это многоблочная структура, используемая для одновременной выплавки большого количества изделий. Различные уровни катушек обеспечивают увеличение скорости и повышение энергоэффективности. 32 - это базовое значение предметов, выплавляемых за одну операцию, и его можно умножить, используя катушки более высокого уровня.
-gregtech.multiblock.large_boiler.description=Большой котел - представляет собой многоблочную структуру, которая генерируют пар из источника энергии и воды. Обычно либо твердое топливо, либо горючая жидкость высокой плотности действует как источник энергии для большого котла. Уровни отличаются только количеством вырабатываемого пара.
+gregtech.multiblock.large_boiler.description=Большой котел - представляет собой многоблочную структуру, которая генерируют пар из источника энергии и воды. Обычно либо твердое топливо, либо горючая жидкость высокой плотности действует как источник энергии для большого котла. Уровни отличаются только кол-вом вырабатываемого пара.
 gregtech.multiblock.large_turbine.description=Большая турбина - это многоблочная структура, которые вырабатывают энергию из пара, газов и плазмы, вращая ротор турбины. Выход энергии зависит от КПД ротора и текущей скорости турбины.
 gregtech.multiblock.assembly_line.description=Сборочная линия представляет собой большую многоблочную конструкцию, состоящую из 5-16 «кусочков». Теоретически это большая сборочная машина, используемая для создания продвинутых компонентов для крафта.
 gregtech.multiblock.fusion_reactor.luv.description=Термоядерный реактор модель 1 - это большая многоблочная структура использующаяся для термоядерного синтеза двух элементов в один. Может использовать LuV+ энергетические разъемы. За каждый энергетический разъём, внутренний буфер увеличивается на 10млн. EU, максимум энергии для старта 160млн. EU.
@@ -110,17 +110,17 @@ gregtech.multiblock.fusion_reactor.zpm.description=Термоядерный ре
 gregtech.multiblock.fusion_reactor.uv.description=Термоядерный реактор модель 3 - это большая многоблочная структура использующаяся для термоядерного синтеза двух элементов в один. Может использовать UV+ энергетические разъемы. За каждый энергетический разъём, внутренний буфер увеличивается на 40млн. EU, максимум энергии для старта 640млн. EU.
 gregtech.multiblock.fusion_reactor.heat=Нагрев: %d
 gregtech.multiblock.large_chemical_reactor.description=Многоблочная версия химического реактора выполняющий операции в больших объёмах с удвоенной эффективностью. Ускорение умножает скорость и энергию на 4. Для мультиблочной структуры требуется ровно 1 блок купроникелевой катушки, который должен быть размещен рядом с корпусом ПТФЭ трубы, расположенным в центре.
-gregtech.multiblock.primitive_water_pump.description=Примитивная водяная помпа — это многоблочная структура до Паровой Эпохи, который собирает воду раз в секунду, в зависимости от биома, в котором он находится. Он может использовать насос, выходной люк ULV или LV, увеличивая количество воды от уровня. Выполняется по формуле: Коэффициент биома * Множитель люка.
-gregtech.multiblock.primitive_water_pump.extra1=Коэффициент биома:/n  Океан, Река: 1000 л/с/н  Болото: 800 л/с/н  Джунгли: 350 л/с/н  Снежный: 300 л/с/н  Равнины, Лес: 250 л/с/н  Тайга : 175 л/с/н  Пляж: 170 л/с/н  Другое: 100 л/с
+gregtech.multiblock.primitive_water_pump.description=Примитивная водяная помпа — это многоблочная структура до Паровой Эпохи, который собирает воду раз в секунду, в зависимости от биома, в котором он находится. Он может использовать насос, выходной люк ULV или LV, увеличивая кол-во воды от уровня. Выполняется по формуле: Коэф. биома * Множитель люка.
+gregtech.multiblock.primitive_water_pump.extra1=Коэф. биома:/n  Океан, Река: 1000 Л/с/n  Болото: 800 Л/с/n  Джунгли: 350 Л/с/n  Снежный: 300 Л/с/н  Равнины, Лес: 250 Л/с/n  Тайга : 175 Л/с/n  Пляж: 170 Л/с/n  Другое: 100 Л/с
 gregtech.multiblock.primitive_water_pump.extra2=Множители люка:/n  Люк насоса: 1x/n  Выходной люк ULV: 2x/n  LV Выходной люк: 4xn/nВо время дождя в биомах работы насоса добыча воды будет увеличена на 50%%.
 gregtech.multiblock.processing_array.description=Массив машин объединяет до 16 одноблочных машин в одном многоблоке.
 gregtech.multiblock.advanced_processing_array.description=Массив машин объединяет до 64 одноблочных машин в одном многоблоке.
 item.invalid.name=Недопустимый предмет
 fluid.empty=Пусто
-gregtech.tooltip.hold_shift=Зажмите SHIFT для дополнительной информации
-gregtech.tooltip.hold_ctrl=Нажмите CTRL, чтобы увидеть больше информации
-gregtech.tooltip.fluid_pipe_hold_shift=Зажмите SHIFT что-бы посмотреть Информацию о Хранимой Жидкости
-gregtech.tooltip.tool_fluid_hold_shift=Зажмите SHIFT что-бы посмотреть Информацию о Инструменте или Хранимой Жидкости
+gregtech.tooltip.hold_shift=Зажмите SHIFT для Информации
+gregtech.tooltip.hold_ctrl=Зажмите CTRL для Информации
+gregtech.tooltip.fluid_pipe_hold_shift=Зажмите SHIFT для Информации о Жидкости
+gregtech.tooltip.tool_fluid_hold_shift=Зажмите SHIFT для Информации о Инструменте или Жидкости
 metaitem.generic.fluid_container.tooltip=%d/%dЛ %s
 metaitem.generic.electric_item.tooltip=%d/%d EU - Уровень §e%d
 metaitem.electric.discharge_mode.enabled=§eРежим разрядки Включен
@@ -130,19 +130,19 @@ metaitem.dust.tooltip.purify=Бросьте в котел, чтобы получ
 metaitem.crushed.tooltip.purify=Бросьте в котел, чтобы получить очищенную руду
 metaitem.int_circuit.configuration=§aКонфигурация: §f%d§7
 metaitem.credit.copper.name=Медный кредит
-metaitem.credit.copper.tooltip=0,125 кредита
+metaitem.credit.copper.tooltip=0,125 Кредита
 metaitem.credit.cupronickel.name=Купроникелевый кредит
-metaitem.credit.cupronickel.tooltip=1 кредит
+metaitem.credit.cupronickel.tooltip=1 Кредит
 metaitem.credit.silver.name=Серебряный кредит
-metaitem.credit.silver.tooltip=8 кредитов
+metaitem.credit.silver.tooltip=8 Кредитов
 metaitem.credit.gold.name=Золотой кредит
-metaitem.credit.gold.tooltip=64 кредита
+metaitem.credit.gold.tooltip=64 Кредита
 metaitem.credit.platinum.name=Платиновый кредит
-metaitem.credit.platinum.tooltip=512 кредитов
+metaitem.credit.platinum.tooltip=512 Кредитов
 metaitem.credit.osmium.name=Осмиевый кредит
-metaitem.credit.osmium.tooltip=4096 кредитов
+metaitem.credit.osmium.tooltip=4096 Кредитов
 metaitem.credit.naquadah.name=Наквадовый кредит
-metaitem.credit.naquadah.tooltip=32768 кредитов
+metaitem.credit.naquadah.tooltip=32768 Кредитов
 metaitem.credit.neutronium.name=Нейтрониевый кредит
 metaitem.credit.neutronium.tooltip=262144 Кредитов
 metaitem.coin.gold.ancient.name=Древняя золотая монета
@@ -164,7 +164,7 @@ metaitem.nano_saber.tooltip=Ryujin no ken wo kurae!
 metaitem.shape.mold.plate.name=Форма (Пластина)
 metaitem.shape.mold.plate.tooltip=Форма для изготовления пластин
 metaitem.shape.mold.casing.name=Форма (Корпус)
-metaitem.shape.mold.casing.tooltip=Форма для изготовления оболочек
+metaitem.shape.mold.casing.tooltip=Форма для изготовления корпусов
 metaitem.shape.mold.gear.name=Форма (Шестерня)
 metaitem.shape.mold.gear.tooltip=Форма для изготовления шестерней
 metaitem.shape.mold.credit.name=Форма (Чеканка)
@@ -177,7 +177,7 @@ metaitem.shape.mold.ball.name=Форма (Шар)
 metaitem.shape.mold.ball.tooltip=Форма для изготовления шариков
 metaitem.shape.mold.block.name=Форма (Блок)
 metaitem.shape.mold.block.tooltip=Форма для изготовления блоков
-metaitem.shape.mold.nugget.name=Форма (Самородки)
+metaitem.shape.mold.nugget.name=Форма (Самородок)
 metaitem.shape.mold.nugget.tooltip=Форма для изготовления самородков
 metaitem.shape.mold.cylinder.name=Форма (Цилиндр)
 metaitem.shape.mold.cylinder.tooltip=Форма для формирования цилиндров
@@ -186,7 +186,7 @@ metaitem.shape.mold.anvil.tooltip=Форма для формирования н
 metaitem.shape.mold.name.name=Форма (Имя)
 metaitem.shape.mold.name.tooltip=Форма для наименования предметов (переименуйте форму с помощью наковальни)
 metaitem.shape.mold.gear.small.name=Форма (Малая шестерня)
-metaitem.shape.mold.gear.small.tooltip=Форма для изготовления маленьких зубчатых колес
+metaitem.shape.mold.gear.small.tooltip=Форма для изготовления маленьких шестерней
 metaitem.shape.mold.rotor.name=Форма (Ротор)
 metaitem.shape.mold.rotor.tooltip=Форма для изготовления роторов
 metaitem.shape.extruder.plate.name=Форма экструдера (Пластина)
@@ -197,16 +197,16 @@ metaitem.shape.extruder.bolt.name=Форма экструдера (Болт)
 metaitem.shape.extruder.bolt.tooltip=Форма экструдера для изготовления болтов
 metaitem.shape.extruder.ring.name=Форма экструдера (Кольцо)
 metaitem.shape.extruder.ring.tooltip=Форма экструдера для изготовления колец
-metaitem.shape.extruder.cell.name=Форма экструдера (Ячейка)
-metaitem.shape.extruder.cell.tooltip=Форма экструдера для изготовления клеток
+metaitem.shape.extruder.cell.name=Форма экструдера (Капсула)
+metaitem.shape.extruder.cell.tooltip=Форма экструдера для изготовления капсул
 metaitem.shape.extruder.ingot.name=Форма экструдера (Слиток)
-metaitem.shape.extruder.ingot.tooltip=Форма экструдера, подожди, мы не можем просто использовать печь?
+metaitem.shape.extruder.ingot.tooltip=Форма экструдера, подожди, может просто использовать печь?
 metaitem.shape.extruder.wire.name=Форма экструдера (Проволока)
 metaitem.shape.extruder.wire.tooltip=Форма экструдера для изготовления проводов
 metaitem.shape.extruder.casing.name=Форма экструдера (Корпус)
-metaitem.shape.extruder.casing.tooltip=Форма экструдера для изготовления оболочек
-metaitem.shape.extruder.pipe.tiny.name=Форма экструдера (Трубка)
-metaitem.shape.extruder.pipe.tiny.tooltip=Форма экструдера для изготовления трубок
+metaitem.shape.extruder.casing.tooltip=Форма экструдера для изготовления корпусов
+metaitem.shape.extruder.pipe.tiny.name=Форма экструдера (Очень маленькая труба)
+metaitem.shape.extruder.pipe.tiny.tooltip=Форма экструдера для изготовления очень маленьких труб
 metaitem.shape.extruder.pipe.small.name=Форма экструдера (Малая труба)
 metaitem.shape.extruder.pipe.small.tooltip=Форма экструдера для изготовления небольших труб
 metaitem.shape.extruder.pipe.normal.name=Форма экструдера (Средняя труба)
@@ -234,15 +234,15 @@ metaitem.shape.extruder.file.tooltip=Форма экструдера для из
 metaitem.shape.extruder.saw.name=Форма экструдера (Пильный диск)
 metaitem.shape.extruder.saw.tooltip=Форма экструдера для изготовления пил
 metaitem.shape.extruder.gear.name=Форма экструдера (Шестерня)
-metaitem.shape.extruder.gear.tooltip=Форма экструдера для изготовления зубчатых колес
+metaitem.shape.extruder.gear.tooltip=Форма экструдера для изготовления шестерней
 metaitem.shape.extruder.bottle.name=Форма экструдера (Бутылка)
 metaitem.shape.extruder.bottle.tooltip=Форма экструдера для изготовления бутылок
 metaitem.shape.extruder.gear_small.name=Форма экструдера (маленькая шестеренка)
-metaitem.shape.extruder.gear_small.tooltip=Форма экструдера для производства маленьких шестеренок
+metaitem.shape.extruder.gear_small.tooltip=Форма экструдера для производства маленьких шестереней
 metaitem.shape.extruder.foil.name=Форма экструдера (Фольга)
 metaitem.shape.extruder.foil.tooltip=Форма экструдера для производства фольги из неметаллов
 metaitem.shape.extruder.rod_long.name=Форма экструдера (Длинный прут)
-metaitem.shape.extruder.rod_long.tooltip=Форма экструдера для производства длинных прутов
+metaitem.shape.extruder.rod_long.tooltip=Форма экструдера для производства прутьев
 metaitem.shape.extruder.rotor.name=Форма экструдера (Ротор)
 metaitem.shape.extruder.rotor.tooltip=Форма экструдера для производства роторов
 metaitem.spray.empty.name=Баллончик (Пустой)
@@ -386,7 +386,7 @@ metaitem.fluid.regulator.iv.name=Регулятор жидкости (§1IV§r)
 metaitem.fluid.regulator.luv.name=Регулятор жидкости (§dLuV§r)
 metaitem.fluid.regulator.zpm.name=Регулятор жидкости (§fZPM§r)
 metaitem.fluid.regulator.uv.name=Регулятор жидкости (§3UV§r)
-metaitem.fluid.regulator.tooltip=Ограничивает передачу §fЖидкостей§7 заданным количеством как §fУлучшение машины§7.
+metaitem.fluid.regulator.tooltip=Ограничивает передачу §fЖидкостей§7 заданным кол-вом как §fУлучшение машины§7.
 metaitem.conveyor.module.lv.name=Конвейерный модуль (§7LV§r)
 metaitem.conveyor.module.mv.name=Конвейерный модуль (§bMV§r)
 metaitem.conveyor.module.hv.name=Конвейерный модуль (§6HV§r)
@@ -427,7 +427,7 @@ metaitem.robot.arm.uev.name=Роботизированный манипулят
 metaitem.robot.arm.uiv.name=Роботизированный манипулятор (§2UIV§r)
 metaitem.robot.arm.uxv.name=Роботизированный манипулятор (§eUXV§r)
 metaitem.robot.arm.opv.name=Роботизированный манипулятор (§9OpV§r)
-metaitem.robot.arm.tooltip=Ограничивает передачу §fПредметов§7 заданным количеством как §fУлучшение механизма§7.
+metaitem.robot.arm.tooltip=Ограничивает передачу §fПредметов§7 заданным кол-вом как §fУлучшение механизма§7.
 metaitem.field.generator.lv.name=Генератор поля (§7LV§r)
 metaitem.field.generator.mv.name=Генератор поля (§bMV§r)
 metaitem.field.generator.hv.name=Генератор поля (§6HV§r)
@@ -511,7 +511,7 @@ metaitem.wafer.naquadah.name=Плаcтина легированная наква
 metaitem.wafer.naquadah.tooltip=Необработанная схема
 metaitem.wafer.neutronium.name=Пластина легированная нейтронием
 metaitem.wafer.neutronium.tooltip=Необработанная схема
-metaitem.board.coated.name=Прорезиненая подложка
+metaitem.board.coated.name=Прорезиненная подложка
 metaitem.board.coated.tooltip=Подложка с покрытием
 metaitem.board.phenolic.name=Профеноленая подложка
 metaitem.board.phenolic.tooltip=Хорошая подложка
@@ -521,7 +521,7 @@ metaitem.board.epoxy.name=Эпоксидная подложка
 metaitem.board.epoxy.tooltip=Продвинутая подложка
 metaitem.board.fiber_reinforced.name=Укрепленная эпоксидная подложка
 metaitem.board.fiber_reinforced.tooltip=Улучшенная подложка
-metaitem.board.multilayer.fiber_reinforced.name=Многослойная текстолитовая печатная плата
+metaitem.board.multilayer.fiber_reinforced.name=Многослойная текстолитовая подложка
 metaitem.board.multilayer.fiber_reinforced.tooltip=Превосходная подложка
 metaitem.board.wetware.name=Питательная подложка
 metaitem.board.wetware.tooltip=Подложка, которая хранит жизнь
@@ -572,9 +572,9 @@ metaitem.component.advanced_smd.resistor.name=Улучшенный SMD рези
 metaitem.component.advanced_smd.resistor.tooltip=Улучшенный электронный компонент
 metaitem.component.advanced_smd.inductor.name=Улучшенный SMD индуктор
 metaitem.component.advanced_smd.inductor.tooltip=Улучшенный электронный компонент
-metaitem.wafer.highly_advanced_system_on_chip.name=Пластина HASoC
-metaitem.wafer.highly_advanced_system_on_chip.tooltip=Необработанная высоковольтажная микросхема
-metaitem.wafer.advanced_system_on_chip.name=Пластина ASoC
+metaitem.wafer.highly_advanced_system_on_chip.name=Пластина ОУСнК
+metaitem.wafer.highly_advanced_system_on_chip.tooltip=Необработанная очень продвинутая микросхема
+metaitem.wafer.advanced_system_on_chip.name=Пластина УСнК
 metaitem.wafer.advanced_system_on_chip.tooltip=Необработанная продвинутая микросхема
 metaitem.wafer.integrated_logic_circuit.name=Пластина IC
 metaitem.wafer.integrated_logic_circuit.tooltip=Необработанная интегральная микросхема
@@ -592,17 +592,17 @@ metaitem.wafer.low_power_integrated_circuit.name=Пластина LPIC
 metaitem.wafer.low_power_integrated_circuit.tooltip=Необработанная низковольтажная микросхема
 metaitem.wafer.power_integrated_circuit.name=Пластина PIC
 metaitem.wafer.power_integrated_circuit.tooltip=Необработанная силовая микросхема
-metaitem.wafer.nano_central_processing_unit.name=Пластина Нано-процессора
+metaitem.wafer.nano_central_processing_unit.name=Пластина нано-процессора
 metaitem.wafer.nano_central_processing_unit.tooltip=Необработанная нано-микросхема
 metaitem.wafer.nor_memory_chip.name=Пластина NOR-памяти
 metaitem.wafer.nor_memory_chip.tooltip=Необработанная логическая схема
-metaitem.wafer.qbit_central_processing_unit.name=Пластина Qubit процессора
-metaitem.wafer.qbit_central_processing_unit.tooltip=Необработанная Qubit микросхема
+metaitem.wafer.qbit_central_processing_unit.name=Пластина кубитного процессора
+metaitem.wafer.qbit_central_processing_unit.tooltip=Необработанная кубитная микросхема
 metaitem.wafer.random_access_memory.name=Пластина RAM
 metaitem.wafer.random_access_memory.tooltip=Необработанная память
-metaitem.wafer.system_on_chip.name=Пластина SoC
+metaitem.wafer.system_on_chip.name=Пластина СнК
 metaitem.wafer.system_on_chip.tooltip=Необработанная обычная микросхема
-metaitem.wafer.simple_system_on_chip.name=Простая пластина SoC
+metaitem.wafer.simple_system_on_chip.name=Простая пластина СнК
 metaitem.wafer.simple_system_on_chip.tooltip=Необработанная простая микросхема
 metaitem.engraved.crystal_chip.name=Гравированный кристальный чип
 metaitem.engraved.crystal_chip.tooltip=Требуется для микросхем
@@ -613,12 +613,12 @@ metaitem.crystal.raw_chip.tooltip=Компонент необработанно
 metaitem.engraved.lapotron_chip.name=Гравированный лапотронный кристальный чип
 metaitem.crystal.central_processing_unit.name=Кристалл CPU
 metaitem.crystal.central_processing_unit.tooltip=Кристалл блока обработки
-metaitem.crystal.system_on_chip.name=Кристальный SoC
-metaitem.crystal.system_on_chip.tooltip=Кристаллическая система на чипе
-metaitem.plate.advanced_system_on_chip.name=ASoC
-metaitem.plate.advanced_system_on_chip.tooltip=Улучшенная система в чипе
-metaitem.plate.highly_advanced_system_on_chip.name=HASoC
-metaitem.plate.highly_advanced_system_on_chip.tooltip=Очень улучшенная система в чипе
+metaitem.crystal.system_on_chip.name=Кристальный СнК
+metaitem.crystal.system_on_chip.tooltip=Кристаллическая система на кристалле
+metaitem.plate.advanced_system_on_chip.name=УСнК
+metaitem.plate.advanced_system_on_chip.tooltip=Улучшенная система на кристалле
+metaitem.plate.highly_advanced_system_on_chip.name=ОУСнК
+metaitem.plate.highly_advanced_system_on_chip.tooltip=Очень улучшенная система на кристалле
 metaitem.plate.integrated_logic_circuit.name=Интегральная схема
 metaitem.plate.integrated_logic_circuit.tooltip=Интегральная логическая схема
 metaitem.plate.central_processing_unit.name=Центральный процессор
@@ -643,10 +643,10 @@ metaitem.plate.qbit_central_processing_unit.name=Кубитный процесс
 metaitem.plate.qbit_central_processing_unit.tooltip=Кубитный центральный процессор
 metaitem.plate.random_access_memory.name=ОЗУ
 metaitem.plate.random_access_memory.tooltip=Оперативная память
-metaitem.plate.system_on_chip.name=SoC
-metaitem.plate.system_on_chip.tooltip=Система в чипе
-metaitem.plate.simple_system_on_chip.name=Обычная SoC
-metaitem.plate.simple_system_on_chip.tooltip=Простая система на чипе
+metaitem.plate.system_on_chip.name=СнК
+metaitem.plate.system_on_chip.tooltip=Система на кристалле
+metaitem.plate.simple_system_on_chip.name=Обычная СнК
+metaitem.plate.simple_system_on_chip.tooltip=Простая система на кристалле
 
 
 # T1: Electronic
@@ -667,7 +667,7 @@ metaitem.circuit.advanced_integrated.tooltip=Меньше и мощнее/n§6HV
 metaitem.circuit.nand_chip.name=NAND чип
 metaitem.circuit.nand_chip.tooltip=Превосходная простая микросхема/n§6ULV уровень
 metaitem.circuit.microprocessor.name=Микропроцессор
-metaitem.circuit.microprocessor.tooltip=Улучшенная обычная микросхема/n§eLV уровень
+metaitem.circuit.microprocessor.tooltip=Совершенная обычная микросхема/n§eLV уровень
 
 # T3: Processor
 metaitem.circuit.processor.name=Интегральный микропроцессор
@@ -759,11 +759,11 @@ metaitem.cover.fluid.detector.tooltip=Выдает §fЗаполнение жи
 metaitem.cover.fluid.detector.advanced.name=Улучшенный детектор жидкости (Улучшение)
 metaitem.cover.fluid.detector.advanced.tooltip=Позволяет §fRS-триггеру§7 управлять §fСостоянием Хранилища жидкости§7 как редстоунов, в качестве §fКрышки§7.
 metaitem.cover.item.detector.name=Детектор предметов (Улучшение)
-metaitem.cover.item.detector.tooltip=Выдает §fКоличество предметов§7 Сигналом Красного камня как §fУлучшение механизма§7.
+metaitem.cover.item.detector.tooltip=Выдает §fКол-во предметов§7 Сигналом Красного камня как §fУлучшение механизма§7.
 metaitem.cover.item.detector.advanced.name=Улучшенный детектор предметов (Улучшение)
 metaitem.cover.item.detector.advanced.tooltip=Позволяет §fRS-триггеру§7 управлять §fСостоянием Хранилища предметов§7 как редстоунов, в качестве §fКрышки§7.
 metaitem.cover.energy.detector.name=Детектор энергии (Улучшение)
-metaitem.cover.energy.detector.tooltip=Выдает §fКоличество энергии§7 Сигналом Красного камня как §fУлучшение механизма§7.
+metaitem.cover.energy.detector.tooltip=Выдает §fКол-во энергии§7 Сигналом Красного камня как §fУлучшение механизма§7.
 metaitem.cover.energy.detector.advanced.name=Улучшенный детектор энергии (Улучшение)
 metaitem.cover.energy.detector.advanced.tooltip=Даёт §fRS-триггерный контроль за Уровнем энергии§7 Сигналом Красного камня как §fУлучшение механизма§7.
 metaitem.cover.fluid.voiding.name=Удаление жидкостей (Улучшение)
@@ -777,7 +777,7 @@ metaitem.cover.item.voiding.advanced.tooltip=Удаляет §fПредметы
 metaitem.cover.storage.name=Хранилище (Улучшение)
 metaitem.cover.storage.tooltip=Небольшое хранилище для хранения мелочей
 metaitem.cover.maintenance.detector.name=Детектор неисправностей (Улучшение)
-metaitem.cover.maintenance.detector.tooltip=Выдает §Количество Неисправностей§7 Сигналом Красного камня как §fУлучшение механизма§7.
+metaitem.cover.maintenance.detector.tooltip=Выдает §Кол-во Неисправностей§7 Сигналом Красного камня как §fУлучшение механизма§7.
 metaitem.cover.facade.name=Фасад (%s)
 metaitem.cover.facade.tooltip=Декоративный элемент.
 metaitem.cover.screen.name=Компьютерный монитор (Улучшение)
@@ -827,7 +827,7 @@ metaitem.plant_ball.name=Комок биомассы
 metaitem.tool_parts_box.name=Ящик для инструментов
 metaitem.tool_parts_box.tooltip=Для хранения инструментов/nЩелкните правой кнопкой, чтобы открыть
 metaitem.foam_sprayer.name=Пенный распылитель
-metaitem.foam_sprayer.tooltip=Распыляет строительную пену/nЩелкните правой кнопкой, чтобы запенить соединенные рамки./nИспользуйте металл для создания армированного бетона/nПена может быть цветной
+metaitem.foam_sprayer.tooltip=Распыляет строительную пену/nЩелкните правой кнопкой, чтобы запенить соединенные Каркасы./nИспользуйте металл для создания армированного бетона/nПена может быть цветной
 metaitem.energium_dust.name=Энергетическая пыль
 metaitem.compressed.clay.name=Сжатая глина
 metaitem.compressed.fireclay.name=Сжатая шамотная глина
@@ -937,7 +937,7 @@ item.gt.tool.harvest_level.3=§bАлмаз
 item.gt.tool.harvest_level.4=§dУльтимет
 item.gt.tool.harvest_level.5=§9Дураний
 item.gt.tool.harvest_level.6=§cНейтроний
-item.gt.tool.tooltip.repair_info=Удерживайте SHIFT для информации о Ремонте
+item.gt.tool.tooltip.repair_info=Зажмите SHIFT для Информации о Ремонте
 item.gt.tool.tooltip.repair_material=Чинится: §a%s
 item.gt.tool.aoe.rows=Рядов
 item.gt.tool.aoe.columns=Столбцов
@@ -1051,14 +1051,14 @@ metaitem.nan.certificate.tooltip=Вызов принят!
 metaitem.fertilizer.name=Удобрение
 metaitem.blacklight.name=Черный свет
 metaitem.blacklight.tooltip=Источник длинноволнового §dультрафиолетового§7 излучения
-gui.widget.incrementButton.default_tooltip=Удерживайте Shift, Ctrl или оба, чтобы изменить количество
+gui.widget.incrementButton.default_tooltip=Удерживайте Shift, Ctrl или оба, чтобы изменить кол-во
 gui.widget.recipeProgressWidget.default_tooltip=Показать рецепт
 gregtech.recipe_memory_widget.tooltip.2=§7Нажмите Shift, чтобы заблокировать/разблокировать этот рецепт
 gregtech.recipe_memory_widget.tooltip.1=§7Щелкните левой кнопкой мыши, чтобы автоматически добавить этот рецепт в сетку крафта
 cover.filter.blacklist.disabled=Белый список
 cover.filter.blacklist.enabled=Черный список
 cover.ore_dictionary_filter.title=Фильтр по словарю руд
-cover.ore_dictionary_filter.info=§bПринимает сложные выражения/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r для группировки/n§6*§r для подстановочного знака/n§6?§r для любого 1 символа/n§6()§r для пустого места (включая предметы из словаря руд)/n§6$c§r для начала выражения с учетов регистра/n§bПример:/n§6dust*Gold | (plate* & !*Double*)/nПодходит для всей золотой пыли всех размеров или всех пластин, но не для двойных пластин
+cover.ore_dictionary_filter.info=§bПринимает сложные выражения/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r для группировки/n§6*§r для подстановочного знака/n§6?§r для любого 1 символа/n§6()§r для пустого места (включая предметы из словаря руд)/n§bПример:/n§6dust*Gold | (plate* & !*Double*)/nПодходит для всей золотой пыли всех размеров или всех пластин, но не для двойных пластин
 cover.ore_dictionary_filter.test_slot.info=Вставьте элемент, чтобы проверить, соответствует ли он выражению фильтра
 cover.ore_dictionary_filter.test_slot.matches=§a* %s
 cover.ore_dictionary_filter.test_slot.matches_not=§c* %s
@@ -1070,7 +1070,7 @@ cover.ore_dictionary_filter.status.warn=§7%s предупреждение(я)
 cover.ore_dictionary_filter.status.no_issues=§aНет проблем
 cover.ore_dictionary_filter.status.explain=Объяснение фильтра руды:
 cover.fluid_filter.title=Жидкостный фильтр
-cover.fluid_filter.config_amount=Колесо прокрутки вверх увеличивает количество, вниз уменьшает./nShift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]/nПравый клик увеличивает количество, левый уменьшает./nУдерживайте Shift, чтобы удвоить/уполовинить./nЩелкните средней кнопкой, чтобы очистить
+cover.fluid_filter.config_amount=Колесо прокрутки вверх увеличивает количество, вниз уменьшает./nShift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]/nПравый клик увеличивает кол-во, левый уменьшает./nУдерживайте Shift, чтобы удвоить/уполовинить./nЩелкните средней кнопкой, чтобы очистить
 cover.fluid_filter.mode.filter_fill=Фильтрует при наполнении
 cover.fluid_filter.mode.filter_drain=Фильтрует при сливе
 cover.fluid_filter.mode.filter_both=Фильтрует при сливе и наполнении
@@ -1098,7 +1098,7 @@ cover.smart_item_filter.title=Умный предметный фильтр
 cover.smart_item_filter.filtering_mode.electrolyzer=Электролизер
 cover.smart_item_filter.filtering_mode.centrifuge=Центрифуга
 cover.smart_item_filter.filtering_mode.sifter=Просеиватель
-cover.smart_item_filter.filtering_mode.description=Выберите механизм для которой будут/не будут фильтроваться предметы для роботической руки.
+cover.smart_item_filter.filtering_mode.description=Выберите машину, которую этот Умный фильтр будет использовать для фильтрации./nОн автоматически отберет нужное кол-во предметов для роб. манипулятора.
 cover.conveyor.title=Настройки улучшения конвейера (%s)
 cover.conveyor.transfer_rate=§7предметов/с
 cover.conveyor.mode.export=Режим: Экспорт
@@ -1115,7 +1115,7 @@ cover.conveyor.item_filter.title=Фильтр предметов
 cover.conveyor.ore_dictionary.title=Название по словарю руд
 cover.conveyor.ore_dictionary.title2=(используйте * как подстановочный знак)
 cover.robotic_arm.title=Настройки роб. манипулятора (%s)
-cover.robotic_arm.transfer_mode.transfer_any=Перемещение любое количество
+cover.robotic_arm.transfer_mode.transfer_any=Перемещение любое кол-во
 cover.robotic_arm.transfer_mode.transfer_exact=Перемещать ровно
 cover.robotic_arm.transfer_mode.keep_exact=Поддерживать ровно
 cover.robotic_arm.transfer_mode.description=§eПеремещение любых предметов§r - в этом режиме улучшение будет передавать как можно больше предметов, соответствующих фильтру./n§eПодавать точно§r - в этом режиме улучшение будет поставлять предметы порциями, указанными в слотах фильтра предметов (или скоростью передачи для §bФильтра Словаря руды§r). Если количество предметов меньше размера порции, предметы не будут перемещены ./n§eСохранять точно§r - в этом режиме обложка сохранит указанное количество предметов в целевом инвентаре, предоставляя дополнительное количество предметов, если это необходимо./n§7Подсказка: щелкните Лкм или Пкм на слотах фильтра, чтобы изменить количество предметов,  используйте Shift, чтобы изменять количество быстрее.
@@ -1162,7 +1162,7 @@ cover.advanced_fluid_detector.label=Улучшенный детектор жид
 cover.advanced_fluid_detector.max=Макс. жидкости:
 cover.advanced_fluid_detector.min=Мин. жидкости:
 cover.advanced_item_detector.label=Улучшенный детектор предметов
-cover.advanced_item_detector.invert_tooltip=Переключите, чтобы инвертировать логику красного камня./nПо умолчанию красный камень перестает испускать сигнал, когда количество предметов меньше минимального, и начинает испускать сигнал, при превышении минимального количества предметов до установленного максимума
+cover.advanced_item_detector.invert_tooltip=Переключите, чтобы инвертировать логику красного камня./nПо умолчанию красный камень перестает испускать сигнал, когда кол-во предметов меньше мин., и начинает испускать сигнал, при превышении мин. кол-ва предметов до установленного макс
 cover.advanced_item_detector.max=Макс. предметов:
 cover.advanced_item_detector.min=Мин. предметов:
 cover.storage.title=Хранилище (Улучшение)
@@ -1203,8 +1203,8 @@ item.material.oreprefix.plateDouble=%s (Двойная пластина)
 item.material.oreprefix.plate=%s (Пластина)
 item.material.oreprefix.plank=Доска (%s)
 item.material.oreprefix.foil=%s (Фольга)
-item.material.oreprefix.stick=%s (Прут)
-item.material.oreprefix.stickLong=%s (Стержень)
+item.material.oreprefix.stick=%s (Стержень)
+item.material.oreprefix.stickLong=%s (Прут)
 item.material.oreprefix.round=%s (Шарик)
 item.material.oreprefix.bolt=%s (Болт)
 item.material.oreprefix.screw=%s (Винт)
@@ -1264,7 +1264,7 @@ item.material.oreprefix.polymer.plate=%s (Лист)
 item.material.oreprefix.polymer.foil=%s (Фольга)
 item.material.oreprefix.polymer.nugget=%s (Осколок)
 item.material.oreprefix.polymer.plateDense=%s (Плотный лист)
-item.material.oreprefix.polymer.plateDouble=%s (Плотный лист)
+item.material.oreprefix.polymer.plateDouble=%s (Двойной лист)
 item.material.oreprefix.polymer.dustTiny=%s (Крохотная кучка)
 item.material.oreprefix.polymer.dustSmall=%s (Маленькая кучка)
 item.material.oreprefix.polymer.dust=%s (Пыль)
@@ -1942,7 +1942,7 @@ item.gregtech.material.cassiterite_sand.dustImpure=Грязная кучка к
 item.gregtech.material.cassiterite_sand.dustPure=Очищеная кучка касситеритного песка
 item.gregtech.material.cassiterite_sand.dust=Касситеритовый песок
 item.gregtech.material.dark_ash.dustTiny=Крошечная кучка пепла
-item.gregtech.material.dark_ash.dustSmall=Маленькая кучка темного пепла
+item.gregtech.material.dark_ash.dustSmall=Маленькая кучка пепла
 item.gregtech.material.dark_ash.dust=Пепел
 item.gregtech.material.ice.dustTiny=Крошечная кучка колотого льда
 item.gregtech.material.ice.dustSmall=Маленькая кучка колотого льда
@@ -2006,9 +2006,9 @@ item.gregtech.material.bentonite.dustPure=Очищеный кучка бенто
 item.gregtech.material.bentonite.dustSmall=Маленькая кучка бентонита
 item.gregtech.material.bentonite.dustTiny=Крошечная кучка бентонита
 item.gregtech.material.bentonite.dust=Бентонит
-item.gregtech.material.fullers_earth.dustSmall=Маленькая кучка странной земли
-item.gregtech.material.fullers_earth.dustTiny=Крошечная кучка странной земли
-item.gregtech.material.fullers_earth.dust=Странная земля
+item.gregtech.material.fullers_earth.dustSmall=Маленькая кучка смектической глины
+item.gregtech.material.fullers_earth.dustTiny=Крошечная кучка cмектической глины
+item.gregtech.material.fullers_earth.dust=Смектическая глина
 item.gregtech.material.pitchblende.crushed=Измельчённый уранит
 item.gregtech.material.pitchblende.crushedCentrifuged=Центрифугированный уранит
 item.gregtech.material.pitchblende.crushedPurified=Очищеный уранит
@@ -2187,7 +2187,7 @@ behavior.tricorder.bedrock_fluid.amount=Жидкость в месторожде
 behavior.tricorder.bedrock_fluid.amount_unknown=Жидкость в месторождении: %s%%
 behavior.tricorder.bedrock_fluid.nothing=Жидкость в месторождении: §6Ничего§r
 behavior.tricorder.eut_per_sec=За последняя секунду прошло %s EU/t
-behavior.tricorder.amp_per_sec=За последняя секунду прошло %s A
+behavior.tricorder.amp_per_sec=За последнюю секунду прошло %s A
 behavior.tricorder.workable_consumption=Примерно использует: %s EU/t при %s A
 behavior.tricorder.workable_production=Примерно производит: %s EU/т при %s A
 behavior.tricorder.workable_progress=Прогресс: %s с / %s с
@@ -2239,7 +2239,7 @@ tile.casing.ev=Корпус машины (§5EV§r)
 tile.casing.iv=Корпус машины (§1IV§r)
 
 # Wire coil blocks
-tile.wire_coil.tooltip_extended_info=Зажмите SHIFT для просмотра Бонуса Катушек
+tile.wire_coil.tooltip_extended_info=Зажмите SHIFT для Информации о Бонуса Катушек
 tile.wire_coil.tooltip_heat=§cТеплоемкость: §f%,d K
 tile.wire_coil.tooltip_smelter=§8Мультиплавильня:
 tile.wire_coil.tooltip_parallel_smelter=§5Параллелей: §f%s
@@ -2365,10 +2365,10 @@ tile.machine_casing.overpowered_voltage.name=Корпус машины (OpV)
 tile.machine_casing.maximum_voltage.name=Корпус машины (MAX)
 
 # Steam casing blocks
-tile.steam_casing.bronze_hull.name=Бронзовый корпус
-tile.steam_casing.bronze_bricks_hull.name=Бронзовый кирпичный корпус
-tile.steam_casing.steel_hull.name=Стальной корпус
-tile.steam_casing.steel_bricks_hull.name=Кирпичный корпус из кованого железа
+tile.steam_casing.bronze_hull.name=Бронзовая оболочка
+tile.steam_casing.bronze_bricks_hull.name=Бронзовая кирпичная оболочка
+tile.steam_casing.steel_hull.name=Стальная оболочка
+tile.steam_casing.steel_bricks_hull.name=Кирпичная оболочка из кованого железа
 tile.steam_casing.bronze.tooltip=Для ваших первых паровых машин
 tile.steam_casing.steel.tooltip=Для улучшенных паровых машин
 tile.steam_casing.pump_deck.name=Насосная палуба
@@ -2924,7 +2924,7 @@ gregtech.machine.canner.uhv.name=Идеальный наполнитель
 gregtech.machine.canner.uhv.tooltip=Электроконсерватор
 gregtech.machine.canner.uev.name=Идеальный наполнитель II
 gregtech.machine.canner.uev.tooltip=Электроконсерватор
-gregtech.machine.canner.uiv.name=Идеальный наполнитель II
+gregtech.machine.canner.uiv.name=Идеальный наполнитель III
 gregtech.machine.canner.uiv.tooltip=Электроконсерватор
 gregtech.machine.canner.uxv.name=Идеальный наполнитель IV
 gregtech.machine.canner.uxv.tooltip=Электроконсерватор
@@ -3082,7 +3082,7 @@ gregtech.machine.distillery.zpm.name=Превосходный дистиллят
 gregtech.machine.distillery.uv.name=Безупречный дистиллятор
 gregtech.machine.distillery.uhv.name=Идеальный дистиллятор
 gregtech.machine.distillery.uev.name=Идеальный дистиллятор II
-gregtech.machine.distillery.uiv.name=Идеальный дистиллятор II
+gregtech.machine.distillery.uiv.name=Идеальный дистиллятор III
 gregtech.machine.distillery.uxv.name=Идеальный дистиллятор IV
 gregtech.machine.distillery.lv.tooltip=Извлечение наиболее важных частей жидкостей
 gregtech.machine.distillery.mv.tooltip=Извлечение наиболее важных частей жидкостей
@@ -3472,7 +3472,7 @@ gregtech.machine.polarizer.zpm.name=Превосходный поляризат
 gregtech.machine.polarizer.uv.name=Безупречный поляризатор
 gregtech.machine.polarizer.uhv.name=Идеальный поляризатор
 gregtech.machine.polarizer.uev.name=Идеальный поляризатор II
-gregtech.machine.polarizer.uiv.name=Идеальный поляризатор II
+gregtech.machine.polarizer.uiv.name=Идеальный поляризатор III
 gregtech.machine.polarizer.uxv.name=Идеальный поляризатор IV
 gregtech.machine.polarizer.lv.tooltip=Биполяризация ваших магнитов
 gregtech.machine.polarizer.mv.tooltip=Биполяризация ваших магнитов
@@ -3722,21 +3722,21 @@ gregtech.creative_tooltip.3=§7 чтобы использовать это
 
 # Machine hulls
 gregtech.machine.hull.tooltip=§7Вам просто нужно §5В§dо§4о§cб§eр§aа§bж§3е§7н§1и§5е§7 чтобы использовать это
-gregtech.machine.hull.ulv.name=Корпус машины (§8ULV§r)
-gregtech.machine.hull.lv.name=Корпус машины (§7LV§r)
-gregtech.machine.hull.mv.name=Корпус машины (§bMV§r)
-gregtech.machine.hull.hv.name=Корпус машины (§6HV§r)
-gregtech.machine.hull.ev.name=Корпус машины (§5EV§r)
-gregtech.machine.hull.iv.name=Корпус машины (§1IV§r)
-gregtech.machine.hull.luv.name=Корпус машины (§dLuV§r)
-gregtech.machine.hull.zpm.name=Корпус машины (§fZPM§r)
-gregtech.machine.hull.uv.name=Корпус машины (§3UV§r)
-gregtech.machine.hull.uhv.name=Корпус машины (§4UHV§r)
-gregtech.machine.hull.uev.name=Корпус машины (§aUEV§r)
-gregtech.machine.hull.uiv.name=Корпус машины (§2UIV§r)
-gregtech.machine.hull.uxv.name=Корпус машины (§eUXV§r)
-gregtech.machine.hull.opv.name=Корпус машины (§9OpV§r)
-gregtech.machine.hull.max.name=Корпус машины (§cMAX§r)
+gregtech.machine.hull.ulv.name=Оболочка машины (§8ULV§r)
+gregtech.machine.hull.lv.name=Оболочка машины (§7LV§r)
+gregtech.machine.hull.mv.name=Оболочка машины (§bMV§r)
+gregtech.machine.hull.hv.name=Оболочка машины (§6HV§r)
+gregtech.machine.hull.ev.name=Оболочка машины (§5EV§r)
+gregtech.machine.hull.iv.name=Оболочка машины (§1IV§r)
+gregtech.machine.hull.luv.name=Оболочка машины (§dLuV§r)
+gregtech.machine.hull.zpm.name=Оболочка машины (§fZPM§r)
+gregtech.machine.hull.uv.name=Оболочка машины (§3UV§r)
+gregtech.machine.hull.uhv.name=Оболочка машины (§4UHV§r)
+gregtech.machine.hull.uev.name=Оболочка машины (§aUEV§r)
+gregtech.machine.hull.uiv.name=Оболочка машины (§2UIV§r)
+gregtech.machine.hull.uxv.name=Оболочка машины (§eUXV§r)
+gregtech.machine.hull.opv.name=Оболочка машины (§9OpV§r)
+gregtech.machine.hull.max.name=Оболочка машины (§cMAX§r)
 
 # Battery buffers
 gregtech.machine.battery_buffer.ulv.4.name=Батарейный буфер (4 ячейки §8ULV§r)
@@ -3789,7 +3789,7 @@ gregtech.battery_buffer.average_input=Ввод в среднем: %s EU/t
 
 # Transformers
 gregtech.machine.transformer.description=Преобразует энергию между уровнями напряжения
-gregtech.machine.transformer.higher_amp.description=Преобразует энергию между уровнями напряжения, теперь с большим количеством ампер!
+gregtech.machine.transformer.higher_amp.description=Преобразует энергию между уровнями напряжения, теперь с большим кол-вом ампер!
 gregtech.machine.transformer.tooltip_tool_usage=По умолчанию §fПонижающий режим§7, используйте киянку чтобы инвертировать режим
 gregtech.machine.transformer.tooltip_transform_down=§aПонижающий режим: §f%dA %d EU (%s§f) -> %dA %d EU (%s§f)
 gregtech.machine.transformer.message_transform_down=Понижает напряжение, вход: %d EU %dA, выход: %d EU %dA
@@ -4263,8 +4263,8 @@ gregtech.advancement.extreme_voltage.50_nano_processor.name=Нано-проце
 gregtech.advancement.extreme_voltage.50_nano_processor.desc=Получите нано-процессор.
 gregtech.advancement.extreme_voltage.51_large_combustion_engine.name=Большой дизельный генератор
 gregtech.advancement.extreme_voltage.51_large_combustion_engine.desc=Соберите большой дизельный генератор, снабдите его смазкой и ускорьте кислородом.
-gregtech.advancement.extreme_voltage.52_soc_wafer.name=Пластина SoC
-gregtech.advancement.extreme_voltage.52_soc_wafer.desc=Сделайте Пластину SoC для более дешёвого производства микропроцессоров и интегральных микросхем.
+gregtech.advancement.extreme_voltage.52_soc_wafer.name=Пластина СНК
+gregtech.advancement.extreme_voltage.52_soc_wafer.desc=Сделайте Пластину СНК для более дешёвого производства микропроцессоров и интегральных микросхем.
 gregtech.advancement.root_iv.name=Безумный вольтаж
 gregtech.advancement.root_iv.desc=Охладите горячую вольфрамовую сталь.
 gregtech.advancement.insane_voltage.53_plutonium_239.name=Плутоний-239
@@ -4295,8 +4295,8 @@ gregtech.advancement.ludicrous_voltage.65_naquadah.name=Материал зве
 gregtech.advancement.ludicrous_voltage.65_naquadah.desc=Охладите горячий слиток наквады.
 gregtech.advancement.ludicrous_voltage.66_naquadah_coil.name=Улучшите ваши катушки до уровня VI
 gregtech.advancement.ludicrous_voltage.66_naquadah_coil.desc=Создайте катушку из наквады.
-gregtech.advancement.ludicrous_voltage.67_asoc_wafer.name=Пластина ASoC
-gregtech.advancement.ludicrous_voltage.67_asoc_wafer.desc=Сделайте Пластину SoC для более дешёвого производства нано-процессоров и квантовых процессоров.
+gregtech.advancement.ludicrous_voltage.67_asoc_wafer.name=Пластина УСНК
+gregtech.advancement.ludicrous_voltage.67_asoc_wafer.desc=Сделайте Пластину СНК для более дешёвого производства нано-процессоров и квантовых процессоров.
 gregtech.advancement.ludicrous_voltage.68_large_plasma_turbine.name=Большая плазменная турбина
 gregtech.advancement.ludicrous_voltage.68_large_plasma_turbine.desc=Создайте плазменную турбину, использующую плазму как топливо.
 gregtech.advancement.root_zpm.name=Модуль нулевой точки
@@ -4325,8 +4325,8 @@ gregtech.advancement.ultimate_voltage.76_neutronium.name=Как можно пл
 gregtech.advancement.ultimate_voltage.76_neutronium.desc=Получите нейтроний.
 gregtech.advancement.ultimate_voltage.77_ultimate_battery.name=И что теперь?
 gregtech.advancement.ultimate_voltage.77_ultimate_battery.desc=Создайте безупречную батарею.
-gregtech.advancement.ultimate_voltage.78_hasoc_wafer.name=Пластина HASoC
-gregtech.advancement.ultimate_voltage.78_hasoc_wafer.desc=Сделайте пластину HASoC для более дешёвого производства органических микросхем.
+gregtech.advancement.ultimate_voltage.78_hasoc_wafer.name=Пластина ОУСнК
+gregtech.advancement.ultimate_voltage.78_hasoc_wafer.desc=Сделайте пластину СУСНК для более дешёвого производства органических микросхем.
 gregtech.advancement.ultimate_voltage.79_tritanium_coil.name=Финальная катушка
 gregtech.advancement.ultimate_voltage.79_tritanium_coil.desc=Изготовьте нагревательную катушку из Тритания.
 
@@ -4431,14 +4431,14 @@ gregtech.machine.cleanroom.tooltip.1=Установите машины внут
 gregtech.machine.cleanroom.tooltip.2=Использует §f30 EU/t§7 когда загрязнена, §f4 EU/t§7 когда очищена.
 gregtech.machine.cleanroom.tooltip.3=Разгон увеличивает очистку за один цикл.
 gregtech.machine.cleanroom.tooltip.4=§bРазмер: от §f5x5x5 до 15x15x15
-gregtech.machine.cleanroom.tooltip.hold_ctrl=Зажмите CTRL для просмотра дополнительной информации о структуре
+gregtech.machine.cleanroom.tooltip.hold_ctrl=Зажмите CTRL для Дополнительной информации о структуре
 gregtech.machine.cleanroom.tooltip.5=Требует установку §fКорпуса фильтра §7в любом месте потолка кроме его граней.
 gregtech.machine.cleanroom.tooltip.6=Позволяет установить до §f4 дверей§7! Требует повторную очистку при открытой двери.
 gregtech.machine.cleanroom.tooltip.7=Генераторы, глушители, буры и примитивные машины слишком грязные для чистой комнаты!
-gregtech.machine.cleanroom.tooltip.8=Подавайте питание через §fКорпуса §7или §fДиоды §7в стенах.
+gregtech.machine.cleanroom.tooltip.8=Подавайте питание через §fОболочку §7или §fДиоды §7в стенах.
 gregtech.machine.cleanroom.tooltip.9=Отправляйте предметы и жидкости с помощью §fСквозных люков§7в стенах.
-gregtech.machine.cleanroom.tooltip.ae2.channels=Отправляйте до §f8 AE2 каналов §7через §fКорпуса§7 в стенах.
-gregtech.machine.cleanroom.tooltip.ae2.no_channels=Отправляйте §aAE2 сеть§7 через §fКорпуса§7 в стенах.
+gregtech.machine.cleanroom.tooltip.ae2.channels=Отправляйте до §f8 AE2 каналов §7через §fОболочку§7 в стенах.
+gregtech.machine.cleanroom.tooltip.ae2.no_channels=Отправляйте §aAE2 сеть§7 через §fОболочку§7 в стенах.
 gregtech.multiblock.cleanroom.dirty_state=Статус: §4ЗАГРЯЗНЕНА
 gregtech.multiblock.cleanroom.clean_state=Статус: §aЧИСТАЯ
 gregtech.machine.charcoal_pile.name=Воспламенитель угольной ямы
@@ -4463,10 +4463,10 @@ gregtech.machine.power_substation.tooltip5=Ограниченно §f%,d EU/t§7
 gregtech.multiblock.power_substation.description=Силовая Подстанция представляет собой многоблочную структуру, используемую для хранения огромного количества Энергии. Способен вместить до 18 слоев батарей. Также можно использовать пустые Накопители для заполнения пространства, так как слои должны быть полностью заполнены.
 gregtech.machine.active_transformer.name=Активный Трансформатор
 gregtech.machine.active_transformer.tooltip1=Трансформеры: Замаскированные лазеры
-gregtech.machine.active_transformer.tooltip2=Может комбинировать любое количество Энергетических §fВходных§7 разъемов в любое количество Энергетических §fВыходных§7 разъемов.
+gregtech.machine.active_transformer.tooltip2=Может комбинировать любое кол-во Энергетических §fВходных§7 разъемов в любое кол-во Энергетических §fВыходных§7 разъемов.
 gregtech.machine.active_transformer.tooltip3=Может передавать энергию на невероятное расстояние с помощью
 gregtech.machine.active_transformer.tooltip3.5=Лазеров§7.
-gregtech.multiblock.active_transformer.description=Активный Трансформатор представляет собой многоблочную структуру, которая может принимать любое количество или уровень энергетических входных разъемов преобразовывать их в любое количество или уровень энергетических выходных разъемов. Они могут быть соединены с Люком для Лазерного Источника и Люком для Лазерного Приемника, что позволяет передавать энергию на большие расстояния без каких-либо потерь. Лазеры должны располагаться по прямой, иначе они не будут посылать энергию.
+gregtech.multiblock.active_transformer.description=Активный Трансформатор представляет собой многоблочную структуру, которая может принимать любое кол-во или уровень энергетических входных разъемов преобразовывать их в любое кол-во или уровень энергетических выходных разъемов. Они могут быть соединены с Люком для Лазерного Источника и Люком для Лазерного Приемника, что позволяет передавать энергию на большие расстояния без каких-либо потерь. Лазеры должны располагаться по прямой, иначе они не будут посылать энергию.
 gregtech.machine.research_station.name=Станция исследований
 gregtech.machine.research_station.tooltip.1=Больше чем Многоблочный Сканнер
 gregtech.machine.research_station.tooltip.2=Используется для сканирования §fСфер данных§7 или §fМодулей данных§7.
@@ -4475,13 +4475,13 @@ gregtech.multiblock.research_station.description=Исследовательск
 gregtech.machine.network_switch.name=Коммутатор
 gregtech.machine.network_switch.tooltip.1=Ethernet-концентратор
 gregtech.machine.network_switch.tooltip.2=Используется для маршрутизации и распределения §fВычислений§7.
-gregtech.machine.network_switch.tooltip.3=Можно объединить любое количество §fПриемников§7 Вычислений в любое количество §fПередатчиков§7 Вычислений.
-gregtech.multiblock.network_switch.description=Коммутатор представляет собой многоблочную структуру, используемую для распределения вычислительных ресурсов из многих источников во многие пункты назначения. Он может принимать любое количество Люков Приема или Передачи вычислительных данных. Это необходимо для Исследовательских Данных, которые требуют гораздо больших Вычислений, поскольку исследовательская станция может принимать только один люк для приема данных вычислений. HPCA должен иметь Компонент Моста, чтобы сетевой коммутатор мог получить доступ к своим вычислениям.
+gregtech.machine.network_switch.tooltip.3=Можно объединить любое кол-во §fПриемников§7 Вычислений в любое кол-во §fПередатчиков§7 Вычислений.
+gregtech.multiblock.network_switch.description=Коммутатор представляет собой многоблочную структуру, используемую для распределения вычислительных ресурсов из многих источников во многие пункты назначения. Он может принимать любое кол-во Люков Приема или Передачи вычислительных данных. Это необходимо для Исследовательских Данных, которые требуют гораздо больших Вычислений, поскольку исследовательская станция может принимать только один люк для приема данных вычислений. HPCA должен иметь Компонент Моста, чтобы сетевой коммутатор мог получить доступ к своим вычислениям.
 gregtech.machine.high_performance_computing_array.name=Высокопроизводительный вычислительный массив
 gregtech.machine.high_performance_computing_array.tooltip.1=Просто самый обычный Суперкомпьютер
 gregtech.machine.high_performance_computing_array.tooltip.2=Используется для генерации §fВычислений§7 (и тепла).
 gregtech.machine.high_performance_computing_array.tooltip.3=Требуются компоненты HPCA для создания §fCWU/t§7 (Вычислительные Рабочие Единицы).
-gregtech.multiblock.high_performance_computing_array.description=Высокопроизводительный Вычислительный Массив (HPCA) представляет собой многоблочную структуру, используемую для создания Вычислительные Рабочие Единицы (CWU/t) для более Сложных Данных Исследования Cборочной Линии. Структура имеет гибкую область 3x3, которая может быть заполнена компонентами HPCA любым способом. Различные компоненты могут обеспечивать разное количество вычислений, охлаждения, а также затрат на энергию, стоимость охлаждающей жидкости и производство тепла. При использовании с компонентом моста HPCA может подключаться к сетевым коммутаторам для объединения и маршрутизации вычислений из нескольких источников в одно или несколько мест назначения.
+gregtech.multiblock.high_performance_computing_array.description=Высокопроизводительный Вычислительный Массив (HPCA) представляет собой многоблочную структуру, используемую для создания Вычислительные Рабочие Единицы (CWU/t) для более Сложных Данных Исследования Cборочной Линии. Структура имеет гибкую область 3x3, которая может быть заполнена компонентами HPCA любым способом. Различные компоненты могут обеспечивать разное ко-во вычислений, охлаждения, а также затрат на энергию, стоимость охлаждающей жидкости и производство тепла. При использовании с компонентом моста HPCA может подключаться к сетевым коммутаторам для объединения и маршрутизации вычислений из нескольких источников в одно или несколько мест назначения.
 gregtech.machine.central_monitor.name=Центральный монитор
 gregtech.multiblock.central_monitor.low_power=Недостаточно энергии
 gregtech.multiblock.central_monitor.height=Высота экрана:
@@ -4573,7 +4573,6 @@ gregtech.machine.item_bus.export.uv.name=Предметный выходной 
 gregtech.machine.item_bus.export.uhv.name=Предметный выходной люк (§4UHV§r)
 gregtech.bus.collapse_true=Люк будет совмещать Предметы
 gregtech.bus.collapse_false=Люк не будет совмещать Предметы
-gregtech.bus.collapse.error=Люк должен быть сперва добавлен в многоблочную структуру
 gregtech.machine.fluid_hatch.import.tooltip=Для подачи жидкости в многоблочную структуру
 gregtech.machine.fluid_hatch.import.ulv.name=Жидкостный входной люк (§8ULV§r)
 gregtech.machine.fluid_hatch.import.lv.name=Жидкостный входной люк (§7LV§r)
@@ -4694,7 +4693,7 @@ gregtech.maintenance.configurable_time=Время: %fx
 gregtech.maintenance.configurable_time.unchanged_description=Проблемы с обслуживанием будут возникать с обычной частотой. Измените конфигурацию для обновления.
 gregtech.maintenance.configurable_time.changed_description=Проблемы с обслуживанием будут возникать в %f раз чаще.
 gregtech.maintenance.configurable.tooltip_basic=Ускоряет время работы машины за счет более частых проблем с обслуживанием
-gregtech.maintenance.configurable.tooltip_more_info=Зажмите SHIFT для особого взаимодействия
+gregtech.maintenance.configurable.tooltip_more_info=Зажмите SHIFT для Особого взаимодействия
 gregtech.maintenance.configurable.tooltip_pss_header=§8Силовая Подстанция:
 gregtech.maintenance.configurable.tooltip_pss_info=§fУменьшает пассивную утечку энергии
 gregtech.machine.muffler_hatch.tooltip1=Восстанавливает отходы от машин
@@ -4778,7 +4777,7 @@ gregtech.universal.tooltip.fluid_stored=§dОбъем жидкости: §f%s, %
 gregtech.universal.tooltip.fluid_transfer_rate=§bСкорость передачи: §f%,d Л/т
 gregtech.universal.tooltip.parallel=§dПаралеллей: §f%d
 gregtech.universal.tooltip.working_area=§bРабочая область: §f%,dx%,d
-gregtech.universal.tooltip.working_area_max=§bМаксимальная рабочая область: §f%,dx%,d
+gregtech.universal.tooltip.working_area_max=§bМакс. рабочая область: §f%,dx%,d
 gregtech.universal.tooltip.working_area_chunks_max=§bMax Working Area: §f%,dx%,d Chunks
 gregtech.universal.tooltip.uses_per_tick=Потребляет §f%,d EU/т §7когда работает
 gregtech.universal.tooltip.uses_per_tick_steam=Потребляет §f%,d Л/т §7 Пара когда работает
@@ -4810,7 +4809,7 @@ gregtech.recipe.computation_per_tick=Мин. Вычисления: %,d CWU/t
 gregtech.fluid.click_to_fill=§7Нажмите с хралищем для жидкости, чтобы §bзаполнить §7резервуар.
 gregtech.fluid.click_to_empty=§7Нажмите с хралищем для жидкости, чтобы §cопустошить §7резервуар.
 gregtech.fluid.click_combined=§7Нажмите с хралищем для жидкости, чтобы §bзаполнить §7или §cопустошить §7резервуар.
-gregtech.tool_action.show_tooltips=Зажмите SHIFT для просмотра информации Инструмента
+gregtech.tool_action.show_tooltips=Зажмите SHIFT для Информации о Инструменте
 gregtech.tool_action.screwdriver.auto_output=§8Используйте отвертку, чтобы переключить Авто-Вывод
 gregtech.tool_action.screwdriver.toggle_mode_covers=§8Используйте отвертку, чтобы переключить Режим или настроить улучшения
 gregtech.tool_action.screwdriver.access_covers=§8Используйте отвертку, чтобы настроить улучшения
@@ -4829,8 +4828,8 @@ gregtech.tool_action.tape=§8Используйте Клейкую Ленту д
 gregtech.fluid.generic=%s
 gregtech.fluid.plasma=Плазма (%s)
 gregtech.fluid.empty=Пустой
-gregtech.fluid.amount=§7%,d/%,d
-gregtech.fluid.temperature=§7Температура: %dK
+gregtech.fluid.amount=§9Количество: %,d/%,d Л
+gregtech.fluid.temperature=§cТемпература: %dK
 gregtech.fluid.temperature.cryogenic=§bКриогенный! Соблюдайте осторожность!
 gregtech.fluid.state_gas=§7Состояние: Газообразный
 gregtech.fluid.state_liquid=§7Состояние: Жидкость
@@ -4838,7 +4837,7 @@ gregtech.fluid.state_plasma=§7Состояние: Плазма
 gregtech.fluid.type_acid.tooltip=§6Кислота! Соблюдайте осторожность!
 gregtech.gui.fuel_amount=Кол. топлива:
 gregtech.gui.fluid_amount=Кол. жидкости:
-gregtech.gui.amount_raw=Количество:
+gregtech.gui.amount_raw=Кол-во:
 gregtech.gui.toggle_view.disabled=Переключить вид (Жидкости)
 gregtech.gui.toggle_view.enabled=Переключить вид (Предметы)
 gregtech.gui.overclock.enabled=Ускорение включено./nНажмите, чтобы отключить
@@ -4851,7 +4850,7 @@ gregtech.gui.fluid_auto_output.tooltip.disabled=Авто. вывод жидко
 gregtech.gui.item_auto_output.tooltip.enabled=Авто. вывод предметов включен
 gregtech.gui.item_auto_output.tooltip.disabled=Авто. вывод предметов отключен
 gregtech.gui.charger_slot.tooltip=§fСлот двухстороннего питания§r/n§7Может потреблять энергию от %s §7аккумуляторов либо-же отдавать
-gregtech.gui.configurator_slot.tooltip=§fСлот Конфигурации§r/n§aУстановить Значение: §f%d§7/n/n§7ЛКМ/ПКМ/Прокрутка для переключения по листу/n§7Shift-ПКМ для очистка
+gregtech.gui.configurator_slot.tooltip=§fСлот Конфигурации§r\n§aУстановить Значение: §f%d§7\n\n§7ЛКМ/ПКМ/Прокрутка для переключения по листу\n§7Shift-ЛКМ чтобы выбрать селектор\n§7Shift-ПКМ для очистка
 gregtech.gui.fluid_lock.tooltip.enabled=Блокировка жидкости включена
 gregtech.gui.fluid_lock.tooltip.disabled=Блокировка жидкости выключена
 gregtech.gui.fluid_voiding.tooltip.enabled=Удаление избытков жидкости Включен
@@ -4866,7 +4865,7 @@ gregtech.gui.me_network.offline=Статус Сети: §2Не в Сети§r
 gregtech.gui.waiting_list=Очередь на отправку:
 gregtech.gui.config_slot=§fНастройка§r
 gregtech.gui.config_slot.set=§7Нажмите для §bвыбора/настройкиt§7 слота.§r
-gregtech.gui.config_slot.scroll=§7Колесо мыши §aизменяет§7 количество.§r
+gregtech.gui.config_slot.scroll=§7Колесо мыши §aизменяет§7 кол-во.§r
 gregtech.gui.config_slot.remove=§7Правая кнопка для §4очистки§7 слота настройки.§r
 ore.spawnlocation.name=Информация о появлении руды
 gregtech.jei.ore.surface_rock_1=Поверхностные залежи с этим материалом обозначают места появления жил.
@@ -4899,8 +4898,8 @@ fluid.spawnlocation.name=Информация о жидкостном место
 
 
 gregtech.jei.materials.average_mass=Средняя масса: %,d
-gregtech.jei.materials.average_neutrons=Среднее количество нейтронов: %,d
-gregtech.jei.materials.average_protons=Среднее количество протонов: %,d
+gregtech.jei.materials.average_neutrons=Ср. кол-во нейтронов: %,d
+gregtech.jei.materials.average_protons=Ср. кол-во протонов: %,d
 gregtech.item_filter.empty_item=Пусто (нет предмета)
 gregtech.item_filter.footer=§eНажмите с предметом, чтобы переопределить
 gregtech.cable.voltage=§aВольтаж: §f%,d §f(%s§f)
@@ -4924,12 +4923,12 @@ gregtech.multiblock.not_enough_energy_output=§eСовет:§f Энергети
 gregtech.multiblock.progress=Прогресс: %s%%
 gregtech.multiblock.invalid_structure=Неверная структура.
 gregtech.multiblock.invalid_structure.tooltip=Этот блок является контроллером многоблочной структуры. для получения справки по созданию см. шаблон структуры в JEI.
-gregtech.multiblock.validation_failed=Неверное количество входов/выходов.
+gregtech.multiblock.validation_failed=Неверное кол-во входов/выходов.
 gregtech.multiblock.max_energy_per_tick=Макс. EU/т: §a%s (%s§r)
 gregtech.multiblock.generation_eu=Генерирует:§a%s EU/t
 gregtech.multiblock.universal.no_problems=Механизм работает исправно!
 gregtech.multiblock.universal.has_problems=Механизм неисправен!
-gregtech.multiblock.universal.has_problems_header=Исправьте следующие проблемы в люке обслуживания:
+gregtech.multiblock.universal.has_problems_header=Исправьте следующие проблемы в Люке обслуживания:
 gregtech.multiblock.universal.problem.wrench=%s§7Труба расшатана. (§aКлюч§7)
 gregtech.multiblock.universal.problem.screwdriver=%s§7Винты не закручены. (§aОтвертка§7)
 gregtech.multiblock.universal.problem.soft_mallet=%s§7Что-то заклинило. (§aКиянка§7)
@@ -4941,7 +4940,7 @@ gregtech.multiblock.universal.distinct_enabled=Раздельные люки: §
 gregtech.multiblock.universal.distinct_disabled=Раздельные люки: §aВsключено§r/nКаждый входной люк будет рассматриваться как комбинированный ввод для поиска рецепта.
 gregtech.multiblock.universal.distinct_not_supported=Эту структура не поддерживает Раздельные Люки
 gregtech.multiblock.universal.no_flex_button=Эта структура не имеет дополнительных функций с этой кнопкой.
-gregtech.multiblock.parallel=Параллельное выполнение до %d рецептов
+gregtech.multiblock.parallel=Макс. Параллелей: %s
 gregtech.multiblock.multiple_recipemaps.header=Режим машины:
 gregtech.multiblock.multiple_recipemaps.tooltip=Нажмите отвёрткой по контроллеру, чтобы изменить режим машины.
 gregtech.multiblock.multiple_recipemaps_recipes.tooltip=Режим машин: §e%s§r
@@ -4971,9 +4970,9 @@ gregtech.multiblock.blast_furnace.max_temperature=Максимальная те
 gregtech.multiblock.multi_furnace.heating_coil_discount=EU усиление нагревательной катушки: %sx
 gregtech.multiblock.distillation_tower.distilling_fluid=Дистилляция %s
 gregtech.multiblock.large_combustion_engine.no_lubricant=Нет Смазки.
-gregtech.multiblock.large_combustion_engine.lubricant_amount=Количество смазки: %smB
-gregtech.multiblock.large_combustion_engine.oxygen_amount=Количество кислорода: %smB
-gregtech.multiblock.large_combustion_engine.liquid_oxygen_amount=Количество жидкого кислорода: %smB
+gregtech.multiblock.large_combustion_engine.lubricant_amount=Кол-во смазки: %smB
+gregtech.multiblock.large_combustion_engine.oxygen_amount=Кол-во кислорода: %smB
+gregtech.multiblock.large_combustion_engine.liquid_oxygen_amount=Кол-во жид. кислорода: %smB
 gregtech.multiblock.large_combustion_engine.oxygen_boosted=§bКислород добавлен.
 gregtech.multiblock.large_combustion_engine.liquid_oxygen_boosted=§bЖидкий кислород добавлен.
 gregtech.multiblock.large_combustion_engine.supply_oxygen_to_boost=Принимает кислород для ускорения.
@@ -4981,11 +4980,11 @@ gregtech.multiblock.large_combustion_engine.supply_liquid_oxygen_to_boost=При
 gregtech.multiblock.large_combustion_engine.obstructed=Что-то мешает воздухозаборнику двигателя.
 gregtech.multiblock.turbine.fuel_amount=Топлива: %smB (%s)
 gregtech.multiblock.turbine.rotor_speed=Скорость: %s/%s об/мин
-gregtech.multiblock.turbine.rotor_durability=Прочность ротора: %s%%
+gregtech.multiblock.turbine.rotor_durability=Прочность ротора: %s
 gregtech.multiblock.turbine.rotor_durability_low=Прочность ротора низкая!
 gregtech.multiblock.turbine.no_rotor=Нет Ротора в Держателе ротора.
 gregtech.multiblock.turbine.fuel_needed=Потребляет %s за %s тиков
-gregtech.multiblock.turbine.efficiency=Эффективность турбины: %s%%
+gregtech.multiblock.turbine.efficiency=Эффективность турбины: %s
 gregtech.multiblock.turbine.energy_per_tick=Выход: %s/%s EU/t
 gregtech.multiblock.turbine.obstructed=Поверхность турбины заблокирована
 gregtech.multiblock.turbine.efficiency_tooltip=Каждый держатель ротора выше %s§7 добавляет §f10%% эффективности§7.
@@ -5071,7 +5070,7 @@ gregtech.command.copy.click_to_copy=Нажмите для копирования
 gregtech.command.copy.copied_start=Скопировано [
 gregtech.command.copy.copied_end=] в буфер обмена
 gregtech.chat.cape=§5Поздравляю: вы только что разблокировали новый плащ! Откройте в терминале Переключатель плащей для подробной информации.§r
-gregtech.universal.clear_nbt_recipe.tooltip=§cЭто уничтожить весь контент!
+gregtech.universal.clear_nbt_recipe.tooltip=§cЭто уничтожит весь контент!
 gregtech.cover.detector_base.message_inverted_state=Статус детектора: Инвертированный
 gregtech.cover.detector_base.message_normal_state=Статус детектора: Обычный
 gregtech.creative.chest.item=Предмет
@@ -5901,3 +5900,10 @@ for.bees.species.fluorine=Фторовая
 
 # Bee Descriptions (many more to do)
 for.bees.description.clay=Органическая пчела, известная своей трудолюбивостью и усердием. Ходят слухи, что их можно найти грязь в нужном биоме.|Пчеловодство 101
+gregtech.gui.item_auto_collapse.tooltip.disabled=Авто-совмещение предметов выключено
+gregtech.gui.item_auto_collapse.tooltip.enabled=Авто-совмещение предметов включено
+gregtech.gui.configurator_slot.unavailable.tooltip=Слот Интегральной схемы недоступен
+cover.ore_dictionary_filter.button.case_sensitive.enabled=С учетом регистра
+cover.ore_dictionary_filter.button.match_all.disabled=Любая из записей из Словаря руд
+cover.ore_dictionary_filter.button.match_all.enabled=Все записи из Словаря руд
+cover.ore_dictionary_filter.button.case_sensitive.disabled=Без учета регистра

From 4939f2fd51decac19391420f25ca7acc47c3fb46 Mon Sep 17 00:00:00 2001
From: ALongStringOfNumbers
 <31759736+ALongStringOfNumbers@users.noreply.github.com>
Date: Wed, 3 Jan 2024 09:55:46 -0700
Subject: [PATCH 32/98] Improve Lighter Opening (#2323)

---
 .../items/behaviors/LighterBehaviour.java     | 23 +++++++++++++++----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java
index 4e1f14cfa61..6dd8d6742c7 100644
--- a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java
+++ b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java
@@ -24,7 +24,13 @@
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.*;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.SoundCategory;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.World;
 import net.minecraftforge.fluids.FluidStack;
@@ -89,20 +95,27 @@ public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity en
     }
 
     @Override
-    public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull World world, BlockPos pos,
-                                           EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) {
+    public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
         ItemStack stack = player.getHeldItem(hand);
         NBTTagCompound compound = GTUtility.getOrCreateNbtCompound(stack);
 
         if (canOpen && player.isSneaking()) {
             compound.setBoolean(LIGHTER_OPEN, !compound.getBoolean(LIGHTER_OPEN));
             stack.setTagCompound(compound);
-            return EnumActionResult.PASS;
         }
+        return ActionResult.newResult(EnumActionResult.PASS, stack);
+    }
+
+    @Override
+    public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull World world, BlockPos pos,
+                                           EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) {
+        ItemStack stack = player.getHeldItem(hand);
+        NBTTagCompound compound = GTUtility.getOrCreateNbtCompound(stack);
 
         if (!player.canPlayerEdit(pos, side, player.getHeldItem(hand))) return EnumActionResult.FAIL;
         // If this item does not have opening mechanics, or if it does and is currently open
-        if ((!canOpen || compound.getBoolean(LIGHTER_OPEN)) && consumeFuel(player, stack)) {
+        // If the item has opening mechanics, and the player is sneaking, close the item instead
+        if ((!canOpen || (compound.getBoolean(LIGHTER_OPEN)) && !player.isSneaking()) && consumeFuel(player, stack)) {
             player.getEntityWorld().playSound(null, player.getPosition(), SoundEvents.ITEM_FLINTANDSTEEL_USE,
                     SoundCategory.PLAYERS, 1.0F, GTValues.RNG.nextFloat() * 0.4F + 0.8F);
             IBlockState blockState = world.getBlockState(pos);

From 089483bc3b4cbf7645c26f2c182e2bb08580f15f Mon Sep 17 00:00:00 2001
From: serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Thu, 4 Jan 2024 18:24:16 -0600
Subject: [PATCH 33/98] nuclear test release script

---
 .github/workflows/nuclear_test_release.yml | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 .github/workflows/nuclear_test_release.yml

diff --git a/.github/workflows/nuclear_test_release.yml b/.github/workflows/nuclear_test_release.yml
new file mode 100644
index 00000000000..fc46d6e83f7
--- /dev/null
+++ b/.github/workflows/nuclear_test_release.yml
@@ -0,0 +1,49 @@
+name: Nuclear Test Release
+
+on:
+  push:
+    branches:
+      - nuclear-fission
+jobs:
+  build:
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: write # needed to create GitHub releases
+
+    steps:
+      - name: Checkout Repository
+        uses: actions/checkout@v3
+
+      - name: Declare some variables
+        id: vars
+        shell: bash
+        run: |
+          echo "::set-output name=sha_short::$(git rev-parse --short $GITHUB_SHA)"
+
+      - name: Setup Java
+        uses: actions/setup-java@v3
+        with:
+          distribution: 'zulu'
+          java-version: '17'
+
+      - name: Build Project
+        uses: gradle/gradle-build-action@v2
+        with:
+          arguments: 'build --build-cache --daemon' # use the daemon here so the rest of the process is faster
+          generate-job-summary: false
+          gradle-home-cache-includes: |
+            caches
+            jdks
+            notifications
+            wrapper
+
+      - name: Publish to GitHub
+        uses: softprops/action-gh-release@v1
+        with:
+          files: "build/libs/*.jar"
+          fail_on_unmatched_files: true
+          prerelease: true
+          tag_name: "nuclear-testing"
+          name: 'Nuclear Testing ' + ${{ steps.vars.outputs.sha_short }}
+          body: "Testing Pre-release for GTCEu Nuclear Update"

From d9e39060db35a6ba3085105d41fd7880cb9e70c7 Mon Sep 17 00:00:00 2001
From: serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Thu, 4 Jan 2024 18:29:36 -0600
Subject: [PATCH 34/98] fix nuclear release script

---
 .github/workflows/nuclear_test_release.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/nuclear_test_release.yml b/.github/workflows/nuclear_test_release.yml
index fc46d6e83f7..5f8d389ee63 100644
--- a/.github/workflows/nuclear_test_release.yml
+++ b/.github/workflows/nuclear_test_release.yml
@@ -45,5 +45,5 @@ jobs:
           fail_on_unmatched_files: true
           prerelease: true
           tag_name: "nuclear-testing"
-          name: 'Nuclear Testing ' + ${{ steps.vars.outputs.sha_short }}
+          name: "Nuclear Testing ${{ steps.vars.outputs.sha_short }}"
           body: "Testing Pre-release for GTCEu Nuclear Update"

From 37905eeb6eb695c27a571a339706cbbd0f37a273 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Fri, 5 Jan 2024 13:14:05 -0500
Subject: [PATCH 35/98] Fix some JEI plugin issues (#2337)

---
 src/main/java/gregtech/api/recipes/Recipe.java     | 11 +++++++++--
 .../integration/jei/JustEnoughItemsModule.java     | 14 +++++++-------
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/src/main/java/gregtech/api/recipes/Recipe.java b/src/main/java/gregtech/api/recipes/Recipe.java
index b291f994301..f52c3adc10e 100644
--- a/src/main/java/gregtech/api/recipes/Recipe.java
+++ b/src/main/java/gregtech/api/recipes/Recipe.java
@@ -29,7 +29,13 @@
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Class that represent machine recipe.
@@ -673,8 +679,9 @@ public boolean hasValidInputsForDisplay() {
                         .anyMatch(s -> !s.isEmpty())) {
                     return true;
                 }
+            } else if (Arrays.stream(ingredient.getInputStacks()).anyMatch(s -> !s.isEmpty())) {
+                return true;
             }
-            return Arrays.stream(ingredient.getInputStacks()).anyMatch(s -> !s.isEmpty());
         }
         for (GTRecipeInput fluidInput : fluidInputs) {
             FluidStack fluidIngredient = fluidInput.getInputFluidStack();
diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java
index be7c1bd50ca..eec16a49641 100644
--- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java
+++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java
@@ -74,10 +74,10 @@
 import org.jetbrains.annotations.NotNull;
 
 import java.lang.reflect.Field;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -214,7 +214,7 @@ public void register(IModRegistry registry) {
         registry.addRecipeCatalyst(MetaTileEntities.LARGE_TITANIUM_BOILER.getStackForm(), semiFluidMapId);
         registry.addRecipeCatalyst(MetaTileEntities.LARGE_TUNGSTENSTEEL_BOILER.getStackForm(), semiFluidMapId);
 
-        List oreByproductList = new CopyOnWriteArrayList<>();
+        List oreByproductList = new ArrayList<>();
         for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) {
             if (material.hasProperty(PropertyKey.ORE)) {
                 oreByproductList.add(new OreByProduct(material));
@@ -222,7 +222,7 @@ public void register(IModRegistry registry) {
         }
         String oreByProductId = GTValues.MODID + ":" + "ore_by_product";
         registry.addRecipes(oreByproductList, oreByProductId);
-        MetaTileEntity[][] machineLists = new MetaTileEntity[][] {
+        MetaTileEntity[][] machineLists = {
                 MetaTileEntities.MACERATOR,
                 MetaTileEntities.ORE_WASHER,
                 MetaTileEntities.CENTRIFUGE,
@@ -237,7 +237,7 @@ public void register(IModRegistry registry) {
         }
 
         // Material Tree
-        List materialTreeList = new CopyOnWriteArrayList<>();
+        List materialTreeList = new ArrayList<>();
         for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) {
             if (material.hasProperty(PropertyKey.DUST)) {
                 materialTreeList.add(new MaterialTree(material));
@@ -247,7 +247,7 @@ public void register(IModRegistry registry) {
 
         // Ore Veins
         List oreVeins = WorldGenRegistry.getOreDeposits();
-        List oreInfoList = new CopyOnWriteArrayList<>();
+        List oreInfoList = new ArrayList<>();
         for (OreDepositDefinition vein : oreVeins) {
             oreInfoList.add(new GTOreInfo(vein));
         }
@@ -261,7 +261,7 @@ public void register(IModRegistry registry) {
 
         // Fluid Veins
         List fluidVeins = WorldGenRegistry.getBedrockVeinDeposits();
-        List fluidVeinInfos = new CopyOnWriteArrayList<>();
+        List fluidVeinInfos = new ArrayList<>();
         for (BedrockFluidDepositDefinition fluidVein : fluidVeins) {
             fluidVeinInfos.add(new GTFluidVeinInfo(fluidVein));
         }
@@ -307,7 +307,7 @@ private void setupInputHandler() {
 
             showsRecipeFocuses.add(new MultiblockInfoRecipeFocusShower());
 
-        } catch (Exception e) {
+        } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException | SecurityException e) {
             getLogger().error("Could not reflect JEI Internal inputHandler", e);
         }
     }

From 8993e932863558261f267e10c5609ac869cdd3f3 Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sat, 6 Jan 2024 14:20:12 -0600
Subject: [PATCH 36/98] Fix treated wood stick saw recipe (#2339)

---
 src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java
index fb06348d385..c790b6c809d 100644
--- a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java
+++ b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java
@@ -482,7 +482,7 @@ private static void registerGTWoodRecipes() {
                 'L', MetaBlocks.PLANKS.getItemVariant(BlockGregPlanks.BlockType.TREATED_PLANK));
         if (ConfigHolder.recipes.nerfWoodCrafting) {
             ModHandler.addShapedRecipe("treated_wood_stick_saw", OreDictUnifier.get(OrePrefix.stick, TreatedWood, 4),
-                    "s", "L",
+                    "s", "L", "L",
                     'L', MetaBlocks.PLANKS.getItemVariant(BlockGregPlanks.BlockType.TREATED_PLANK));
         }
     }

From f92e1c6ab1c4f4c081427ae7a344d9a7233fc5ea Mon Sep 17 00:00:00 2001
From: iouter <62897714+iouter@users.noreply.github.com>
Date: Mon, 8 Jan 2024 11:19:55 +0800
Subject: [PATCH 37/98] update zh_cn.lang (#2334)

---
 .../resources/assets/gregtech/lang/zh_cn.lang | 41 +++++++++++--------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang
index 88906474bcf..8fa4c506934 100644
--- a/src/main/resources/assets/gregtech/lang/zh_cn.lang
+++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang
@@ -531,7 +531,7 @@ metaitem.tool.datamodule.name=数据模块
 metaitem.tool.datamodule.tooltip=超复杂数据存储/n§c只能用数据库读取
 metaitem.circuit.integrated.name=编程电路
 metaitem.circuit.integrated.tooltip=右击以打开配置界面/n/n手持并潜行右击带有编程电路槽位的机器可应用相应配置。/n
-metaitem.circuit.integrated.gui=编程电路配置
+metaitem.circuit.integrated.gui=电路配置
 metaitem.circuit.integrated.jei_description=JEI将仅显示匹配当前编程电路配置的配方。\n\n在编程电路配置界面中调整配置以查看对应配方。
 
 item.glass.lens=玻璃透镜(白色)
@@ -1175,7 +1175,7 @@ cover.filter.blacklist.disabled=白名单
 cover.filter.blacklist.enabled=黑名单
 
 cover.ore_dictionary_filter.title=矿物词典过滤
-cover.ore_dictionary_filter.info=§b接受复杂表达式/n§6a & b§r = 且/n§6a | b§r = 或/n§6a ^ b§r = 异或/n§6! abc§r = 非/n§6( abc )§r 表示组别/n§6*§r 表示通配(也即零或多个字符)/n§6?§r 表示任意一个字符/n§6()§r 匹配空条目(包括不带矿物词典的物品)/n在表达式开头添加 §6$c§r 可严格区分大小写/n§b使用范例:/n§6dust*Gold | (plate* & !*Double*)/n匹配双层板以外的板与包括小撮、小堆在内的所有金粉
+cover.ore_dictionary_filter.info=§b接受复杂表达式/n§6a & b§r = 且/n§6a | b§r = 或/n§6a ^ b§r = 异或/n§6! abc§r = 非/n§6( abc )§r 表示组别/n§6*§r 表示通配(也即零或多个字符)/n§6?§r 表示任意一个字符/n§6()§r 匹配空条目(包括不带矿物词典的物品)/n在表达式开头添加 §b使用范例:/n§6dust*Gold | (plate* & !*Double*)/n匹配双层板以外的板与包括小撮、小堆在内的所有金粉
 cover.ore_dictionary_filter.test_slot.info=放入一件物品以测试是否匹配过滤表达式
 cover.ore_dictionary_filter.test_slot.matches=§a* %s
 cover.ore_dictionary_filter.test_slot.matches_not=§c* %s
@@ -1186,6 +1186,10 @@ cover.ore_dictionary_filter.status.err_warn=§c%s个错误、%s个警告
 cover.ore_dictionary_filter.status.warn=§7%s个警告
 cover.ore_dictionary_filter.status.no_issues=§a无问题
 cover.ore_dictionary_filter.status.explain=矿物过滤说明:
+cover.ore_dictionary_filter.button.case_sensitive.disabled=匹配大小写
+cover.ore_dictionary_filter.button.case_sensitive.enabled=忽略大小写
+cover.ore_dictionary_filter.button.match_all.disabled=匹配物品的任一矿词条目
+cover.ore_dictionary_filter.button.match_all.enabled=匹配物品的所有矿词条目
 
 cover.ore_dictionary_filter.preview.next=...接着是
 cover.ore_dictionary_filter.preview.match='%s'
@@ -1300,11 +1304,6 @@ cover.fluid_regulator.transfer_mode.description=§e任意传输§r - 在此模
 cover.fluid_regulator.supply_exact=精确补给:%s
 cover.fluid_regulator.keep_exact=保持补给:%s
 
-cover.machine_controller.title=机器控制设定
-cover.machine_controller.normal=普通
-cover.machine_controller.inverted=反相
-cover.machine_controller.inverted.description=§e普通§r - 该模式下的覆盖板需要比设定强度小的红石信号来触发/n§e反相§r - 该模式下的覆盖板需要比设定强度大的红石信号来触发
-cover.machine_controller.redstone=最小红石信号强度:%,d
 cover.machine_controller.mode.machine=控制目标:机器
 cover.machine_controller.mode.cover_up=控制目标:覆盖板(顶面)
 cover.machine_controller.mode.cover_down=控制目标:覆盖板(底面)
@@ -1312,6 +1311,12 @@ cover.machine_controller.mode.cover_south=控制目标:覆盖板(南面)
 cover.machine_controller.mode.cover_north=控制目标:覆盖板(北面)
 cover.machine_controller.mode.cover_east=控制目标:覆盖板(东面)
 cover.machine_controller.mode.cover_west=控制目标:覆盖板(西面)
+cover.machine_controller.this_cover=§c此覆盖板
+cover.machine_controller.cover_not_controllable=§c不可控制的覆盖板
+cover.machine_controller.machine_not_controllable=§c不可控制的机器
+cover.machine_controller.control=控制:
+cover.machine_controller.enable_with_redstone=接收红石信号时开启
+cover.machine_controller.disable_with_redstone=接收红石信号时关闭
 
 cover.ender_fluid_link.title=末影流体连接
 cover.ender_fluid_link.iomode.enabled=已启用I/O
@@ -1356,9 +1361,9 @@ item.material.oreprefix.oreBasalt=玄武岩%s矿石
 item.material.oreprefix.oreSand=沙子%s矿石
 item.material.oreprefix.oreRedSand=红沙%s矿石
 item.material.oreprefix.oreNetherrack=地狱岩%s矿石
-item.material.oreprefix.oreNether=下界%s矿石
+item.material.oreprefix.oreNether=地狱岩%s矿石
 item.material.oreprefix.oreEndstone=末地石%s矿石
-item.material.oreprefix.oreEnd=末地%s矿石
+item.material.oreprefix.oreEnd=末地石%s矿石
 item.material.oreprefix.ore=%s矿石
 item.material.oreprefix.oreGranite=花岗岩%s矿石
 item.material.oreprefix.oreDiorite=闪长岩%s矿石
@@ -4146,7 +4151,7 @@ gregtech.machine.transformer.adjustable.opv.name=过载压高能变压器(§9O
 gregtech.machine.diode.message=电流吞吐上限:%s
 gregtech.machine.diode.tooltip_tool_usage=手持软锤右击以调节电流。
 gregtech.machine.diode.tooltip_general=使能量作单向传输并限制电流
-gregtech.machine.diode.tooltip_starts_at=默认为§f1A§7,使用软锤来轮换电流设定
+gregtech.machine.diode.tooltip_starts_at=默认允许§f1A§r电流通行,使用软锤切换。
 
 gregtech.machine.diode.ulv.name=超低压二极管(§8ULV§r)
 gregtech.machine.diode.lv.name=低压二极管(§7LV§r)
@@ -4400,7 +4405,7 @@ gregtech.machine.world_accelerator.zpm.name=精英世界加速器 III
 gregtech.machine.world_accelerator.zpm.tooltip=“时间之§m瓶§r”§7方块
 gregtech.machine.world_accelerator.uv.name=终极世界加速器
 gregtech.machine.world_accelerator.uv.tooltip=时间扭曲者
-gregtech.machine.world_accelerator.description=使用§f螺丝刀§7在§f方块实体§7或§f随机刻§7模式中切换。
+gregtech.machine.world_accelerator.description=使用§f螺丝刀§7在§f方块实体§r或§f随机刻§7模式中切换。
 gregtech.machine.world_accelerator.power_usage=§7在随机刻模式下最多使用§f%dA,§7在方块实体模式下最多使用§f%dA 。
 gregtech.machine.world_accelerator.acceleration=§d加速倍率: §f%dx
 gregtech.machine.world_accelerator.working_area=§b作用范围:
@@ -4709,7 +4714,7 @@ gregtech.machine.large_chemical_reactor.name=大型化学反应釜
 gregtech.machine.large_combustion_engine.name=大型内燃引擎
 gregtech.machine.extreme_combustion_engine.name=极限内燃引擎
 gregtech.machine.large_combustion_engine.tooltip.boost_regular=提供§f20 L/s§7的氧气,并消耗§f双倍§7燃料以产生高达§f%s§7 EU/t的功率。
-gregtech.machine.large_combustion_engine.tooltip.boost_extreme=提供§f80 L/s§7的液氧,并消耗§f双倍§7燃料以产生高达§f%s§7 EU/t的功率。
+gregtech.machine.large_combustion_engine.tooltip.boost_extreme=提供§f80L/s§7的液态氧,并消耗§f双倍§7燃料以产生高达§f%s§7EU/t的功率。
 
 gregtech.machine.large_turbine.steam.name=大型蒸汽涡轮
 gregtech.machine.large_turbine.gas.name=大型燃气涡轮
@@ -4740,7 +4745,7 @@ gregtech.machine.large_miner.ev.name=基础采矿场
 gregtech.machine.large_miner.iv.name=进阶采矿场
 gregtech.machine.large_miner.luv.name=进阶采矿场 II
 gregtech.machine.miner.multi.modes=具有精准采集模式与区块对齐模式。
-gregtech.machine.miner.multi.production=粉碎矿石的产出量为§f研磨机§7的§f3倍§7。
+gregtech.machine.miner.multi.production=产出§f研磨机§7§f3x§7倍的粉碎矿石。
 gregtech.machine.miner.fluid_usage=每tick消耗§f%,d L§7的§f%s§7,超频时翻倍。
 gregtech.machine.miner.multi.description=一台工作范围极广的多方块采矿机,能够提供巨量矿石。
 gregtech.machine.miner.multi.needsfluid=钻井液不足!
@@ -4933,7 +4938,6 @@ gregtech.machine.item_bus.export.uhv.name=§4UHV§r输出总线
 
 gregtech.bus.collapse_true=已启用物品堆叠自动合并
 gregtech.bus.collapse_false=已禁用物品堆叠自动合并
-gregtech.bus.collapse.error=总线位于已成型的多方块结构后方可进行该操作
 
 gregtech.machine.fluid_hatch.import.tooltip=为多方块结构输入流体
 
@@ -5270,7 +5274,7 @@ gregtech.universal.tooltip.item_stored=§d内含物品:§f%2$,d + %3$,d 个%1$
 gregtech.universal.tooltip.item_transfer_rate=§b传输速率:§f%,d件物品/s
 gregtech.universal.tooltip.item_transfer_rate_stacks=§b传输速率:§f%,d组物品/s
 gregtech.universal.tooltip.fluid_storage_capacity=§9流体容量:§f%,d L
-gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:共§f%d§7个流体槽,每个§f%dL§7
+gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:§r共§f%d§7个流体槽,每个§f%dL§7
 gregtech.universal.tooltip.fluid_stored=§d内含流体:§f%2$,d L %1$s
 gregtech.universal.tooltip.fluid_transfer_rate=§b传输速率:§f%,d L/t
 gregtech.universal.tooltip.parallel=§d最大并行:§f%d
@@ -5366,9 +5370,12 @@ gregtech.gui.fluid_auto_output.tooltip.enabled=流体自动输出已启用
 gregtech.gui.fluid_auto_output.tooltip.disabled=流体自动输出已禁用
 gregtech.gui.item_auto_output.tooltip.enabled=物品自动输出已启用
 gregtech.gui.item_auto_output.tooltip.disabled=物品自动输出已禁用
+gregtech.gui.item_auto_collapse.tooltip.enabled=物品堆叠自动合并已启用
+gregtech.gui.item_auto_collapse.tooltip.disabled=物品堆叠自动合并已禁用
 gregtech.gui.charger_slot.tooltip=§f充电槽§r/n§7从%s电池中取电§7/n§7也可为%s工具或电池充电
-gregtech.gui.configurator_slot.tooltip=§f编程电路槽§r/n§a配置值:§f%d§7/n/n§7左击/右击/滚轮可浏览循环列表/n§7Shift+右键单击以清除
+gregtech.gui.configurator_slot.tooltip=§f编程电路槽§r\n§a配置值:§f%d§7\n\n§7左击/右击/滚轮可循环浏览列表\n§7Shift+左键单击以打开选择GUI\n§7Shift+右键单击以清除
 gregtech.gui.configurator_slot.no_value=空
+gregtech.gui.configurator_slot.unavailable.tooltip=编程电路槽位无法使用
 gregtech.gui.fluid_lock.tooltip.enabled=流体锁定已启用
 gregtech.gui.fluid_lock.tooltip.disabled=流体锁定已禁用
 gregtech.gui.fluid_voiding.tooltip.enabled=过量流体销毁已启用
@@ -5555,7 +5562,7 @@ gregtech.multiblock.pattern.error.batteries=§c必须至少有一个不是空电
 gregtech.multiblock.pattern.error.filters=§c必须使用同种过滤器§r
 gregtech.multiblock.pattern.clear_amount_1=§6前方必须有1x1x1大小的空间§r
 gregtech.multiblock.pattern.clear_amount_3=§6前方必须有3x3x1大小的空间§r
-gregtech.multiblock.pattern.single=§6仅可使用该种方块§r
+gregtech.multiblock.pattern.single=§6仅可使用该种方块类型§r
 gregtech.multiblock.pattern.location_end=§c最末端§r
 gregtech.multiblock.pattern.replaceable_air=可为空气
 

From 7d9f90cd3c59306b1cfd826e1bc1d1a5d9449538 Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 7 Jan 2024 21:33:34 -0600
Subject: [PATCH 38/98] Update build script version to 1704659416 (#2341)

Co-authored-by: DStrand1 
Co-authored-by: alongstringofnumbers 
---
 build.gradle      | 67 ++++++++++++++++++++++++++++++++++++++---------
 gradle.properties |  3 +++
 settings.gradle   |  4 +--
 3 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/build.gradle b/build.gradle
index 913152a71c5..ebae36cf19e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,4 @@
-//version: 1702805890
+//version: 1704659416
 /*
  * DO NOT CHANGE THIS FILE!
  * Also, you may replace this file at any time if there is an update available.
@@ -62,6 +62,7 @@ propertyDefaultIfUnset("generateGradleTokenClass", "")
 propertyDefaultIfUnset("gradleTokenModId", "")
 propertyDefaultIfUnset("gradleTokenModName", "")
 propertyDefaultIfUnset("gradleTokenVersion", "")
+propertyDefaultIfUnset("useSrcApiPath", false)
 propertyDefaultIfUnset("includeWellKnownRepositories", true)
 propertyDefaultIfUnset("includeCommonDevEnvMods", true)
 propertyDefaultIfUnset("noPublishedSources", false)
@@ -105,9 +106,16 @@ if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists(
 }
 
 if (apiPackage) {
-    targetPackageJava = javaSourceDir + modGroupPath + '/' + apiPackagePath
-    targetPackageScala = scalaSourceDir + modGroupPath + '/' + apiPackagePath
-    targetPackageKotlin = kotlinSourceDir + modGroupPath + '/' + apiPackagePath
+    final String endApiPath = modGroupPath + '/' + apiPackagePath
+    if (useSrcApiPath) {
+        targetPackageJava = 'src/api/java/' + endApiPath
+        targetPackageScala = 'src/api/scala/' + endApiPath
+        targetPackageKotlin = 'src/api/kotlin/' + endApiPath
+    } else {
+        targetPackageJava = javaSourceDir + endApiPath
+        targetPackageScala = scalaSourceDir + endApiPath
+        targetPackageKotlin = kotlinSourceDir + endApiPath
+    }
     if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists() && !getFile(targetPackageKotlin).exists()) {
         throw new GradleException("Could not resolve \"apiPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala} or ${targetPackageKotlin}")
     }
@@ -436,8 +444,7 @@ repositories {
         }
         maven {
             name 'GTNH Maven'
-            url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public'
-            allowInsecureProtocol = true
+            url 'https://nexus.gtnewhorizons.com/repository/public/'
         }
     }
     if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
@@ -675,6 +682,19 @@ jar {
             it.isDirectory() ? it : zipTree(it)
         }
     }
+
+    if (useSrcApiPath && apiPackage) {
+        from sourceSets.api.output
+        dependsOn apiClasses
+
+        include "${modGroupPath}/**"
+        include "assets/**"
+        include "mcmod.info"
+        include "pack.mcmeta"
+        if (accessTransformersFile) {
+            include "META-INF/${accessTransformersFile}"
+        }
+    }
 }
 
 // Configure default run tasks
@@ -691,12 +711,21 @@ if (separateRunDirectories.toBoolean()) {
 // Create API library jar
 tasks.register('apiJar', Jar) {
     archiveClassifier.set 'api'
-    from(sourceSets.main.java) {
-        include "${modGroupPath}/${apiPackagePath}/**"
-    }
+    if (useSrcApiPath) {
+        from(sourceSets.api.java) {
+            include "${modGroupPath}/${apiPackagePath}/**"
+        }
+        from(sourceSets.api.output) {
+            include "${modGroupPath}/${apiPackagePath}/**"
+        }
+    } else {
+        from(sourceSets.main.java) {
+            include "${modGroupPath}/${apiPackagePath}/**"
+        }
 
-    from(sourceSets.main.output) {
-        include "${modGroupPath}/${apiPackagePath}/**"
+        from(sourceSets.main.output) {
+            include "${modGroupPath}/${apiPackagePath}/**"
+        }
     }
 }
 
@@ -906,6 +935,12 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
                     }
                     String[] parts = dep.split(':')
                     String type = parts[0], slug = parts[1]
+                    def types = [
+                            'req'   : 'requiredDependency', 'required': 'requiredDependency',
+                            'opt'   : 'optionalDependency', 'optional': 'optionalDependency',
+                            'embed' : 'embeddedLibrary',    'embedded': 'embeddedLibrary',
+                            'incomp': 'incompatible',       'fail'    : 'incompatible']
+                    if (types.containsKey(type)) type = types[type]
                     if (!(type in ['requiredDependency', 'embeddedLibrary', 'optionalDependency', 'tool', 'incompatible'])) {
                         throw new Exception('Invalid Curseforge dependency type: ' + type)
                     }
@@ -948,7 +983,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
             }
             String[] parts = dep.split(':')
             String[] qual = parts[0].split('-')
-            addModrinthDep(qual[0], qual[1], parts[1])
+            addModrinthDep(qual[0], qual.length > 1 ? qual[1] : 'project', parts[1])
         }
     }
     tasks.modrinth.dependsOn(build)
@@ -957,9 +992,17 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
 
 def addModrinthDep(String scope, String type, String name) {
     com.modrinth.minotaur.dependencies.Dependency dep
+    def types = [
+            'req'   : 'required',
+            'opt'   : 'optional',
+            'embed' : 'embedded',
+            'incomp': 'incompatible', 'fail': 'incompatible']
+    if (types.containsKey(scope)) scope = types[scope]
     if (!(scope in ['required', 'optional', 'incompatible', 'embedded'])) {
         throw new Exception('Invalid modrinth dependency scope: ' + scope)
     }
+    types = ['proj': 'project', '': 'project', 'p': 'project', 'ver': 'version', 'v': 'version']
+    if (types.containsKey(type)) type = types[type]
     switch (type) {
         case 'project':
             dep = new ModDependency(name, scope)
diff --git a/gradle.properties b/gradle.properties
index 2408eee2147..43e31d58feb 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -42,6 +42,8 @@ gradleTokenVersion = VERSION
 # leave this property empty.
 # Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
 apiPackage =
+# If you want to keep your API code in src/api instead of src/main
+useSrcApiPath=false
 
 # Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/
 # There can be multiple files in a comma-separated list.
@@ -90,6 +92,7 @@ relocateShadowedDependencies = true
 # Separate run directories into "run/client" for runClient task, and "run/server" for runServer task.
 # Useful for debugging a server and client simultaneously. If not enabled, it will be in the standard location "run/"
 separateRunDirectories = false
+
 # The display name format of versions published to Curse and Modrinth. $MOD_NAME and $VERSION are available variables.
 # Default: $MOD_NAME \u2212 $VERSION. \u2212 is the minus character which looks much better than the hyphen minus on Curse.
 versionDisplayFormat=$MOD_NAME: $VERSION
diff --git a/settings.gradle b/settings.gradle
index b6371aad5ab..771def37e1f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,9 +3,7 @@ pluginManagement {
         maven {
             // RetroFuturaGradle
             name 'GTNH Maven'
-            //noinspection HttpUrlsUsage
-            url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/'
-            allowInsecureProtocol = true
+            url 'https://nexus.gtnewhorizons.com/repository/public/'
             //noinspection GroovyAssignabilityCheck
             mavenContent {
                 includeGroup 'com.gtnewhorizons'

From 588695e97b549c555c498a8e16a5ac3575c72fe5 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Wed, 10 Jan 2024 09:18:26 -0500
Subject: [PATCH 39/98] prevent potential ThreadLocal memory leaks (#2320)

---
 .../gregtech/api/block/machines/BlockMachine.java | 15 ++++++++++++---
 .../gregtech/api/pipenet/block/BlockPipe.java     |  9 +++++++--
 .../gregtech/api/unification/ore/OrePrefix.java   | 14 +++++++++++---
 src/main/java/gregtech/asm/hooks/CTMHooks.java    |  2 +-
 .../renderer/handler/MetaTileEntityRenderer.java  |  2 +-
 .../client/renderer/pipe/PipeRenderer.java        |  2 +-
 6 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java
index f9a77ccbe07..d2deda21283 100644
--- a/src/main/java/gregtech/api/block/machines/BlockMachine.java
+++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java
@@ -40,7 +40,11 @@
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.*;
+import net.minecraft.util.BlockRenderLayer;
+import net.minecraft.util.EnumBlockRenderType;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
 import net.minecraft.util.math.AxisAlignedBB;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.math.RayTraceResult;
@@ -63,7 +67,12 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
 
 import static gregtech.api.util.GTUtility.getMetaTileEntity;
 
@@ -423,7 +432,7 @@ public void harvestBlock(@NotNull World worldIn, @NotNull EntityPlayer player, @
                              @NotNull IBlockState state, @Nullable TileEntity te, @NotNull ItemStack stack) {
         tileEntities.set(te == null ? tileEntities.get() : ((IGregTechTileEntity) te).getMetaTileEntity());
         super.harvestBlock(worldIn, player, pos, state, te, stack);
-        tileEntities.set(null);
+        tileEntities.remove();
     }
 
     @Nullable
diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java
index 5468aae38dd..667b67fcf52 100644
--- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java
+++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java
@@ -34,7 +34,12 @@
 import net.minecraft.item.EnumDyeColor;
 import net.minecraft.item.ItemStack;
 import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.*;
+import net.minecraft.util.BlockRenderLayer;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.SoundCategory;
 import net.minecraft.util.math.AxisAlignedBB;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.math.RayTraceResult;
@@ -485,7 +490,7 @@ public void harvestBlock(@NotNull World worldIn, @NotNull EntityPlayer player, @
                              @NotNull IBlockState state, @Nullable TileEntity te, @NotNull ItemStack stack) {
         tileEntities.set(te == null ? tileEntities.get() : (IPipeTile) te);
         super.harvestBlock(worldIn, player, pos, state, te, stack);
-        tileEntities.set(null);
+        tileEntities.remove();
     }
 
     @Override
diff --git a/src/main/java/gregtech/api/unification/ore/OrePrefix.java b/src/main/java/gregtech/api/unification/ore/OrePrefix.java
index 30239988324..0a159028f1d 100644
--- a/src/main/java/gregtech/api/unification/ore/OrePrefix.java
+++ b/src/main/java/gregtech/api/unification/ore/OrePrefix.java
@@ -23,7 +23,15 @@
 import stanhebben.zenscript.annotations.ZenClass;
 import stanhebben.zenscript.annotations.ZenMethod;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -631,11 +639,11 @@ private void runGeneratedMaterialHandlers() {
             for (IOreRegistrationHandler registrationHandler : oreProcessingHandlers) {
                 registrationHandler.processMaterial(this, registeredMaterial);
             }
-            currentMaterial.set(null);
+            currentMaterial.remove();
         }
         // clear generated materials for next pass
         generatedMaterials.clear();
-        currentProcessingPrefix.set(null);
+        currentProcessingPrefix.remove();
     }
 
     public void setAlternativeOreName(String name) {
diff --git a/src/main/java/gregtech/asm/hooks/CTMHooks.java b/src/main/java/gregtech/asm/hooks/CTMHooks.java
index 33ddc0d7754..eaf4f7ad51c 100644
--- a/src/main/java/gregtech/asm/hooks/CTMHooks.java
+++ b/src/main/java/gregtech/asm/hooks/CTMHooks.java
@@ -43,7 +43,7 @@ public static List getQuadsWithOptiFine(List ret, BlockRen
                 ForgeHooksClient.setRenderLayer(BloomEffectUtil.getBloomLayer());
                 result.addAll(bakedModel.getQuads(state, side, rand));
                 ForgeHooksClient.setRenderLayer(layer);
-                CTMHooks.ENABLE.set(null);
+                CTMHooks.ENABLE.remove();
                 return result;
             }
         }
diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java
index 5aa513fea8c..9436d30dc8d 100644
--- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java
+++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java
@@ -115,7 +115,7 @@ public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state,
 
         metaTileEntity.renderCovers(renderState, translation.copy(), renderLayer);
 
-        Textures.RENDER_STATE.set(null);
+        Textures.RENDER_STATE.remove();
         return true;
     }
 
diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java
index 632bdad8f2b..d16ca9ace07 100644
--- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java
+++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java
@@ -218,7 +218,7 @@ public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state,
             CoverHolder coverHolder = pipeTile.getCoverableImplementation();
             coverHolder.renderCovers(renderState, new Matrix4().translate(pos.getX(), pos.getY(), pos.getZ()),
                     renderLayer);
-            Textures.RENDER_STATE.set(null);
+            Textures.RENDER_STATE.remove();
         }
         return true;
     }

From 996e6cfcb711258d0d22dbcc8dee6bb3d821a263 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Thu, 11 Jan 2024 16:57:44 -0500
Subject: [PATCH 40/98] move creative tabs out of GregTechAPI (#2317)

---
 src/main/java/gregtech/api/GregTechAPI.java   |  26 ----
 .../java/gregtech/api/block/VariantBlock.java |   4 +-
 .../api/block/machines/BlockMachine.java      |   3 +-
 .../api/block/machines/MachineItemBlock.java  |   5 +-
 .../BaseCreativeTab.java                      |  19 +--
 .../api/items/armor/ArmorMetaItem.java        |   4 +-
 .../items/materialitem/MetaPrefixItem.java    |   4 +-
 .../gregtech/api/items/metaitem/MetaItem.java |  32 ++++-
 .../api/items/toolitem/ItemGTAxe.java         |  11 +-
 .../api/items/toolitem/ItemGTHoe.java         |  11 +-
 .../api/items/toolitem/ItemGTSword.java       |  11 +-
 .../api/items/toolitem/ItemGTTool.java        |  11 +-
 .../api/metatileentity/MetaTileEntity.java    |  29 +++-
 .../longdist/BlockLongDistancePipe.java       |   6 +-
 .../gregtech/common/blocks/BlockAsphalt.java  |   4 +-
 .../common/blocks/BlockCompressed.java        |   4 +-
 .../gregtech/common/blocks/BlockFrame.java    |   4 +-
 .../common/blocks/BlockGregStairs.java        |   4 +-
 .../gregtech/common/blocks/BlockLamp.java     |   4 +-
 .../java/gregtech/common/blocks/BlockOre.java |   6 +-
 .../common/blocks/BlockWarningSign.java       |   4 +-
 .../common/blocks/BlockWarningSign1.java      |   4 +-
 .../common/blocks/StoneVariantBlock.java      |   4 +-
 .../common/blocks/wood/BlockGregFence.java    |   4 +-
 .../blocks/wood/BlockGregFenceGate.java       |   4 +-
 .../common/blocks/wood/BlockGregWoodSlab.java |   4 +-
 .../common/blocks/wood/BlockRubberLeaves.java |   4 +-
 .../common/blocks/wood/BlockRubberLog.java    |   4 +-
 .../blocks/wood/BlockRubberSapling.java       |   4 +-
 .../common/creativetab/GTCreativeTabs.java    |  34 +++++
 .../java/gregtech/common/items/MetaItem1.java | 129 +++++++++++-------
 .../common/pipelike/cable/BlockCable.java     |   4 +-
 .../pipelike/fluidpipe/BlockFluidPipe.java    |   4 +-
 .../pipelike/itempipe/BlockItemPipe.java      |   4 +-
 .../common/pipelike/laser/BlockLaserPipe.java |   4 +-
 .../pipelike/optical/BlockOpticalPipe.java    |   4 +-
 36 files changed, 259 insertions(+), 162 deletions(-)
 rename src/main/java/gregtech/api/{util => creativetab}/BaseCreativeTab.java (78%)
 create mode 100644 src/main/java/gregtech/common/creativetab/GTCreativeTabs.java

diff --git a/src/main/java/gregtech/api/GregTechAPI.java b/src/main/java/gregtech/api/GregTechAPI.java
index f3279eb5b3b..c4506dfbfc0 100644
--- a/src/main/java/gregtech/api/GregTechAPI.java
+++ b/src/main/java/gregtech/api/GregTechAPI.java
@@ -12,23 +12,14 @@
 import gregtech.api.modules.IModuleManager;
 import gregtech.api.network.INetworkHandler;
 import gregtech.api.sound.ISoundManager;
-import gregtech.api.unification.OreDictUnifier;
 import gregtech.api.unification.material.Material;
-import gregtech.api.unification.material.Materials;
 import gregtech.api.unification.material.registry.IMaterialRegistryManager;
 import gregtech.api.unification.material.registry.MarkerMaterialRegistry;
-import gregtech.api.unification.ore.OrePrefix;
 import gregtech.api.unification.ore.StoneType;
-import gregtech.api.util.BaseCreativeTab;
 import gregtech.api.util.GTControlledRegistry;
 import gregtech.api.util.GTLog;
 import gregtech.api.util.IBlockOre;
 import gregtech.common.ConfigHolder;
-import gregtech.common.blocks.BlockWarningSign;
-import gregtech.common.blocks.MetaBlocks;
-import gregtech.common.items.MetaItems;
-import gregtech.common.items.ToolItems;
-import gregtech.common.metatileentities.MetaTileEntities;
 
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.util.ResourceLocation;
@@ -78,23 +69,6 @@ public class GregTechAPI {
     public static final Object2ObjectMap HEATING_COILS = new Object2ObjectOpenHashMap<>();
     public static final Object2ObjectMap PSS_BATTERIES = new Object2ObjectOpenHashMap<>();
 
-    public static final BaseCreativeTab TAB_GREGTECH = new BaseCreativeTab(GTValues.MODID + ".main",
-            () -> MetaItems.LOGO.getStackForm(), true);
-    public static final BaseCreativeTab TAB_GREGTECH_MACHINES = new BaseCreativeTab(GTValues.MODID + ".machines",
-            () -> MetaTileEntities.ELECTRIC_BLAST_FURNACE.getStackForm(), true);
-    public static final BaseCreativeTab TAB_GREGTECH_CABLES = new BaseCreativeTab(GTValues.MODID + ".cables",
-            () -> OreDictUnifier.get(OrePrefix.cableGtDouble, Materials.Aluminium), true);
-    public static final BaseCreativeTab TAB_GREGTECH_PIPES = new BaseCreativeTab(GTValues.MODID + ".pipes",
-            () -> OreDictUnifier.get(OrePrefix.pipeNormalFluid, Materials.Aluminium), true);
-    public static final BaseCreativeTab TAB_GREGTECH_TOOLS = new BaseCreativeTab(GTValues.MODID + ".tools",
-            () -> ToolItems.HARD_HAMMER.get(Materials.Aluminium), true);
-    public static final BaseCreativeTab TAB_GREGTECH_MATERIALS = new BaseCreativeTab(GTValues.MODID + ".materials",
-            () -> OreDictUnifier.get(OrePrefix.ingot, Materials.Aluminium), true);
-    public static final BaseCreativeTab TAB_GREGTECH_ORES = new BaseCreativeTab(GTValues.MODID + ".ores",
-            () -> OreDictUnifier.get(OrePrefix.ore, Materials.Aluminium), true);
-    public static final BaseCreativeTab TAB_GREGTECH_DECORATIONS = new BaseCreativeTab(GTValues.MODID + ".decorations",
-            () -> MetaBlocks.WARNING_SIGN.getItemVariant(BlockWarningSign.SignType.YELLOW_STRIPES), true);
-
     /** Will be available at the Pre-Initialization stage */
     public static boolean isHighTier() {
         return highTier;
diff --git a/src/main/java/gregtech/api/block/VariantBlock.java b/src/main/java/gregtech/api/block/VariantBlock.java
index 5b0310263ef..7e31dd48c3b 100644
--- a/src/main/java/gregtech/api/block/VariantBlock.java
+++ b/src/main/java/gregtech/api/block/VariantBlock.java
@@ -1,7 +1,7 @@
 package gregtech.api.block;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.util.LocalizationUtils;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.material.Material;
@@ -43,7 +43,7 @@ public VariantBlock(Material materialIn) {
                         state);
             }
         }
-        setCreativeTab(GregTechAPI.TAB_GREGTECH);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH);
         setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, VALUES[0]));
     }
 
diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java
index d2deda21283..6c23ce8c5f5 100644
--- a/src/main/java/gregtech/api/block/machines/BlockMachine.java
+++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java
@@ -16,6 +16,7 @@
 import gregtech.api.pipenet.IBlockAppearance;
 import gregtech.api.util.GTUtility;
 import gregtech.client.renderer.handler.MetaTileEntityRenderer;
+import gregtech.common.creativetab.GTCreativeTabs;
 import gregtech.common.items.MetaItems;
 import gregtech.integration.ctm.IFacadeWrapper;
 
@@ -92,7 +93,7 @@ public class BlockMachine extends BlockCustomParticle implements ITileEntityProv
 
     public BlockMachine() {
         super(Material.IRON);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_MACHINES);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MACHINES);
         setSoundType(SoundType.METAL);
         setHardness(6.0f);
         setResistance(6.0f);
diff --git a/src/main/java/gregtech/api/block/machines/MachineItemBlock.java b/src/main/java/gregtech/api/block/machines/MachineItemBlock.java
index 1186eaefa7c..ca0cd6417dd 100644
--- a/src/main/java/gregtech/api/block/machines/MachineItemBlock.java
+++ b/src/main/java/gregtech/api/block/machines/MachineItemBlock.java
@@ -10,6 +10,7 @@
 import gregtech.api.util.LocalizationUtils;
 import gregtech.client.utils.TooltipHelper;
 import gregtech.common.ConfigHolder;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.state.IBlockState;
@@ -61,8 +62,8 @@ public class MachineItemBlock extends ItemBlock {
      */
     public static void addCreativeTab(CreativeTabs creativeTab) {
         Preconditions.checkNotNull(creativeTab, "creativeTab");
-        if (creativeTab == GregTechAPI.TAB_GREGTECH_MACHINES) {
-            throw new IllegalArgumentException("Adding " + GregTechAPI.TAB_GREGTECH_MACHINES.tabLabel +
+        if (creativeTab == GTCreativeTabs.TAB_GREGTECH_MACHINES) {
+            throw new IllegalArgumentException("Adding " + GTCreativeTabs.TAB_GREGTECH_MACHINES.tabLabel +
                     " as additional creative tab is redundant.");
         } else if (creativeTab == CreativeTabs.SEARCH) {
             throw new IllegalArgumentException(
diff --git a/src/main/java/gregtech/api/util/BaseCreativeTab.java b/src/main/java/gregtech/api/creativetab/BaseCreativeTab.java
similarity index 78%
rename from src/main/java/gregtech/api/util/BaseCreativeTab.java
rename to src/main/java/gregtech/api/creativetab/BaseCreativeTab.java
index 0b9fd926651..4607cf05d08 100644
--- a/src/main/java/gregtech/api/util/BaseCreativeTab.java
+++ b/src/main/java/gregtech/api/creativetab/BaseCreativeTab.java
@@ -1,4 +1,6 @@
-package gregtech.api.util;
+package gregtech.api.creativetab;
+
+import gregtech.api.util.GTLog;
 
 import net.minecraft.creativetab.CreativeTabs;
 import net.minecraft.init.Blocks;
@@ -13,31 +15,32 @@ public class BaseCreativeTab extends CreativeTabs {
     private final boolean hasSearchBar;
     private final Supplier iconSupplier;
 
-    public BaseCreativeTab(String TabName, Supplier iconSupplier, boolean hasSearchBar) {
-        super(TabName);
+    public BaseCreativeTab(String tabName, Supplier iconSupplier, boolean hasSearchBar) {
+        super(tabName);
         this.iconSupplier = iconSupplier;
         this.hasSearchBar = hasSearchBar;
 
-        if (hasSearchBar)
+        if (hasSearchBar) {
             setBackgroundImageName("item_search.png");
+        }
     }
 
     @NotNull
     @Override
     public ItemStack createIcon() {
         if (iconSupplier == null) {
-            GTLog.logger.error("Icon supplier was null for CreativeTab " + getTabLabel());
+            GTLog.logger.error("Icon supplier was null for CreativeTab {}", getTabLabel());
             return new ItemStack(Blocks.STONE);
         }
 
         ItemStack stack = iconSupplier.get();
         if (stack == null) {
-            GTLog.logger.error("Icon supplier return null for CreativeTab " + getTabLabel());
+            GTLog.logger.error("Icon supplier return null for CreativeTab {}", getTabLabel());
             return new ItemStack(Blocks.STONE);
         }
 
-        if (stack == ItemStack.EMPTY) {
-            GTLog.logger.error("Icon built from iconSupplied is EMPTY for CreativeTab " + getTabLabel());
+        if (stack.isEmpty()) {
+            GTLog.logger.error("Icon built from iconSupplied is EMPTY for CreativeTab {}", getTabLabel());
             return new ItemStack(Blocks.STONE);
         }
 
diff --git a/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java b/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java
index e7e663377d0..a972b669c95 100644
--- a/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java
+++ b/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java
@@ -1,9 +1,9 @@
 package gregtech.api.items.armor;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.metaitem.MetaItem;
 import gregtech.api.items.metaitem.stats.IEnchantabilityHelper;
 import gregtech.api.items.metaitem.stats.IItemComponent;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.client.gui.ScaledResolution;
 import net.minecraft.client.model.ModelBiped;
@@ -33,7 +33,7 @@ public class ArmorMetaItem.ArmorMetaValueItem> extend
 
     public ArmorMetaItem() {
         super((short) 0);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS);
     }
 
     @SuppressWarnings("unchecked")
diff --git a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java
index 35172727add..614e5fa1076 100644
--- a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java
+++ b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java
@@ -1,7 +1,6 @@
 package gregtech.api.items.materialitem;
 
 import gregtech.api.GTValues;
-import gregtech.api.GregTechAPI;
 import gregtech.api.damagesources.DamageSources;
 import gregtech.api.items.armor.ArmorMetaItem;
 import gregtech.api.items.metaitem.StandardMetaItem;
@@ -15,6 +14,7 @@
 import gregtech.api.unification.material.registry.MaterialRegistry;
 import gregtech.api.unification.ore.OrePrefix;
 import gregtech.api.unification.stack.UnificationEntry;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.BlockCauldron;
 import net.minecraft.block.state.IBlockState;
@@ -58,7 +58,7 @@ public MetaPrefixItem(@NotNull MaterialRegistry registry, @NotNull OrePrefix ore
         super();
         this.registry = registry;
         this.prefix = orePrefix;
-        this.setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS);
+        this.setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS);
     }
 
     @Override
diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java
index ba1f713f010..f4cedc0f729 100644
--- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java
+++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java
@@ -1,7 +1,6 @@
 package gregtech.api.items.metaitem;
 
 import gregtech.api.GTValues;
-import gregtech.api.GregTechAPI;
 import gregtech.api.capability.GregtechCapabilities;
 import gregtech.api.capability.IElectricItem;
 import gregtech.api.capability.IFilteredFluidContainer;
@@ -12,7 +11,18 @@
 import gregtech.api.items.OreDictNames;
 import gregtech.api.items.gui.ItemUIFactory;
 import gregtech.api.items.gui.PlayerInventoryHolder;
-import gregtech.api.items.metaitem.stats.*;
+import gregtech.api.items.metaitem.stats.IEnchantabilityHelper;
+import gregtech.api.items.metaitem.stats.IFoodBehavior;
+import gregtech.api.items.metaitem.stats.IItemBehaviour;
+import gregtech.api.items.metaitem.stats.IItemCapabilityProvider;
+import gregtech.api.items.metaitem.stats.IItemColorProvider;
+import gregtech.api.items.metaitem.stats.IItemComponent;
+import gregtech.api.items.metaitem.stats.IItemContainerItemProvider;
+import gregtech.api.items.metaitem.stats.IItemDurabilityManager;
+import gregtech.api.items.metaitem.stats.IItemMaxStackSizeProvider;
+import gregtech.api.items.metaitem.stats.IItemNameProvider;
+import gregtech.api.items.metaitem.stats.IItemUseManager;
+import gregtech.api.items.metaitem.stats.ISubItemHandler;
 import gregtech.api.recipes.ingredients.IntCircuitIngredient;
 import gregtech.api.unification.OreDictUnifier;
 import gregtech.api.unification.material.Material;
@@ -22,6 +32,7 @@
 import gregtech.api.util.LocalizationUtils;
 import gregtech.client.utils.ToolChargeBarRenderer;
 import gregtech.common.ConfigHolder;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.renderer.block.model.ModelBakery;
@@ -40,7 +51,12 @@
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.*;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.ResourceLocation;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.World;
 import net.minecraftforge.client.model.ModelLoader;
@@ -72,7 +88,13 @@
 
 import java.time.Duration;
 import java.time.Instant;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * MetaItem is item that can have up to Short.MAX_VALUE items inside one id.
@@ -107,7 +129,7 @@ public static List> getMetaItems() {
 
     protected final short metaItemOffset;
 
-    private CreativeTabs[] defaultCreativeTabs = new CreativeTabs[] { GregTechAPI.TAB_GREGTECH };
+    private CreativeTabs[] defaultCreativeTabs = new CreativeTabs[] { GTCreativeTabs.TAB_GREGTECH };
     private final Set additionalCreativeTabs = new ObjectArraySet<>();
 
     public MetaItem(short metaItemOffset) {
diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java b/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java
index 5acd7f41780..2537884399a 100644
--- a/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java
+++ b/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java
@@ -1,7 +1,7 @@
 package gregtech.api.items.toolitem;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.util.LocalizationUtils;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.client.util.ITooltipFlag;
@@ -14,7 +14,12 @@
 import net.minecraft.item.ItemAxe;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.*;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.SoundEvent;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.IBlockAccess;
 import net.minecraft.world.World;
@@ -59,7 +64,7 @@ protected ItemGTAxe(String domain, String id, int tier, IGTToolDefinition toolSt
         this.secondaryOreDicts = secondaryOreDicts;
         this.markerItem = markerItem;
         setMaxStackSize(1);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         setTranslationKey("gt.tool." + id + ".name");
         setRegistryName(domain, id);
     }
diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java b/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java
index 7f52587be7c..13e14e8e574 100644
--- a/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java
+++ b/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java
@@ -1,7 +1,7 @@
 package gregtech.api.items.toolitem;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.util.LocalizationUtils;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.client.util.ITooltipFlag;
@@ -14,7 +14,12 @@
 import net.minecraft.item.ItemHoe;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.*;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.SoundEvent;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.IBlockAccess;
 import net.minecraft.world.World;
@@ -59,7 +64,7 @@ protected ItemGTHoe(String domain, String id, int tier, IGTToolDefinition toolSt
         this.secondaryOreDicts = secondaryOreDicts;
         this.markerItem = markerItem;
         setMaxStackSize(1);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         setTranslationKey("gt.tool." + id + ".name");
         setRegistryName(domain, id);
     }
diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java b/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java
index 5b95f6f3718..2786f91d558 100644
--- a/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java
+++ b/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java
@@ -1,7 +1,7 @@
 package gregtech.api.items.toolitem;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.util.LocalizationUtils;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.client.util.ITooltipFlag;
@@ -14,7 +14,12 @@
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemSword;
 import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.*;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.SoundEvent;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.IBlockAccess;
 import net.minecraft.world.World;
@@ -61,7 +66,7 @@ protected ItemGTSword(String domain, String id, int tier, IGTToolDefinition tool
         this.secondaryOreDicts = secondaryOreDicts;
         this.markerItem = markerItem;
         setMaxStackSize(1);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         setTranslationKey("gt.tool." + id + ".name");
         setRegistryName(domain, id);
     }
diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java b/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java
index edcfa83126d..375aadb845c 100644
--- a/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java
+++ b/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java
@@ -1,7 +1,7 @@
 package gregtech.api.items.toolitem;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.util.LocalizationUtils;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.client.util.ITooltipFlag;
@@ -14,7 +14,12 @@
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemTool;
 import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.*;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.SoundEvent;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.IBlockAccess;
 import net.minecraft.world.World;
@@ -65,7 +70,7 @@ protected ItemGTTool(String domain, String id, int tier, IGTToolDefinition toolS
         this.secondaryOreDicts = secondaryOreDicts;
         this.markerItem = markerItem;
         setMaxStackSize(1);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         setTranslationKey("gt.tool." + id + ".name");
         setRegistryName(domain, id);
     }
diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
index 8b922ffc3f6..96bb366b87d 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
@@ -7,8 +7,16 @@
 import gregtech.api.capability.GregtechTileCapabilities;
 import gregtech.api.capability.IControllable;
 import gregtech.api.capability.IEnergyContainer;
-import gregtech.api.capability.impl.*;
-import gregtech.api.cover.*;
+import gregtech.api.capability.impl.AbstractRecipeLogic;
+import gregtech.api.capability.impl.FluidHandlerProxy;
+import gregtech.api.capability.impl.FluidTankList;
+import gregtech.api.capability.impl.ItemHandlerProxy;
+import gregtech.api.capability.impl.NotifiableFluidTank;
+import gregtech.api.cover.Cover;
+import gregtech.api.cover.CoverHolder;
+import gregtech.api.cover.CoverRayTracer;
+import gregtech.api.cover.CoverSaveHandler;
+import gregtech.api.cover.CoverUtil;
 import gregtech.api.gui.ModularUI;
 import gregtech.api.items.itemhandlers.GTItemStackHandler;
 import gregtech.api.items.toolitem.ToolClasses;
@@ -25,6 +33,7 @@
 import gregtech.client.renderer.texture.Textures;
 import gregtech.client.utils.BloomEffectUtil;
 import gregtech.common.ConfigHolder;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.state.BlockFaceShape;
@@ -40,7 +49,13 @@
 import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.network.PacketBuffer;
 import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.*;
+import net.minecraft.util.BlockRenderLayer;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.SoundEvent;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.text.TextComponentTranslation;
 import net.minecraft.world.World;
@@ -84,7 +99,11 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 
@@ -328,7 +347,7 @@ public void getSubItems(CreativeTabs creativeTab, NonNullList subItem
      *      MachineItemBlock#addCreativeTab(CreativeTabs)
      */
     public boolean isInCreativeTab(CreativeTabs creativeTab) {
-        return creativeTab == CreativeTabs.SEARCH || creativeTab == GregTechAPI.TAB_GREGTECH_MACHINES;
+        return creativeTab == CreativeTabs.SEARCH || creativeTab == GTCreativeTabs.TAB_GREGTECH_MACHINES;
     }
 
     public String getItemSubTypeId(ItemStack itemStack) {
diff --git a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java
index cb3a9a5abbb..28339dd7ef2 100644
--- a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java
+++ b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java
@@ -1,7 +1,7 @@
 package gregtech.api.pipenet.longdist;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.material.Material;
@@ -33,7 +33,7 @@ public BlockLongDistancePipe(LongDistancePipeType pipeType) {
         super(Material.IRON);
         this.pipeType = pipeType;
         setTranslationKey("long_distance_" + pipeType.getName() + "_pipeline");
-        setCreativeTab(GregTechAPI.TAB_GREGTECH);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH);
         setHarvestLevel(ToolClasses.WRENCH, 1);
     }
 
@@ -101,7 +101,7 @@ public void breakBlock(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull I
 
     @Override
     public void getSubBlocks(@NotNull CreativeTabs itemIn, @NotNull NonNullList items) {
-        if (itemIn == GregTechAPI.TAB_GREGTECH) {
+        if (itemIn == GTCreativeTabs.TAB_GREGTECH) {
             items.add(new ItemStack(this));
         }
     }
diff --git a/src/main/java/gregtech/common/blocks/BlockAsphalt.java b/src/main/java/gregtech/common/blocks/BlockAsphalt.java
index 281e47c76b8..728245fcd90 100644
--- a/src/main/java/gregtech/common/blocks/BlockAsphalt.java
+++ b/src/main/java/gregtech/common/blocks/BlockAsphalt.java
@@ -1,8 +1,8 @@
 package gregtech.common.blocks;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.block.IStateHarvestLevel;
 import gregtech.api.block.VariantBlock;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.SoundType;
 import net.minecraft.block.material.Material;
@@ -23,7 +23,7 @@ public BlockAsphalt() {
         setResistance(10.0f);
         setSoundType(SoundType.STONE);
         setDefaultState(getState(BlockType.ASPHALT));
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
     }
 
     @Override
diff --git a/src/main/java/gregtech/common/blocks/BlockCompressed.java b/src/main/java/gregtech/common/blocks/BlockCompressed.java
index 18b71b293d6..9f2fb91fb16 100644
--- a/src/main/java/gregtech/common/blocks/BlockCompressed.java
+++ b/src/main/java/gregtech/common/blocks/BlockCompressed.java
@@ -1,6 +1,5 @@
 package gregtech.common.blocks;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
 import gregtech.api.unification.material.Material;
 import gregtech.api.unification.material.info.MaterialIconType;
@@ -9,6 +8,7 @@
 import gregtech.client.model.modelfactories.MaterialBlockModelLoader;
 import gregtech.common.ConfigHolder;
 import gregtech.common.blocks.properties.PropertyMaterial;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.SoundType;
 import net.minecraft.block.state.IBlockState;
@@ -46,7 +46,7 @@ private BlockCompressed() {
         setTranslationKey("compressed");
         setHardness(5.0f);
         setResistance(10.0f);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS);
     }
 
     @Override
diff --git a/src/main/java/gregtech/common/blocks/BlockFrame.java b/src/main/java/gregtech/common/blocks/BlockFrame.java
index f4bb81f675d..88bbf3c2374 100644
--- a/src/main/java/gregtech/common/blocks/BlockFrame.java
+++ b/src/main/java/gregtech/common/blocks/BlockFrame.java
@@ -1,6 +1,5 @@
 package gregtech.common.blocks;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
 import gregtech.api.items.toolitem.ToolHelper;
 import gregtech.api.pipenet.block.BlockPipe;
@@ -15,6 +14,7 @@
 import gregtech.client.model.modelfactories.MaterialBlockModelLoader;
 import gregtech.common.ConfigHolder;
 import gregtech.common.blocks.properties.PropertyMaterial;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.SoundType;
@@ -68,7 +68,7 @@ private BlockFrame() {
         setTranslationKey("frame");
         setHardness(3.0f);
         setResistance(6.0f);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS);
     }
 
     @Override
diff --git a/src/main/java/gregtech/common/blocks/BlockGregStairs.java b/src/main/java/gregtech/common/blocks/BlockGregStairs.java
index f04cddbe6df..e8b2a12f2c7 100644
--- a/src/main/java/gregtech/common/blocks/BlockGregStairs.java
+++ b/src/main/java/gregtech/common/blocks/BlockGregStairs.java
@@ -1,7 +1,7 @@
 package gregtech.common.blocks;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.BlockStairs;
 import net.minecraft.block.state.IBlockState;
@@ -15,7 +15,7 @@ public class BlockGregStairs extends BlockStairs {
 
     public BlockGregStairs(IBlockState state) {
         super(state);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
         this.useNeighborBrightness = true;
         this.setHarvestLevel(ToolClasses.AXE, 0);
     }
diff --git a/src/main/java/gregtech/common/blocks/BlockLamp.java b/src/main/java/gregtech/common/blocks/BlockLamp.java
index 3cc7c273ddc..28d26cfd41a 100644
--- a/src/main/java/gregtech/common/blocks/BlockLamp.java
+++ b/src/main/java/gregtech/common/blocks/BlockLamp.java
@@ -1,13 +1,13 @@
 package gregtech.common.blocks;
 
 import gregtech.api.GTValues;
-import gregtech.api.GregTechAPI;
 import gregtech.api.unification.OreDictUnifier;
 import gregtech.api.unification.material.MarkerMaterials;
 import gregtech.api.unification.ore.OrePrefix;
 import gregtech.client.model.lamp.LampBakedModel;
 import gregtech.client.model.lamp.LampModelType;
 import gregtech.client.utils.BloomEffectUtil;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.SoundType;
@@ -66,7 +66,7 @@ public BlockLamp(EnumDyeColor color) {
                 .withProperty(LIGHT, true)
                 .withProperty(INVERTED, false)
                 .withProperty(POWERED, false));
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
     }
 
     public boolean isLightEnabled(ItemStack stack) {
diff --git a/src/main/java/gregtech/common/blocks/BlockOre.java b/src/main/java/gregtech/common/blocks/BlockOre.java
index c0fc037097b..db69901b8ff 100644
--- a/src/main/java/gregtech/common/blocks/BlockOre.java
+++ b/src/main/java/gregtech/common/blocks/BlockOre.java
@@ -1,6 +1,5 @@
 package gregtech.common.blocks;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
 import gregtech.api.unification.material.Material;
 import gregtech.api.unification.material.info.MaterialFlags;
@@ -13,6 +12,7 @@
 import gregtech.client.model.OreBakedModel;
 import gregtech.client.utils.BloomEffectUtil;
 import gregtech.common.blocks.properties.PropertyStoneType;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.SoundType;
@@ -54,7 +54,7 @@ public BlockOre(Material material, StoneType[] allowedValues) {
         this.material = Objects.requireNonNull(material, "Material in BlockOre can not be null!");
         STONE_TYPE = PropertyStoneType.create("stone_type", allowedValues);
         initBlockState();
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_ORES);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_ORES);
     }
 
     @NotNull
@@ -173,7 +173,7 @@ public boolean isFireSource(@NotNull World world, @NotNull BlockPos pos, @NotNul
 
     @Override
     public void getSubBlocks(@NotNull CreativeTabs tab, @NotNull NonNullList list) {
-        if (tab == CreativeTabs.SEARCH || tab == GregTechAPI.TAB_GREGTECH_ORES) {
+        if (tab == CreativeTabs.SEARCH || tab == GTCreativeTabs.TAB_GREGTECH_ORES) {
             blockState.getValidStates().stream()
                     .filter(state -> state.getValue(STONE_TYPE).shouldBeDroppedAsItem)
                     .forEach(blockState -> list.add(GTUtility.toItem(blockState)));
diff --git a/src/main/java/gregtech/common/blocks/BlockWarningSign.java b/src/main/java/gregtech/common/blocks/BlockWarningSign.java
index e452e203528..4fdf97dd2fd 100644
--- a/src/main/java/gregtech/common/blocks/BlockWarningSign.java
+++ b/src/main/java/gregtech/common/blocks/BlockWarningSign.java
@@ -1,8 +1,8 @@
 package gregtech.common.blocks;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.block.VariantBlock;
 import gregtech.api.items.toolitem.ToolClasses;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.SoundType;
 import net.minecraft.block.material.Material;
@@ -24,7 +24,7 @@ public BlockWarningSign() {
         setSoundType(SoundType.METAL);
         setHarvestLevel(ToolClasses.WRENCH, 1);
         setDefaultState(getState(SignType.YELLOW_STRIPES));
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
     }
 
     @Override
diff --git a/src/main/java/gregtech/common/blocks/BlockWarningSign1.java b/src/main/java/gregtech/common/blocks/BlockWarningSign1.java
index b25d74c9397..199a892d781 100644
--- a/src/main/java/gregtech/common/blocks/BlockWarningSign1.java
+++ b/src/main/java/gregtech/common/blocks/BlockWarningSign1.java
@@ -1,8 +1,8 @@
 package gregtech.common.blocks;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.block.VariantBlock;
 import gregtech.api.items.toolitem.ToolClasses;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.SoundType;
 import net.minecraft.block.material.Material;
@@ -24,7 +24,7 @@ public BlockWarningSign1() {
         setSoundType(SoundType.METAL);
         setHarvestLevel(ToolClasses.WRENCH, 1);
         setDefaultState(getState(SignType.MOB_SPAWNER_HAZARD));
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
     }
 
     @Override
diff --git a/src/main/java/gregtech/common/blocks/StoneVariantBlock.java b/src/main/java/gregtech/common/blocks/StoneVariantBlock.java
index 39194eea2a0..72fcb6d5180 100644
--- a/src/main/java/gregtech/common/blocks/StoneVariantBlock.java
+++ b/src/main/java/gregtech/common/blocks/StoneVariantBlock.java
@@ -1,11 +1,11 @@
 package gregtech.common.blocks;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.block.VariantBlock;
 import gregtech.api.items.toolitem.ToolClasses;
 import gregtech.api.unification.material.Material;
 import gregtech.api.unification.material.Materials;
 import gregtech.api.unification.ore.OrePrefix;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.SoundType;
 import net.minecraft.block.material.MapColor;
@@ -40,7 +40,7 @@ public StoneVariantBlock(@NotNull StoneVariant stoneVariant) {
         setSoundType(SoundType.STONE);
         setHarvestLevel(ToolClasses.PICKAXE, 0);
         setDefaultState(getState(StoneType.BLACK_GRANITE));
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
     }
 
     @NotNull
diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java b/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java
index 975c0708a22..ba3188cac78 100644
--- a/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java
+++ b/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java
@@ -1,7 +1,7 @@
 package gregtech.common.blocks.wood;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.BlockFence;
 import net.minecraft.block.SoundType;
@@ -15,7 +15,7 @@ public BlockGregFence() {
         setHardness(2.0F);
         setResistance(5.0F);
         setSoundType(SoundType.WOOD);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
         setHarvestLevel(ToolClasses.AXE, 0);
     }
 }
diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java b/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java
index 29c539eca35..aff946015e2 100644
--- a/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java
+++ b/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java
@@ -1,7 +1,7 @@
 package gregtech.common.blocks.wood;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.BlockFenceGate;
 import net.minecraft.block.BlockPlanks;
@@ -14,7 +14,7 @@ public BlockGregFenceGate() {
         setHardness(2.0F);
         setResistance(5.0F);
         setSoundType(SoundType.WOOD);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
         setHarvestLevel(ToolClasses.AXE, 0);
     }
 }
diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java b/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java
index acab4c9dd43..d2cc8e2b96e 100644
--- a/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java
+++ b/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java
@@ -1,8 +1,8 @@
 package gregtech.common.blocks.wood;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
 import gregtech.common.blocks.MetaBlocks;
+import gregtech.common.creativetab.GTCreativeTabs;
 
 import net.minecraft.block.BlockSlab;
 import net.minecraft.block.SoundType;
@@ -35,7 +35,7 @@ public BlockGregWoodSlab() {
         setResistance(5.0F);
         setSoundType(SoundType.WOOD);
         setHarvestLevel(ToolClasses.AXE, 0);
-        setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
         this.useNeighborBrightness = true;
     }
 
diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java
index 533cf4249d2..2149165afa4 100644
--- a/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java
+++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java
@@ -1,7 +1,7 @@
 package gregtech.common.blocks.wood;
 
-import gregtech.api.GregTechAPI;
 import gregtech.common.blocks.MetaBlocks;
+import gregtech.common.creativetab.GTCreativeTabs;
 import gregtech.core.CoreModule;
 
 import net.minecraft.block.BlockLeaves;
@@ -31,7 +31,7 @@ public BlockRubberLeaves() {
                 .withProperty(CHECK_DECAY, true)
                 .withProperty(DECAYABLE, true));
         setTranslationKey("rubber_leaves");
-        setCreativeTab(GregTechAPI.TAB_GREGTECH);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH);
         Blocks.FIRE.setFireInfo(this, 30, 60);
     }
 
diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java
index bd89801a699..7c2f2b09f85 100644
--- a/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java
+++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java
@@ -1,7 +1,7 @@
 package gregtech.common.blocks.wood;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.items.toolitem.ToolClasses;
+import gregtech.common.creativetab.GTCreativeTabs;
 import gregtech.common.items.MetaItems;
 
 import net.minecraft.block.BlockLog;
@@ -27,7 +27,7 @@ public BlockRubberLog() {
                 .withProperty(LOG_AXIS, BlockLog.EnumAxis.Y)
                 .withProperty(NATURAL, false));
         setTranslationKey("rubber_log");
-        setCreativeTab(GregTechAPI.TAB_GREGTECH);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH);
         setHarvestLevel(ToolClasses.AXE, 0);
     }
 
diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java
index cd9b35d8232..653a31fc9a8 100644
--- a/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java
+++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java
@@ -1,6 +1,6 @@
 package gregtech.common.blocks.wood;
 
-import gregtech.api.GregTechAPI;
+import gregtech.common.creativetab.GTCreativeTabs;
 import gregtech.common.worldgen.WorldGenRubberTree;
 
 import net.minecraft.block.BlockBush;
@@ -28,7 +28,7 @@ public BlockRubberSapling() {
         this.setDefaultState(this.blockState.getBaseState()
                 .withProperty(STAGE, 0));
         setTranslationKey("rubber_sapling");
-        setCreativeTab(GregTechAPI.TAB_GREGTECH);
+        setCreativeTab(GTCreativeTabs.TAB_GREGTECH);
         setHardness(0.0F);
         setSoundType(SoundType.PLANT);
     }
diff --git a/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java b/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java
new file mode 100644
index 00000000000..95d308dde3e
--- /dev/null
+++ b/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java
@@ -0,0 +1,34 @@
+package gregtech.common.creativetab;
+
+import gregtech.api.GTValues;
+import gregtech.api.creativetab.BaseCreativeTab;
+import gregtech.api.unification.OreDictUnifier;
+import gregtech.api.unification.material.Materials;
+import gregtech.api.unification.ore.OrePrefix;
+import gregtech.common.blocks.BlockWarningSign;
+import gregtech.common.blocks.MetaBlocks;
+import gregtech.common.items.MetaItems;
+import gregtech.common.items.ToolItems;
+import gregtech.common.metatileentities.MetaTileEntities;
+
+public final class GTCreativeTabs {
+
+    public static final BaseCreativeTab TAB_GREGTECH = new BaseCreativeTab(GTValues.MODID + ".main",
+            () -> MetaItems.LOGO.getStackForm(), true);
+    public static final BaseCreativeTab TAB_GREGTECH_MACHINES = new BaseCreativeTab(GTValues.MODID + ".machines",
+            () -> MetaTileEntities.ELECTRIC_BLAST_FURNACE.getStackForm(), true);
+    public static final BaseCreativeTab TAB_GREGTECH_CABLES = new BaseCreativeTab(GTValues.MODID + ".cables",
+            () -> OreDictUnifier.get(OrePrefix.cableGtDouble, Materials.Aluminium), true);
+    public static final BaseCreativeTab TAB_GREGTECH_PIPES = new BaseCreativeTab(GTValues.MODID + ".pipes",
+            () -> OreDictUnifier.get(OrePrefix.pipeNormalFluid, Materials.Aluminium), true);
+    public static final BaseCreativeTab TAB_GREGTECH_TOOLS = new BaseCreativeTab(GTValues.MODID + ".tools",
+            () -> ToolItems.HARD_HAMMER.get(Materials.Aluminium), true);
+    public static final BaseCreativeTab TAB_GREGTECH_MATERIALS = new BaseCreativeTab(GTValues.MODID + ".materials",
+            () -> OreDictUnifier.get(OrePrefix.ingot, Materials.Aluminium), true);
+    public static final BaseCreativeTab TAB_GREGTECH_ORES = new BaseCreativeTab(GTValues.MODID + ".ores",
+            () -> OreDictUnifier.get(OrePrefix.ore, Materials.Aluminium), true);
+    public static final BaseCreativeTab TAB_GREGTECH_DECORATIONS = new BaseCreativeTab(GTValues.MODID + ".decorations",
+            () -> MetaBlocks.WARNING_SIGN.getItemVariant(BlockWarningSign.SignType.YELLOW_STRIPES), true);
+
+    private GTCreativeTabs() {}
+}
diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java
index 9620ccaa60b..d194fedd4f5 100644
--- a/src/main/java/gregtech/common/items/MetaItem1.java
+++ b/src/main/java/gregtech/common/items/MetaItem1.java
@@ -3,7 +3,11 @@
 import gregtech.api.GTValues;
 import gregtech.api.GregTechAPI;
 import gregtech.api.capability.impl.CommonFluidFilters;
-import gregtech.api.items.metaitem.*;
+import gregtech.api.items.metaitem.ElectricStats;
+import gregtech.api.items.metaitem.FilteredFluidStats;
+import gregtech.api.items.metaitem.FoodStats;
+import gregtech.api.items.metaitem.MusicDiscStats;
+import gregtech.api.items.metaitem.StandardMetaItem;
 import gregtech.api.items.metaitem.stats.IItemComponent;
 import gregtech.api.items.metaitem.stats.IItemContainerItemProvider;
 import gregtech.api.items.metaitem.stats.ItemFluidContainer;
@@ -22,8 +26,27 @@
 import gregtech.api.util.RandomPotionEffect;
 import gregtech.common.ConfigHolder;
 import gregtech.common.blocks.MetaBlocks;
+import gregtech.common.creativetab.GTCreativeTabs;
 import gregtech.common.entities.GTBoatEntity.GTBoatType;
-import gregtech.common.items.behaviors.*;
+import gregtech.common.items.behaviors.ClipboardBehavior;
+import gregtech.common.items.behaviors.ColorSprayBehaviour;
+import gregtech.common.items.behaviors.DataItemBehavior;
+import gregtech.common.items.behaviors.DoorBehavior;
+import gregtech.common.items.behaviors.DynamiteBehaviour;
+import gregtech.common.items.behaviors.FacadeItem;
+import gregtech.common.items.behaviors.FertilizerBehavior;
+import gregtech.common.items.behaviors.FoamSprayerBehavior;
+import gregtech.common.items.behaviors.GTBoatBehavior;
+import gregtech.common.items.behaviors.IntCircuitBehaviour;
+import gregtech.common.items.behaviors.ItemMagnetBehavior;
+import gregtech.common.items.behaviors.LighterBehaviour;
+import gregtech.common.items.behaviors.MultiblockBuilderBehavior;
+import gregtech.common.items.behaviors.NanoSaberBehavior;
+import gregtech.common.items.behaviors.ProspectorScannerBehavior;
+import gregtech.common.items.behaviors.TerminalBehaviour;
+import gregtech.common.items.behaviors.TooltipBehavior;
+import gregtech.common.items.behaviors.TricorderBehavior;
+import gregtech.common.items.behaviors.TurbineRotorBehavior;
 import gregtech.common.items.behaviors.monitorplugin.AdvancedMonitorPluginBehavior;
 import gregtech.common.items.behaviors.monitorplugin.FakeGuiPluginBehavior;
 import gregtech.common.items.behaviors.monitorplugin.OnlinePicPluginBehavior;
@@ -149,53 +172,53 @@ public void registerSubItems() {
         // out of registry order so it can reference the Empty Spray Can
         SPRAY_SOLVENT = addItem(60, "spray.solvent").setMaxStackSize(1)
                 .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 1024, -1))
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         for (int i = 0; i < EnumDyeColor.values().length; i++) {
             SPRAY_CAN_DYES[i] = addItem(62 + i, "spray.can.dyes." + EnumDyeColor.values()[i].getName())
                     .setMaxStackSize(1)
                     .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 512, i))
-                    .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                    .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         }
 
         // Fluid Cells: ID 78-88
         FLUID_CELL = addItem(78, "fluid_cell")
                 .addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, false),
                         new ItemFluidContainer())
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         FLUID_CELL_UNIVERSAL = addItem(79, "fluid_cell.universal")
                 .addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, true),
                         new ItemFluidContainer())
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         FLUID_CELL_LARGE_STEEL = addItem(80, "large_fluid_cell.steel")
                 .addComponents(new FilteredFluidStats(8000,
                         Materials.Steel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false,
                         false, false, true), new ItemFluidContainer())
                 .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Steel, M * 4))) // ingot * 4
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         FLUID_CELL_LARGE_ALUMINIUM = addItem(81, "large_fluid_cell.aluminium")
                 .addComponents(new FilteredFluidStats(32000,
                         Materials.Aluminium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false,
                         false, false, true), new ItemFluidContainer())
                 .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Aluminium, M * 4))) // ingot * 4
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         FLUID_CELL_LARGE_STAINLESS_STEEL = addItem(82, "large_fluid_cell.stainless_steel")
                 .addComponents(new FilteredFluidStats(64000,
                         Materials.StainlessSteel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true,
                         true, true, false, true), new ItemFluidContainer())
                 .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.StainlessSteel, M * 6))) // ingot * 6
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         FLUID_CELL_LARGE_TITANIUM = addItem(83, "large_fluid_cell.titanium")
                 .addComponents(new FilteredFluidStats(128000,
                         Materials.Titanium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, true,
                         false, false, true), new ItemFluidContainer())
                 .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Titanium, M * 6))) // ingot * 6
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         FLUID_CELL_LARGE_TUNGSTEN_STEEL = addItem(84, "large_fluid_cell.tungstensteel")
                 .addComponents(new FilteredFluidStats(512000,
@@ -203,36 +226,36 @@ public void registerSubItems() {
                         true, false, false, true), new ItemFluidContainer())
                 .setMaxStackSize(32)
                 .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.TungstenSteel, M * 8))) // ingot * 8
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         FLUID_CELL_GLASS_VIAL = addItem(85, "fluid_cell.glass_vial")
                 .addComponents(new FilteredFluidStats(1000, 1200, false, true, false, false, true),
                         new ItemFluidContainer())
                 .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Glass, M / 4))) // small dust
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         // Limited-Use Items: ID 89-95
 
         TOOL_MATCHES = addItem(89, "tool.matches")
                 .addComponents(new LighterBehaviour(false, false, false))
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         TOOL_MATCHBOX = addItem(90, "tool.matchbox")
                 .addComponents(new LighterBehaviour(false, true, false, Items.PAPER, 16))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         TOOL_LIGHTER_INVAR = addItem(91, "tool.lighter.invar")
                 .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Invar, M * 2)))
                 .addComponents(new LighterBehaviour(GTUtility.gregtechId("lighter_open"), true, true, true))
                 .addComponents(new FilteredFluidStats(100, true, CommonFluidFilters.LIGHTER_FUEL))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         TOOL_LIGHTER_PLATINUM = addItem(92, "tool.lighter.platinum")
                 .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Platinum, M * 2)))
                 .addComponents(new LighterBehaviour(GTUtility.gregtechId("lighter_open"), true, true, true))
                 .addComponents(new FilteredFluidStats(1000, true, CommonFluidFilters.LIGHTER_FUEL))
                 .setMaxStackSize(1)
                 .setRarity(EnumRarity.UNCOMMON)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         BOTTLE_PURPLE_DRINK = addItem(93, "bottle.purple.drink").addComponents(new FoodStats(8, 0.2F, true, true,
                 new ItemStack(Items.GLASS_BOTTLE), new RandomPotionEffect(MobEffects.HASTE, 800, 1, 90)));
@@ -737,69 +760,69 @@ public void registerSubItems() {
         // Usable Items: ID 460-490
         DYNAMITE = addItem(460, "dynamite")
                 .addComponents(new DynamiteBehaviour())
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         INTEGRATED_CIRCUIT = addItem(461, "circuit.integrated").addComponents(new IntCircuitBehaviour())
                 .setModelAmount(33);
         FOAM_SPRAYER = addItem(462, "foam_sprayer").addComponents(new FoamSprayerBehavior())
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         NANO_SABER = addItem(463, "nano_saber").addComponents(ElectricStats.createElectricItem(4_000_000L, GTValues.HV))
                 .addComponents(new NanoSaberBehavior())
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         NANO_SABER.getMetaItem().addPropertyOverride(NanoSaberBehavior.OVERRIDE_KEY_LOCATION,
                 (stack, worldIn, entityIn) -> NanoSaberBehavior.isItemActive(stack) ? 1.0f : 0.0f);
 
         CLIPBOARD = addItem(464, "clipboard")
                 .addComponents(new ClipboardBehavior())
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         TERMINAL = addItem(465, "terminal")
                 .addComponents(new HardwareProvider(), new TerminalBehaviour())
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         PROSPECTOR_LV = addItem(466, "prospector.lv")
                 .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.LV),
                         new ProspectorScannerBehavior(2, GTValues.LV))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         PROSPECTOR_HV = addItem(467, "prospector.hv")
                 .addComponents(ElectricStats.createElectricItem(1_600_000L, GTValues.HV),
                         new ProspectorScannerBehavior(3, GTValues.HV))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         PROSPECTOR_LUV = addItem(468, "prospector.luv")
                 .addComponents(ElectricStats.createElectricItem(1_000_000_000L, GTValues.LuV),
                         new ProspectorScannerBehavior(5, GTValues.LuV))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         TRICORDER_SCANNER = addItem(469, "tricorder_scanner")
                 .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.MV), new TricorderBehavior(2))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         DEBUG_SCANNER = addItem(470, "debug_scanner")
                 .addComponents(new TricorderBehavior(3))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         ITEM_MAGNET_LV = addItem(471, "item_magnet.lv")
                 .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.LV), new ItemMagnetBehavior(8))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         ITEM_MAGNET_HV = addItem(472, "item_magnet.hv")
                 .addComponents(ElectricStats.createElectricItem(1_600_000L, GTValues.HV), new ItemMagnetBehavior(32))
                 .setMaxStackSize(1)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         RUBBER_WOOD_BOAT = addItem(473, "rubber_wood_boat")
                 .addComponents(new GTBoatBehavior(GTBoatType.RUBBER_WOOD_BOAT)).setMaxStackSize(1).setBurnValue(400);
         TREATED_WOOD_BOAT = addItem(474, "treated_wood_boat")
                 .addComponents(new GTBoatBehavior(GTBoatType.TREATED_WOOD_BOAT)).setMaxStackSize(1).setBurnValue(400);
         RUBBER_WOOD_DOOR = addItem(475, "rubber_wood_door").addComponents(new DoorBehavior(MetaBlocks.RUBBER_WOOD_DOOR))
-                .setBurnValue(200).setCreativeTabs(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+                .setBurnValue(200).setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
         TREATED_WOOD_DOOR = addItem(476, "treated_wood_door")
                 .addComponents(new DoorBehavior(MetaBlocks.TREATED_WOOD_DOOR)).setBurnValue(200)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_DECORATIONS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_DECORATIONS);
 
         // Misc Crafting Items: ID 491-515
         ENERGIUM_DUST = addItem(491, "energium_dust");
@@ -976,105 +999,105 @@ public void registerSubItems() {
         // Batteries: 731-775
         BATTERY_ULV_TANTALUM = addItem(731, "battery.re.ulv.tantalum")
                 .addComponents(ElectricStats.createRechargeableBattery(1000, GTValues.ULV))
-                .setUnificationData(OrePrefix.battery, Tier.ULV).setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setUnificationData(OrePrefix.battery, Tier.ULV).setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         BATTERY_LV_SODIUM = addItem(732, "battery.re.lv.sodium")
                 .addComponents(ElectricStats.createRechargeableBattery(80000, GTValues.LV))
                 .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_MV_SODIUM = addItem(733, "battery.re.mv.sodium")
                 .addComponents(ElectricStats.createRechargeableBattery(360000, GTValues.MV))
                 .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_HV_SODIUM = addItem(734, "battery.re.hv.sodium")
                 .addComponents(ElectricStats.createRechargeableBattery(1200000, GTValues.HV))
                 .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         BATTERY_LV_LITHIUM = addItem(735, "battery.re.lv.lithium")
                 .addComponents(ElectricStats.createRechargeableBattery(120000, GTValues.LV))
                 .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_MV_LITHIUM = addItem(736, "battery.re.mv.lithium")
                 .addComponents(ElectricStats.createRechargeableBattery(420000, GTValues.MV))
                 .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_HV_LITHIUM = addItem(737, "battery.re.hv.lithium")
                 .addComponents(ElectricStats.createRechargeableBattery(1800000, GTValues.HV))
                 .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         BATTERY_LV_CADMIUM = addItem(738, "battery.re.lv.cadmium")
                 .addComponents(ElectricStats.createRechargeableBattery(100000, GTValues.LV))
                 .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_MV_CADMIUM = addItem(739, "battery.re.mv.cadmium")
                 .addComponents(ElectricStats.createRechargeableBattery(400000, GTValues.MV))
                 .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_HV_CADMIUM = addItem(740, "battery.re.hv.cadmium")
                 .addComponents(ElectricStats.createRechargeableBattery(1600000, GTValues.HV))
                 .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         ENERGIUM_CRYSTAL = addItem(741, "energy_crystal")
                 .addComponents(ElectricStats.createRechargeableBattery(6_400_000L, GTValues.HV))
                 .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         LAPOTRON_CRYSTAL = addItem(742, "lapotron_crystal")
                 .addComponents(ElectricStats.createRechargeableBattery(25_000_000L, GTValues.EV))
                 .setUnificationData(OrePrefix.battery, Tier.EV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         BATTERY_EV_VANADIUM = addItem(743, "battery.ev.vanadium")
                 .addComponents(ElectricStats.createRechargeableBattery(10_240_000L, GTValues.EV))
                 .setUnificationData(OrePrefix.battery, Tier.EV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_IV_VANADIUM = addItem(744, "battery.iv.vanadium")
                 .addComponents(ElectricStats.createRechargeableBattery(40_960_000L, GTValues.IV))
                 .setUnificationData(OrePrefix.battery, Tier.IV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_LUV_VANADIUM = addItem(745, "battery.luv.vanadium")
                 .addComponents(ElectricStats.createRechargeableBattery(163_840_000L, GTValues.LuV))
                 .setUnificationData(OrePrefix.battery, Tier.LuV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         BATTERY_ZPM_NAQUADRIA = addItem(746, "battery.zpm.naquadria")
                 .addComponents(ElectricStats.createRechargeableBattery(655_360_000L, GTValues.ZPM))
                 .setUnificationData(OrePrefix.battery, Tier.ZPM).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         BATTERY_UV_NAQUADRIA = addItem(747, "battery.uv.naquadria")
                 .addComponents(ElectricStats.createRechargeableBattery(2_621_440_000L, GTValues.UV))
                 .setUnificationData(OrePrefix.battery, Tier.UV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         ENERGY_LAPOTRONIC_ORB = addItem(748, "energy.lapotronic_orb")
                 .addComponents(ElectricStats.createRechargeableBattery(250_000_000L, GTValues.IV))
                 .setUnificationData(OrePrefix.battery, Tier.IV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         ENERGY_LAPOTRONIC_ORB_CLUSTER = addItem(749, "energy.lapotronic_orb_cluster")
                 .addComponents(ElectricStats.createRechargeableBattery(1_000_000_000L, GTValues.LuV))
                 .setUnificationData(OrePrefix.battery, Tier.LuV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         ENERGY_MODULE = addItem(750, "energy.module")
                 .addComponents(
                         new IItemComponent[] { ElectricStats.createRechargeableBattery(4_000_000_000L, GTValues.ZPM) })
                 .setUnificationData(OrePrefix.battery, Tier.ZPM).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         ENERGY_CLUSTER = addItem(751, "energy.cluster")
                 .addComponents(
                         new IItemComponent[] { ElectricStats.createRechargeableBattery(20_000_000_000L, GTValues.UV) })
                 .setUnificationData(OrePrefix.battery, Tier.UV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         ZERO_POINT_MODULE = addItem(752, "zpm")
                 .addComponents(ElectricStats.createBattery(2000000000000L, GTValues.ZPM, true)).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
         ULTIMATE_BATTERY = addItem(753, "max.battery")
                 .addComponents(ElectricStats.createRechargeableBattery(Long.MAX_VALUE, GTValues.UHV))
                 .setUnificationData(OrePrefix.battery, Tier.UHV).setModelAmount(8)
-                .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS);
+                .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
 
         POWER_THRUSTER = addItem(776, "power_thruster").setRarity(EnumRarity.UNCOMMON);
         POWER_THRUSTER_ADVANCED = addItem(777, "power_thruster_advanced").setRarity(EnumRarity.RARE);
diff --git a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java
index d384e22e608..7c8c2e153d4 100644
--- a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java
+++ b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java
@@ -1,6 +1,5 @@
 package gregtech.common.pipelike.cable;
 
-import gregtech.api.GregTechAPI;
 import gregtech.api.capability.GregtechCapabilities;
 import gregtech.api.damagesources.DamageSources;
 import gregtech.api.items.toolitem.ToolClasses;
@@ -14,6 +13,7 @@
 import gregtech.api.util.GTUtility;
 import gregtech.client.renderer.pipe.CableRenderer;
 import gregtech.client.renderer.pipe.PipeRenderer;
+import gregtech.common.creativetab.GTCreativeTabs;
 import gregtech.common.pipelike.cable.net.WorldENet;
 import gregtech.common.pipelike.cable.tile.TileEntityCable;
 import gregtech.common.pipelike.cable.tile.TileEntityCableTickable;
@@ -54,7 +54,7 @@ public class BlockCable extends BlockMaterialPipe
Date: Fri, 12 Jan 2024 08:03:59 +0900
Subject: [PATCH 41/98] Make translation key of MetaItems modifiable (#2259)

Co-authored-by: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com>
---
 .../gregtech/api/items/metaitem/MetaItem.java | 56 +++++++++++++------
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java
index f4cedc0f729..4fd8b940a93 100644
--- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java
+++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java
@@ -94,21 +94,21 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 
 /**
- * MetaItem is item that can have up to Short.MAX_VALUE items inside one id.
- * These items even can be edible, have custom behaviours, be electric or act like fluid containers!
- * They can also have different burn time, plus be handheld, oredicted or invisible!
- * They also can be reactor components.
+ * MetaItem is item that can have up to Short.MAX_VALUE items inside one id. These items even can be edible, have custom
+ * behaviours, be electric or act like fluid containers! They can also have different burn time, plus be handheld,
+ * oredicted or invisible! They also can be reactor components.
  * 

* You can also extend this class and occupy some of it's MetaData, and just pass an meta offset in constructor, and * everything will work properly. *

* Items are added in MetaItem via {@link #addItem(int, String)}. You will get {@link MetaValueItem} instance, which you * can configure in builder-alike pattern: - * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } - * This will add single-use (not rechargeable) LV battery with initial capacity 10000 EU + * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } This will add single-use (not + * rechargeable) LV battery with initial capacity 10000 EU */ @Optional.Interface(modid = GTValues.MODID_ECORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") public abstract class MetaItem.MetaValueItem> extends Item @@ -132,8 +132,9 @@ public static List> getMetaItems() { private CreativeTabs[] defaultCreativeTabs = new CreativeTabs[] { GTCreativeTabs.TAB_GREGTECH }; private final Set additionalCreativeTabs = new ObjectArraySet<>(); + private String translationKey = "metaitem"; + public MetaItem(short metaItemOffset) { - setTranslationKey("meta_item"); setHasSubtypes(true); this.metaItemOffset = metaItemOffset; META_ITEMS.add(this); @@ -376,6 +377,7 @@ public void onPlayerStoppedUsing(@NotNull ItemStack stack, @NotNull World world, } } + @NotNull @Override public ItemStack onItemUseFinish(@NotNull ItemStack stack, @NotNull World world, @NotNull EntityLivingBase player) { if (player instanceof EntityPlayer) { @@ -549,10 +551,28 @@ public boolean shouldCauseReequipAnimation(@NotNull ItemStack oldStack, @NotNull return !ItemStack.areItemStacksEqual(oldStack, newStack); } + @NotNull @Override - public String getTranslationKey(ItemStack stack) { - T metaItem = getItem(stack); - return metaItem == null ? getTranslationKey() : getTranslationKey() + "." + metaItem.unlocalizedName; + public MetaItem setTranslationKey(@NotNull String key) { + this.translationKey = Objects.requireNonNull(key, "key == null"); + return this; + } + + @NotNull + @Override + public String getTranslationKey() { + return getTranslationKey((T) null); + } + + @NotNull + @Override + public String getTranslationKey(@NotNull ItemStack stack) { + return getTranslationKey(getItem(stack)); + } + + @NotNull + protected String getTranslationKey(@Nullable T metaValueItem) { + return metaValueItem == null ? this.translationKey : this.translationKey + "." + metaValueItem.unlocalizedName; } @NotNull @@ -563,7 +583,7 @@ public String getItemStackDisplayName(ItemStack stack) { if (item == null) { return "invalid item"; } - String unlocalizedName = String.format("metaitem.%s.name", item.unlocalizedName); + String unlocalizedName = getTranslationKey(item) + ".name"; if (item.getNameProvider() != null) { return item.getNameProvider().getItemStackDisplayName(stack, unlocalizedName); } @@ -586,7 +606,7 @@ public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn @NotNull ITooltipFlag tooltipFlag) { T item = getItem(itemStack); if (item == null) return; - String unlocalizedTooltip = "metaitem." + item.unlocalizedName + ".tooltip"; + String unlocalizedTooltip = getTranslationKey(item) + ".tooltip"; if (I18n.hasKey(unlocalizedTooltip)) { Collections.addAll(lines, LocalizationUtils.formatLines(unlocalizedTooltip)); } @@ -682,25 +702,27 @@ public ItemStack getContainerItem(@NotNull ItemStack itemStack) { @NotNull @Override - public CreativeTabs[] getCreativeTabs() { + public CreativeTabs @NotNull [] getCreativeTabs() { if (additionalCreativeTabs.isEmpty()) return defaultCreativeTabs; // short circuit Set tabs = new ObjectArraySet<>(additionalCreativeTabs); tabs.addAll(Arrays.asList(defaultCreativeTabs)); return tabs.toArray(new CreativeTabs[0]); } + @NotNull @Override - public MetaItem setCreativeTab(CreativeTabs tab) { + public MetaItem setCreativeTab(@NotNull CreativeTabs tab) { this.defaultCreativeTabs = new CreativeTabs[] { tab }; return this; } - public MetaItem setCreativeTabs(CreativeTabs... tabs) { + @NotNull + public MetaItem setCreativeTabs(@NotNull CreativeTabs @NotNull... tabs) { this.defaultCreativeTabs = tabs; return this; } - public void addAdditionalCreativeTabs(CreativeTabs... tabs) { + public void addAdditionalCreativeTabs(@NotNull CreativeTabs @NotNull... tabs) { for (CreativeTabs tab : tabs) { if (!ArrayUtils.contains(defaultCreativeTabs, tab) && tab != CreativeTabs.SEARCH) { additionalCreativeTabs.add(tab); @@ -709,7 +731,7 @@ public void addAdditionalCreativeTabs(CreativeTabs... tabs) { } @Override - protected boolean isInCreativeTab(CreativeTabs tab) { + protected boolean isInCreativeTab(@NotNull CreativeTabs tab) { return tab == CreativeTabs.SEARCH || ArrayUtils.contains(defaultCreativeTabs, tab) || additionalCreativeTabs.contains(tab); From e0434c7077b4e23df04d9e58d1e9f29f77732084 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sat, 13 Jan 2024 22:39:15 -0600 Subject: [PATCH 42/98] Update build script version to 1705076830 (#2344) Co-authored-by: DStrand1 --- build.gradle | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ebae36cf19e..f4c0964bd89 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1704659416 +//version: 1705076830 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -24,7 +24,7 @@ plugins { id 'eclipse' id 'maven-publish' id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7' - id 'com.gtnewhorizons.retrofuturagradle' version '1.3.25' + id 'com.gtnewhorizons.retrofuturagradle' version '1.3.28' id 'net.darkhax.curseforgegradle' version '1.1.17' apply false id 'com.modrinth.minotaur' version '2.8.6' apply false id 'com.diffplug.spotless' version '6.13.0' apply false @@ -541,6 +541,12 @@ pluginManager.withPlugin('org.jetbrains.kotlin.kapt') { } } +configurations.configureEach { + resolutionStrategy.dependencySubstitution { + substitute module('org.scala-lang:scala-library:2.11.1') using module('org.scala-lang:scala-library:2.11.5') because('To allow mixing with Java 8 targets') + } +} + if (getFile('dependencies.gradle').exists()) { apply from: 'dependencies.gradle' } else if (getFile('dependencies.gradle.kts').exists()) { From 9022c0f16699228d98bb9f4ea7c689827c337024 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Sat, 13 Jan 2024 22:52:49 -0600 Subject: [PATCH 43/98] Overload AbstractRecipeLogic functions (#2311) Co-authored-by: alongstringofnumbers --- .../capability/impl/AbstractRecipeLogic.java | 63 ++++++++++++++++--- .../LargeTurbineWorkableHandler.java | 2 +- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index cc2ce878aee..e00cdc21235 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -1,7 +1,11 @@ package gregtech.api.capability.impl; import gregtech.api.GTValues; -import gregtech.api.capability.*; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IMultiblockController; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.capability.IWorkable; import gregtech.api.metatileentity.MTETrait; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.multiblock.CleanroomType; @@ -432,34 +436,53 @@ protected boolean checkCleanroomRequirement(@NotNull Recipe recipe) { *

    *
  1. The recipe is run in parallel if possible.
  2. *
  3. The potentially parallel recipe is then checked to exist.
  4. - *
  5. If it exists, it checks if the recipe is runnable with the current inputs.
  6. + *
  7. If it exists, it checks if the recipe is runnable with the inputs provided.
  8. *
* If the above conditions are met, the recipe is engaged to be run * - * @param recipe the recipe to prepare + * @param recipe the recipe to prepare + * @param inputInventory the inventory to draw items from + * @param inputFluidInventory the fluid tanks to draw fluid from * @return true if the recipe was successfully prepared, else false */ - protected boolean prepareRecipe(Recipe recipe) { + public boolean prepareRecipe(Recipe recipe, IItemHandlerModifiable inputInventory, + IMultipleTankHandler inputFluidInventory) { recipe = Recipe.trimRecipeOutputs(recipe, getRecipeMap(), metaTileEntity.getItemOutputLimit(), metaTileEntity.getFluidOutputLimit()); // Pass in the trimmed recipe to the parallel logic recipe = findParallelRecipe( recipe, - getInputInventory(), - getInputTank(), + inputInventory, + inputFluidInventory, getOutputInventory(), getOutputTank(), getMaxParallelVoltage(), getParallelLimit()); - if (recipe != null && setupAndConsumeRecipeInputs(recipe, getInputInventory())) { + if (recipe != null && setupAndConsumeRecipeInputs(recipe, inputInventory, inputFluidInventory)) { setupRecipe(recipe); return true; } return false; } + /** + * Prepares the recipe to be run. + *
    + *
  1. The recipe is run in parallel if possible.
  2. + *
  3. The potentially parallel recipe is then checked to exist.
  4. + *
  5. If it exists, it checks if the recipe is runnable with the current inputs.
  6. + *
+ * If the above conditions are met, the recipe is engaged to be run + * + * @param recipe the recipe to prepare + * @return true if the recipe was successfully prepared from the default inventory, else false + */ + public boolean prepareRecipe(Recipe recipe) { + return prepareRecipe(recipe, getInputInventory(), getInputTank()); + } + /** * DO NOT use the parallelLimit field directly, EVER * @@ -549,11 +572,14 @@ protected static boolean areItemStacksEqual(@NotNull ItemStack stackA, @NotNull * @param recipe - The Recipe that will be consumed from the inputs and ran in the machine * @param importInventory - The inventory that the recipe should be consumed from. * Used mainly for Distinct bus implementation for multiblocks to specify - * a specific bus + * a specific bus, or for addons to use external inventories. + * @param importFluids - The tanks that the recipe should be consumed from + * Used currently in addons to use external tanks. * @return - true if the recipe is successful, false if the recipe is not successful */ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, - @NotNull IItemHandlerModifiable importInventory) { + @NotNull IItemHandlerModifiable importInventory, + @NotNull IMultipleTankHandler importFluids) { this.overclockResults = calculateOverclock(recipe); modifyOverclockPost(overclockResults, recipe.getRecipePropertyStorage()); @@ -563,7 +589,6 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, } IItemHandlerModifiable exportInventory = getOutputInventory(); - IMultipleTankHandler importFluids = getInputTank(); IMultipleTankHandler exportFluids = getOutputTank(); // We have already trimmed outputs and chanced outputs at this time @@ -589,6 +614,24 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, return false; } + /** + * Determines if the provided recipe is possible to run from the provided inventory, or if there is anything + * preventing + * the Recipe from being completed. + *

+ * Will consume the inputs of the Recipe if it is possible to run. + * + * @param recipe - The Recipe that will be consumed from the inputs and ran in the machine + * @param importInventory - The inventory that the recipe should be consumed from. + * Used mainly for Distinct bus implementation for multiblocks to specify + * a specific bus + * @return - true if the recipe is successful, false if the recipe is not successful + */ + protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory) { + return setupAndConsumeRecipeInputs(recipe, importInventory, this.getInputTank()); + } + /** * @param resultOverclock the overclock data to use. Format: {@code [EUt, duration]}. * @return true if there is enough energy to continue recipe progress diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java index db414ae4da7..f9f393216e6 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java @@ -131,7 +131,7 @@ protected boolean checkPreviousRecipe() { } @Override - protected boolean prepareRecipe(Recipe recipe) { + public boolean prepareRecipe(Recipe recipe) { IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder(); if (rotorHolder == null || !rotorHolder.hasRotor()) return false; From 3e0835e98de8745753d7fd374186f2dd74128bce Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Sat, 13 Jan 2024 23:01:55 -0600 Subject: [PATCH 44/98] Fix erroring material handlers when liquids don't exist (#2343) --- .../material/properties/FluidProperty.java | 34 +++++++++++++++++++ .../handlers/MaterialRecipeHandler.java | 13 +++---- .../recipe/handlers/PartsRecipeHandler.java | 13 +++---- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java index 48f92084252..80c971fb4f1 100644 --- a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java @@ -2,6 +2,10 @@ import gregtech.api.fluids.store.FluidStorage; import gregtech.api.fluids.store.FluidStorageKey; +import gregtech.api.fluids.store.FluidStorageKeys; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -10,6 +14,7 @@ public class FluidProperty implements IMaterialProperty { private final FluidStorage storage = new FluidStorage(); private @Nullable FluidStorageKey primaryKey = null; + private @Nullable Fluid solidifyingFluid = null; public FluidProperty() {} @@ -33,4 +38,33 @@ public void setPrimaryKey(@Nullable FluidStorageKey primaryKey) { @Override public void verifyProperty(MaterialProperties properties) {} + + /** + * @return the Fluid which solidifies into the material. + */ + + public Fluid solidifiesFrom() { + if (this.solidifyingFluid == null) { + return getStorage().get(FluidStorageKeys.LIQUID); + } + return solidifyingFluid; + } + + /** + * @param amount the size of the returned FluidStack. + * @return a FluidStack of the Fluid which solidifies into the material. + */ + public FluidStack solidifiesFrom(int amount) { + return new FluidStack(solidifiesFrom(), amount); + } + + /** + * Sets the fluid that solidifies into the material. + * + * @param solidifyingFluid The Fluid which solidifies into the material. If left null, it will be left as the + * default value: the material's liquid. + */ + public void setSolidifyingFluid(@Nullable Fluid solidifyingFluid) { + this.solidifyingFluid = solidifyingFluid; + } } diff --git a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java index ac915b45dc7..74239ff12ae 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java @@ -286,10 +286,10 @@ public static void processIngot(OrePrefix ingotPrefix, Material material, IngotP } } - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_INGOT) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(ingotPrefix, material)) .duration(20).EUt(VA[ULV]) .buildAndRegister(); @@ -424,10 +424,10 @@ public static void processNugget(OrePrefix orePrefix, Material material, DustPro .output(ingot, material) .buildAndRegister(); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_NUGGET) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(orePrefix, material, 9)) .duration((int) material.getMass()) .EUt(VA[ULV]) @@ -465,10 +465,11 @@ public static void processFrame(OrePrefix framePrefix, Material material, DustPr public static void processBlock(OrePrefix blockPrefix, Material material, DustProperty property) { ItemStack blockStack = OreDictUnifier.get(blockPrefix, material); long materialAmount = blockPrefix.getMaterialAmount(material); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_BLOCK) - .fluidInputs(material.getFluid((int) (materialAmount * L / M))) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom( + ((int) (materialAmount * L / M)))) .outputs(blockStack) .duration((int) material.getMass()).EUt(VA[ULV]) .buildAndRegister(); diff --git a/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java index 24ec5349133..ddff63fd34a 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java @@ -200,11 +200,12 @@ public static void processGear(OrePrefix gearPrefix, Material material, DustProp } } - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { boolean isSmall = gearPrefix == OrePrefix.gearSmall; RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(isSmall ? MetaItems.SHAPE_MOLD_GEAR_SMALL : MetaItems.SHAPE_MOLD_GEAR) - .fluidInputs(material.getFluid(L * (isSmall ? 1 : 4))) + .fluidInputs( + material.getProperty(PropertyKey.FLUID).solidifiesFrom(L * (isSmall ? 1 : 4))) .outputs(stack) .duration(isSmall ? 20 : 100) .EUt(VA[ULV]) @@ -285,10 +286,10 @@ public static void processLens(OrePrefix lensPrefix, Material material, GemPrope } public static void processPlate(OrePrefix platePrefix, Material material, DustProperty property) { - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_PLATE) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(platePrefix, material)) .duration(40) .EUt(VA[ULV]) @@ -399,10 +400,10 @@ public static void processRotor(OrePrefix rotorPrefix, Material material, IngotP 'S', new UnificationEntry(screw, material), 'R', new UnificationEntry(ring, material)); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_ROTOR) - .fluidInputs(material.getFluid(L * 4)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L * 4)) .outputs(GTUtility.copy(stack)) .duration(120) .EUt(20) From 06a31af59ded8b819f52d9b41579dccdb2937460 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:09:24 -0600 Subject: [PATCH 45/98] Fix reservoir hatch issues (#2349) --- .../MetaTileEntityReservoirHatch.java | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java index 9981538731d..e8cf6d7b59b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java @@ -63,7 +63,6 @@ public void update() { super.update(); if (!getWorld().isRemote) { fillContainerFromInternalTank(fluidTank); - fillInternalTankFromFluidContainer(fluidTank); if (getOffsetTimer() % 20 == 0) { fluidTank.refillWater(); } @@ -129,7 +128,7 @@ public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, Entity // Add input/output-specific widgets tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, true); + .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, false); builder.image(7, 16, 81, 55, GuiTextures.DISPLAY) .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) @@ -180,47 +179,39 @@ public void addToolUsages(ItemStack stack, @Nullable World world, List t private static class InfiniteWaterTank extends NotifiableFluidTank { - private final FluidStack BIG_WATER = new FluidStack(FluidRegistry.WATER, FLUID_AMOUNT); - public InfiniteWaterTank(int capacity, MetaTileEntity entityToNotify) { super(capacity, entityToNotify, false); - setFluid(BIG_WATER); + // start with the full amount + setFluid(new FluidStack(FluidRegistry.WATER, FLUID_AMOUNT)); + // don't allow external callers to fill this tank + setCanFill(false); } private void refillWater() { - if (BIG_WATER.amount != FLUID_AMOUNT) { - BIG_WATER.amount = FLUID_AMOUNT; - onContentsChanged(); + int fillAmount = Math.max(0, FLUID_AMOUNT - getFluidAmount()); + if (fillAmount > 0) { + // call super since our overrides don't allow any kind of filling + super.fillInternal(new FluidStack(FluidRegistry.WATER, fillAmount), true); } } @Override - public FluidStack drainInternal(int maxDrain, boolean doDrain) { - return new FluidStack(BIG_WATER, maxDrain); - } - - @Nullable - @Override - public FluidStack drainInternal(FluidStack resource, boolean doDrain) { - return new FluidStack(BIG_WATER, resource.amount); + public boolean canDrainFluidType(@Nullable FluidStack fluid) { + return fluid != null && fluid.getFluid() == FluidRegistry.WATER; } + // don't allow external filling @Override public int fillInternal(FluidStack resource, boolean doFill) { - return resource.amount; - } - - @Override - public boolean canDrainFluidType(@Nullable FluidStack fluid) { - return fluid != null && fluid.getFluid() == BIG_WATER.getFluid(); + return 0; } @Override public boolean canFillFluidType(FluidStack fluid) { - return fluid.getFluid() == BIG_WATER.getFluid(); + return false; } - // serialization is unnecessary here, it should always have the same amount of fluid + // serialization is unnecessary here, we can always recreate it completely full since it would refill anyway @Override public FluidTank readFromNBT(NBTTagCompound nbt) { return this; From b86e268cdbeaf44b9fa1e0249dfe6dc272adfd97 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:09:39 -0600 Subject: [PATCH 46/98] Fix LCE/ECE obstruction check (#2346) --- .../gregtech/api/util/RelativeDirection.java | 29 +++++++++++++++++++ .../MetaTileEntityLargeCombustionEngine.java | 23 ++++++++------- .../MetaTileEntityRotorHolder.java | 20 ++++++++----- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/main/java/gregtech/api/util/RelativeDirection.java b/src/main/java/gregtech/api/util/RelativeDirection.java index 1e4b2102761..c55db969ee4 100644 --- a/src/main/java/gregtech/api/util/RelativeDirection.java +++ b/src/main/java/gregtech/api/util/RelativeDirection.java @@ -163,4 +163,33 @@ public static EnumFacing simulateAxisRotation(EnumFacing newFrontFacing, EnumFac return upwardsFacing.getOpposite(); } } + + /** + * Offset a BlockPos relatively in any direction by any amount. Pass negative values to offset down, right or + * backwards. + */ + public static BlockPos offsetPos(BlockPos pos, EnumFacing frontFacing, EnumFacing upwardsFacing, boolean isFlipped, + int upOffset, int leftOffset, int forwardOffset) { + if (upOffset == 0 && leftOffset == 0 && forwardOffset == 0) { + return pos; + } + + int oX = 0, oY = 0, oZ = 0; + final EnumFacing relUp = UP.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relUp.getXOffset() * upOffset; + oY += relUp.getYOffset() * upOffset; + oZ += relUp.getZOffset() * upOffset; + + final EnumFacing relLeft = LEFT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relLeft.getXOffset() * leftOffset; + oY += relLeft.getYOffset() * leftOffset; + oZ += relLeft.getZOffset() * leftOffset; + + final EnumFacing relForward = FRONT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relForward.getXOffset() * forwardOffset; + oY += relForward.getYOffset() * forwardOffset; + oZ += relForward.getZOffset() * forwardOffset; + + return pos.add(oX, oY, oZ); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java index 4b298f25cd0..7d58be463fe 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java @@ -16,6 +16,7 @@ import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.RecipeMaps; import gregtech.api.unification.material.Materials; +import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.ICubeRenderer; @@ -28,7 +29,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; @@ -192,18 +192,19 @@ protected void formStructure(PatternMatchContext context) { } private boolean checkIntakesObstructed() { - EnumFacing facing = this.getFrontFacing(); - boolean permuteXZ = facing.getAxis() == EnumFacing.Axis.Z; - BlockPos centerPos = this.getPos().offset(facing); - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - // Skip the controller block itself - if (x == 0 && y == 0) + for (int left = -1; left <= 1; left++) { + for (int up = -1; up <= 1; up++) { + if (left == 0 && up == 0) { + // Skip the controller block itself continue; - BlockPos blockPos = centerPos.add(permuteXZ ? x : 0, y, permuteXZ ? 0 : x); - IBlockState blockState = this.getWorld().getBlockState(blockPos); - if (!blockState.getBlock().isAir(blockState, this.getWorld(), blockPos)) + } + + final BlockPos checkPos = RelativeDirection.offsetPos( + getPos(), getFrontFacing(), getUpwardsFacing(), isFlipped(), up, left, 1); + final IBlockState state = getWorld().getBlockState(checkPos); + if (!state.getBlock().isAir(state, getWorld(), checkPos)) { return true; + } } } return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java index e36b9bb24d4..d78b7fe5042 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java @@ -12,6 +12,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.RelativeDirection; import gregtech.client.renderer.texture.Textures; import gregtech.common.items.behaviors.AbstractMaterialPartBehavior; import gregtech.common.items.behaviors.TurbineRotorBehavior; @@ -163,14 +164,17 @@ public boolean isFrontFaceFree() { } private boolean checkTurbineFaceFree() { - EnumFacing facing = getFrontFacing(); - boolean permuteXZ = facing.getAxis() == EnumFacing.Axis.Z; - BlockPos centerPos = getPos().offset(facing); - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - BlockPos blockPos = centerPos.add(permuteXZ ? x : 0, y, permuteXZ ? 0 : x); - IBlockState blockState = getWorld().getBlockState(blockPos); - if (!blockState.getBlock().isAir(blockState, getWorld(), blockPos)) { + final EnumFacing front = getFrontFacing(); + // this can be anything really, as long as it is not up/down when on Y axis + final EnumFacing upwards = front.getAxis() == EnumFacing.Axis.Y ? EnumFacing.NORTH : EnumFacing.UP; + + for (int left = -1; left <= 1; left++) { + for (int up = -1; up <= 1; up++) { + // flip doesn't affect anything here since we are checking a square anyway + final BlockPos checkPos = RelativeDirection.offsetPos( + getPos(), front, upwards, false, up, left, 1); + final IBlockState state = getWorld().getBlockState(checkPos); + if (!state.getBlock().isAir(state, getWorld(), checkPos)) { return false; } } From 55106f1a1be2f9f8c57cc190e2994d9e0f4e3100 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:11:47 -0700 Subject: [PATCH 47/98] Fix electric tool damage config innacuracy (#2350) --- src/main/java/gregtech/api/items/toolitem/ToolHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java index 2e0a3335df0..23d3145ca9b 100644 --- a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java +++ b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java @@ -270,7 +270,7 @@ public static void damageItem(@NotNull ItemStack stack, @Nullable EntityLivingBa if (electricItem != null) { electricItem.discharge(electricDamage, tool.getElectricTier(), true, false, false); if (electricItem.getCharge() > 0 && - random.nextInt(100) > ConfigHolder.tools.rngDamageElectricTools) { + random.nextInt(100) >= ConfigHolder.tools.rngDamageElectricTools) { return; } } else { From add8fc15dc4094450776a55945ef03db1d650dbf Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:15:54 -0500 Subject: [PATCH 48/98] weaken recipe logic type in WorkableTieredMetaTileEntity (#2342) --- .../metatileentity/WorkableTieredMetaTileEntity.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java index 69c42322da8..5e648be0f60 100644 --- a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java @@ -1,7 +1,12 @@ package gregtech.api.metatileentity; import gregtech.api.GTValues; -import gregtech.api.capability.impl.*; +import gregtech.api.capability.impl.AbstractRecipeLogic; +import gregtech.api.capability.impl.EnergyContainerHandler; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.capability.impl.RecipeLogicEnergy; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.multiblock.ICleanroomProvider; import gregtech.api.metatileentity.multiblock.ICleanroomReceiver; @@ -34,7 +39,7 @@ public abstract class WorkableTieredMetaTileEntity extends TieredMetaTileEntity implements IDataInfoProvider, ICleanroomReceiver { - protected final RecipeLogicEnergy workable; + protected final AbstractRecipeLogic workable; protected final RecipeMap recipeMap; protected final ICubeRenderer renderer; @@ -63,7 +68,7 @@ public WorkableTieredMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap reinitializeEnergyContainer(); } - protected RecipeLogicEnergy createWorkable(RecipeMap recipeMap) { + protected AbstractRecipeLogic createWorkable(RecipeMap recipeMap) { return new RecipeLogicEnergy(this, recipeMap, () -> energyContainer); } From e2eebbcdd1f1aa7d0f63deed3ba3fddb3f1c320f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 18 Jan 2024 23:48:58 -0700 Subject: [PATCH 49/98] Fix Issues with Fusion Reactor Overclocking (#2352) --- .../multi/electric/MetaTileEntityFusionReactor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java index 90b8b70886c..35c06785bab 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java @@ -640,7 +640,7 @@ protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipeProper // MK3 reactor can overclock a MK2 recipe once, or a MK1 recipe twice. long euToStart = storage.getRecipePropertyValue(FusionEUToStartProperty.getInstance(), 0L); int fusionTier = FusionEUToStartProperty.getFusionTier(euToStart); - if (fusionTier != 0) fusionTier -= MetaTileEntityFusionReactor.this.tier; + if (fusionTier != 0) fusionTier = MetaTileEntityFusionReactor.this.tier - fusionTier; values[2] = Math.min(fusionTier, values[2]); } From b4f7e1702cdc046dc074ef545d2e1e7791297432 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 19 Jan 2024 14:14:04 -0600 Subject: [PATCH 50/98] Separate PSS average IO into in and out (#2353) --- .../MetaTileEntityPowerSubstation.java | 85 +++++++++++-------- .../specific/DriverPowerSubstation.java | 11 ++- .../resources/assets/gregtech/lang/en_us.lang | 6 +- 3 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java index c6ee87449d2..7814f3dccc9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java @@ -81,8 +81,10 @@ public class MetaTileEntityPowerSubstation extends MultiblockWithDisplayBase private boolean isActive, isWorkingEnabled = true; // Stats tracked for UI display - private long netIOLastSec; - private long averageIOLastSec; + private long netInLastSec; + private long averageInLastSec; + private long netOutLastSec; + private long averageOutLastSec; public MetaTileEntityPowerSubstation(ResourceLocation metaTileEntityId) { super(metaTileEntityId); @@ -138,8 +140,10 @@ public void invalidateStructure() { inputHatches = null; outputHatches = null; passiveDrain = 0; - netIOLastSec = 0; - averageIOLastSec = 0; + netInLastSec = 0; + averageInLastSec = 0; + netOutLastSec = 0; + averageOutLastSec = 0; super.invalidateStructure(); } @@ -149,25 +153,27 @@ protected void updateFormedValid() { if (getOffsetTimer() % 20 == 0) { // active here is just used for rendering setActive(energyBank.hasEnergy()); - averageIOLastSec = netIOLastSec / 20; - netIOLastSec = 0; + averageInLastSec = netInLastSec / 20; + averageOutLastSec = netOutLastSec / 20; + netInLastSec = 0; + netOutLastSec = 0; } if (isWorkingEnabled()) { // Bank from Energy Input Hatches long energyBanked = energyBank.fill(inputHatches.getEnergyStored()); inputHatches.changeEnergy(-energyBanked); - netIOLastSec += energyBanked; + netInLastSec += energyBanked; // Passive drain long energyPassiveDrained = energyBank.drain(getPassiveDrain()); - netIOLastSec -= energyPassiveDrained; + netOutLastSec += energyPassiveDrained; // Debank to Dynamo Hatches long energyDebanked = energyBank .drain(outputHatches.getEnergyCapacity() - outputHatches.getEnergyStored()); outputHatches.changeEnergy(energyDebanked); - netIOLastSec -= energyDebanked; + netOutLastSec += energyDebanked; } } } @@ -359,44 +365,45 @@ protected void addDisplayText(List textList) { "gregtech.multiblock.power_substation.passive_drain", passiveDrain)); - // Average I/O line - TextFormatting averageIOColor = TextFormatting.GRAY; - if (isActive() && isWorkingEnabled() && averageIOLastSec == 0) { - // only set to yellow on zero if the machine is on, avoids a yellow "warning" - // color when the machine is first formed and not yet plugged in. - averageIOColor = TextFormatting.YELLOW; - } else if (averageIOLastSec > 0) { - averageIOColor = TextFormatting.GREEN; - } else if (averageIOLastSec < 0) { - averageIOColor = TextFormatting.RED; - } - - ITextComponent averageIO = TextComponentUtil.stringWithColor( - averageIOColor, - TextFormattingUtil.formatNumbers(averageIOLastSec) + " EU/t"); - + // Average EU IN line + ITextComponent avgValue = TextComponentUtil.stringWithColor( + TextFormatting.GREEN, + TextFormattingUtil.formatNumbers(averageInLastSec) + " EU/t"); ITextComponent base = TextComponentUtil.translationWithColor( TextFormatting.GRAY, - "gregtech.multiblock.power_substation.average_io", - averageIO); - + "gregtech.multiblock.power_substation.average_in", + avgValue); ITextComponent hover = TextComponentUtil.translationWithColor( TextFormatting.GRAY, - "gregtech.multiblock.power_substation.average_io_hover"); + "gregtech.multiblock.power_substation.average_in_hover"); + tl.add(TextComponentUtil.setHover(base, hover)); + + // Average EU OUT line + avgValue = TextComponentUtil.stringWithColor( + TextFormatting.RED, + TextFormattingUtil.formatNumbers(averageOutLastSec) + " EU/t"); + base = TextComponentUtil.translationWithColor( + TextFormatting.GRAY, + "gregtech.multiblock.power_substation.average_out", + avgValue); + hover = TextComponentUtil.translationWithColor( + TextFormatting.GRAY, + "gregtech.multiblock.power_substation.average_out_hover"); tl.add(TextComponentUtil.setHover(base, hover)); // Time to fill/drain line - if (averageIOLastSec > 0) { + if (averageInLastSec > averageOutLastSec) { ITextComponent timeToFill = getTimeToFillDrainText(energyCapacity.subtract(energyStored) - .divide(BigInteger.valueOf(averageIOLastSec * 20))); + .divide(BigInteger.valueOf((averageInLastSec - averageOutLastSec) * 20))); TextComponentUtil.setColor(timeToFill, TextFormatting.GREEN); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, "gregtech.multiblock.power_substation.time_to_fill", timeToFill)); - } else if (averageIOLastSec < 0) { + } else if (averageInLastSec < averageOutLastSec) { ITextComponent timeToDrain = getTimeToFillDrainText( - energyStored.divide(BigInteger.valueOf(Math.abs(averageIOLastSec) * 20))); + energyStored.divide(BigInteger.valueOf( + (averageOutLastSec - averageInLastSec) * 20))); TextComponentUtil.setColor(timeToDrain, TextFormatting.RED); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, @@ -412,9 +419,9 @@ protected void addDisplayText(List textList) { protected void addWarningText(List textList) { super.addWarningText(textList); if (isStructureFormed()) { - if (averageIOLastSec < 0) { // decreasing + if (averageInLastSec < averageOutLastSec) { // decreasing BigInteger timeToDrainSeconds = energyBank.getStored() - .divide(BigInteger.valueOf(Math.abs(averageIOLastSec) * 20)); + .divide(BigInteger.valueOf((averageOutLastSec - averageInLastSec) * 20)); if (timeToDrainSeconds.compareTo(BigInteger.valueOf(60 * 60)) < 0) { // less than 1 hour left textList.add(TextComponentUtil.translationWithColor( TextFormatting.YELLOW, @@ -550,8 +557,12 @@ public String getCapacity() { return TextFormattingUtil.formatNumbers(energyBank.getCapacity()); } - public long getAverageIOLastSec() { - return averageIOLastSec; + public long getAverageInLastSec() { + return averageInLastSec; + } + + public long getAverageOutLastSec() { + return averageOutLastSec; } @Override diff --git a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java index 509de932b1b..53a506db55b 100644 --- a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java +++ b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java @@ -63,9 +63,14 @@ public Object[] getPassiveDrain(final Context context, final Arguments args) { return new Object[] { tileEntity.getPassiveDrain() }; } - @Callback(doc = "function():number -- Returns the average net EU/t in or out over the last second.") - public Object[] getAverageIOLastSec(final Context context, final Arguments args) { - return new Object[] { tileEntity.getAverageIOLastSec() }; + @Callback(doc = "function():number -- Returns the average EU/t in over the last second.") + public Object[] getAverageInLastSec(final Context context, final Arguments args) { + return new Object[] { tileEntity.getAverageInLastSec() }; + } + + @Callback(doc = "function():number -- Returns the average EU/t out over the last second.") + public Object[] getAverageOutLastSec(final Context context, final Arguments args) { + return new Object[] { tileEntity.getAverageOutLastSec() }; } } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index df5124812b5..12a9bba8f0d 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5647,8 +5647,10 @@ gregtech.multiblock.computation.not_enough_computation=Machine needs more comput gregtech.multiblock.power_substation.stored=Stored: %s gregtech.multiblock.power_substation.capacity=Capacity: %s gregtech.multiblock.power_substation.passive_drain=Passive Drain: %s -gregtech.multiblock.power_substation.average_io=Avg. I/O: %s -gregtech.multiblock.power_substation.average_io_hover=The average change in energy of the Power Substation's internal energy bank +gregtech.multiblock.power_substation.average_in=Avg. EU IN: %s +gregtech.multiblock.power_substation.average_out=Avg. EU OUT: %s +gregtech.multiblock.power_substation.average_in_hover=The average EU/t input into the Power Substation's internal energy bank +gregtech.multiblock.power_substation.average_out_hover=The average EU/t output from the Power Substation's internal energy bank, both passive loss and outputs gregtech.multiblock.power_substation.time_to_fill=Time to fill: %s gregtech.multiblock.power_substation.time_to_drain=Time to drain: %s gregtech.multiblock.power_substation.time_seconds=%s Seconds From 6ebe74dc8fd16ba6577477e3771ae61ba4fbca7f Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:46:14 -0500 Subject: [PATCH 51/98] fix gt tile entities not rendering in AE2 pattern outputs (#2319) --- src/main/java/gregtech/api/GTValues.java | 3 +- .../gregtech/api/util/ModCompatibility.java | 60 +------ .../java/gregtech/client/ClientProxy.java | 11 +- .../renderer/handler/CCLBlockRenderer.java | 10 +- .../renderer/handler/FacadeRenderer.java | 4 +- .../handler/MetaTileEntityRenderer.java | 4 +- .../client/renderer/pipe/PipeRenderer.java | 4 +- .../client/utils/ItemRenderCompat.java | 170 ++++++++++++++++++ 8 files changed, 199 insertions(+), 67 deletions(-) create mode 100644 src/main/java/gregtech/client/utils/ItemRenderCompat.java diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 7a1b5d34f4f..0d57fc6d5f9 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -158,7 +158,8 @@ public class GTValues { MODID_TCON = "tconstruct", MODID_PROJRED_CORE = "projectred-core", MODID_RC = "railcraft", - MODID_CHISEL = "chisel"; + MODID_CHISEL = "chisel", + MODID_RS = "refinedstorage"; private static Boolean isClient; diff --git a/src/main/java/gregtech/api/util/ModCompatibility.java b/src/main/java/gregtech/api/util/ModCompatibility.java index 9881948147d..d6b627d3b6a 100644 --- a/src/main/java/gregtech/api/util/ModCompatibility.java +++ b/src/main/java/gregtech/api/util/ModCompatibility.java @@ -1,66 +1,22 @@ package gregtech.api.util; -import gregtech.api.util.world.DummyWorld; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Objects; +import org.jetbrains.annotations.ApiStatus; @SideOnly(Side.CLIENT) public class ModCompatibility { - private static RefinedStorage refinedStorage; - - public static void initCompat() { - try { - Class itemClass = Class.forName("com.raoulvdberge.refinedstorage.item.ItemPattern"); - refinedStorage = new RefinedStorage(itemClass); - GTLog.logger.info("RefinedStorage found; enabling integration."); - } catch (ClassNotFoundException ignored) { - GTLog.logger.info("RefinedStorage not found; skipping integration."); - } catch (Throwable exception) { - GTLog.logger.error("Failed to enable RefinedStorage integration", exception); - } - } - + /** + * @deprecated Use {@link ItemRenderCompat#getRepresentedStack(ItemStack)} + */ + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + @Deprecated public static ItemStack getRealItemStack(ItemStack itemStack) { - if (refinedStorage != null && RefinedStorage.canHandleItemStack(itemStack)) { - return refinedStorage.getRealItemStack(itemStack); - } - return itemStack; - } - - private static class RefinedStorage { - - private final Method getPatternFromCacheMethod; - private final Method getOutputsMethod; - - public RefinedStorage(Class itemPatternClass) throws ReflectiveOperationException { - this.getPatternFromCacheMethod = itemPatternClass.getMethod("getPatternFromCache", World.class, - ItemStack.class); - this.getOutputsMethod = getPatternFromCacheMethod.getReturnType().getMethod("getOutputs"); - } - - public static boolean canHandleItemStack(ItemStack itemStack) { - ResourceLocation registryName = Objects.requireNonNull(itemStack.getItem().getRegistryName()); - return registryName.getNamespace().equals("refinedstorage") && - registryName.getPath().equals("pattern"); - } - - public ItemStack getRealItemStack(ItemStack itemStack) { - try { - Object craftingPattern = getPatternFromCacheMethod.invoke(null, DummyWorld.INSTANCE, itemStack); - List outputs = (List) getOutputsMethod.invoke(craftingPattern); - return outputs.isEmpty() ? itemStack : outputs.get(0); - } catch (ReflectiveOperationException ex) { - throw new RuntimeException("Failed to obtain item from ItemPattern", ex); - } - } + return ItemRenderCompat.getRepresentedStack(itemStack); } } diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index 0210563b18c..2b7207a232d 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -10,12 +10,17 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.IBlockOre; -import gregtech.api.util.ModCompatibility; import gregtech.client.model.customtexture.CustomTextureModelHandler; import gregtech.client.model.customtexture.MetadataSectionCTM; import gregtech.client.renderer.handler.FacadeRenderer; import gregtech.client.renderer.handler.MetaTileEntityRenderer; -import gregtech.client.renderer.pipe.*; +import gregtech.client.renderer.pipe.CableRenderer; +import gregtech.client.renderer.pipe.FluidPipeRenderer; +import gregtech.client.renderer.pipe.ItemPipeRenderer; +import gregtech.client.renderer.pipe.LaserPipeRenderer; +import gregtech.client.renderer.pipe.OpticalPipeRenderer; +import gregtech.client.renderer.pipe.PipeRenderer; +import gregtech.client.utils.ItemRenderCompat; import gregtech.client.utils.TooltipHelper; import gregtech.common.CommonProxy; import gregtech.common.ConfigHolder; @@ -101,7 +106,7 @@ public void onLoad() { public void onPostLoad() { super.onPostLoad(); TerminalRegistry.initTerminalFiles(); - ModCompatibility.initCompat(); + ItemRenderCompat.init(); FacadeRenderer.init(); } diff --git a/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java b/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java index 5dabff41d6a..e2046685f86 100644 --- a/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java @@ -2,9 +2,9 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.ICCLBlockRenderer; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -60,10 +60,10 @@ public void onModelsBake(ModelBakeEvent event) { @Override public void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType) { - ItemStack stack = ModCompatibility.getRealItemStack(rawStack); - if (stack.getItem() instanceof ItemBlock && - ((ItemBlock) stack.getItem()).getBlock() instanceof ICCLBlockRenderer) { - ((ICCLBlockRenderer) ((ItemBlock) stack.getItem()).getBlock()).renderItem(stack, transformType); + ItemStack stack = ItemRenderCompat.getRepresentedStack(rawStack); + if (stack.getItem() instanceof ItemBlock itemBlock && + itemBlock.getBlock() instanceof ICCLBlockRenderer renderer) { + renderer.renderItem(stack, transformType); } } diff --git a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java index fcd0c3ba523..6db1848659a 100644 --- a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java @@ -2,11 +2,11 @@ import gregtech.api.cover.CoverUtil; import gregtech.api.items.metaitem.MetaItem; -import gregtech.api.util.ModCompatibility; import gregtech.client.model.pipeline.VertexLighterFlatSpecial; import gregtech.client.model.pipeline.VertexLighterSmoothAoSpecial; import gregtech.client.utils.AdvCCRSConsumer; import gregtech.client.utils.FacadeBlockAccess; +import gregtech.client.utils.ItemRenderCompat; import gregtech.common.covers.facade.FacadeHelper; import gregtech.common.items.behaviors.FacadeItem; @@ -82,7 +82,7 @@ public static void init() { @Override public void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType) { - ItemStack itemStack = ModCompatibility.getRealItemStack(rawStack); + ItemStack itemStack = ItemRenderCompat.getRepresentedStack(rawStack); if (!(itemStack.getItem() instanceof MetaItem)) { return; } diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java index 9436d30dc8d..846bcc08860 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java @@ -4,9 +4,9 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.BufferBuilder; @@ -72,7 +72,7 @@ public void onModelsBake(ModelBakeEvent event) { @Override public void renderItem(ItemStack rawStack, TransformType transformType) { - ItemStack stack = ModCompatibility.getRealItemStack(rawStack); + ItemStack stack = ItemRenderCompat.getRepresentedStack(rawStack); MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(stack); if (metaTileEntity == null) { return; diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java index d16ca9ace07..e3195dba22c 100644 --- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java +++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java @@ -11,9 +11,9 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialIconType; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -150,7 +150,7 @@ public abstract void buildRenderer(PipeRenderContext renderContext, BlockPipe + * Primarily used to retrieve the output stack from AE2 or RS Patterns. + * + * @param stack the stack to retrieve from + * @return the actual represented ItemStack + */ + public static @NotNull ItemStack getRepresentedStack(@NotNull ItemStack stack) { + if (ae2Handler != null && ae2Handler.canHandleStack(stack)) { + return ae2Handler.getActualStack(stack); + } + if (rsHandler != null && rsHandler.canHandleStack(stack)) { + return rsHandler.getActualStack(stack); + } + return stack; + } + + /** + * An extractor to retrieve a represented stack from an ItemStack + */ + public interface RepresentativeStackExtractor { + + /** + * @param stack the stack to test + * @return if the extractor can handle the stack + */ + boolean canHandleStack(@NotNull ItemStack stack); + + /** + * @param stack the stack to retrieve from + * @return the represented stack + */ + @NotNull + ItemStack getActualStack(@NotNull ItemStack stack); + } + + /** + * Extracts the output stack from AE2 Patterns + */ + private static final class AE2StackExtractor implements RepresentativeStackExtractor { + + public static @Nullable ItemRenderCompat.AE2StackExtractor create() { + if (!Loader.isModLoaded(GTValues.MODID_APPENG)) return null; + GTLog.logger.info("AppliedEnergistics2 found; enabling render integration."); + return new AE2StackExtractor(); + } + + @Override + public boolean canHandleStack(@NotNull ItemStack stack) { + return stack.getItem() instanceof ItemEncodedPattern; + } + + @Override + public @NotNull ItemStack getActualStack(@NotNull ItemStack stack) { + if (stack.isEmpty()) return ItemStack.EMPTY; + if (stack.getItem() instanceof ItemEncodedPattern encodedPattern) { + return encodedPattern.getOutput(stack); + } + return stack; + } + } + + /** + * Extracts the output stack from RS Patterns + */ + @SuppressWarnings("ClassCanBeRecord") + private static final class RSStackExtractor implements RepresentativeStackExtractor { + + private final MethodHandle getPatternFromCacheHandle; + private final MethodHandle getOutputsHandle; + private final Class itemPatternClass; + + private RSStackExtractor(MethodHandle getPatternFromCacheHandle, MethodHandle getOutputsHandle, + Class itemPatternClass) { + this.getPatternFromCacheHandle = getPatternFromCacheHandle; + this.getOutputsHandle = getOutputsHandle; + this.itemPatternClass = itemPatternClass; + } + + public static @Nullable ItemRenderCompat.RSStackExtractor create() { + if (!Loader.isModLoaded(GTValues.MODID_RS)) return null; + + Class clazz; + try { + clazz = Class.forName("com.raoulvdberge.refinedstorage.item.ItemPattern"); + GTLog.logger.info("RefinedStorage found; enabling render integration."); + } catch (ClassNotFoundException ignored) { + GTLog.logger.error("RefinedStorage classes not found; skipping render integration."); + return null; + } + + try { + Method method = clazz.getMethod("getPatternFromCache", World.class, ItemStack.class); + + MethodHandles.Lookup lookup = MethodHandles.publicLookup(); + + MethodHandle getPatternFromCacheHandle = lookup.unreflect(method); + + method = method.getReturnType().getMethod("getOutputs"); + MethodHandle getOutputsHandle = lookup.unreflect(method); + + return new RSStackExtractor(getPatternFromCacheHandle, getOutputsHandle, clazz); + } catch (NoSuchMethodException | IllegalAccessException e) { + GTLog.logger.error("Failed to enable RefinedStorage integration", e); + return null; + } + } + + @Override + public boolean canHandleStack(@NotNull ItemStack stack) { + return itemPatternClass.isAssignableFrom(stack.getItem().getClass()); + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull ItemStack getActualStack(@NotNull ItemStack stack) { + if (stack.isEmpty()) return ItemStack.EMPTY; + + List outputs; + try { + // ItemPattern.getPatternFromCache: (World, ItemStack) -> CraftingPattern + Object craftingPattern = getPatternFromCacheHandle.invoke(DummyWorld.INSTANCE, stack); + // CraftingPattern#getOutputs: () -> List + outputs = (List) getOutputsHandle.invoke(craftingPattern); + } catch (Throwable e) { + GTLog.logger.error("Failed to obtain item from ItemPattern", e); + return stack; + } + + if (outputs.isEmpty()) { + return stack; + } + return outputs.get(0); + } + } +} From 7a54450ab57175d8408ef8c79fe3a42263a31759 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 21 Jan 2024 16:50:18 -0600 Subject: [PATCH 52/98] 2.8.6 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 43e31d58feb..4739812b018 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 2.8.5-beta +modVersion = 2.8.6-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true From 36d1507c4eedcc4a669a3b95a8c4e52d94d88349 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 28 Jan 2024 19:02:48 -0700 Subject: [PATCH 53/98] Fix Player Unable to Climb Frames on Certain Pipes (#2359) --- src/main/java/gregtech/common/pipelike/cable/BlockCable.java | 1 + .../java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java index 7c8c2e153d4..204010ed522 100644 --- a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java +++ b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java @@ -163,6 +163,7 @@ public boolean isHoldingPipe(EntityPlayer player) { @Override public void onEntityCollision(World worldIn, @NotNull BlockPos pos, @NotNull IBlockState state, @NotNull Entity entityIn) { + super.onEntityCollision(worldIn, pos, state, entityIn); if (worldIn.isRemote) return; Insulation insulation = getPipeTileEntity(worldIn, pos).getPipeType(); if (insulation.insulationLevel == -1 && entityIn instanceof EntityLivingBase) { diff --git a/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java b/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java index 31d5d8ef646..20ac0640a0f 100644 --- a/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java +++ b/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java @@ -129,6 +129,7 @@ public boolean isHoldingPipe(EntityPlayer player) { @Override public void onEntityCollision(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull IBlockState state, @NotNull Entity entityIn) { + super.onEntityCollision(worldIn, pos, state, entityIn); if (worldIn.isRemote) return; TileEntityFluidPipe pipe = (TileEntityFluidPipe) getPipeTileEntity(worldIn, pos); if (pipe instanceof TileEntityFluidPipeTickable && pipe.getFrameMaterial() == null && From 9a7ac23d8ead406967ac92dfafd2099c64e02520 Mon Sep 17 00:00:00 2001 From: mtbo <111296252+loxoDev@users.noreply.github.com> Date: Mon, 29 Jan 2024 03:04:00 +0100 Subject: [PATCH 54/98] Fix recipe properties offsetting info text too much (#2360) --- .../api/recipes/recipeproperties/CleanroomProperty.java | 7 +++++++ .../api/recipes/recipeproperties/PrimitiveProperty.java | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java index ccbe97bdc17..2152e3a3e43 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java @@ -32,6 +32,13 @@ public void drawInfo(@NotNull Minecraft minecraft, int x, int y, int color, Obje minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.cleanroom", getName(type)), x, y, color); } + @Override + public int getInfoHeight(Object value) { + CleanroomType type = castValue(value); + if (type == null) return 0; + return super.getInfoHeight(value); + } + @NotNull private static String getName(@NotNull CleanroomType value) { String name = I18n.format(value.getTranslationKey()); diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java index 524fd7180fe..6419cd2aab0 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java @@ -24,6 +24,11 @@ public static PrimitiveProperty getInstance() { @Override public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) {} + @Override + public int getInfoHeight(Object value) { + return 0; + } + @Override public boolean hideTotalEU() { return true; From 4c8b7ffd7c5eee3704083554472798b38251136e Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:54:59 -0600 Subject: [PATCH 55/98] Fix central monitor jei page (#2364) --- src/main/java/gregtech/client/utils/RenderUtil.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index ed91be4e57e..070ff054c10 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -153,6 +153,9 @@ public static void useStencil(Runnable mask, Runnable renderInMask, boolean shou renderInMask.run(); GL11.glDisable(GL11.GL_STENCIL_TEST); + GL11.glClearStencil(0); + GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); + GL11.glStencilFunc(GL11.GL_ALWAYS, 0, 0xFF); } public static void useLightMap(float x, float y, Runnable codeBlock) { From f670d7e42401e1d3c1d519b85d43590ebf9dd9e4 Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:55:41 -0700 Subject: [PATCH 56/98] Fix unlocalized name of GT fluids in drums (#2361) --- .../metatileentities/storage/MetaTileEntityDrum.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java index ae83ad54a49..321012fcf8f 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java @@ -44,6 +44,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -97,7 +98,7 @@ protected void initializeInventory() { IPropertyFluidFilter filter = this.material.getProperty(PropertyKey.FLUID_PIPE); if (filter == null) { throw new IllegalArgumentException( - String.format("Material %s requires FluidPipePropety for Drums", material)); + String.format("Material %s requires FluidPipeProperty for Drums", material)); } this.fluidInventory = this.fluidTank = new FilteredFluidHandler(tankSize).setFilter(filter); } @@ -129,7 +130,7 @@ public ICapabilityProvider initItemStackCapabilities(ItemStack itemStack) { } @Override - public void writeInitialSyncData(PacketBuffer buf) { + public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); FluidStack fluidStack = fluidTank.getFluid(); buf.writeBoolean(fluidStack != null); @@ -142,7 +143,7 @@ public void writeInitialSyncData(PacketBuffer buf) { } @Override - public void receiveInitialSyncData(PacketBuffer buf) { + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); FluidStack fluidStack = null; if (buf.readBoolean()) { @@ -156,7 +157,7 @@ public void receiveInitialSyncData(PacketBuffer buf) { } @Override - public void receiveCustomData(int dataId, PacketBuffer buf) { + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_AUTO_OUTPUT) { this.isAutoOutput = buf.readBoolean(); @@ -266,7 +267,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(tagCompound.getCompoundTag("Fluid")); if (fluidStack == null) return; tooltip.add(I18n.format("gregtech.machine.fluid_tank.fluid", fluidStack.amount, - I18n.format(fluidStack.getUnlocalizedName()))); + fluidStack.getFluid().getLocalizedName(fluidStack))); } } From 2b1a619bec3ffa5be4692e7b18f292e60dc893ba Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:55:56 -0600 Subject: [PATCH 57/98] Add OpenComputers functions for maintenance problems (#2356) --- .../drivers/DriverRecipeMapMultiblockController.java | 5 +++++ .../drivers/specific/DriverPowerSubstation.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java b/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java index 344b1d6b806..7db4e9bd232 100644 --- a/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java +++ b/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java @@ -152,5 +152,10 @@ public Object[] getInputTank(final Context context, final Arguments args) { public Object[] getOutputTank(final Context context, final Arguments args) { return getTank(tileEntity.getOutputFluidInventory()); } + + @Callback(doc = "function():number -- Gets the number of maintenance problems.") + public Object[] getMaintenanceProblems(final Context context, final Arguments args) { + return new Object[] { tileEntity.getNumMaintenanceProblems() }; + } } } diff --git a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java index 53a506db55b..956ec6a760c 100644 --- a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java +++ b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java @@ -72,5 +72,10 @@ public Object[] getAverageInLastSec(final Context context, final Arguments args) public Object[] getAverageOutLastSec(final Context context, final Arguments args) { return new Object[] { tileEntity.getAverageOutLastSec() }; } + + @Callback(doc = "function():number -- Gets the number of maintenance problems.") + public Object[] getMaintenanceProblems(final Context context, final Arguments args) { + return new Object[] { tileEntity.getNumMaintenanceProblems() }; + } } } From 47544f68a6efdb95c922fdbcd9f8a1e43fdfb440 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Tue, 30 Jan 2024 00:04:24 -0600 Subject: [PATCH 58/98] Add Powderbarrel and ITNT (#2314) --- .../renderer/handler/GTExplosiveRenderer.java | 81 ++++++++ .../java/gregtech/common/CommonProxy.java | 4 + .../java/gregtech/common/EventHandlers.java | 12 ++ .../java/gregtech/common/MetaEntities.java | 9 + .../gregtech/common/blocks/MetaBlocks.java | 10 + .../blocks/explosive/BlockGTExplosive.java | 175 ++++++++++++++++++ .../common/blocks/explosive/BlockITNT.java | 40 ++++ .../blocks/explosive/BlockPowderbarrel.java | 42 +++++ .../blocks/material/GTBlockMaterials.java | 18 ++ .../common/entities/EntityGTExplosive.java | 136 ++++++++++++++ .../gregtech/common/entities/ITNTEntity.java | 41 ++++ .../common/entities/PowderbarrelEntity.java | 36 ++++ .../items/behaviors/LighterBehaviour.java | 10 +- .../forestry/bees/GTBeeDefinition.java | 4 +- .../loaders/recipe/CraftingRecipeLoader.java | 5 + .../recipe/chemistry/ReactorRecipes.java | 8 + .../handlers/MaterialRecipeHandler.java | 19 +- .../assets/gregtech/blockstates/itnt.json | 16 ++ .../gregtech/blockstates/powderbarrel.json | 14 ++ .../resources/assets/gregtech/lang/en_us.lang | 11 ++ .../gregtech/textures/blocks/misc/itnt.png | Bin 0 -> 212 bytes .../textures/blocks/misc/powderbarrel.png | Bin 0 -> 243 bytes src/main/resources/gregtech_at.cfg | 3 + 23 files changed, 688 insertions(+), 6 deletions(-) create mode 100644 src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java create mode 100644 src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java create mode 100644 src/main/java/gregtech/common/blocks/explosive/BlockITNT.java create mode 100644 src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java create mode 100644 src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java create mode 100644 src/main/java/gregtech/common/entities/EntityGTExplosive.java create mode 100644 src/main/java/gregtech/common/entities/ITNTEntity.java create mode 100644 src/main/java/gregtech/common/entities/PowderbarrelEntity.java create mode 100644 src/main/resources/assets/gregtech/blockstates/itnt.json create mode 100644 src/main/resources/assets/gregtech/blockstates/powderbarrel.json create mode 100644 src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png diff --git a/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java b/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java new file mode 100644 index 00000000000..4b0efe1ae63 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java @@ -0,0 +1,81 @@ +package gregtech.client.renderer.handler; + +import gregtech.common.entities.EntityGTExplosive; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +@SideOnly(Side.CLIENT) +public class GTExplosiveRenderer extends Render { + + public GTExplosiveRenderer(RenderManager renderManager) { + super(renderManager); + this.shadowSize = 0.5F; + } + + @Override + public void doRender(@NotNull T entity, double x, double y, double z, float entityYaw, float partialTicks) { + BlockRendererDispatcher brd = Minecraft.getMinecraft().getBlockRendererDispatcher(); + GlStateManager.pushMatrix(); + GlStateManager.translate((float) x, (float) y + 0.5F, (float) z); + float f2; + if ((float) entity.getFuse() - partialTicks + 1.0F < 10.0F) { + f2 = 1.0F - ((float) entity.getFuse() - partialTicks + 1.0F) / 10.0F; + f2 = MathHelper.clamp(f2, 0.0F, 1.0F); + f2 *= f2; + f2 *= f2; + float f1 = 1.0F + f2 * 0.3F; + GlStateManager.scale(f1, f1, f1); + } + + f2 = (1.0F - ((float) entity.getFuse() - partialTicks + 1.0F) / 100.0F) * 0.8F; + this.bindEntityTexture(entity); + GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.translate(-0.5F, -0.5F, 0.5F); + + IBlockState state = entity.getExplosiveState(); + brd.renderBlockBrightness(state, entity.getBrightness()); + GlStateManager.translate(0.0F, 0.0F, 1.0F); + if (this.renderOutlines) { + GlStateManager.enableColorMaterial(); + GlStateManager.enableOutlineMode(this.getTeamColor(entity)); + brd.renderBlockBrightness(state, 1.0F); + GlStateManager.disableOutlineMode(); + GlStateManager.disableColorMaterial(); + } else if (entity.getFuse() / 5 % 2 == 0) { + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.DST_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, f2); + GlStateManager.doPolygonOffset(-3.0F, -3.0F); + GlStateManager.enablePolygonOffset(); + brd.renderBlockBrightness(state, 1.0F); + GlStateManager.doPolygonOffset(0.0F, 0.0F); + GlStateManager.disablePolygonOffset(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + } + + GlStateManager.popMatrix(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + + @Override + protected ResourceLocation getEntityTexture(@NotNull T entity) { + return TextureMap.LOCATION_BLOCKS_TEXTURE; + } +} diff --git a/src/main/java/gregtech/common/CommonProxy.java b/src/main/java/gregtech/common/CommonProxy.java index f8a956e201b..b9927847cd4 100644 --- a/src/main/java/gregtech/common/CommonProxy.java +++ b/src/main/java/gregtech/common/CommonProxy.java @@ -153,6 +153,8 @@ public static void registerBlocks(RegistryEvent.Register event) { registry.register(RUBBER_WOOD_DOOR); registry.register(TREATED_WOOD_DOOR); registry.register(BRITTLE_CHARCOAL); + registry.register(POWDERBARREL); + registry.register(ITNT); registry.register(METAL_SHEET); registry.register(LARGE_METAL_SHEET); registry.register(STUDS); @@ -273,6 +275,8 @@ public static void registerItems(RegistryEvent.Register event) { registry.register(createItemBlock(RUBBER_LOG, ItemBlock::new)); registry.register(createItemBlock(RUBBER_LEAVES, ItemBlock::new)); registry.register(createItemBlock(RUBBER_SAPLING, ItemBlock::new)); + registry.register(createItemBlock(POWDERBARREL, ItemBlock::new)); + registry.register(createItemBlock(ITNT, ItemBlock::new)); for (BlockCompressed block : COMPRESSED_BLOCKS) { registry.register(createItemBlock(block, b -> new MaterialItemBlock(b, OrePrefix.block))); diff --git a/src/main/java/gregtech/common/EventHandlers.java b/src/main/java/gregtech/common/EventHandlers.java index da32dd83ca5..588909961e5 100644 --- a/src/main/java/gregtech/common/EventHandlers.java +++ b/src/main/java/gregtech/common/EventHandlers.java @@ -14,6 +14,7 @@ import gregtech.api.util.GTUtility; import gregtech.api.util.VirtualTankRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinSaveData; +import gregtech.common.entities.EntityGTExplosive; import gregtech.common.items.MetaItems; import gregtech.common.items.armor.IStepAssist; import gregtech.common.items.armor.PowerlessJetpack; @@ -26,6 +27,7 @@ import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.player.EntityPlayer; @@ -48,6 +50,7 @@ import net.minecraftforge.event.entity.player.AdvancementEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; +import net.minecraftforge.event.world.ExplosionEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fml.common.Mod; @@ -373,4 +376,13 @@ public static void onFurnaceFuelBurnTime(FurnaceFuelBurnTimeEvent event) { event.setBurnTime(6400); } } + + @SubscribeEvent + public static void onExplosionDetonate(ExplosionEvent.Detonate event) { + if (event.getExplosion().exploder instanceof EntityGTExplosive explosive) { + if (explosive.dropsAllBlocks()) { + event.getAffectedEntities().removeIf(entity -> entity instanceof EntityItem); + } + } + } } diff --git a/src/main/java/gregtech/common/MetaEntities.java b/src/main/java/gregtech/common/MetaEntities.java index 00efb35f87d..965ce3bfb18 100644 --- a/src/main/java/gregtech/common/MetaEntities.java +++ b/src/main/java/gregtech/common/MetaEntities.java @@ -4,10 +4,13 @@ import gregtech.api.util.GTUtility; import gregtech.client.renderer.handler.DynamiteRenderer; import gregtech.client.renderer.handler.GTBoatRenderer; +import gregtech.client.renderer.handler.GTExplosiveRenderer; import gregtech.client.renderer.handler.PortalRenderer; import gregtech.common.entities.DynamiteEntity; import gregtech.common.entities.GTBoatEntity; +import gregtech.common.entities.ITNTEntity; import gregtech.common.entities.PortalEntity; +import gregtech.common.entities.PowderbarrelEntity; import net.minecraft.client.Minecraft; import net.minecraftforge.fml.client.registry.RenderingRegistry; @@ -24,6 +27,10 @@ public static void init() { GregTechAPI.instance, 64, 5, true); EntityRegistry.registerModEntity(GTUtility.gregtechId("gtboat"), GTBoatEntity.class, "GTBoat", 3, GregTechAPI.instance, 64, 2, true); + EntityRegistry.registerModEntity(GTUtility.gregtechId("powderbarrel"), PowderbarrelEntity.class, "Powderbarrel", + 4, GregTechAPI.instance, 64, 3, true); + EntityRegistry.registerModEntity(GTUtility.gregtechId("itnt"), ITNTEntity.class, "ITNT", 5, + GregTechAPI.instance, 64, 3, true); } @SideOnly(Side.CLIENT) @@ -32,5 +39,7 @@ public static void initRenderers() { manager -> new DynamiteRenderer(manager, Minecraft.getMinecraft().getRenderItem())); RenderingRegistry.registerEntityRenderingHandler(PortalEntity.class, PortalRenderer::new); RenderingRegistry.registerEntityRenderingHandler(GTBoatEntity.class, GTBoatRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(PowderbarrelEntity.class, GTExplosiveRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(ITNTEntity.class, GTExplosiveRenderer::new); } } diff --git a/src/main/java/gregtech/common/blocks/MetaBlocks.java b/src/main/java/gregtech/common/blocks/MetaBlocks.java index ada71a669ac..1cacda968e6 100644 --- a/src/main/java/gregtech/common/blocks/MetaBlocks.java +++ b/src/main/java/gregtech/common/blocks/MetaBlocks.java @@ -24,6 +24,8 @@ import gregtech.client.renderer.pipe.LaserPipeRenderer; import gregtech.client.renderer.pipe.OpticalPipeRenderer; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.explosive.BlockITNT; +import gregtech.common.blocks.explosive.BlockPowderbarrel; import gregtech.common.blocks.foam.BlockFoam; import gregtech.common.blocks.foam.BlockPetrifiedFoam; import gregtech.common.blocks.wood.BlockGregFence; @@ -164,6 +166,8 @@ private MetaBlocks() {} public static BlockFenceGate TREATED_WOOD_FENCE_GATE; public static BlockWoodenDoor RUBBER_WOOD_DOOR; public static BlockWoodenDoor TREATED_WOOD_DOOR; + public static BlockPowderbarrel POWDERBARREL; + public static BlockITNT ITNT; public static BlockBrittleCharcoal BRITTLE_CHARCOAL; @@ -312,6 +316,10 @@ public static void init() { RUBBER_WOOD_DOOR.setRegistryName("rubber_wood_door").setTranslationKey("rubber_wood_door"); TREATED_WOOD_DOOR = new BlockWoodenDoor(() -> MetaItems.TREATED_WOOD_DOOR.getStackForm()); TREATED_WOOD_DOOR.setRegistryName("treated_wood_door").setTranslationKey("treated_wood_door"); + POWDERBARREL = new BlockPowderbarrel(); + POWDERBARREL.setRegistryName("powderbarrel").setTranslationKey("powderbarrel"); + ITNT = new BlockITNT(); + ITNT.setRegistryName("itnt").setTranslationKey("itnt"); BRITTLE_CHARCOAL = new BlockBrittleCharcoal(); BRITTLE_CHARCOAL.setRegistryName("brittle_charcoal"); @@ -481,6 +489,8 @@ public static void registerItemModels() { new ModelResourceLocation(Objects.requireNonNull(TREATED_WOOD_FENCE_GATE.getRegistryName()), "inventory")); registerItemModel(BRITTLE_CHARCOAL); + registerItemModel(POWDERBARREL); + registerItemModel(ITNT); registerItemModel(METAL_SHEET); registerItemModel(LARGE_METAL_SHEET); diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java new file mode 100644 index 00000000000..e18a97abbbf --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java @@ -0,0 +1,175 @@ +package gregtech.common.blocks.explosive; + +import gregtech.common.creativetab.GTCreativeTabs; +import gregtech.common.entities.EntityGTExplosive; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.Explosion; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +@SuppressWarnings("deprecation") +public abstract class BlockGTExplosive extends Block { + + private final boolean canRedstoneActivate; + private final boolean explodeOnMine; + private final int fuseLength; + + /** + * @param canRedstoneActivate whether redstone signal can prime this explosive + * @param explodeOnMine whether mining this block should prime it (sneak mine to drop normally) + * @param fuseLength explosion countdown after priming. Vanilla TNT is 80. + */ + public BlockGTExplosive(Material materialIn, boolean canRedstoneActivate, boolean explodeOnMine, int fuseLength) { + super(materialIn); + this.canRedstoneActivate = canRedstoneActivate; + this.explodeOnMine = explodeOnMine; + this.fuseLength = fuseLength; + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); + } + + protected abstract EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder); + + @Override + public float getExplosionResistance(@NotNull Entity exploder) { + return 1.0f; + } + + @Override + public boolean canBeReplacedByLeaves(@NotNull IBlockState state, @NotNull IBlockAccess world, + @NotNull BlockPos pos) { + return false; + } + + @Override + public boolean isNormalCube(@NotNull IBlockState state) { + return true; + } + + @Override + public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAccess world, @NotNull BlockPos pos, + @NotNull EntityLiving.SpawnPlacementType type) { + return false; + } + + @Override + public boolean canDropFromExplosion(@NotNull Explosion explosion) { + return false; + } + + public void explode(World world, BlockPos pos, EntityLivingBase exploder) { + if (!world.isRemote) { + EntityGTExplosive entity = createEntity(world, pos, exploder); + entity.setFuse(fuseLength); + world.spawnEntity(entity); + world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_TNT_PRIMED, + SoundCategory.BLOCKS, 1.0f, 1.0f); + } + } + + @Override + public void onExplosionDestroy(@NotNull World world, @NotNull BlockPos pos, @NotNull Explosion explosion) { + if (!world.isRemote) { + EntityGTExplosive entity = createEntity(world, pos, explosion.getExplosivePlacedBy()); + entity.setFuse(world.rand.nextInt(fuseLength / 4) + fuseLength / 8); + world.spawnEntity(entity); + } + } + + @Override + public boolean onBlockActivated(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + @NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull EnumFacing facing, + float hitX, float hitY, float hitZ) { + ItemStack stack = player.getHeldItem(hand); + if (!stack.isEmpty() && (stack.getItem() == Items.FLINT_AND_STEEL || stack.getItem() == Items.FIRE_CHARGE)) { + this.explode(world, pos, player); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + if (stack.getItem() == Items.FLINT_AND_STEEL) { + stack.damageItem(1, player); + } else if (!player.capabilities.isCreativeMode) { + stack.shrink(1); + } + return true; + } + return super.onBlockActivated(world, pos, state, player, hand, facing, hitX, hitY, hitZ); + } + + @Override + public void dropBlockAsItemWithChance(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + float chance, int fortune) { + if (explodeOnMine) { + EntityPlayer player = this.harvesters.get(); + if (!player.isSneaking()) { + this.explode(world, pos, player); + return; + } + } + super.dropBlockAsItemWithChance(world, pos, state, chance, fortune); + } + + @Override + public void onEntityCollision(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + @NotNull Entity entity) { + if (!world.isRemote && entity instanceof EntityArrow arrow) { + if (arrow.isBurning()) { + this.explode(world, pos, arrow.shootingEntity instanceof EntityLivingBase living ? living : null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void onBlockAdded(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state) { + super.onBlockAdded(world, pos, state); + if (canRedstoneActivate) { + if (world.isBlockPowered(pos)) { + explode(world, pos, null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void neighborChanged(@NotNull IBlockState state, @NotNull World world, @NotNull BlockPos pos, + @NotNull Block block, @NotNull BlockPos fromPos) { + if (canRedstoneActivate) { + if (world.isBlockPowered(pos)) { + explode(world, pos, null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + if (explodeOnMine) { + tooltip.add(I18n.format("tile.gt_explosive.breaking_tooltip")); + } + if (!canRedstoneActivate) { + tooltip.add(I18n.format("tile.gt_explosive.lighting_tooltip")); + } + } +} diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java b/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java new file mode 100644 index 00000000000..91a9614d4c4 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java @@ -0,0 +1,40 @@ +package gregtech.common.blocks.explosive; + +import gregtech.common.entities.EntityGTExplosive; +import gregtech.common.entities.ITNTEntity; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BlockITNT extends BlockGTExplosive { + + public BlockITNT() { + super(Material.TNT, true, true, 40); + setHardness(0); + setSoundType(SoundType.PLANT); + } + + @Override + protected EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder) { + float x = pos.getX() + 0.5F, y = pos.getY(), z = pos.getZ() + 0.5F; + return new ITNTEntity(world, x, y, z, exploder); + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + tooltip.add(I18n.format("tile.itnt.drops_tooltip")); + super.addInformation(stack, world, tooltip, flag); + } +} diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java b/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java new file mode 100644 index 00000000000..a2549ad7ee5 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java @@ -0,0 +1,42 @@ +package gregtech.common.blocks.explosive; + +import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.blocks.material.GTBlockMaterials; +import gregtech.common.entities.EntityGTExplosive; +import gregtech.common.entities.PowderbarrelEntity; + +import net.minecraft.block.SoundType; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BlockPowderbarrel extends BlockGTExplosive { + + public BlockPowderbarrel() { + super(GTBlockMaterials.POWDERBARREL, false, true, 100); + setHarvestLevel(ToolClasses.AXE, 1); + setHardness(0.5F); + setSoundType(SoundType.WOOD); + } + + @Override + protected EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder) { + float x = pos.getX() + 0.5F, y = pos.getY(), z = pos.getZ() + 0.5F; + return new PowderbarrelEntity(world, x, y, z, exploder); + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + tooltip.add(I18n.format("tile.powderbarrel.drops_tooltip")); + super.addInformation(stack, world, tooltip, flag); + } +} diff --git a/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java b/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java new file mode 100644 index 00000000000..213ba58fdd9 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java @@ -0,0 +1,18 @@ +package gregtech.common.blocks.material; + +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; + +public class GTBlockMaterials { + + public static final Material POWDERBARREL = new PowderbarrelMaterial(); + + private static class PowderbarrelMaterial extends Material { + + public PowderbarrelMaterial() { + super(MapColor.STONE); + setAdventureModeExempt(); + setImmovableMobility(); + } + } +} diff --git a/src/main/java/gregtech/common/entities/EntityGTExplosive.java b/src/main/java/gregtech/common/entities/EntityGTExplosive.java new file mode 100644 index 00000000000..70233d7f17b --- /dev/null +++ b/src/main/java/gregtech/common/entities/EntityGTExplosive.java @@ -0,0 +1,136 @@ +package gregtech.common.entities; + +import gregtech.api.util.BlockUtility; +import gregtech.api.util.GregFakePlayer; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.MoverType; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public abstract class EntityGTExplosive extends EntityTNTPrimed { + + public EntityGTExplosive(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public EntityGTExplosive(World world) { + super(world); + } + + /** + * @return The strength of the explosive. + */ + protected abstract float getStrength(); + + /** + * @return Whether to drop all blocks, or use default logic + */ + public abstract boolean dropsAllBlocks(); + + /** + * @return The range of the explosive, if {@link #dropsAllBlocks} is true. + */ + protected int getRange() { + return 2; + } + + /** + * @return The block state of the block this explosion entity is created by. + */ + public abstract @NotNull IBlockState getExplosiveState(); + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + if (!this.hasNoGravity()) { + this.motionY -= 0.03999999910593033D; + } + + this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + } + + setFuse(this.getFuse() - 1); + if (this.getFuse() <= 0) { + this.setDead(); + if (!this.world.isRemote) { + this.explodeTNT(); + } + } else { + this.handleWaterMovement(); + this.world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, + 0.0D); + } + } + + protected void explodeTNT() { + this.world.createExplosion(this, this.posX, this.posY + (double) (this.height / 16.0F), this.posZ, + getStrength(), !dropsAllBlocks()); + + // If we don't drop all blocks, then skip the drop capture logic + if (!dropsAllBlocks()) return; + + // Create the fake explosion but don't destroy any blocks in water, per MC behavior + if (this.inWater) return; + + EntityPlayer player = GregFakePlayer.get((WorldServer) world); + + int range = getRange(); + for (BlockPos pos : BlockPos.getAllInBox(this.getPosition().add(-range, -range, -range), + this.getPosition().add(range, range, range))) { + IBlockState state = world.getBlockState(pos); + + if (state.getMaterial() == Material.AIR) continue; + if (state.getMaterial() == Material.WATER || state.getMaterial() == Material.LAVA) continue; + + float hardness = state.getBlockHardness(world, pos); + float resistance = state.getBlock().getExplosionResistance(player); + + if (hardness >= 0.0f && resistance < 100 && world.isBlockModifiable(player, pos)) { + List drops = attemptBreakBlockAndObtainDrops(pos, state, player); + + for (ItemStack stack : drops) { + EntityItem entity = new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack); + entity.setDefaultPickupDelay(); + world.spawnEntity(entity); + } + } + } + } + + private List attemptBreakBlockAndObtainDrops(BlockPos pos, IBlockState state, EntityPlayer player) { + if (state.getBlock().removedByPlayer(state, world, pos, player, true)) { + world.playEvent(null, 2001, pos, Block.getStateId(state)); + state.getBlock().onPlayerDestroy(world, pos, state); + + BlockUtility.startCaptureDrops(); + state.getBlock().harvestBlock(world, player, pos, state, world.getTileEntity(pos), ItemStack.EMPTY); + return BlockUtility.stopCaptureDrops(); + } + return Collections.emptyList(); + } +} diff --git a/src/main/java/gregtech/common/entities/ITNTEntity.java b/src/main/java/gregtech/common/entities/ITNTEntity.java new file mode 100644 index 00000000000..3fa60cf4860 --- /dev/null +++ b/src/main/java/gregtech/common/entities/ITNTEntity.java @@ -0,0 +1,41 @@ +package gregtech.common.entities; + +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +public class ITNTEntity extends EntityGTExplosive { + + public ITNTEntity(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public ITNTEntity(World world) { + super(world); + } + + @Override + protected float getStrength() { + return 5.0F; + } + + @Override + public boolean dropsAllBlocks() { + return true; + } + + @Override + protected int getRange() { + return 3; + } + + @Override + public @NotNull IBlockState getExplosiveState() { + return MetaBlocks.ITNT.getDefaultState(); + } +} diff --git a/src/main/java/gregtech/common/entities/PowderbarrelEntity.java b/src/main/java/gregtech/common/entities/PowderbarrelEntity.java new file mode 100644 index 00000000000..39f1ed4df56 --- /dev/null +++ b/src/main/java/gregtech/common/entities/PowderbarrelEntity.java @@ -0,0 +1,36 @@ +package gregtech.common.entities; + +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +public class PowderbarrelEntity extends EntityGTExplosive { + + public PowderbarrelEntity(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public PowderbarrelEntity(World world) { + super(world); + } + + @Override + protected float getStrength() { + return 3.5F; + } + + @Override + public boolean dropsAllBlocks() { + return true; + } + + @Override + public @NotNull IBlockState getExplosiveState() { + return MetaBlocks.POWDERBARREL.getDefaultState(); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java index 6dd8d6742c7..bdff9524d0d 100644 --- a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java @@ -7,6 +7,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; import gregtech.api.util.GradientUtil; +import gregtech.common.blocks.explosive.BlockGTExplosive; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; @@ -120,8 +121,13 @@ public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull Wo SoundCategory.PLAYERS, 1.0F, GTValues.RNG.nextFloat() * 0.4F + 0.8F); IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); - if (block instanceof BlockTNT) { - ((BlockTNT) block).explode(world, pos, blockState.withProperty(BlockTNT.EXPLODE, true), player); + if (block instanceof BlockTNT tnt) { + tnt.explode(world, pos, blockState.withProperty(BlockTNT.EXPLODE, true), player); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + return EnumActionResult.SUCCESS; + } + if (block instanceof BlockGTExplosive powderbarrel) { + powderbarrel.explode(world, pos, player); world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); return EnumActionResult.SUCCESS; } diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 97fed7a25c3..269e992be1b 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -5,6 +5,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryModule; @@ -821,8 +822,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), EXPLOSIVE(GTBranchDefinition.GT_INDUSTRIAL, "Explosionis", false, 0x7E270F, 0x747474, beeSpecies -> { - beeSpecies.addProduct(new ItemStack(Blocks.TNT), 0.2f); - // todo if we add a ITNT substitute, put it here instead of TNT + beeSpecies.addProduct(new ItemStack(MetaBlocks.ITNT), 0.2f); beeSpecies.setHumidity(EnumHumidity.ARID); beeSpecies.setTemperature(EnumTemperature.HELLISH); beeSpecies.setHasEffect(); diff --git a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java index 0b0d513a7f7..8b18ba7a811 100644 --- a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java @@ -336,6 +336,11 @@ private static void loadCraftingRecipes() { new UnificationEntry(OrePrefix.wireGtQuadruple, Osmium), 'P', new UnificationEntry(OrePrefix.plateDouble, Iridium), 'O', MetaItems.ENERGY_LAPOTRONIC_ORB.getStackForm()); + + ModHandler.addShapedRecipe("powderbarrel", new ItemStack(MetaBlocks.POWDERBARREL), "PSP", "GGG", "PGP", + 'P', new UnificationEntry(OrePrefix.plate, Wood), + 'S', new ItemStack(Items.STRING), + 'G', new UnificationEntry(OrePrefix.dust, Gunpowder)); } private static void registerFacadeRecipe(Material material, int facadeAmount) { diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java index 7871a518e8c..ebe5ed15505 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java @@ -3,6 +3,7 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.MarkerMaterials; import gregtech.api.unification.material.Materials; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import net.minecraft.init.Blocks; @@ -570,6 +571,13 @@ public static void init() { .outputs(new ItemStack(Blocks.TNT)) .duration(200).EUt(24).buildAndRegister(); + CHEMICAL_RECIPES.recipeBuilder() + .inputs(MetaItems.GELLED_TOLUENE.getStackForm(4)) + .fluidInputs(NitrationMixture.getFluid(200)) + .outputs(new ItemStack(MetaBlocks.ITNT)) + .fluidOutputs(DilutedSulfuricAcid.getFluid(150)) + .duration(80).EUt(VA[HV]).buildAndRegister(); + CHEMICAL_RECIPES.recipeBuilder() .input(dust, SodiumHydroxide, 6) .fluidInputs(Dichlorobenzene.getFluid(1000)) diff --git a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java index 74239ff12ae..cbdf94add16 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java @@ -13,6 +13,7 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import gregtech.loaders.recipe.CraftingComponent; @@ -90,14 +91,28 @@ public static void processDust(OrePrefix dustPrefix, Material mat, DustProperty .inputs(GTUtility.copy(4, dustStack)) .outputs(GTUtility.copy(3, gemStack)) .chancedOutput(dust, Materials.DarkAsh, 2500, 0) - .explosivesAmount(2) + .explosivesType(new ItemStack(MetaBlocks.POWDERBARREL, 8)) .buildAndRegister(); RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() .inputs(GTUtility.copy(4, dustStack)) .outputs(GTUtility.copy(3, gemStack)) .chancedOutput(dust, Materials.DarkAsh, 2500, 0) - .explosivesType(MetaItems.DYNAMITE.getStackForm()) + .explosivesAmount(4) + .buildAndRegister(); + + RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() + .inputs(GTUtility.copy(4, dustStack)) + .outputs(GTUtility.copy(3, gemStack)) + .chancedOutput(dust, Materials.DarkAsh, 2500, 0) + .explosivesType(MetaItems.DYNAMITE.getStackForm(2)) + .buildAndRegister(); + + RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() + .inputs(GTUtility.copy(4, dustStack)) + .outputs(GTUtility.copy(3, gemStack)) + .chancedOutput(dust, Materials.DarkAsh, 2500, 0) + .explosivesType(new ItemStack(MetaBlocks.ITNT)) .buildAndRegister(); } diff --git a/src/main/resources/assets/gregtech/blockstates/itnt.json b/src/main/resources/assets/gregtech/blockstates/itnt.json new file mode 100644 index 00000000000..79c7d216ccb --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/itnt.json @@ -0,0 +1,16 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_bottom_top", + "textures": { + "bottom": "minecraft:blocks/tnt_bottom", + "top": "minecraft:blocks/tnt_top", + "side": "gregtech:blocks/misc/itnt" + } + }, + "variants": { + "normal": [ + {} + ] + } +} diff --git a/src/main/resources/assets/gregtech/blockstates/powderbarrel.json b/src/main/resources/assets/gregtech/blockstates/powderbarrel.json new file mode 100644 index 00000000000..60d676619f5 --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/powderbarrel.json @@ -0,0 +1,14 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_all", + "textures": { + "all": "gregtech:blocks/misc/powderbarrel" + } + }, + "variants": { + "normal": [ + {} + ] + } +} diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 12a9bba8f0d..38436e8da3d 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -2348,6 +2348,17 @@ tile.treated_wood_fence.name=Treated Wood Fence tile.rubber_wood_fence_gate.name=Rubber Wood Fence Gate tile.treated_wood_fence_gate.name=Treated Wood Fence Gate +tile.gt_explosive.breaking_tooltip=Primes explosion when mined, sneak mine to pick back up +tile.gt_explosive.lighting_tooltip=Cannot be lit with Redstone + +tile.powderbarrel.name=Powderbarrel +tile.powderbarrel.drops_tooltip=Slightly larger than TNT, drops all destroyed Blocks as Items +entity.Powderbarrel.name=Powderbarrel + +tile.itnt.name=Industrial TNT +tile.itnt.drops_tooltip=Much larger than TNT, drops all destroyed Blocks as Items +entity.ITNT.name=Industrial TNT + tile.brittle_charcoal.name=Brittle Charcoal tile.brittle_charcoal.tooltip.1=Produced by the Charcoal Pile Igniter. tile.brittle_charcoal.tooltip.2=Mine this to get Charcoal. diff --git a/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png b/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png new file mode 100644 index 0000000000000000000000000000000000000000..a167e1676b7580be61b14f3826bfb49e4cad4476 GIT binary patch literal 212 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`vproLLn>}1?|7^9_5YH&KmNZJ zTl9bWY>xlxQ_nL9S!5{xt8eW*@xOCd(|^yW{M^iW_y6%9etvH5@BTCH;>;T_{^Ut$ zYGl-5Sd=KC#&@|vr)?2iq@tPGu0)9(C$9IWD)H zQ&Ty~^1nL`EJf1Q$bayygUG~{_2k1-& MPgg&ebxsLQ0H8ovI{*Lx literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png b/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png new file mode 100644 index 0000000000000000000000000000000000000000..b5624295e93db2bb52a3ccddb55b6ee450b0e7da GIT binary patch literal 243 zcmV Date: Tue, 30 Jan 2024 21:24:47 -0600 Subject: [PATCH 59/98] Refactor other mod id handling (#2354) --- src/main/java/gregtech/api/GTValues.java | 12 +- .../api/block/VariantActiveBlock.java | 5 +- .../api/block/machines/BlockMachine.java | 5 +- .../gregtech/api/fluids/FluidBuilder.java | 5 +- .../api/gui/widgets/SortingButtonWidget.java | 12 +- .../api/items/metaitem/ElectricStats.java | 4 +- .../gregtech/api/items/metaitem/MetaItem.java | 5 +- .../gregtech/api/items/toolitem/IGTTool.java | 24 +- .../api/metatileentity/MetaTileEntity.java | 7 +- .../metatileentity/MetaTileEntityHolder.java | 40 +-- .../java/gregtech/api/recipes/ModHandler.java | 5 +- .../gregtech/api/recipes/RecipeBuilder.java | 13 +- .../java/gregtech/api/recipes/RecipeMap.java | 9 +- .../api/terminal/TerminalRegistry.java | 3 +- .../api/unification/ore/StoneType.java | 5 +- .../java/gregtech/api/util/CapesRegistry.java | 5 +- .../api/util/ModIncompatibilityException.java | 35 +++ src/main/java/gregtech/api/util/Mods.java | 252 ++++++++++++++++++ .../api/worldgen/config/WorldGenRegistry.java | 3 +- .../gregtech/asm/GregTechTransformer.java | 11 +- .../java/gregtech/asm/hooks/CTMHooks.java | 6 +- .../asm/visitors/RenderItemVisitor.java | 4 +- .../java/gregtech/client/ClientProxy.java | 4 +- .../pipeline/VertexLighterFlatSpecial.java | 4 +- .../VertexLighterSmoothAoSpecial.java | 8 +- .../java/gregtech/client/shader/Shaders.java | 32 +-- .../client/utils/BloomEffectUtil.java | 12 +- .../client/utils/DepthTextureUtil.java | 4 +- .../client/utils/ItemRenderCompat.java | 7 +- .../items/behaviors/ColorSprayBehaviour.java | 7 +- .../items/behaviors/ItemMagnetBehavior.java | 4 +- .../metatileentities/MetaTileEntities.java | 6 +- .../electric/MetaTileEntityHull.java | 8 +- .../electric/MetaTileEntityCleanroom.java | 4 +- .../MetaTileEntityCharcoalPileIgniter.java | 3 +- .../widget/WidgetProspectingMap.java | 17 +- .../worldprospector/WorldProspectorARApp.java | 3 +- .../integration/IntegrationModule.java | 6 +- .../gregtech/integration/IntegrationUtil.java | 33 ++- .../integration/baubles/BaublesModule.java | 3 +- .../integration/chisel/ChiselModule.java | 5 +- .../crafttweaker/CraftTweakerModule.java | 3 +- .../material/CTMaterialBuilder.java | 4 +- .../material/MaterialExpansion.java | 8 +- .../integration/ctm/IFacadeWrapper.java | 4 +- .../integration/forestry/ForestryModule.java | 35 ++- .../integration/forestry/ForestryUtil.java | 49 ++-- .../forestry/bees/BeeRemovals.java | 8 +- .../forestry/bees/ForestryScannerLogic.java | 8 +- .../forestry/bees/GTBeeDefinition.java | 105 ++++---- .../integration/forestry/bees/GTCombItem.java | 3 +- .../integration/forestry/bees/GTCombType.java | 8 +- .../integration/forestry/bees/GTDropItem.java | 3 +- .../forestry/frames/GTItemFrame.java | 3 +- .../forestry/recipes/CombRecipes.java | 14 +- .../recipes/ForestryElectrodeRecipes.java | 14 +- .../recipes/ForestryExtractorRecipes.java | 238 ++++++----------- .../forestry/recipes/ForestryMiscRecipes.java | 55 ++-- .../forestry/tools/ScoopBehavior.java | 5 +- .../groovy/GroovyScriptModule.java | 5 +- .../integration/hwyla/HWYLAModule.java | 3 +- .../jei/JustEnoughItemsModule.java | 3 +- .../integration/jei/basic/GTOreInfo.java | 5 +- .../JEIResourceDepositCategoryUtils.java | 6 +- .../opencomputers/OpenComputersModule.java | 9 +- .../theoneprobe/TheOneProbeModule.java | 3 +- .../loaders/recipe/MachineRecipeLoader.java | 4 +- .../MetaTileEntityMachineRecipeLoader.java | 11 +- 68 files changed, 731 insertions(+), 525 deletions(-) create mode 100644 src/main/java/gregtech/api/util/ModIncompatibilityException.java create mode 100644 src/main/java/gregtech/api/util/Mods.java diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 0d57fc6d5f9..05053d6fbb8 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -7,6 +7,8 @@ import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.ApiStatus; + import java.time.LocalDate; import java.util.Random; import java.util.function.Supplier; @@ -120,10 +122,14 @@ public class GTValues { "Overpowered Voltage", "Maximum Voltage" }; /** - * ModID strings, since they are quite common parameters + * GregTech Mod ID */ - public static final String MODID = "gregtech", - MODID_FR = "forestry", + public static final String MODID = "gregtech"; + + /** @deprecated Use {@link gregtech.api.util.Mods} instead */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + public static final String MODID_FR = "forestry", MODID_CT = "crafttweaker", MODID_TOP = "theoneprobe", MODID_CTM = "ctm", diff --git a/src/main/java/gregtech/api/block/VariantActiveBlock.java b/src/main/java/gregtech/api/block/VariantActiveBlock.java index 4818c4a933a..ba4ac712a03 100644 --- a/src/main/java/gregtech/api/block/VariantActiveBlock.java +++ b/src/main/java/gregtech/api/block/VariantActiveBlock.java @@ -1,6 +1,6 @@ package gregtech.api.block; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.client.model.ActiveVariantBlockBakedModel; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; @@ -22,7 +22,6 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -135,7 +134,7 @@ public IExtendedBlockState getExtendedState(@NotNull IBlockState state, @NotNull .withProperty(ACTIVE, Minecraft.getMinecraft().world != null && isBlockActive(Minecraft.getMinecraft().world.provider.getDimension(), pos)); - if (Loader.isModLoaded(GTValues.MODID_CTM)) { + if (Mods.CTM.isModLoaded()) { // if the Connected Textures Mod is loaded we wrap our IExtendedBlockState with their wrapper, // so that the CTM renderer can render the block properly. return new CTMExtendedState(ext, world, pos); diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index 6c23ce8c5f5..d45dfdf1e1d 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -1,6 +1,5 @@ package gregtech.api.block.machines; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.block.BlockCustomParticle; import gregtech.api.block.UnlistedIntegerProperty; @@ -15,6 +14,7 @@ import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.pipenet.IBlockAppearance; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.renderer.handler.MetaTileEntityRenderer; import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.items.MetaItems; @@ -56,7 +56,6 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -282,7 +281,7 @@ public void onBlockPlacedBy(World worldIn, @NotNull BlockPos pos, @NotNull IBloc } } } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { if (metaTileEntity.getProxy() != null) { metaTileEntity.getProxy().setOwner((EntityPlayer) placer); } diff --git a/src/main/java/gregtech/api/fluids/FluidBuilder.java b/src/main/java/gregtech/api/fluids/FluidBuilder.java index f7a75111cc4..a7c9d6528ef 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -1,6 +1,5 @@ package gregtech.api.fluids; -import gregtech.api.GTValues; import gregtech.api.fluids.attribute.AttributedFluid; import gregtech.api.fluids.attribute.FluidAttribute; import gregtech.api.fluids.store.FluidStorageKey; @@ -12,13 +11,13 @@ import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.block.material.MaterialLiquid; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.BlockFluidBase; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fml.common.Loader; import com.google.common.base.Preconditions; import io.github.drmanganese.topaddons.reference.Colors; @@ -380,7 +379,7 @@ private static int convertViscosity(double viscosity) { } // register cross mod compat for colors - if (Loader.isModLoaded(GTValues.MODID_TOP_ADDONS)) { + if (Mods.TOPAddons.isModLoaded()) { int displayColor = isColorEnabled || material == null ? color : material.getMaterialRGB(); Colors.FLUID_NAME_COLOR_MAP.put(name, displayColor); } diff --git a/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java b/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java index d053c49e7d1..2c491d18ecc 100644 --- a/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java @@ -1,14 +1,13 @@ package gregtech.api.gui.widgets; +import gregtech.api.util.Mods; + import net.minecraft.client.settings.KeyBinding; -import net.minecraftforge.fml.common.Loader; import java.util.function.Consumer; public class SortingButtonWidget extends ClickButtonWidget { - private static boolean inventoryTweaksChecked; - private static boolean inventoryTweaksPresent; private static KeyBinding sortKeyBinding; public SortingButtonWidget(int xPosition, int yPosition, int width, int height, String displayText, @@ -43,13 +42,10 @@ public boolean keyTyped(char charTyped, int keyCode) { } private static int getInvTweaksSortCode() { - if (!inventoryTweaksChecked) { - inventoryTweaksChecked = true; - inventoryTweaksPresent = Loader.isModLoaded("inventorytweaks"); - } - if (!inventoryTweaksPresent) { + if (!Mods.InventoryTweaks.isModLoaded()) { return 0; } + try { if (sortKeyBinding == null) { Class proxyClass = Class.forName("invtweaks.forge.ClientProxy"); diff --git a/src/main/java/gregtech/api/items/metaitem/ElectricStats.java b/src/main/java/gregtech/api/items/metaitem/ElectricStats.java index 91bd1b739da..bf336ec4676 100644 --- a/src/main/java/gregtech/api/items/metaitem/ElectricStats.java +++ b/src/main/java/gregtech/api/items/metaitem/ElectricStats.java @@ -6,6 +6,7 @@ import gregtech.api.capability.IElectricItem; import gregtech.api.capability.impl.ElectricItem; import gregtech.api.items.metaitem.stats.*; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.integration.baubles.BaublesModule; @@ -25,7 +26,6 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.IEnergyStorage; -import net.minecraftforge.fml.common.Loader; import java.time.Duration; import java.time.Instant; @@ -75,7 +75,7 @@ public void onUpdate(ItemStack itemStack, Entity entity) { IInventory inventoryPlayer = entityPlayer.inventory; long transferLimit = electricItem.getTransferLimit(); - if (Loader.isModLoaded(GTValues.MODID_BAUBLES)) { + if (Mods.Baubles.isModLoaded()) { inventoryPlayer = BaublesModule.getBaublesWrappedInventory(entityPlayer); } diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index 4fd8b940a93..f2674add426 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -30,6 +30,7 @@ import gregtech.api.unification.stack.ItemMaterialInfo; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.common.ConfigHolder; import gregtech.common.creativetab.GTCreativeTabs; @@ -110,7 +111,9 @@ * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } This will add single-use (not * rechargeable) LV battery with initial capacity 10000 EU */ -@Optional.Interface(modid = GTValues.MODID_ECORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") +@Optional.Interface( + modid = Mods.Names.ENDER_CORE, + iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") public abstract class MetaItem.MetaValueItem> extends Item implements ItemUIFactory, IOverlayRenderAware { diff --git a/src/main/java/gregtech/api/items/toolitem/IGTTool.java b/src/main/java/gregtech/api/items/toolitem/IGTTool.java index 4c3ba369341..94ae45effb9 100644 --- a/src/main/java/gregtech/api/items/toolitem/IGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/IGTTool.java @@ -24,6 +24,7 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.client.utils.TooltipHelper; @@ -89,14 +90,21 @@ * Backing of every variation of a GT Tool */ @Optional.InterfaceList({ - @Optional.Interface(modid = GTValues.MODID_APPENG, iface = "appeng.api.implementations.items.IAEWrench"), - @Optional.Interface(modid = GTValues.MODID_BC, iface = "buildcraft.api.tools.IToolWrench"), - @Optional.Interface(modid = GTValues.MODID_COFH, iface = "cofh.api.item.IToolHammer"), - @Optional.Interface(modid = GTValues.MODID_EIO, iface = "crazypants.enderio.api.tool.ITool"), - @Optional.Interface(modid = GTValues.MODID_FR, iface = "forestry.api.arboriculture.IToolGrafter"), - @Optional.Interface(modid = GTValues.MODID_PROJRED_CORE, iface = "mrtjp.projectred.api.IScrewdriver"), - @Optional.Interface(modid = GTValues.MODID_RC, iface = "mods.railcraft.api.items.IToolCrowbar"), - @Optional.Interface(modid = GTValues.MODID_ECORE, + @Optional.Interface(modid = Mods.Names.APPLIED_ENERGISTICS2, + iface = "appeng.api.implementations.items.IAEWrench"), + @Optional.Interface(modid = Mods.Names.BUILD_CRAFT_CORE, + iface = "buildcraft.api.tools.IToolWrench"), + @Optional.Interface(modid = Mods.Names.COFH_CORE, + iface = "cofh.api.item.IToolHammer"), + @Optional.Interface(modid = Mods.Names.ENDER_IO, + iface = "crazypants.enderio.api.tool.ITool"), + @Optional.Interface(modid = Mods.Names.FORESTRY, + iface = "forestry.api.arboriculture.IToolGrafter"), + @Optional.Interface(modid = Mods.Names.PROJECT_RED_CORE, + iface = "mrtjp.projectred.api.IScrewdriver"), + @Optional.Interface(modid = Mods.Names.RAILCRAFT, + iface = "mods.railcraft.api.items.IToolCrowbar"), + @Optional.Interface(modid = Mods.Names.ENDER_CORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") }) public interface IGTTool extends ItemUIFactory, IAEWrench, IToolWrench, IToolHammer, ITool, IToolGrafter, IOverlayRenderAware, IScrewdriver, IToolCrowbar { diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 96bb366b87d..2ba29cb597d 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -30,6 +30,7 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; @@ -1547,17 +1548,17 @@ public boolean canVoidRecipeFluidOutputs() { } @NotNull - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return AECableType.NONE; } @Nullable - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { return null; } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() {} } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java index 9d5662a1153..5c6487e6180 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java @@ -1,6 +1,5 @@ package gregtech.api.metatileentity; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.block.machines.BlockMachine; import gregtech.api.capability.GregtechDataCodes; @@ -8,6 +7,7 @@ import gregtech.api.gui.IUIHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.util.TextFormattingUtil; import gregtech.client.particle.GTNameTagParticle; import gregtech.client.particle.GTParticleManager; @@ -29,7 +29,6 @@ import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.Constants.NBT; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional.Interface; import net.minecraftforge.fml.common.Optional.InterfaceList; import net.minecraftforge.fml.common.Optional.Method; @@ -54,10 +53,11 @@ @InterfaceList(value = { @Interface(iface = "appeng.api.networking.security.IActionHost", - modid = GTValues.MODID_APPENG, + modid = Mods.Names.APPLIED_ENERGISTICS2, striprefs = true), - @Interface(iface = "appeng.me.helpers.IGridProxyable", modid = GTValues.MODID_APPENG, striprefs = true), -}) + @Interface(iface = "appeng.me.helpers.IGridProxyable", + modid = Mods.Names.APPLIED_ENERGISTICS2, + striprefs = true) }) public class MetaTileEntityHolder extends TickableTileEntityBase implements IGregTechTileEntity, IUIHolder, IWorldNameable, IActionHost, IGridProxyable { @@ -138,7 +138,7 @@ public void readFromNBT(@NotNull NBTTagCompound compound) { } else { GTLog.logger.error("Failed to load MetaTileEntity with invalid ID " + metaTileEntityIdRaw); } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { readFromNBT_AENetwork(compound); } } @@ -154,7 +154,7 @@ public NBTTagCompound writeToNBT(@NotNull NBTTagCompound compound) { NBTTagCompound metaTileEntityData = new NBTTagCompound(); metaTileEntity.writeToNBT(metaTileEntityData); compound.setTag("MetaTileEntity", metaTileEntityData); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { writeToNBT_AENetwork(compound); } } @@ -167,7 +167,7 @@ public void invalidate() { metaTileEntity.invalidate(); } super.invalidate(); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { invalidateAE(); } } @@ -375,7 +375,7 @@ public void onChunkUnload() { if (metaTileEntity != null) { metaTileEntity.onUnload(); } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { onChunkUnloadAE(); } } @@ -505,7 +505,7 @@ public ITextComponent getDisplayName() { @Nullable @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public IGridNode getGridNode(@NotNull AEPartLocation part) { // Forbid it connects the faces it shouldn't connect. if (this.getCableConnectionType(part) == AECableType.NONE) { @@ -517,44 +517,44 @@ public IGridNode getGridNode(@NotNull AEPartLocation part) { @NotNull @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return metaTileEntity == null ? AECableType.NONE : metaTileEntity.getCableConnectionType(part); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void securityBreak() {} @NotNull @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public IGridNode getActionableNode() { AENetworkProxy proxy = getProxy(); return proxy == null ? null : proxy.getNode(); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { return metaTileEntity == null ? null : metaTileEntity.getProxy(); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public DimensionalCoord getLocation() { return new DimensionalCoord(this); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() { if (metaTileEntity != null) { metaTileEntity.gridChanged(); } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void readFromNBT_AENetwork(NBTTagCompound data) { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -562,7 +562,7 @@ public void readFromNBT_AENetwork(NBTTagCompound data) { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void writeToNBT_AENetwork(NBTTagCompound data) { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -570,7 +570,7 @@ public void writeToNBT_AENetwork(NBTTagCompound data) { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) void onChunkUnloadAE() { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -578,7 +578,7 @@ void onChunkUnloadAE() { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) void invalidateAE() { AENetworkProxy proxy = getProxy(); if (proxy != null) { diff --git a/src/main/java/gregtech/api/recipes/ModHandler.java b/src/main/java/gregtech/api/recipes/ModHandler.java index 010d1c22346..1fe7ce05f07 100644 --- a/src/main/java/gregtech/api/recipes/ModHandler.java +++ b/src/main/java/gregtech/api/recipes/ModHandler.java @@ -16,6 +16,7 @@ import gregtech.api.util.DummyContainer; import gregtech.api.util.GTLog; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.api.util.world.DummyWorld; import gregtech.common.ConfigHolder; import gregtech.common.crafting.FluidReplaceRecipe; @@ -679,8 +680,6 @@ public static Pair getRecipeOutput(@Nullable World world, @N * disable the config and remove the recipes manually */ public static void removeSmeltingEBFMetals() { - boolean isCTLoaded = Loader.isModLoaded(GTValues.MODID_CT); - Field actionAddFurnaceRecipe$output = null; Map furnaceList = FurnaceRecipes.instance().getSmeltingList(); @@ -702,7 +701,7 @@ public static void removeSmeltingEBFMetals() { ItemStack ingot = OreDictUnifier.get(OrePrefix.ingot, material); // Check if the inputs are actually dust -> ingot if (ingot.isItemEqual(output) && dust.isItemEqual(input)) { - if (isCTLoaded) { + if (Mods.CraftTweaker.isModLoaded()) { if (actionAddFurnaceRecipe$output == null) { try { actionAddFurnaceRecipe$output = ActionAddFurnaceRecipe.class diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index dd5fee598df..87175224c5d 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -22,6 +22,7 @@ import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.ValidationResult; import gregtech.common.ConfigHolder; import gregtech.integration.groovy.GroovyScriptModule; @@ -607,12 +608,12 @@ public R chancedFluidOutputLogic(@NotNull ChancedOutputLogic logic) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(IIngredient ingredient) { return input(ofGroovyIngredient(ingredient)); } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(IIngredient... ingredients) { for (IIngredient ingredient : ingredients) { inputs(ingredient); @@ -620,7 +621,7 @@ public R inputs(IIngredient... ingredients) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(Collection ingredients) { for (IIngredient ingredient : ingredients) { inputs(ingredient); @@ -628,12 +629,12 @@ public R inputs(Collection ingredients) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R notConsumable(IIngredient ingredient) { return notConsumable(ofGroovyIngredient(ingredient)); } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) private static GTRecipeInput ofGroovyIngredient(IIngredient ingredient) { if (ingredient instanceof OreDictIngredient) { return new GTRecipeOreInput(((OreDictIngredient) ingredient).getOreDict(), ingredient.getAmount()); @@ -857,7 +858,7 @@ protected EnumValidationResult validate() { return recipeStatus; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) protected void validateGroovy(GroovyLog.Msg errorMsg) { errorMsg.add(EUt == 0, () -> "EU/t must not be to 0"); errorMsg.add(duration <= 0, () -> "Duration must not be less or equal to 0"); diff --git a/src/main/java/gregtech/api/recipes/RecipeMap.java b/src/main/java/gregtech/api/recipes/RecipeMap.java index 2f9417afe27..1103deef462 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMap.java +++ b/src/main/java/gregtech/api/recipes/RecipeMap.java @@ -27,6 +27,7 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.api.util.ValidationResult; import gregtech.common.ConfigHolder; import gregtech.integration.crafttweaker.CTRecipeHelper; @@ -942,7 +943,7 @@ private boolean shouldShiftWidgets() { return false; } - @Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Method(modid = Mods.Names.GROOVY_SCRIPT) private VirtualizedRecipeMap getGroovyScriptRecipeMap() { return ((VirtualizedRecipeMap) grsVirtualizedRecipeMap); } @@ -1291,7 +1292,7 @@ public Collection getRecipeList() { } @ZenMethod("findRecipe") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) @Nullable public CTRecipe ctFindRecipe(long maxVoltage, IItemStack[] itemInputs, ILiquidStack[] fluidInputs, @Optional(valueLong = Integer.MAX_VALUE) int outputFluidTankCapacity) { @@ -1304,7 +1305,7 @@ public CTRecipe ctFindRecipe(long maxVoltage, IItemStack[] itemInputs, ILiquidSt } @ZenGetter("recipes") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) public List ctGetRecipeList() { return getRecipeList().stream().map(recipe -> new CTRecipe(this, recipe)).collect(Collectors.toList()); } @@ -1393,7 +1394,7 @@ public R recipeBuilder() { } @ZenMethod("recipeBuilder") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) public CTRecipeBuilder ctRecipeBuilder() { return new CTRecipeBuilder(recipeBuilder()); } diff --git a/src/main/java/gregtech/api/terminal/TerminalRegistry.java b/src/main/java/gregtech/api/terminal/TerminalRegistry.java index 6da73912e23..e842eb0c7a9 100644 --- a/src/main/java/gregtech/api/terminal/TerminalRegistry.java +++ b/src/main/java/gregtech/api/terminal/TerminalRegistry.java @@ -5,6 +5,7 @@ import gregtech.api.terminal.hardware.Hardware; import gregtech.api.util.FileUtility; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.common.items.MetaItems; import gregtech.common.terminal.app.VirtualTankApp; @@ -131,7 +132,7 @@ public static void init() { .upgrade(1, MetaItems.EMITTER_HV.getStackForm(4), MetaItems.WORKSTATION_EV.getStackForm(2)) .defaultApp() .build(); - if (Loader.isModLoaded(GTValues.MODID_JEI)) { + if (Mods.JustEnoughItems.isModLoaded()) { AppRegistryBuilder.create(new RecipeChartApp()) .battery(GTValues.LV, 160) .upgrade(0, new ItemStack(Items.PAPER, 32)) diff --git a/src/main/java/gregtech/api/unification/ore/StoneType.java b/src/main/java/gregtech/api/unification/ore/StoneType.java index f92bb9c68bf..9e87a43a0b8 100644 --- a/src/main/java/gregtech/api/unification/ore/StoneType.java +++ b/src/main/java/gregtech/api/unification/ore/StoneType.java @@ -1,9 +1,9 @@ package gregtech.api.unification.ore; -import gregtech.api.GTValues; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.util.GTControlledRegistry; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.integration.jei.basic.OreByProduct; @@ -11,7 +11,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; -import net.minecraftforge.fml.common.Loader; import com.google.common.base.Preconditions; import org.jetbrains.annotations.NotNull; @@ -50,7 +49,7 @@ public StoneType(int id, String name, SoundType soundType, OrePrefix processingP this.predicate = predicate::test; this.shouldBeDroppedAsItem = shouldBeDroppedAsItem || ConfigHolder.worldgen.allUniqueStoneTypes; STONE_TYPE_REGISTRY.register(id, name, this); - if (Loader.isModLoaded(GTValues.MODID_JEI) && this.shouldBeDroppedAsItem) { + if (Mods.JustEnoughItems.isModLoaded() && this.shouldBeDroppedAsItem) { OreByProduct.addOreByProductPrefix(this.processingPrefix); } } diff --git a/src/main/java/gregtech/api/util/CapesRegistry.java b/src/main/java/gregtech/api/util/CapesRegistry.java index 50972a56236..7d0acaa0ba6 100644 --- a/src/main/java/gregtech/api/util/CapesRegistry.java +++ b/src/main/java/gregtech/api/util/CapesRegistry.java @@ -1,6 +1,5 @@ package gregtech.api.util; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.client.renderer.texture.Textures; import gregtech.core.network.packets.PacketNotifyCapeChange; @@ -214,13 +213,13 @@ public static void addFreeCape(ResourceLocation cape) { private static final List> ctRegisterCapes = new ArrayList<>(); private static final List ctFreeCapes = new ArrayList<>(); - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @ZenMethod public static void registerCape(String advancement, String cape) { ctRegisterCapes.add(new Tuple<>(new ResourceLocation(advancement), new ResourceLocation(cape))); } - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @ZenMethod public static void registerFreeCape(String cape) { ctFreeCapes.add(new ResourceLocation(cape)); diff --git a/src/main/java/gregtech/api/util/ModIncompatibilityException.java b/src/main/java/gregtech/api/util/ModIncompatibilityException.java new file mode 100644 index 00000000000..c21439cc5fe --- /dev/null +++ b/src/main/java/gregtech/api/util/ModIncompatibilityException.java @@ -0,0 +1,35 @@ +package gregtech.api.util; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiErrorScreen; +import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.List; + +@SideOnly(Side.CLIENT) +public class ModIncompatibilityException extends CustomModLoadingErrorDisplayException { + + @SuppressWarnings("all") + private static final long serialVersionUID = 1L; + + private final List messages; + + public ModIncompatibilityException(List messages) { + this.messages = messages; + } + + @Override + public void initGui(GuiErrorScreen guiErrorScreen, FontRenderer fontRenderer) {} + + @Override + public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseX, int mouseY, float time) { + int x = errorScreen.width / 2; + int y = 75; + for (String message : messages) { + errorScreen.drawCenteredString(fontRenderer, message, x, y, 0xFFFFFF); + y += 15; + } + } +} diff --git a/src/main/java/gregtech/api/util/Mods.java b/src/main/java/gregtech/api/util/Mods.java new file mode 100644 index 00000000000..c022672f095 --- /dev/null +++ b/src/main/java/gregtech/api/util/Mods.java @@ -0,0 +1,252 @@ +package gregtech.api.util; + +import gregtech.api.GTValues; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +public enum Mods { + + AdvancedRocketry(Names.ADVANCED_ROCKETRY), + AppliedEnergistics2(Names.APPLIED_ENERGISTICS2), + Baubles(Names.BAUBLES), + BinnieCore(Names.BINNIE_CORE), + BiomesOPlenty(Names.BIOMES_O_PLENTY), + BuildCraftCore(Names.BUILD_CRAFT_CORE), + Chisel(Names.CHISEL), + CoFHCore(Names.COFH_CORE), + CTM(Names.CONNECTED_TEXTURES_MOD), + CubicChunks(Names.CUBIC_CHUNKS), + CraftTweaker(Names.CRAFT_TWEAKER), + EnderCore(Names.ENDER_CORE), + EnderIO(Names.ENDER_IO), + ExtraBees(Names.EXTRA_BEES), + ExtraTrees(Names.EXTRA_TREES), + ExtraUtilities2(Names.EXTRA_UTILITIES2), + Forestry(Names.FORESTRY), + ForestryApiculture(Names.FORESTRY, forestryModule(Names.FORESTRY_APICULTURE)), + ForestryArboriculture(Names.FORESTRY, forestryModule(Names.FORESTRY_ARBORICULTURE)), + ForestryLepidopterology(Names.FORESTRY, forestryModule(Names.FORESTRY_LEPIDOPTEROLOGY)), + GalacticraftCore(Names.GALACTICRAFT_CORE), + Genetics(Names.GENETICS), + GregTech(Names.GREGTECH), + GregTechFoodOption(Names.GREGTECH_FOOD_OPTION), + GroovyScript(Names.GROOVY_SCRIPT), + GTCE2OC(Names.GTCE_2_OC), + HWYLA(Names.HWYLA), + ImmersiveEngineering(Names.IMMERSIVE_ENGINEERING), + IndustrialCraft2(Names.INDUSTRIAL_CRAFT2), + InventoryTweaks(Names.INVENTORY_TWEAKS), + JourneyMap(Names.JOURNEY_MAP), + JustEnoughItems(Names.JUST_ENOUGH_ITEMS), + MagicBees(Names.MAGIC_BEES), + Nothirium(Names.NOTHIRIUM), + NuclearCraft(Names.NUCLEAR_CRAFT, versionExcludes("2o")), + NuclearCraftOverhauled(Names.NUCLEAR_CRAFT, versionContains("2o")), + OpenComputers(Names.OPEN_COMPUTERS), + ProjectRedCore(Names.PROJECT_RED_CORE), + Railcraft(Names.RAILCRAFT), + RefinedStorage(Names.REFINED_STORAGE), + TechReborn(Names.TECH_REBORN), + TheOneProbe(Names.THE_ONE_PROBE), + TinkersConstruct(Names.TINKERS_CONSTRUCT), + TOPAddons(Names.TOP_ADDONS), + VoxelMap(Names.VOXEL_MAP), + XaerosMinimap(Names.XAEROS_MINIMAP), + + // Special Optifine handler, but consolidated here for simplicity + Optifine(null) { + + @Override + public boolean isModLoaded() { + if (this.modLoaded == null) { + try { + Class c = Class.forName("net.optifine.shaders.Shaders"); + Field f = c.getDeclaredField("shaderPackLoaded"); + f.setAccessible(true); + this.modLoaded = f.getBoolean(null); + } catch (Exception ignored) { + this.modLoaded = false; + } + } + return this.modLoaded; + } + }; + + public static class Names { + + public static final String ADVANCED_ROCKETRY = "advancedrocketry"; + public static final String APPLIED_ENERGISTICS2 = "appliedenergistics2"; + public static final String BAUBLES = "baubles"; + public static final String BINNIE_CORE = "binniecore"; + public static final String BIOMES_O_PLENTY = "biomesoplenty"; + public static final String BUILD_CRAFT_CORE = "buildcraftcore"; + public static final String CHISEL = "chisel"; + public static final String COFH_CORE = "cofhcore"; + public static final String CONNECTED_TEXTURES_MOD = "ctm"; + public static final String CUBIC_CHUNKS = "cubicchunks"; + public static final String CRAFT_TWEAKER = "crafttweaker"; + public static final String ENDER_CORE = "endercore"; + public static final String ENDER_IO = "enderio"; + public static final String EXTRA_BEES = "extrabees"; + public static final String EXTRA_TREES = "extratrees"; + public static final String EXTRA_UTILITIES2 = "extrautils2"; + public static final String FORESTRY = "forestry"; + public static final String FORESTRY_APICULTURE = "apiculture"; + public static final String FORESTRY_ARBORICULTURE = "arboriculture"; + public static final String FORESTRY_LEPIDOPTEROLOGY = "lepidopterology"; + public static final String GALACTICRAFT_CORE = "galacticraftcore"; + public static final String GENETICS = "genetics"; + public static final String GREGTECH = GTValues.MODID; + public static final String GREGTECH_FOOD_OPTION = "gregtechfoodoption"; + public static final String GROOVY_SCRIPT = "groovyscript"; + public static final String GTCE_2_OC = "gtce2oc"; + public static final String HWYLA = "hwyla"; + public static final String IMMERSIVE_ENGINEERING = "immersiveengineering"; + public static final String INDUSTRIAL_CRAFT2 = "ic2"; + public static final String INVENTORY_TWEAKS = "inventorytweaks"; + public static final String JOURNEY_MAP = "journeymap"; + public static final String JUST_ENOUGH_ITEMS = "jei"; + public static final String MAGIC_BEES = "magicbees"; + public static final String NOTHIRIUM = "nothirium"; + public static final String NUCLEAR_CRAFT = "nuclearcraft"; + public static final String OPEN_COMPUTERS = "opencomputers"; + public static final String PROJECT_RED_CORE = "projred-core"; + public static final String RAILCRAFT = "railcraft"; + public static final String REFINED_STORAGE = "refinedstorage"; + public static final String TECH_REBORN = "techreborn"; + public static final String THE_ONE_PROBE = "theoneprobe"; + public static final String TINKERS_CONSTRUCT = "tconstruct"; + public static final String TOP_ADDONS = "topaddons"; + public static final String VOXEL_MAP = "voxelmap"; + public static final String XAEROS_MINIMAP = "xaerominimap"; + } + + private final String ID; + private final Function extraCheck; + protected Boolean modLoaded; + + Mods(String ID) { + this.ID = ID; + this.extraCheck = null; + } + + /** + * @param extraCheck A supplier that can be used to test additional factors, such as + * checking if a mod is at a specific version, or a sub-mod is loaded. + * Used in cases like NC vs NCO, where the mod id is the same + * so the version has to be parsed to test which is loaded. + * Another case is checking for specific Forestry modules, checking + * if Forestry is loaded and if a specific module is enabled. + */ + Mods(String ID, Function extraCheck) { + this.ID = ID; + this.extraCheck = extraCheck; + } + + public boolean isModLoaded() { + if (this.modLoaded == null) { + this.modLoaded = Loader.isModLoaded(this.ID); + if (this.modLoaded) { + if (this.extraCheck != null && !this.extraCheck.apply(this)) { + this.modLoaded = false; + } + } + } + return this.modLoaded; + } + + /** + * Throw an exception if this mod is found to be loaded. + * This must be called in or after + * {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent}! + */ + public void throwIncompatibilityIfLoaded(String... customMessages) { + if (isModLoaded()) { + String modName = TextFormatting.BOLD + ID + TextFormatting.RESET; + List messages = new ArrayList<>(); + messages.add(modName + " mod detected, this mod is incompatible with GregTech CE Unofficial."); + messages.addAll(Arrays.asList(customMessages)); + if (FMLLaunchHandler.side() == Side.SERVER) { + throw new RuntimeException(String.join(",", messages)); + } else { + throwClientIncompatibility(messages); + } + } + } + + @SideOnly(Side.CLIENT) + private static void throwClientIncompatibility(List messages) { + throw new ModIncompatibilityException(messages); + } + + public ItemStack getItem(@NotNull String name) { + return getItem(name, 0, 1, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta) { + return getItem(name, meta, 1, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta, int amount) { + return getItem(name, meta, amount, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta, int amount, @Nullable String nbt) { + if (!isModLoaded()) { + return ItemStack.EMPTY; + } + return GameRegistry.makeItemStack(ID + ":" + name, meta, amount, nbt); + } + + // Helpers for the extra checker + + /** Test if the mod version string contains the passed value. */ + private static Function versionContains(String versionPart) { + return mod -> { + if (mod.ID == null) return false; + if (!mod.isModLoaded()) return false; + ModContainer container = Loader.instance().getIndexedModList().get(mod.ID); + if (container == null) return false; + return container.getVersion().contains(versionPart); + }; + } + + /** Test if the mod version string does not contain the passed value. */ + private static Function versionExcludes(String versionPart) { + return mod -> { + if (mod.ID == null) return false; + if (!mod.isModLoaded()) return false; + ModContainer container = Loader.instance().getIndexedModList().get(mod.ID); + if (container == null) return false; + return !container.getVersion().contains(versionPart); + }; + } + + /** Test if a specific Forestry module is enabled. */ + private static Function forestryModule(String moduleID) { + if (Forestry.isModLoaded()) { + return mod -> forestry.modules.ModuleHelper.isEnabled(moduleID); + } else { + return $ -> false; + } + } +} diff --git a/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java b/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java index 2a30f9e1eeb..858f28bc328 100644 --- a/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java +++ b/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.util.FileUtility; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.worldgen.filler.BlacklistedBlockFiller; import gregtech.api.worldgen.filler.BlockFiller; import gregtech.api.worldgen.filler.LayeredBlockFiller; @@ -123,7 +124,7 @@ public void initializeRegistry() { } catch (IOException | RuntimeException exception) { GTLog.logger.fatal("Failed to initialize worldgen registry.", exception); } - if (Loader.isModLoaded("galacticraftcore")) { + if (Mods.GalacticraftCore.isModLoaded()) { try { Class transformerHooksClass = Class.forName("micdoodle8.mods.galacticraft.core.TransformerHooks"); Field otherModGeneratorsWhitelistField = transformerHooksClass diff --git a/src/main/java/gregtech/asm/GregTechTransformer.java b/src/main/java/gregtech/asm/GregTechTransformer.java index 4d98621cfa8..005ec295075 100644 --- a/src/main/java/gregtech/asm/GregTechTransformer.java +++ b/src/main/java/gregtech/asm/GregTechTransformer.java @@ -1,6 +1,6 @@ package gregtech.asm; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.asm.util.ObfMapping; import gregtech.asm.util.TargetClassVisitor; import gregtech.asm.visitors.*; @@ -8,8 +8,6 @@ import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.Launch; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.ModContainer; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; @@ -136,13 +134,12 @@ public byte[] transform(String name, String transformedName, byte[] basicClass) ClassReader classReader = new ClassReader(basicClass); ClassWriter classWriter = new ClassWriter(0); - // fix NC recipe compat different depending on overhaul vs underhaul - ModContainer container = Loader.instance().getIndexedModList().get(GTValues.MODID_NC); - if (container.getVersion().contains("2o")) { // overhauled + // fix NC recipe compat different depending on overhaul vs normal + if (Mods.NuclearCraftOverhauled.isModLoaded()) { classReader.accept(new TargetClassVisitor(classWriter, NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NCO, NuclearCraftRecipeHelperVisitor::new), 0); - } else { + } else if (Mods.NuclearCraft.isModLoaded()) { classReader.accept(new TargetClassVisitor(classWriter, NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NC, NuclearCraftRecipeHelperVisitor::new), 0); } diff --git a/src/main/java/gregtech/asm/hooks/CTMHooks.java b/src/main/java/gregtech/asm/hooks/CTMHooks.java index eaf4f7ad51c..bf254934d5c 100644 --- a/src/main/java/gregtech/asm/hooks/CTMHooks.java +++ b/src/main/java/gregtech/asm/hooks/CTMHooks.java @@ -1,6 +1,6 @@ package gregtech.asm.hooks; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import gregtech.client.utils.BloomEffectUtil; import net.minecraft.block.state.IBlockState; @@ -20,7 +20,7 @@ public class CTMHooks { public static ThreadLocal ENABLE = new ThreadLocal<>(); public static boolean checkLayerWithOptiFine(boolean canRenderInLayer, byte layers, BlockRenderLayer layer) { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { if (canRenderInLayer) { if (layer == BloomEffectUtil.getBloomLayer()) return false; } else if ((layers >> BloomEffectUtil.getBloomLayer().ordinal() & 1) == 1 && @@ -34,7 +34,7 @@ public static boolean checkLayerWithOptiFine(boolean canRenderInLayer, byte laye public static List getQuadsWithOptiFine(List ret, BlockRenderLayer layer, IBakedModel bakedModel, IBlockState state, EnumFacing side, long rand) { - if (Shaders.isOptiFineShaderPackLoaded() && CTMHooks.ENABLE.get() == null) { + if (Mods.Optifine.isModLoaded() && CTMHooks.ENABLE.get() == null) { if (layer == BloomEffectUtil.getBloomLayer()) { return Collections.emptyList(); } else if (layer == BloomEffectUtil.getEffectiveBloomLayer()) { diff --git a/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java b/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java index f1b87a1fc12..750de53af3b 100644 --- a/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java +++ b/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java @@ -1,6 +1,6 @@ package gregtech.asm.visitors; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.asm.util.ObfMapping; import net.minecraftforge.fml.common.Loader; @@ -28,7 +28,7 @@ public static void transform(Iterator methods) { callRenderLampOverlay.add(new MethodInsnNode(INVOKESTATIC, "gregtech/asm/hooks/RenderItemHooks", "renderLampOverlay", "(Lnet/minecraft/item/ItemStack;II)V", false)); - boolean enderCoreLoaded = Loader.instance().getIndexedModList().containsKey(GTValues.MODID_ECORE); + boolean enderCoreLoaded = Loader.instance().getIndexedModList().containsKey(Mods.Names.ENDER_CORE); // do not conflict with EnderCore's changes, which already do what we need InsnList callRenderElectricBar; diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index 2b7207a232d..7fb4773d478 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -10,6 +10,7 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.IBlockOre; +import gregtech.api.util.Mods; import gregtech.client.model.customtexture.CustomTextureModelHandler; import gregtech.client.model.customtexture.MetadataSectionCTM; import gregtech.client.renderer.handler.FacadeRenderer; @@ -52,7 +53,6 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidBlock; import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -77,7 +77,7 @@ public void onPreLoad() { SoundSystemConfig.setNumberNormalChannels(ConfigHolder.client.maxNumSounds); - if (!Loader.isModLoaded(GTValues.MODID_CTM)) { + if (!Mods.CTM.isModLoaded()) { Minecraft.getMinecraft().metadataSerializer.registerMetadataSectionType(new MetadataSectionCTM.Serializer(), MetadataSectionCTM.class); MinecraftForge.EVENT_BUS.register(CustomTextureModelHandler.INSTANCE); diff --git a/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java b/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java index 75f05440797..9f8580344ec 100644 --- a/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java +++ b/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java @@ -1,6 +1,6 @@ package gregtech.client.model.pipeline; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.client.renderer.vertex.VertexFormat; @@ -134,7 +134,7 @@ protected void processQuad() { updateColor(normal[v], color[v], x, y, z, tint, multiplier); // When enabled this causes the rendering to be black with Optifine - if (!Shaders.isOptiFineShaderPackLoaded() && diffuse) { + if (!Mods.Optifine.isModLoaded() && diffuse) { float d = LightUtil.diffuseLight(normal[v][0], normal[v][1], normal[v][2]); for (int i = 0; i < 3; i++) { color[v][i] *= d; diff --git a/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java b/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java index 79b83e9998e..f1d6f852e3c 100644 --- a/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java +++ b/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java @@ -1,6 +1,6 @@ package gregtech.client.model.pipeline; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.util.math.MathHelper; @@ -15,7 +15,7 @@ public VertexLighterSmoothAoSpecial(BlockColors colors) { @Override protected void updateLightmap(float[] normal, float[] lightmap, float x, float y, float z) { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { super.updateLightmap(normal, lightmap, x, y, z); return; } @@ -28,7 +28,7 @@ protected void updateLightmap(float[] normal, float[] lightmap, float x, float y protected void updateColor(float[] normal, float[] color, float x, float y, float z, float tint, int multiplier) { super.updateColor(normal, color, x, y, z, tint, multiplier); - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { return; } @@ -146,7 +146,7 @@ protected float getAo(float x, float y, float z) { @Override public void updateBlockInfo() { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { super.updateBlockInfo(); return; } diff --git a/src/main/java/gregtech/client/shader/Shaders.java b/src/main/java/gregtech/client/shader/Shaders.java index e1eb6ef0474..1d20438bbbb 100644 --- a/src/main/java/gregtech/client/shader/Shaders.java +++ b/src/main/java/gregtech/client/shader/Shaders.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import net.minecraft.client.Minecraft; @@ -15,11 +16,10 @@ import codechicken.lib.render.shader.ShaderObject; import codechicken.lib.render.shader.ShaderProgram; +import org.jetbrains.annotations.ApiStatus; -import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; -import java.util.function.BooleanSupplier; import java.util.function.Consumer; import static codechicken.lib.render.shader.ShaderHelper.getStream; @@ -57,35 +57,12 @@ public class Shaders { public static ShaderObject S_BLUR; public static ShaderObject COMPOSITE; - // OptiFine - private static BooleanSupplier isShaderPackLoaded; - static { mc = Minecraft.getMinecraft(); FULL_IMAGE_PROGRAMS = new HashMap<>(); if (allowedShader()) { initShaders(); } - try { // hook optFine. thanks to Scannable. - final Class clazz = Class.forName("net.optifine.shaders.Shaders"); - final Field shaderPackLoaded = clazz.getDeclaredField("shaderPackLoaded"); - shaderPackLoaded.setAccessible(true); - isShaderPackLoaded = () -> { - try { - return shaderPackLoaded.getBoolean(null); - } catch (final IllegalAccessException e) { - GTLog.logger.warn( - "Failed reading field indicating whether shaders are enabled. Shader mod integration disabled."); - isShaderPackLoaded = null; - return false; - } - }; - GTLog.logger.info("Find optiFine mod loaded."); - } catch (ClassNotFoundException e) { - GTLog.logger.info("No optiFine mod found."); - } catch (NoSuchFieldException | NoClassDefFoundError e) { - GTLog.logger.warn("Failed integrating with shader mod. Ignoring."); - } } public static void initShaders() { @@ -128,8 +105,11 @@ public static boolean allowedShader() { return OpenGlHelper.shadersSupported && ConfigHolder.client.shader.useShader; } + /** @deprecated Use {@link Mods#Optifine} to check this instead. */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static boolean isOptiFineShaderPackLoaded() { - return isShaderPackLoaded != null && isShaderPackLoaded.getAsBoolean(); + return Mods.Optifine.isModLoaded(); } public static Framebuffer renderFullImageInFBO(Framebuffer fbo, ShaderObject frag, diff --git a/src/main/java/gregtech/client/utils/BloomEffectUtil.java b/src/main/java/gregtech/client/utils/BloomEffectUtil.java index d1ac6f07cc0..2dcc7d0be14 100644 --- a/src/main/java/gregtech/client/utils/BloomEffectUtil.java +++ b/src/main/java/gregtech/client/utils/BloomEffectUtil.java @@ -1,6 +1,7 @@ package gregtech.client.utils; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.Mods; import gregtech.client.particle.GTParticle; import gregtech.client.renderer.IRenderSetup; import gregtech.client.shader.Shaders; @@ -20,7 +21,6 @@ import net.minecraft.launchwrapper.Launch; import net.minecraft.util.BlockRenderLayer; import net.minecraftforge.common.util.EnumHelper; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -101,7 +101,7 @@ public static BlockRenderLayer getEffectiveBloomLayer() { */ @Contract("null -> _; !null -> !null") public static BlockRenderLayer getEffectiveBloomLayer(BlockRenderLayer fallback) { - return Shaders.isOptiFineShaderPackLoaded() ? fallback : bloom; + return Mods.Optifine.isModLoaded() ? fallback : bloom; } /** @@ -133,7 +133,7 @@ public static BlockRenderLayer getEffectiveBloomLayer(boolean isBloomActive) { */ @Contract("_, null -> _; _, !null -> !null") public static BlockRenderLayer getEffectiveBloomLayer(boolean isBloomActive, BlockRenderLayer fallback) { - return Shaders.isOptiFineShaderPackLoaded() || !isBloomActive ? fallback : bloom; + return Mods.Optifine.isModLoaded() || !isBloomActive ? fallback : bloom; } /** @@ -221,7 +221,7 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup @NotNull BloomType bloomType, @NotNull IBloomEffect render, @Nullable Predicate validityChecker) { - if (Shaders.isOptiFineShaderPackLoaded()) return null; + if (Mods.Optifine.isModLoaded()) return null; BloomRenderTicket ticket = new BloomRenderTicket(setup, bloomType, render, validityChecker); SCHEDULED_BLOOM_RENDERS.add(ticket); return ticket; @@ -253,7 +253,7 @@ public boolean test(BloomRenderTicket bloomRenderTicket) { public static void init() { bloom = EnumHelper.addEnum(BlockRenderLayer.class, "BLOOM", new Class[] { String.class }, "Bloom"); BLOOM = bloom; - if (Loader.isModLoaded("nothirium")) { + if (Mods.Nothirium.isModLoaded()) { try { // Nothirium hard copies the BlockRenderLayer enum into a ChunkRenderPass enum. Add our BLOOM layer to // that too. @@ -285,7 +285,7 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, Minecraft mc = Minecraft.getMinecraft(); mc.profiler.endStartSection("BTLayer"); - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { return renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); } diff --git a/src/main/java/gregtech/client/utils/DepthTextureUtil.java b/src/main/java/gregtech/client/utils/DepthTextureUtil.java index 3aa59bf75b4..d3bd1c4f06d 100644 --- a/src/main/java/gregtech/client/utils/DepthTextureUtil.java +++ b/src/main/java/gregtech/client/utils/DepthTextureUtil.java @@ -1,6 +1,6 @@ package gregtech.client.utils; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import net.minecraft.client.Minecraft; @@ -40,7 +40,7 @@ public class DepthTextureUtil { private static int lastWidth, lastHeight; private static boolean shouldRenderDepthTexture() { - return lastBind && !Shaders.isOptiFineShaderPackLoaded() && ConfigHolder.client.hookDepthTexture && + return lastBind && !Mods.Optifine.isModLoaded() && ConfigHolder.client.hookDepthTexture && OpenGlHelper.isFramebufferEnabled(); } diff --git a/src/main/java/gregtech/client/utils/ItemRenderCompat.java b/src/main/java/gregtech/client/utils/ItemRenderCompat.java index bff1b3e5cb9..4ea385c8910 100644 --- a/src/main/java/gregtech/client/utils/ItemRenderCompat.java +++ b/src/main/java/gregtech/client/utils/ItemRenderCompat.java @@ -1,12 +1,11 @@ package gregtech.client.utils; -import gregtech.api.GTValues; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.util.world.DummyWorld; import net.minecraft.item.ItemStack; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import appeng.items.misc.ItemEncodedPattern; import org.jetbrains.annotations.ApiStatus; @@ -74,7 +73,7 @@ public interface RepresentativeStackExtractor { private static final class AE2StackExtractor implements RepresentativeStackExtractor { public static @Nullable ItemRenderCompat.AE2StackExtractor create() { - if (!Loader.isModLoaded(GTValues.MODID_APPENG)) return null; + if (!Mods.AppliedEnergistics2.isModLoaded()) return null; GTLog.logger.info("AppliedEnergistics2 found; enabling render integration."); return new AE2StackExtractor(); } @@ -112,7 +111,7 @@ private RSStackExtractor(MethodHandle getPatternFromCacheHandle, MethodHandle ge } public static @Nullable ItemRenderCompat.RSStackExtractor create() { - if (!Loader.isModLoaded(GTValues.MODID_RS)) return null; + if (!Mods.RefinedStorage.isModLoaded()) return null; Class clazz; try { diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java index 6cda26f8ce5..69bf9e9640c 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java @@ -1,11 +1,11 @@ package gregtech.common.items.behaviors; -import gregtech.api.GTValues; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.GradientUtil; +import gregtech.api.util.Mods; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.Block; @@ -23,7 +23,6 @@ import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import appeng.api.util.AEColor; import appeng.tile.networking.TileCableBus; @@ -93,7 +92,7 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos world.setBlockState(pos, newBlockState); return true; } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { TileEntity te = world.getTileEntity(pos); if (te instanceof TileCableBus) { TileCableBus cable = (TileCableBus) te; @@ -146,7 +145,7 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc } // AE2 cable special case - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { if (te instanceof TileCableBus) { TileCableBus cable = (TileCableBus) te; // do not try to strip color if it is already colorless diff --git a/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java b/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java index 15a3ebc2599..f5ce22ba925 100644 --- a/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java @@ -5,6 +5,7 @@ import gregtech.api.capability.IElectricItem; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.util.Mods; import gregtech.integration.baubles.BaublesModule; import net.minecraft.client.resources.I18n; @@ -26,7 +27,6 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.player.PlayerPickupXpEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.jetbrains.annotations.NotNull; @@ -162,7 +162,7 @@ public void onItemToss(@NotNull ItemTossEvent event) { if (event.getPlayer() == null) return; IInventory inventory = event.getPlayer().inventory; - if (Loader.isModLoaded(GTValues.MODID_BAUBLES)) { + if (Mods.Baubles.isModLoaded()) { inventory = BaublesModule.getBaublesWrappedInventory(event.getPlayer()); } diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index c346ac65e23..28e89934d0e 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -13,6 +13,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -128,7 +129,6 @@ import gregtech.integration.jei.multiblock.MultiblockInfoCategory; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.Loader; import java.util.HashMap; import java.util.Map; @@ -1169,7 +1169,7 @@ public static void init() { // organization. // ME Hatches, IDs 1745-1748 - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { FLUID_EXPORT_HATCH_ME = registerMetaTileEntity(1745, new MetaTileEntityMEOutputHatch(gregtechId("me_export_fluid_hatch"))); ITEM_EXPORT_BUS_ME = registerMetaTileEntity(1746, @@ -1290,7 +1290,7 @@ public static T registerMetaTileEntity(int id, T samp if (sampleMetaTileEntity instanceof IMultiblockAbilityPart abilityPart) { MultiblockAbility.registerMultiblockAbility(abilityPart.getAbility(), sampleMetaTileEntity); } - if (sampleMetaTileEntity instanceof MultiblockControllerBase && Loader.isModLoaded(GTValues.MODID_JEI)) { + if (sampleMetaTileEntity instanceof MultiblockControllerBase && Mods.JustEnoughItems.isModLoaded()) { if (((MultiblockControllerBase) sampleMetaTileEntity).shouldShowInJei()) { MultiblockInfoCategory.registerMultiblock((MultiblockControllerBase) sampleMetaTileEntity); } diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java index 926f7386174..f953dff1b4e 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java @@ -9,6 +9,7 @@ import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IPassthroughHatch; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.Mods; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.PipelineUtil; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; @@ -19,7 +20,6 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import appeng.api.util.AECableType; @@ -89,21 +89,21 @@ public void addInformation(ItemStack stack, @Nullable World player, List @Override public void update() { super.update(); - if (isFirstTick() && Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (isFirstTick() && Mods.AppliedEnergistics2.isModLoaded()) { if (getProxy() != null) getProxy().onReady(); } } @NotNull @Override - @Optional.Method(modid = GTValues.MODID_APPENG) + @Optional.Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return AECableType.SMART; } @Nullable @Override - @Optional.Method(modid = GTValues.MODID_APPENG) + @Optional.Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { if (gridProxy == null && getHolder() instanceof MetaTileEntityHolder) { gridProxy = new AENetworkProxy((MetaTileEntityHolder) getHolder(), "proxy", getStackForm(), true); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java index 0c34ab575ec..c09b9b91203 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java @@ -28,6 +28,7 @@ import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.util.BlockInfo; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.TextComponentUtil; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -64,7 +65,6 @@ import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -543,7 +543,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.7")); tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.8")); tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.9")); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { tooltip.add(I18n.format(AEConfig.instance().isFeatureEnabled(AEFeature.CHANNELS) ? "gregtech.machine.cleanroom.tooltip.ae2.channels" : "gregtech.machine.cleanroom.tooltip.ae2.no_channels")); diff --git a/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java b/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java index 56a96fb43ca..1439a5c5554 100644 --- a/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java +++ b/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java @@ -13,6 +13,7 @@ import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.pattern.*; +import gregtech.api.util.Mods; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -449,7 +450,7 @@ public static void addWallBlock(@NotNull Block block) { } @ZenMethod("addWallBlock") - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @SuppressWarnings("unused") public static void addWallBlockCT(@NotNull IBlock block) { WALL_BLOCKS.add(CraftTweakerMC.getBlock(block)); diff --git a/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java b/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java index 106b142c66f..ba42b1a29cc 100644 --- a/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java +++ b/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java @@ -1,6 +1,5 @@ package gregtech.common.terminal.app.prospector.widget; -import gregtech.api.GTValues; import gregtech.api.gui.IRenderContext; import gregtech.api.gui.Widget; import gregtech.api.unification.OreDictUnifier; @@ -33,7 +32,6 @@ import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -308,8 +306,7 @@ public void drawInForeground(int mouseX, int mouseY) { } } - if (Loader.isModLoaded(GTValues.MODID_JOURNEYMAP) || Loader.isModLoaded(GTValues.MODID_VOXELMAP) || - Loader.isModLoaded(GTValues.MODID_XAERO_MINIMAP)) { + if (Mods.JourneyMap.isModLoaded() || Mods.VoxelMap.isModLoaded() || Mods.XaerosMinimap.isModLoaded()) { tooltips.add(I18n.format("terminal.prospector.waypoint.add")); } this.drawHoveringText(ItemStack.EMPTY, tooltips, 300, mouseX, mouseY); @@ -336,11 +333,11 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { boolean added = false; trimHoveredNames(); - if (Loader.isModLoaded(GTValues.MODID_JOURNEYMAP)) { + if (Mods.JourneyMap.isModLoaded()) { added = addJourneymapWaypoint(b); - } else if (Loader.isModLoaded(GTValues.MODID_VOXELMAP)) { + } else if (Mods.VoxelMap.isModLoaded()) { added = addVoxelMapWaypoint(b); - } else if (Loader.isModLoaded(GTValues.MODID_XAERO_MINIMAP)) { + } else if (Mods.XaerosMinimap.isModLoaded()) { added = addXaeroMapWaypoint(b); } if (added) { @@ -382,7 +379,7 @@ private String createVeinName() { return s.substring(1, s.length() - 1); } - @Optional.Method(modid = GTValues.MODID_JOURNEYMAP) + @Optional.Method(modid = Mods.Names.JOURNEY_MAP) private boolean addJourneymapWaypoint(BlockPos b) { journeymap.client.model.Waypoint journeyMapWaypoint = new journeymap.client.model.Waypoint(createVeinName(), b, @@ -396,7 +393,7 @@ private boolean addJourneymapWaypoint(BlockPos b) { return false; } - @Optional.Method(modid = GTValues.MODID_VOXELMAP) + @Optional.Method(modid = Mods.Names.VOXEL_MAP) private boolean addVoxelMapWaypoint(@NotNull BlockPos b) { Color c = new Color(color); TreeSet world = new TreeSet<>(); @@ -425,7 +422,7 @@ private boolean addVoxelMapWaypoint(@NotNull BlockPos b) { return false; } - @Optional.Method(modid = GTValues.MODID_XAERO_MINIMAP) + @Optional.Method(modid = Mods.Names.XAEROS_MINIMAP) private boolean addXaeroMapWaypoint(@NotNull BlockPos b) { int red = clampColor(color >> 16 & 0xFF); int green = clampColor(color >> 8 & 0xFF); diff --git a/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java b/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java index f4b7fe6f2e1..8ead4466af8 100644 --- a/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java +++ b/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java @@ -17,6 +17,7 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.client.shader.Shaders; import gregtech.client.utils.DepthTextureUtil; import gregtech.client.utils.RenderBufferHelper; @@ -490,7 +491,7 @@ private static void renderScan(float getPartialTicks) { Minecraft mc = Minecraft.getMinecraft(); World world = mc.world; Entity viewer = mc.getRenderViewEntity(); - if (world != null && viewer != null && !Shaders.isOptiFineShaderPackLoaded()) { + if (world != null && viewer != null && !Mods.Optifine.isModLoaded()) { Framebuffer fbo = mc.getFramebuffer(); diff --git a/src/main/java/gregtech/integration/IntegrationModule.java b/src/main/java/gregtech/integration/IntegrationModule.java index 15d760b4a63..65f02e3c938 100644 --- a/src/main/java/gregtech/integration/IntegrationModule.java +++ b/src/main/java/gregtech/integration/IntegrationModule.java @@ -2,12 +2,12 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.modules.BaseGregTechModule; import gregtech.modules.GregTechModules; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -47,13 +47,13 @@ public List> getEventBusSubscribers() { public void init(FMLInitializationEvent event) { super.init(event); - if (Loader.isModLoaded(GTValues.MODID_IE)) { + if (Mods.ImmersiveEngineering.isModLoaded()) { BelljarHandler.registerBasicItemFertilizer(MetaItems.FERTILIZER.getStackForm(), 1.25f); logger.info("Registered Immersive Engineering Compat"); } } - @Optional.Method(modid = GTValues.MODID_EIO) + @Optional.Method(modid = Mods.Names.ENDER_IO) @SubscribeEvent public static void registerFertilizer(@NotNull RegistryEvent.Register event) { event.getRegistry().register(new Bonemeal(MetaItems.FERTILIZER.getStackForm())); diff --git a/src/main/java/gregtech/integration/IntegrationUtil.java b/src/main/java/gregtech/integration/IntegrationUtil.java index 88cfe6ec990..c25edab7be0 100644 --- a/src/main/java/gregtech/integration/IntegrationUtil.java +++ b/src/main/java/gregtech/integration/IntegrationUtil.java @@ -11,6 +11,7 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,9 +19,16 @@ import java.util.Arrays; import java.util.List; +@Deprecated public class IntegrationUtil { - /** Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} */ + /** + * Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} + * + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void throwIncompatibilityIfLoaded(String modID, String... customMessages) { if (Loader.isModLoaded(modID)) { String modName = TextFormatting.BOLD + modID + TextFormatting.RESET; @@ -31,7 +39,13 @@ public static void throwIncompatibilityIfLoaded(String modID, String... customMe } } - /** Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} */ + /** + * Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} + * + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void throwIncompatibility(List messages) { if (FMLLaunchHandler.side() == Side.SERVER) { throw new RuntimeException(String.join(",", messages)); @@ -40,16 +54,31 @@ public static void throwIncompatibility(List messages) { } } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta) { return getModItem(modid, name, meta, 1, null); } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta, int amount) { return getModItem(modid, name, meta, amount, null); } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta, int amount, @Nullable String nbt) { diff --git a/src/main/java/gregtech/integration/baubles/BaublesModule.java b/src/main/java/gregtech/integration/baubles/BaublesModule.java index 4371d5a032d..6f725211e8f 100644 --- a/src/main/java/gregtech/integration/baubles/BaublesModule.java +++ b/src/main/java/gregtech/integration/baubles/BaublesModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.integration.IntegrationSubmodule; import gregtech.modules.GregTechModules; @@ -24,7 +25,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_BAUBLES, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_BAUBLES, + modDependencies = Mods.Names.BAUBLES, name = "GregTech Baubles Integration", description = "Baubles Integration Module") public class BaublesModule extends IntegrationSubmodule { diff --git a/src/main/java/gregtech/integration/chisel/ChiselModule.java b/src/main/java/gregtech/integration/chisel/ChiselModule.java index c6dc3cafe05..c8a5f8d3416 100644 --- a/src/main/java/gregtech/integration/chisel/ChiselModule.java +++ b/src/main/java/gregtech/integration/chisel/ChiselModule.java @@ -5,6 +5,7 @@ import gregtech.api.modules.GregTechModule; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; +import gregtech.api.util.Mods; import gregtech.common.blocks.BlockColored; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockWarningSign; @@ -31,7 +32,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_CHISEL, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_CHISEL, + modDependencies = Mods.Names.CHISEL, name = "GregTech Chisel Integration", description = "Chisel Integration Module") public class ChiselModule extends IntegrationSubmodule { @@ -110,7 +111,7 @@ private void addVariation(String group, Block block, int meta) { tag.setString("group", group); tag.setString("block", Objects.requireNonNull(block.getRegistryName()).toString()); tag.setInteger("meta", meta); - FMLInterModComms.sendMessage(GTValues.MODID_CHISEL, "add_variation", tag); + FMLInterModComms.sendMessage(Mods.Names.CHISEL, "add_variation", tag); } private boolean doesGroupExist(String group) { diff --git a/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java b/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java index 400c41a1110..37fb6535fe5 100644 --- a/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java +++ b/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java @@ -4,6 +4,7 @@ import gregtech.api.items.metaitem.MetaOreDictItem; import gregtech.api.modules.GregTechModule; import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.crafttweaker.recipe.MetaItemBracketHandler; @@ -27,7 +28,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_CT, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_CT, + modDependencies = Mods.Names.CRAFT_TWEAKER, name = "GregTech CraftTweaker Integration", description = "CraftTweaker Integration Module") public class CraftTweakerModule extends IntegrationSubmodule { diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java index b8dc8e77a9b..d12a134adc5 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java @@ -1,6 +1,5 @@ package gregtech.integration.crafttweaker.material; -import gregtech.api.GTValues; import gregtech.api.fluids.FluidBuilder; import gregtech.api.fluids.FluidState; import gregtech.api.fluids.store.FluidStorageKey; @@ -14,6 +13,7 @@ import gregtech.api.unification.material.properties.ToolProperty; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.enchantment.Enchantment; @@ -264,7 +264,7 @@ public CTMaterialBuilder itemPipeProperties(int priority, float stacksPerSec) { } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public CTMaterialBuilder addDefaultEnchant(IEnchantment enchantment) { Enchantment enchantmentType = (Enchantment) enchantment.getDefinition().getInternal(); backingBuilder.addDefaultEnchant(enchantmentType, enchantment.getLevel()); diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java index 3f8e854cb29..aeef7c2ac07 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java @@ -1,11 +1,11 @@ package gregtech.integration.crafttweaker.material; -import gregtech.api.GTValues; import gregtech.api.fluids.store.FluidStorageKeys; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.*; +import gregtech.api.util.Mods; import net.minecraft.enchantment.Enchantment; @@ -65,7 +65,7 @@ public static boolean isGaseous(Material m) { // TODO May need to move this to Material @ZenGetter("fluid") - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static ILiquidDefinition getFluid(Material m) { FluidProperty prop = m.getProperty(PropertyKey.FLUID); if (prop != null) { @@ -164,13 +164,13 @@ public static int toolEnchant(Material m) { } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static void addToolEnchantment(Material m, IEnchantment enchantment) { addScaledToolEnchantment(m, enchantment, 0); } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static void addScaledToolEnchantment(Material m, IEnchantment enchantment, double levelGrowth) { if (checkFrozen("add tool enchantment")) return; ToolProperty prop = m.getProperty(PropertyKey.TOOL); diff --git a/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java b/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java index 76d76eb64c9..287b9a9e647 100644 --- a/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java +++ b/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java @@ -1,6 +1,6 @@ package gregtech.integration.ctm; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.block.state.IBlockState; import net.minecraft.util.EnumFacing; @@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull; import team.chisel.ctm.api.IFacade; -@Optional.Interface(modid = GTValues.MODID_CTM, iface = "team.chisel.ctm.api.IFacade") +@Optional.Interface(modid = Mods.Names.CONNECTED_TEXTURES_MOD, iface = "team.chisel.ctm.api.IFacade") public interface IFacadeWrapper extends IFacade { @NotNull diff --git a/src/main/java/gregtech/integration/forestry/ForestryModule.java b/src/main/java/gregtech/integration/forestry/ForestryModule.java index de316640666..b938f4ab228 100644 --- a/src/main/java/gregtech/integration/forestry/ForestryModule.java +++ b/src/main/java/gregtech/integration/forestry/ForestryModule.java @@ -15,6 +15,7 @@ import gregtech.api.unification.material.properties.OreProperty; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.Mods; import gregtech.common.items.ToolItems; import gregtech.integration.IntegrationModule; import gregtech.integration.IntegrationSubmodule; @@ -31,7 +32,6 @@ import net.minecraft.item.crafting.IRecipe; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -52,7 +52,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_FR, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_FR, + modDependencies = Mods.Names.FORESTRY, name = "GregTech Forestry Integration", description = "Forestry Integration Module") public class ForestryModule extends IntegrationSubmodule { @@ -100,7 +100,7 @@ public void preInit(FMLPreInitializationEvent event) { // GT Frames if (ForestryConfig.enableGTFrames) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { FRAME_ACCELERATED = new GTItemFrame(GTFrameType.ACCELERATED); FRAME_MUTAGENIC = new GTItemFrame(GTFrameType.MUTAGENIC); FRAME_WORKING = new GTItemFrame(GTFrameType.WORKING); @@ -126,7 +126,7 @@ public void preInit(FMLPreInitializationEvent event) { // GT Bees if (ForestryConfig.enableGTBees) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { DROPS = new GTDropItem(); COMBS = new GTCombItem(); } else { @@ -137,7 +137,7 @@ public void preInit(FMLPreInitializationEvent event) { // Remove duplicate/conflicting bees from other Forestry addons. // Done in init to have our changes applied before their registration, // since we load after other Forestry addons purposefully. - if (ForestryConfig.disableConflictingBees && ForestryUtil.apicultureEnabled()) { + if (ForestryConfig.disableConflictingBees && Mods.ForestryApiculture.isModLoaded()) { BeeRemovals.init(); } @@ -154,7 +154,7 @@ public void init(FMLInitializationEvent event) { ForestryElectrodeRecipes.onInit(); } - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.harderForestryRecipes) { ForestryMiscRecipes.initRemoval(); } @@ -165,12 +165,12 @@ public void init(FMLInitializationEvent event) { } } - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { registerAlvearyMutators(); } if (event.getSide() == Side.CLIENT) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTBees) { Minecraft.getMinecraft().getItemColors().registerItemColorHandler((stack, tintIndex) -> { if (stack.getItem() instanceof IColoredItem coloredItem) { @@ -185,7 +185,7 @@ public void init(FMLInitializationEvent event) { @Override public void postInit(FMLPostInitializationEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { getLogger().info("Copying Forestry Centrifuge recipes to GT Centrifuge"); CombRecipes.initForestryCombs(); } @@ -196,7 +196,7 @@ public static void registerItems(RegistryEvent.Register event) { IForgeRegistry registry = event.getRegistry(); // GT Frames - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { registry.register(FRAME_ACCELERATED); registry.register(FRAME_MUTAGENIC); @@ -222,20 +222,19 @@ public static void registerItems(RegistryEvent.Register event) { ELECTRODE_OBSIDIAN = forestryMetaItem.addItem(10, "electrode.obsidian"); ELECTRODE_TIN = forestryMetaItem.addItem(11, "electrode.tin"); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { ELECTRODE_IRON = forestryMetaItem.addItem(12, "electrode.iron"); } - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { ELECTRODE_ORCHID = forestryMetaItem.addItem(13, "electrode.orchid"); } - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_TR) || - Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.TechReborn.isModLoaded() || Mods.BinnieCore.isModLoaded()) { ELECTRODE_RUBBER = forestryMetaItem.addItem(14, "electrode.rubber"); } } // GT Drops - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTBees) { registry.register(DROPS); registry.register(COMBS); @@ -246,7 +245,7 @@ public static void registerItems(RegistryEvent.Register event) { @SideOnly(Side.CLIENT) @SubscribeEvent public static void registerModels(ModelRegistryEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { FRAME_ACCELERATED.registerModel(FRAME_ACCELERATED, ForestryAPI.modelManager); FRAME_MUTAGENIC.registerModel(FRAME_MUTAGENIC, ForestryAPI.modelManager); @@ -265,7 +264,7 @@ public static void registerModels(ModelRegistryEvent event) { @SubscribeEvent public static void registerRecipes(RegistryEvent.Register event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { // GT Frames if (ForestryConfig.enableGTFrames) { ForestryFrameRecipes.init(); @@ -294,7 +293,7 @@ public static void registerRecipes(RegistryEvent.Register event) { @SubscribeEvent public static void registerMaterials(MaterialEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { Materials.TreatedWood.addFlags(MaterialFlags.GENERATE_LONG_ROD); Materials.Uranium235.addFlags(MaterialFlags.GENERATE_LONG_ROD); diff --git a/src/main/java/gregtech/integration/forestry/ForestryUtil.java b/src/main/java/gregtech/integration/forestry/ForestryUtil.java index 32fff8e1e19..1bc2a8df6c0 100644 --- a/src/main/java/gregtech/integration/forestry/ForestryUtil.java +++ b/src/main/java/gregtech/integration/forestry/ForestryUtil.java @@ -1,6 +1,6 @@ package gregtech.integration.forestry; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; import gregtech.integration.forestry.bees.GTCombType; import gregtech.integration.forestry.bees.GTDropType; @@ -11,52 +11,39 @@ import forestry.api.apiculture.IAlleleBeeSpecies; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAlleleFlowers; -import forestry.modules.ModuleHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ForestryUtil { - public static boolean apicultureEnabled() { - return ModuleHelper.isEnabled("apiculture"); - } - - public static boolean arboricultureEnabled() { - return ModuleHelper.isEnabled("arboriculture"); - } - - public static boolean lepidopterologyEnabled() { - return ModuleHelper.isEnabled("lepidopterology"); - } - @Nullable - public static IAlleleBeeEffect getEffect(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.effect." + name; - case GTValues.MODID_MB -> "magicbees.effect" + name; - case GTValues.MODID -> "gregtech.effect." + name; + public static IAlleleBeeEffect getEffect(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.effect." + name; + case MagicBees -> "magicbees.effect" + name; + case GregTech -> "gregtech.effect." + name; default -> "forestry.effect" + name; }; return (IAlleleBeeEffect) AlleleManager.alleleRegistry.getAllele(s); } @Nullable - public static IAlleleFlowers getFlowers(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.flower." + name; - case GTValues.MODID_MB -> "magicbees.flower" + name; - case GTValues.MODID -> "gregtech.flower." + name; + public static IAlleleFlowers getFlowers(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.flower." + name; + case MagicBees -> "magicbees.flower" + name; + case GregTech -> "gregtech.flower." + name; default -> "forestry.flowers" + name; }; return (IAlleleFlowers) AlleleManager.alleleRegistry.getAllele(s); } @Nullable - public static IAlleleBeeSpecies getSpecies(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.species." + name; - case GTValues.MODID_MB -> "magicbees.species" + name; - case GTValues.MODID -> "gregtech.species." + name; + public static IAlleleBeeSpecies getSpecies(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.species." + name; + case MagicBees -> "magicbees.species" + name; + case GregTech -> "gregtech.species." + name; default -> "forestry.species" + name; }; return (IAlleleBeeSpecies) AlleleManager.alleleRegistry.getAllele(s); @@ -74,7 +61,7 @@ public static ItemStack getCombStack(@NotNull GTCombType type, int amount) { .error("Tried to get GregTech Comb stack, but GregTech Bees config is not enabled!"); return ItemStack.EMPTY; } - if (!apicultureEnabled()) { + if (!Mods.ForestryApiculture.isModLoaded()) { IntegrationModule.logger.error("Tried to get GregTech Comb stack, but Apiculture module is not enabled!"); return ItemStack.EMPTY; } @@ -93,7 +80,7 @@ public static ItemStack getDropStack(@NotNull GTDropType type, int amount) { .error("Tried to get GregTech Drop stack, but GregTech Bees config is not enabled!"); return ItemStack.EMPTY; } - if (!apicultureEnabled()) { + if (!Mods.ForestryApiculture.isModLoaded()) { IntegrationModule.logger.error("Tried to get GregTech Drop stack, but Apiculture module is not enabled!"); return ItemStack.EMPTY; } diff --git a/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java b/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java index 65546dfe020..39dcb08e103 100644 --- a/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java +++ b/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java @@ -1,10 +1,8 @@ package gregtech.integration.forestry.bees; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; -import net.minecraftforge.fml.common.Loader; - import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -16,10 +14,10 @@ public class BeeRemovals { private static final List EB_REMOVALS = new ArrayList<>(); public static void init() { - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { removeMagicBees(); } - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { removeExtraBees(); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java b/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java index 891a8277bc9..0bd8d25bf53 100644 --- a/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java +++ b/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java @@ -3,7 +3,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.machines.IScannerRecipeMap; -import gregtech.integration.forestry.ForestryUtil; +import gregtech.api.util.Mods; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -60,7 +60,7 @@ public List getRepresentativeRecipes() { List recipes = new ArrayList<>(); ItemStack outputStack; - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { outputStack = ModuleApiculture.getItems().beeDroneGE.getItemStack(); outputStack.setTagCompound(BeeDefinition.COMMON.getIndividual().writeToNBT(new NBTTagCompound())); outputStack.setTranslatableName("gregtech.scanner.forestry.drone"); @@ -98,7 +98,7 @@ public List getRepresentativeRecipes() { .duration(DURATION).EUt(EUT).build().getResult()); } - if (ForestryUtil.arboricultureEnabled()) { + if (Mods.ForestryArboriculture.isModLoaded()) { outputStack = ModuleArboriculture.getItems().sapling.getItemStack(); outputStack.setTagCompound(TreeDefinition.Oak.getIndividual().writeToNBT(new NBTTagCompound())); outputStack.setTranslatableName("gregtech.scanner.forestry.sapling"); @@ -118,7 +118,7 @@ public List getRepresentativeRecipes() { .duration(DURATION).EUt(EUT).build().getResult()); } - if (ForestryUtil.lepidopterologyEnabled()) { + if (Mods.ForestryLepidopterology.isModLoaded()) { outputStack = ModuleLepidopterology.getItems().butterflyGE.getItemStack(); outputStack .setTagCompound(ButterflyDefinition.CabbageWhite.getIndividual().writeToNBT(new NBTTagCompound())); diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 269e992be1b..d4a967e4bfe 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -5,9 +5,9 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryModule; import gregtech.integration.forestry.ForestryUtil; @@ -15,7 +15,6 @@ import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.common.BiomeDictionary; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import appeng.core.Api; @@ -48,7 +47,7 @@ public enum GTBeeDefinition implements IBeeDefinition { // Organic CLAY(GTBranchDefinition.GT_ORGANIC, "Lutum", true, 0xC8C8DA, 0x0000FF, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(22), 0.30f); // CLAY } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.30f); @@ -56,8 +55,8 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addProduct(new ItemStack(Items.CLAY_BALL), 0.15f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.NORMAL); - if (Loader.isModLoaded(GTValues.MODID_BOP)) { - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_BOP, "mudball", 0), 0.05f); + if (Mods.BiomesOPlenty.isModLoaded()) { + beeSpecies.addSpecialty(Mods.BiomesOPlenty.getItem("mudball", 0), 0.05f); } }, template -> { @@ -77,10 +76,9 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addSpecialty(getGTComb(GTCombType.STICKY), 0.05f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.NORMAL); - if (Loader.isModLoaded(GTValues.MODID_TCON)) { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_TCON, "edible", 1), 0.10f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_TCON, "slime_congealed", 2), - 0.01f); + if (Mods.TinkersConstruct.isModLoaded()) { + beeSpecies.addProduct(Mods.TinkersConstruct.getItem("edible", 1), 0.10f); + beeSpecies.addSpecialty(Mods.TinkersConstruct.getItem("slime_congealed", 2), 0.01f); } else { beeSpecies.addSpecialty(new ItemStack(Blocks.SLIME_BLOCK), 0.01f); } @@ -90,9 +88,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.SLOWER); AlleleHelper.getInstance().set(template, TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.BOTH_1); AlleleHelper.getInstance().set(template, HUMIDITY_TOLERANCE, EnumAllele.Tolerance.BOTH_1); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "water")); + ForestryUtil.getFlowers(Mods.ExtraBees, "water")); } }, dis -> { @@ -167,15 +165,15 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER); AlleleHelper.getInstance().set(template, TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.NONE); AlleleHelper.getInstance().set(template, HUMIDITY_TOLERANCE, EnumAllele.Tolerance.NONE); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "water")); + ForestryUtil.getFlowers(Mods.ExtraBees, "water")); } }, dis -> dis.registerMutation(COAL, STICKYRESIN, 4)), ASH(GTBranchDefinition.GT_ORGANIC, "Cinis", true, 0x1E1A18, 0xC6C6C6, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.30f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.30f); @@ -197,7 +195,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), APATITE(GTBranchDefinition.GT_ORGANIC, "Stercorat", true, 0x7FCEF5, 0x654525, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.15f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.15f); @@ -211,9 +209,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.LONGER); AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, EnumAllele.Flowers.WHEAT); AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.FASTER); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "rock")); + ForestryUtil.getFlowers(Mods.ExtraBees, "rock")); } }, dis -> { @@ -239,7 +237,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), FERTILIZER(GTBranchDefinition.GT_ORGANIC, "Stercorat", true, 0x7FCEF5, 0x654525, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.15f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.MOSSY), 0.15f); @@ -247,7 +245,7 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addSpecialty(OreDictUnifier.get(OrePrefix.dustTiny, Materials.Ash), 0.2f); beeSpecies.addSpecialty(OreDictUnifier.get(OrePrefix.dustTiny, Materials.DarkAsh), 0.2f); beeSpecies.addSpecialty(MetaItems.FERTILIZER.getStackForm(), 0.3f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_compound", 0), 0.3f); + beeSpecies.addSpecialty(Mods.Forestry.getItem("fertilizer_compound", 0), 0.3f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.WARM); }, @@ -273,16 +271,12 @@ public enum GTBeeDefinition implements IBeeDefinition { }), SANDWICH(GTBranchDefinition.GT_ORGANIC, "Sandwico", true, 0x32CD32, 0xDAA520, beeSpecies -> { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 81), 0.05f); // Cucumber - // Slice - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 80), 0.05f); // Onion - // Slice - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 79), 0.05f); // Tomato - // Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 81), 0.05f); // Cucumber Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 80), 0.05f); // Onion Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 79), 0.05f); // Tomato Slice beeSpecies.addSpecialty(new ItemStack(Items.COOKED_PORKCHOP), 0.05f); beeSpecies.addSpecialty(new ItemStack(Items.COOKED_BEEF), 0.15f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 97), 0.05f); // Cheddar - // Slice + beeSpecies.addSpecialty(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 97), 0.05f); // Cheddar Slice beeSpecies.setHumidity(EnumHumidity.NORMAL); beeSpecies.setTemperature(EnumTemperature.NORMAL); }, @@ -296,14 +290,13 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.FASTER); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB)) { - dis.registerMutation(BeeDefinition.AGRARIAN, ForestryUtil.getSpecies(GTValues.MODID_MB, "Batty"), - 10); + if (Mods.MagicBees.isModLoaded()) { + dis.registerMutation(BeeDefinition.AGRARIAN, ForestryUtil.getSpecies(Mods.MagicBees, "Batty"), 10); } else { dis.registerMutation(BeeDefinition.AGRARIAN, BeeDefinition.IMPERIAL, 10); } }, - () -> Loader.isModLoaded(GTValues.MODID_GTFO)), + Mods.GregTechFoodOption::isModLoaded), // Gems REDSTONE(GTBranchDefinition.GT_GEM, "Rubrumlapis", true, 0x7D0F0F, 0xD11919, @@ -357,7 +350,7 @@ public enum GTBeeDefinition implements IBeeDefinition { Api.INSTANCE.definitions().blocks().fluixBlock().maybeBlock() .ifPresent(block -> mutation.requireResource(block.getDefaultState())); }, - () -> Loader.isModLoaded(GTValues.MODID_APPENG)), + Mods.AppliedEnergistics2::isModLoaded), DIAMOND(GTBranchDefinition.GT_GEM, "Adamas", false, 0xCCFFFF, 0xA3CCCC, beeSpecies -> { beeSpecies.addProduct(getGTComb(GTCombType.STONE), 0.30f); @@ -422,7 +415,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), SPARKLING(GTBranchDefinition.GT_GEM, "Vesperstella", true, 0x7A007A, 0xFFFFFF, beeSpecies -> { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 3), 0.20f); + beeSpecies.addProduct(Mods.MagicBees.getItem("resource", 3), 0.20f); beeSpecies.addSpecialty(getGTComb(GTCombType.SPARKLING), 0.125f); beeSpecies.setHumidity(EnumHumidity.NORMAL); beeSpecies.setTemperature(EnumTemperature.NORMAL); @@ -438,12 +431,12 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation( - ForestryUtil.getSpecies(GTValues.MODID_MB, "Withering"), - ForestryUtil.getSpecies(GTValues.MODID_MB, "Draconic"), 1); + ForestryUtil.getSpecies(Mods.MagicBees, "Withering"), + ForestryUtil.getSpecies(Mods.MagicBees, "Draconic"), 1); mutation.requireResource("blockNetherStar"); mutation.restrictBiomeType(BiomeDictionary.Type.END); }, - () -> Loader.isModLoaded(GTValues.MODID_MB)), + Mods.MagicBees::isModLoaded), // Metals COPPER(GTBranchDefinition.GT_METAL, "Cuprum", true, 0xFF6600, 0xE65C00, @@ -588,9 +581,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, TOLERATES_RAIN, true); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB) && Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.MagicBees.isModLoaded() && Mods.AppliedEnergistics2.isModLoaded()) { // MB Skystone bee is only registered if AE2 is also active - dis.registerMutation(IRON, ForestryUtil.getSpecies(GTValues.MODID_MB, "AESkystone"), 17); + dis.registerMutation(IRON, ForestryUtil.getSpecies(Mods.MagicBees, "AESkystone"), 17); } else { dis.registerMutation(IRON, BeeDefinition.IMPERIAL, 17); } @@ -768,7 +761,7 @@ public enum GTBeeDefinition implements IBeeDefinition { // Industrial ENERGY(GTBranchDefinition.GT_INDUSTRIAL, "Industria", false, 0xC11F1F, 0xEBB9B9, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(14), 0.30f); // STATIC } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.SIMMERING), 0.30f); @@ -789,9 +782,9 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { mutation = dis.registerMutation(BeeDefinition.DEMONIC, - ForestryUtil.getSpecies(GTValues.MODID_EB, "volcanic"), 10); + ForestryUtil.getSpecies(Mods.ExtraBees, "volcanic"), 10); } else { mutation = dis.registerMutation(BeeDefinition.DEMONIC, BeeDefinition.FIENDISH, 10); } @@ -988,8 +981,8 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_EB)) { - mutation = dis.registerMutation(THORIUM, ForestryUtil.getSpecies(GTValues.MODID_EB, "rotten"), 1); + if (Mods.ExtraBees.isModLoaded()) { + mutation = dis.registerMutation(THORIUM, ForestryUtil.getSpecies(Mods.ExtraBees, "rotten"), 1); } else { mutation = dis.registerMutation(THORIUM, BeeDefinition.IMPERIAL, 1); } @@ -1041,9 +1034,9 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { mutation = dis.registerMutation(STAINLESSSTEEL, - ForestryUtil.getSpecies(GTValues.MODID_MB, "Watery"), 10); + ForestryUtil.getSpecies(Mods.MagicBees, "Watery"), 10); } else { mutation = dis.registerMutation(STAINLESSSTEEL, BeeDefinition.INDUSTRIOUS, 10); } @@ -1060,9 +1053,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(HELIUM, ForestryUtil.getSpecies(GTValues.MODID_MB, "Supernatural"), - 8); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(HELIUM, ForestryUtil.getSpecies(Mods.MagicBees, "Supernatural"), 8); } else { mutation = dis.registerMutation(HELIUM, BeeDefinition.IMPERIAL, 8); } @@ -1092,9 +1084,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(NEON, ForestryUtil.getSpecies(GTValues.MODID_MB, "Supernatural"), - 4); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(NEON, ForestryUtil.getSpecies(Mods.MagicBees, "Supernatural"), 4); } else { mutation = dis.registerMutation(NEON, BeeDefinition.AVENGING, 4); } @@ -1139,8 +1130,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(OXYGEN, ForestryUtil.getSpecies(GTValues.MODID_MB, "Watery"), 15); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(OXYGEN, ForestryUtil.getSpecies(Mods.MagicBees, "Watery"), 15); } else { mutation = dis.registerMutation(OXYGEN, BeeDefinition.INDUSTRIOUS, 15); } @@ -1233,14 +1224,14 @@ private static ItemStack getForestryComb(EnumHoneyComb type) { return ModuleApiculture.getItems().beeComb.get(type, 1); } - @Optional.Method(modid = GTValues.MODID_EB) + @Optional.Method(modid = Mods.Names.EXTRA_BEES) private static ItemStack getExtraBeesComb(int meta) { - return IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_comb", meta); + return Mods.ExtraBees.getItem("honey_comb", meta); } - @Optional.Method(modid = GTValues.MODID_MB) + @Optional.Method(modid = Mods.Names.MAGIC_BEES) private static ItemStack getMagicBeesComb(int meta) { - return IntegrationUtil.getModItem(GTValues.MODID_MB, "beecomb", meta); + return Mods.MagicBees.getItem("beecomb", meta); } private static ItemStack getGTComb(GTCombType type) { diff --git a/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java b/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java index 0769ad034bf..e037872f2cf 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.bees; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; @@ -37,7 +38,7 @@ public GTCombItem() { public void registerModel(@NotNull Item item, IModelManager manager) { manager.registerItemModel(item, 0); for (int i = 0; i < GTCombType.values().length; i++) { - manager.registerItemModel(item, i, GTValues.MODID_FR, "gt.comb"); + manager.registerItemModel(item, i, Mods.Names.FORESTRY, "gt.comb"); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/GTCombType.java b/src/main/java/gregtech/integration/forestry/bees/GTCombType.java index f774e6f68d0..e17fc00a429 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTCombType.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTCombType.java @@ -1,8 +1,6 @@ package gregtech.integration.forestry.bees; -import gregtech.api.GTValues; - -import net.minecraftforge.fml.common.Loader; +import gregtech.api.util.Mods; public enum GTCombType { @@ -27,7 +25,7 @@ public enum GTCombType { // Gem STONE("stone", 0x808080, 0x999999), CERTUS("certus", 0x57CFFB, 0xBBEEFF), - FLUIX("fluix", 0xA375FF, 0xB591FF, Loader.isModLoaded(GTValues.MODID_APPENG)), + FLUIX("fluix", 0xA375FF, 0xB591FF, Mods.AppliedEnergistics2.isModLoaded()), REDSTONE("redstone", 0x7D0F0F, 0xD11919), RAREEARTH("rareearth", 0x555643, 0x343428), LAPIS("lapis", 0x1947D1, 0x476CDA), @@ -38,7 +36,7 @@ public enum GTCombType { EMERALD("emerald", 0x248F24, 0x2EB82E), PYROPE("pyrope", 0x763162, 0x8B8B8B), GROSSULAR("grossular", 0x9B4E00, 0x8B8B8B), - SPARKLING("sparkling", 0x7A007A, 0xFFFFFF, Loader.isModLoaded(GTValues.MODID_MB)), + SPARKLING("sparkling", 0x7A007A, 0xFFFFFF, Mods.MagicBees.isModLoaded()), // Metal SLAG("slag", 0xD4D4D4, 0x58300B), diff --git a/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java b/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java index 45a67068b2a..a8453a6a151 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.bees; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; @@ -44,7 +45,7 @@ private void setResearchSuitability(@Nullable ISpeciesRoot speciesRoot) { public void registerModel(@NotNull Item item, @NotNull IModelManager manager) { manager.registerItemModel(item, 0); for (int i = 0; i < GTDropType.VALUES.length; i++) { - manager.registerItemModel(item, i, GTValues.MODID_FR, "gt.honey_drop"); + manager.registerItemModel(item, i, Mods.Names.FORESTRY, "gt.honey_drop"); } } diff --git a/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java b/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java index 088c5ed7e73..e8f9a46d45e 100644 --- a/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java +++ b/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.frames; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.Item; @@ -62,7 +63,7 @@ public IBeeModifier getBeeModifier() { @SuppressWarnings("deprecation") @Override public void registerModel(@NotNull Item item, @NotNull IModelManager manager) { - manager.registerItemModel(item, 0, GTValues.MODID_FR, "gt.frame_" + type.getName().toLowerCase()); + manager.registerItemModel(item, 0, Mods.Names.FORESTRY, "gt.frame_" + type.getName().toLowerCase()); } public ItemStack getItemStack() { diff --git a/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java index 66df87dc408..a7661982176 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java @@ -12,8 +12,8 @@ import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryUtil; import gregtech.integration.forestry.bees.GTCombItem; import gregtech.integration.forestry.bees.GTCombType; @@ -21,7 +21,6 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import appeng.core.Api; import com.google.common.collect.ImmutableMap; @@ -98,8 +97,8 @@ public static void initGTCombs() { ModuleCore.getItems().refractoryWax.getItemStack() }, new int[] { 20 * 100, 50 * 100 }, Voltage.HV, 196); ItemStack wax = ModuleCore.getItems().beeswax.getItemStack(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { - wax = IntegrationUtil.getModItem(GTValues.MODID_MB, "wax", 2); + if (Mods.MagicBees.isModLoaded()) { + wax = Mods.MagicBees.getItem("wax", 2); } addCentrifugeToItemStack(GTCombType.LAPOTRON, new ItemStack[] { OreDictUnifier.get(OrePrefix.dust, Materials.Lapotron), wax }, @@ -271,11 +270,10 @@ public static void initGTCombs() { .cleanroom(CleanroomType.CLEANROOM) .duration(3000).EUt(Voltage.UV.getChemicalEnergy()).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { addProcessGT(GTCombType.SPARKLING, new Material[] { Materials.NetherStar }, Voltage.EV); addCentrifugeToItemStack(GTCombType.SPARKLING, - new ItemStack[] { IntegrationUtil.getModItem(GTValues.MODID_MB, "wax", 0), - IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 5), + new ItemStack[] { Mods.MagicBees.getItem("wax", 0), Mods.MagicBees.getItem("resource", 5), OreDictUnifier.get(OrePrefix.dustTiny, Materials.NetherStar) }, new int[] { 50 * 100, 10 * 100, 10 * 100 }, Voltage.EV); } @@ -290,7 +288,7 @@ public static void initGTCombs() { addExtractorProcess(GTCombType.HYDROGEN, Materials.Hydrogen.getFluid(500), Voltage.MV, 100); addExtractorProcess(GTCombType.FLUORINE, Materials.Fluorine.getFluid(250), Voltage.MV, 128); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { ItemStack fluixDust = OreDictUnifier.get("dustFluix"); if (fluixDust == ItemStack.EMPTY) { fluixDust = Api.INSTANCE.definitions().materials().fluixDust().maybeStack(1).orElse(ItemStack.EMPTY); diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java index 171f575bc32..72014ca62c6 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java @@ -1,14 +1,13 @@ package gregtech.integration.forestry.recipes; -import gregtech.api.GTValues; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; import gregtech.integration.forestry.ForestryModule; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import forestry.api.recipes.RecipeManagers; import forestry.core.ModuleCore; @@ -137,7 +136,7 @@ public static void addGregTechMachineRecipes() { .output(ForestryModule.ELECTRODE_GOLD, 2) .buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_IRON) .fluidInputs(Glass.getFluid(100)) @@ -176,7 +175,7 @@ public static void addGregTechMachineRecipes() { .output(ForestryModule.ELECTRODE_OBSIDIAN, 4) .buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_ORCHID) .fluidInputs(Glass.getFluid(100)) @@ -191,8 +190,7 @@ public static void addGregTechMachineRecipes() { } // todo mixin forestry to allow this tube always, since we have rubber (once mixin port is done) - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_TR) || - Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.TechReborn.isModLoaded() || Mods.BinnieCore.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_RUBBER) .fluidInputs(Glass.getFluid(100)) @@ -248,7 +246,7 @@ private static void addForestryMachineRecipes() { '#', new UnificationEntry(wireGtSingle, RedAlloy).toString(), 'X', new UnificationEntry(plate, Bronze).toString()); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { addFabricatorRecipe(EnumElectronTube.IRON, "SXS", "#X#", "XXX", 'S', new UnificationEntry(screw, Iron).toString(), @@ -301,7 +299,7 @@ private static void addForestryMachineRecipes() { '#', new UnificationEntry(plate, EnderEye).toString(), 'X', new ItemStack(Blocks.END_STONE)); - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { addFabricatorRecipe(EnumElectronTube.ORCHID, " X ", "#X#", "XXX", '#', new ItemStack(Items.REPEATER), diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java index 5a57da584cc..e1face8fe9e 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java @@ -1,16 +1,14 @@ package gregtech.integration.forestry.recipes; -import gregtech.api.GTValues; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMaps; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; -import gregtech.integration.IntegrationUtil; +import gregtech.api.util.Mods; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import forestry.core.fluids.Fluids; @@ -18,171 +16,107 @@ public class ForestryExtractorRecipes { public static void init() { // Commonly used items - ItemStack mulch = IntegrationUtil.getModItem(GTValues.MODID_FR, "mulch", 0); - ItemStack propolis = IntegrationUtil.getModItem(GTValues.MODID_FR, "propolis", 0); + ItemStack mulch = Mods.Forestry.getItem("mulch"); + ItemStack propolis = Mods.Forestry.getItem("propolis"); // Vanilla Fruit Juice items addFruitJuiceRecipe(new ItemStack(Items.CARROT), 200, GTUtility.copy(mulch), 2000); addFruitJuiceRecipe(new ItemStack(Items.APPLE), 200, GTUtility.copy(mulch), 2000); // Forestry fruits - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 0), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 1), 180, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 2), 220, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 3), 400, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 4), 100, GTUtility.copy(mulch), - 6000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 5), 50, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 6), 600, GTUtility.copy(mulch), - 1000); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 0), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 1), 180, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 2), 220, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 3), 400, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 4), 100, GTUtility.copy(mulch), 6000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 5), 50, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 6), 600, GTUtility.copy(mulch), 1000); // Honey, Honeydew - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "honey_drop", 0), 100, GTUtility.copy(propolis), - 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "honeydew", 0), 100); + addHoneyRecipe(Mods.Forestry.getItem("honey_drop"), 100, GTUtility.copy(propolis), 0); + addHoneyRecipe(Mods.Forestry.getItem("honeydew"), 100); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { // Propolis - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 0), - Materials.Water.getFluid(500)); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 1), - Materials.Oil.getFluid(500)); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 2), - Materials.Creosote.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 0), Materials.Water.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 1), Materials.Oil.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 2), Materials.Creosote.getFluid(500)); // Drops - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 3), 200); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 6), - Fluids.MILK.getFluid(200)); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 13), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 19), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 14), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 20), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 15), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 21), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 16), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 22), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 17), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 24), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 18), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 23), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 19), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 25), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 20), 200, - new ItemStack(Items.DYE, 1, 14), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 21), 200, - new ItemStack(Items.DYE, 1, 6), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 22), 200, - new ItemStack(Items.DYE, 1, 5), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 23), 200, - new ItemStack(Items.DYE, 1, 8), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 24), 200, - new ItemStack(Items.DYE, 1, 12), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 25), 200, - new ItemStack(Items.DYE, 1, 9), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 26), 200, - new ItemStack(Items.DYE, 1, 10), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 27), 200, - new ItemStack(Items.DYE, 1, 13), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 28), 200, - new ItemStack(Items.DYE, 1, 7), 0); + addFruitJuiceRecipe(Mods.ExtraBees.getItem("honey_drop", 3), 200); + addExtractorRecipe(Mods.ExtraBees.getItem("honey_drop", 6), Fluids.MILK.getFluid(200)); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 13), 200, Mods.ExtraBees.getItem("misc", 19), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 14), 200, Mods.ExtraBees.getItem("misc", 20), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 15), 200, Mods.ExtraBees.getItem("misc", 21), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 16), 200, Mods.ExtraBees.getItem("misc", 22), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 17), 200, Mods.ExtraBees.getItem("misc", 24), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 18), 200, Mods.ExtraBees.getItem("misc", 23), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 19), 200, Mods.ExtraBees.getItem("misc", 25), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 20), 200, new ItemStack(Items.DYE, 1, 14), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 21), 200, new ItemStack(Items.DYE, 1, 6), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 22), 200, new ItemStack(Items.DYE, 1, 5), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 23), 200, new ItemStack(Items.DYE, 1, 8), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 24), 200, new ItemStack(Items.DYE, 1, 12), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 25), 200, new ItemStack(Items.DYE, 1, 9), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 26), 200, new ItemStack(Items.DYE, 1, 10), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 27), 200, new ItemStack(Items.DYE, 1, 13), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 28), 200, new ItemStack(Items.DYE, 1, 7), 0); } - if (Loader.isModLoaded(GTValues.MODID_ET)) { + if (Mods.ExtraTrees.isModLoaded()) { // Fruits - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 0), 150, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 1), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 2), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 3), 300, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 4), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 5), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 6), 50, GTUtility.copy(mulch), 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 7), 50, GTUtility.copy(mulch), - 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 8), 100, GTUtility.copy(mulch), - 6000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 9), 80, GTUtility.copy(mulch), 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 10), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 11), 500, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 12), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 13), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 14), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 15), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 16), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 17), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 18), 400, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 19), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 20), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 21), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 22), 300, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 23), 200, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 24), 150, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 25), 180, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 26), 100, GTUtility.copy(mulch), - 400); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 27), 50, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 28), 100, GTUtility.copy(mulch), - 3000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 29), 100, GTUtility.copy(mulch), - 3000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 30), 100, GTUtility.copy(mulch), - 4000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 31), 20, GTUtility.copy(mulch), 200); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 32), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 33), 50, GTUtility.copy(mulch), 300); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 34), 100, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 35), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 36), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 37), 20, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 38), 300, GTUtility.copy(mulch), - 1500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 39), 25, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 46), 50, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 50), 300, GTUtility.copy(mulch), - 2500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 51), 150, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 52), 300, GTUtility.copy(mulch), - 1500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 53), 50, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 54), 50, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 55), 100, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 56), 100, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 57), 400, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 58), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 59), 50, GTUtility.copy(mulch), - 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 0), 150, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 1), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 2), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 3), 300, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 4), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 5), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 6), 50, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 7), 50, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 8), 100, GTUtility.copy(mulch), 6000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 9), 80, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 10), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 11), 500, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 12), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 13), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 14), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 15), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 16), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 17), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 18), 400, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 19), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 20), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 21), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 22), 300, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 23), 200, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 24), 150, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 25), 180, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 26), 100, GTUtility.copy(mulch), 400); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 27), 50, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 28), 100, GTUtility.copy(mulch), 3000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 29), 100, GTUtility.copy(mulch), 3000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 30), 100, GTUtility.copy(mulch), 4000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 31), 20, GTUtility.copy(mulch), 200); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 32), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 33), 50, GTUtility.copy(mulch), 300); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 34), 100, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 35), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 36), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 37), 20, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 38), 300, GTUtility.copy(mulch), 1500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 39), 25, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 46), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 50), 300, GTUtility.copy(mulch), 2500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 51), 150, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 52), 300, GTUtility.copy(mulch), 1500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 53), 50, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 54), 50, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 55), 100, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 56), 100, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 57), 400, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 58), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 59), 50, GTUtility.copy(mulch), 1000); } } diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java index 5f4f214c294..85239b0a1a5 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java @@ -6,8 +6,8 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryConfig; import gregtech.integration.forestry.ForestryUtil; import gregtech.integration.forestry.bees.GTDropType; @@ -15,7 +15,6 @@ import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.Loader; import forestry.api.recipes.RecipeManagers; import forestry.apiculture.ModuleApiculture; @@ -28,7 +27,7 @@ public class ForestryMiscRecipes { public static void init() { - if (ForestryConfig.enableGTBees) { + if (ForestryConfig.enableGTBees && Mods.ForestryApiculture.isModLoaded()) { // Oil Drop ItemStack dropStack = ForestryUtil.getDropStack(GTDropType.OIL); RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() @@ -45,8 +44,8 @@ public static void init() { // Biomass Drop dropStack = ForestryUtil.getDropStack(GTDropType.BIOMASS); ItemStack propolisStack = ModuleApiculture.getItems().propolis.get(EnumPropolis.NORMAL, 1); - if (Loader.isModLoaded(GTValues.MODID_EB)) { - propolisStack = IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 7); + if (Mods.ExtraBees.isModLoaded()) { + propolisStack = Mods.ExtraBees.getItem("propolis", 7); } RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() .inputs(dropStack) @@ -202,7 +201,7 @@ public static void init() { } // Fertilizer - ItemStack fertilizer = IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_compound", 0); + ItemStack fertilizer = Mods.Forestry.getItem("fertilizer_compound"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input("sand", 2) .input(OrePrefix.dust, Materials.Apatite) @@ -224,8 +223,8 @@ public static void init() { .outputs(GTUtility.copy(30, fertilizer)) .duration(100).EUt(16).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { - ItemStack concentratedCompound = IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 2); + if (Mods.MagicBees.isModLoaded()) { + ItemStack concentratedCompound = Mods.MagicBees.getItem("resource", 2); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input("sand", 2) .inputs(GTUtility.copy(concentratedCompound)) @@ -249,7 +248,7 @@ public static void init() { } // Compost - ItemStack compost = IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_bio", 0); + ItemStack compost = Mods.Forestry.getItem("fertilizer_bio"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(Blocks.DIRT, 1, true) .input(Items.WHEAT, 4) @@ -279,19 +278,19 @@ public static void init() { // Phosphor RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "phosphor", 0)) + .inputs(Mods.Forestry.getItem("phosphor")) .chancedOutput(OrePrefix.dust, Materials.Phosphorus, 1000, 0) .fluidOutputs(Materials.Lava.getFluid(800)) .duration(256).EUt(GTValues.VA[GTValues.MV]).buildAndRegister(); // Ice Shard RecipeMaps.MACERATOR_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "crafting_material", 5)) + .inputs(Mods.Forestry.getItem("crafting_material", 5)) .output(OrePrefix.dust, Materials.Ice) .duration(16).EUt(4).buildAndRegister(); // Mulch - ItemStack mulch = IntegrationUtil.getModItem(GTValues.MODID_FR, "mulch", 0); + ItemStack mulch = Mods.Forestry.getItem("mulch"); RecipeMaps.CHEMICAL_BATH_RECIPES.recipeBuilder() .input(MetaItems.BIO_CHAFF) .fluidInputs(Materials.Water.getFluid(750)) @@ -300,9 +299,9 @@ public static void init() { .chancedOutput(GTUtility.copy(4, mulch), 2000, 0) .duration(500).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_ET)) { + if (Mods.ExtraTrees.isModLoaded()) { RecipeMaps.MIXER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_ET, "misc", 1)) + .inputs(Mods.ExtraTrees.getItem("misc", 1)) .fluidInputs(Materials.Water.getFluid(500)) .outputs(GTUtility.copy(mulch)) .duration(600).EUt(2).buildAndRegister(); @@ -328,7 +327,7 @@ public static void init() { .duration(900).EUt(10).buildAndRegister(); // Humus - ItemStack humus = IntegrationUtil.getModItem(GTValues.MODID_FR, "humus", 0); + ItemStack humus = Mods.Forestry.getItem("humus"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .inputs(GTUtility.copy(2, mulch)) .input(Blocks.DIRT, 2, true) @@ -362,35 +361,35 @@ public static void init() { .input(OrePrefix.plate, Materials.Tin, 2) .input(Blocks.GLASS_PANE) .circuitMeta(1) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "can", 0)) + .outputs(Mods.Forestry.getItem("can")) .duration(120).EUt(7).buildAndRegister(); RecipeMaps.EXTRUDER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "beeswax", 0)) + .inputs(Mods.Forestry.getItem("beeswax")) .notConsumable(MetaItems.SHAPE_EXTRUDER_CELL) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "capsule", 0)) + .outputs(Mods.Forestry.getItem("capsule")) .duration(64).EUt(16).buildAndRegister(); RecipeMaps.EXTRUDER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "refractory_wax", 0)) + .inputs(Mods.Forestry.getItem("refractory_wax")) .notConsumable(MetaItems.SHAPE_EXTRUDER_CELL) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "refractory", 0)) + .outputs(Mods.Forestry.getItem("refractory")) .duration(128).EUt(16).buildAndRegister(); // Propolis RecipeMaps.CENTRIFUGE_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "propolis", 0)) + .inputs(Mods.Forestry.getItem("propolis")) .output(MetaItems.STICKY_RESIN) .duration(128).EUt(5).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_GENETICS)) { + if (Mods.Genetics.isModLoaded()) { // DNA Dye RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(OrePrefix.dust, Materials.Glowstone) .input("dyePurple") .input("dyeBlue") - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 1, 8)) + .outputs(Mods.Genetics.getItem("misc", 1, 8)) .duration(100).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); // Fluorescent Dye @@ -398,14 +397,14 @@ public static void init() { .input(OrePrefix.dust, Materials.Glowstone) .input("dyeOrange") .input("dyeYellow") - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 2, 2)) + .outputs(Mods.Genetics.getItem("misc", 2, 2)) .duration(100).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); // Growth Medium RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(OrePrefix.dust, Materials.Sugar) .input(OrePrefix.dust, Materials.Bone) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 4, 2)) + .outputs(Mods.Genetics.getItem("misc", 4, 2)) .duration(400).EUt(16).buildAndRegister(); } @@ -413,7 +412,7 @@ public static void init() { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_NUGGET) .fluidInputs(Fluids.FOR_HONEY.getFluid(200)) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "honey_drop", 0)) + .outputs(Mods.Forestry.getItem("honey_drop")) .duration(400).EUt(7).buildAndRegister(); RecipeMaps.CENTRIFUGE_RECIPES.recipeBuilder() @@ -425,7 +424,7 @@ public static void init() { public static void initRemoval() { ModHandler.removeRecipeByName("forestry:sand_to_fertilizer"); ModHandler.removeRecipeByName("forestry:ash_to_fertilizer"); - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { ModHandler.removeRecipeByName("magicbees:fertilizer1"); ModHandler.removeRecipeByName("magicbees:fertilizer2"); ModHandler.removeRecipeByName("magicbees:fertilizer3"); @@ -437,7 +436,7 @@ public static void initRemoval() { ModHandler.removeRecipeByName("forestry:tin_can"); ModHandler.removeRecipeByName("forestry:wax_capsule"); ModHandler.removeRecipeByName("forestry:refractory_capsule"); - if (Loader.isModLoaded(GTValues.MODID_GENETICS)) { + if (Mods.Genetics.isModLoaded()) { ModHandler.removeRecipeByName("genetics:dna_dye_from_glowstone"); ModHandler.removeRecipeByName("genetics:dna_dye"); ModHandler.removeRecipeByName("genetics:fluorescent_dye"); diff --git a/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java b/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java index 221fadaa6f6..6eed93239d8 100644 --- a/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java +++ b/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java @@ -1,8 +1,8 @@ package gregtech.integration.forestry.tools; -import gregtech.api.GTValues; import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.items.toolitem.behavior.IToolBehavior; +import gregtech.api.util.Mods; import net.minecraft.client.resources.I18n; import net.minecraft.client.util.ITooltipFlag; @@ -13,7 +13,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.fml.common.Loader; import forestry.api.lepidopterology.EnumFlutterType; import forestry.api.lepidopterology.IAlleleButterflySpecies; @@ -32,7 +31,7 @@ private ScoopBehavior() {/**/} @Override public void hitEntity(@NotNull ItemStack stack, @NotNull EntityLivingBase target, @NotNull EntityLivingBase attacker) { - if (!Loader.isModLoaded(GTValues.MODID_FR)) return; + if (!Mods.Forestry.isModLoaded()) return; if (!(target instanceof IEntityButterfly butterfly)) return; if (!(attacker instanceof EntityPlayer player)) return; if (attacker.world == null || attacker.world.isRemote) return; diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index adb308fe4e6..b6b603bb07e 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -10,6 +10,7 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.Mods; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockFrame; import gregtech.common.blocks.MetaBlocks; @@ -46,13 +47,13 @@ import java.util.Objects; import java.util.function.Supplier; -@Optional.Interface(modid = GTValues.MODID_GROOVYSCRIPT, +@Optional.Interface(modid = Mods.Names.GROOVY_SCRIPT, iface = "com.cleanroommc.groovyscript.api.GroovyPlugin", striprefs = true) @GregTechModule( moduleID = GregTechModules.MODULE_GRS, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_GROOVYSCRIPT, + modDependencies = Mods.Names.GROOVY_SCRIPT, name = "GregTech GroovyScript Integration", description = "GroovyScript Integration Module") public class GroovyScriptModule extends IntegrationSubmodule implements GroovyPlugin { diff --git a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java index bce36365fc0..d26defcbde3 100644 --- a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java +++ b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.hwyla.provider.*; import gregtech.modules.GregTechModules; @@ -17,7 +18,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_HWYLA, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_HWYLA, + modDependencies = Mods.Names.HWYLA, name = "GregTech HWYLA Integration", description = "HWYLA (WAILA) Integration Module") public class HWYLAModule extends IntegrationSubmodule implements IWailaPlugin { diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index eec16a49641..491db7fb1f1 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -20,6 +20,7 @@ import gregtech.api.recipes.machines.RecipeMapFurnace; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.BedrockFluidDepositDefinition; import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.config.WorldGenRegistry; @@ -85,7 +86,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_JEI, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_JEI, + modDependencies = Mods.Names.JUST_ENOUGH_ITEMS, name = "GregTech JEI Integration", description = "JustEnoughItems Integration Module") public class JustEnoughItemsModule extends IntegrationSubmodule implements IModPlugin { diff --git a/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java b/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java index 0f5bd90bf9f..75d8c11f81a 100644 --- a/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java +++ b/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java @@ -4,6 +4,7 @@ import gregtech.api.unification.material.Material; import gregtech.api.util.FileUtility; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.FillerConfigUtils; import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.filler.BlockFiller; @@ -26,7 +27,6 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidBlock; -import net.minecraftforge.fml.common.Loader; import com.google.common.collect.ImmutableList; import mezz.jei.api.ingredients.IIngredients; @@ -41,7 +41,6 @@ import java.util.function.Function; import static gregtech.api.GTValues.M; -import static gregtech.api.GTValues.MODID_CC; public class GTOreInfo implements IRecipeWrapper { @@ -64,7 +63,7 @@ public GTOreInfo(OreDepositDefinition definition) { // Don't default to vanilla Maximums and minimums if the values are not defined and Cubic Chunks is loaded // This could be improved to use the actual minimum and maximum heights, at the cost of including the CC Api - if (Loader.isModLoaded(MODID_CC)) { + if (Mods.CubicChunks.isModLoaded()) { this.maxHeight = definition.getMaximumHeight() == Integer.MAX_VALUE ? Integer.MAX_VALUE : definition.getMaximumHeight(); this.minHeight = definition.getMinimumHeight() == Integer.MIN_VALUE ? Integer.MIN_VALUE : diff --git a/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java b/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java index 77ee3c8bcb7..bc5042b0d64 100644 --- a/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java +++ b/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java @@ -1,6 +1,7 @@ package gregtech.integration.jei.utils; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.OreDepositDefinition; import net.minecraft.client.Minecraft; @@ -10,7 +11,6 @@ import net.minecraft.world.WorldProvider; import net.minecraft.world.biome.Biome; import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.fml.common.Loader; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.IntArrayList; @@ -27,8 +27,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import static gregtech.api.GTValues.MODID_AR; - /** * Common util methods shared between {@link gregtech.integration.jei.basic.GTOreCategory} * and {@link gregtech.integration.jei.basic.GTFluidVeinCategory} @@ -139,7 +137,7 @@ public static int[] getAllRegisteredDimensions(@Nullable Predicate Date: Wed, 31 Jan 2024 11:30:42 +0800 Subject: [PATCH 60/98] Update zh_cn.lang (#2362) --- .../resources/assets/gregtech/lang/zh_cn.lang | 226 +++++++++--------- 1 file changed, 114 insertions(+), 112 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang index 8fa4c506934..60613d04a2c 100644 --- a/src/main/resources/assets/gregtech/lang/zh_cn.lang +++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang @@ -924,7 +924,7 @@ metaitem.wooden_form.brick.name=木制砖模具 item.gt.tool.replace_tool_head=在合成栏用新的工具头替换 item.gt.tool.usable_as=可用作:§f%s -item.gt.tool.behavior.silk_ice=§b切冰利刃:§f精准采集冰 +item.gt.tool.behavior.silk_ice=§b切冰利刃:§f精准采集冰块 item.gt.tool.behavior.torch_place=§e洞窟探客:§f右击可放置火把 item.gt.tool.behavior.tree_felling=§4伐木好手:§f一次性砍下整棵树木 item.gt.tool.behavior.shield_disable=§c野兽蛮攻:§f破除盾牌 @@ -1650,7 +1650,7 @@ gregtech.material.rose_gold=玫瑰金 gregtech.material.black_bronze=黑青铜 gregtech.material.bismuth_bronze=铋青铜 gregtech.material.biotite=黑云母 -gregtech.material.powellite=钼钨钙矿 +gregtech.material.powellite=钼钙矿 gregtech.material.pyrite=黄铁矿 gregtech.material.pyrolusite=软锰矿 gregtech.material.pyrope=镁铝榴石 @@ -2913,9 +2913,9 @@ gregtech.machine.steam_hammer_bronze.tooltip=锤锻机器 gregtech.machine.steam_hammer_steel.name=高压蒸汽锻造锤 gregtech.machine.steam_hammer_steel.tooltip=锤锻机器 gregtech.machine.steam_furnace_bronze.name=蒸汽熔炉 -gregtech.machine.steam_furnace_bronze.tooltip=利用蒸汽来熔炼物品 +gregtech.machine.steam_furnace_bronze.tooltip=利用蒸汽冶炼物品 gregtech.machine.steam_furnace_steel.name=高压蒸汽熔炉 -gregtech.machine.steam_furnace_steel.tooltip=利用蒸汽来熔炼物品 +gregtech.machine.steam_furnace_steel.tooltip=利用蒸汽冶炼物品 gregtech.machine.steam_alloy_smelter_bronze.name=蒸汽合金炉 gregtech.machine.steam_alloy_smelter_bronze.tooltip=熔合冶炼炉 gregtech.machine.steam_alloy_smelter_steel.name=高压合金炉 @@ -2994,9 +2994,9 @@ gregtech.machine.macerator.lv.tooltip=粉碎矿石 gregtech.machine.macerator.mv.name=进阶研磨机 gregtech.machine.macerator.mv.tooltip=粉碎矿石 gregtech.machine.macerator.hv.name=进阶研磨机 II -gregtech.machine.macerator.hv.tooltip=粉碎矿石,且能产出副产物 +gregtech.machine.macerator.hv.tooltip=粉碎矿石并获得副产物 gregtech.machine.macerator.ev.name=进阶研磨机 III -gregtech.machine.macerator.ev.tooltip=粉碎矿石,且能产出副产物 +gregtech.machine.macerator.ev.tooltip=粉碎矿石并获得副产物 gregtech.machine.macerator.iv.name=精英研磨机 gregtech.machine.macerator.iv.tooltip=全自动破壁机 9001 gregtech.machine.macerator.luv.name=精英研磨机 II @@ -3054,11 +3054,11 @@ gregtech.machine.arc_furnace.hv.tooltip=谁还要高炉啊? gregtech.machine.arc_furnace.ev.name=进阶电弧炉 III gregtech.machine.arc_furnace.ev.tooltip=谁还要高炉啊? gregtech.machine.arc_furnace.iv.name=精英电弧炉 -gregtech.machine.arc_furnace.iv.tooltip=解体加热器 +gregtech.machine.arc_furnace.iv.tooltip=放电加热器 gregtech.machine.arc_furnace.luv.name=精英电弧炉 II -gregtech.machine.arc_furnace.luv.tooltip=解体加热器 +gregtech.machine.arc_furnace.luv.tooltip=放电加热器 gregtech.machine.arc_furnace.zpm.name=精英电弧炉 III -gregtech.machine.arc_furnace.zpm.tooltip=解体加热器 +gregtech.machine.arc_furnace.zpm.tooltip=放电加热器 gregtech.machine.arc_furnace.uv.name=终极电弧炉 gregtech.machine.arc_furnace.uv.tooltip=短路加热器 gregtech.machine.arc_furnace.uhv.name=史诗电弧炉 @@ -3280,23 +3280,23 @@ gregtech.machine.chemical_reactor.hv.tooltip=使化学品相互反应 gregtech.machine.chemical_reactor.ev.name=进阶化学反应釜 III gregtech.machine.chemical_reactor.ev.tooltip=使化学品相互反应 gregtech.machine.chemical_reactor.iv.name=精英化学反应釜 -gregtech.machine.chemical_reactor.iv.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.iv.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.luv.name=精英化学反应釜 II -gregtech.machine.chemical_reactor.luv.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.luv.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.zpm.name=精英化学反应釜 III -gregtech.machine.chemical_reactor.zpm.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.zpm.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.uv.name=终极化学反应釜 -gregtech.machine.chemical_reactor.uv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uhv.name=史诗化学反应釜 -gregtech.machine.chemical_reactor.uhv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uhv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uev.name=史诗化学反应釜 II -gregtech.machine.chemical_reactor.uev.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uev.tooltip=反应催化器 gregtech.machine.chemical_reactor.uiv.name=史诗化学反应釜 III -gregtech.machine.chemical_reactor.uiv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uiv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uxv.name=史诗化学反应釜 IV -gregtech.machine.chemical_reactor.uxv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uxv.tooltip=反应催化器 gregtech.machine.chemical_reactor.opv.name=传奇化学反应釜 -gregtech.machine.chemical_reactor.opv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.opv.tooltip=反应催化器 # Compressor gregtech.machine.compressor.lv.name=基础压缩机 @@ -3342,17 +3342,17 @@ gregtech.machine.cutter.luv.tooltip=物质切削器 gregtech.machine.cutter.zpm.name=精英切割机 III gregtech.machine.cutter.zpm.tooltip=物质切削器 gregtech.machine.cutter.uv.name=终极切割机 -gregtech.machine.cutter.uv.tooltip=物品对象分割者 +gregtech.machine.cutter.uv.tooltip=对象分割者 gregtech.machine.cutter.uhv.name=史诗切割机 -gregtech.machine.cutter.uhv.tooltip=物品对象分割者 +gregtech.machine.cutter.uhv.tooltip=对象分割者 gregtech.machine.cutter.uev.name=史诗切割机 II -gregtech.machine.cutter.uev.tooltip=物品对象分割者 +gregtech.machine.cutter.uev.tooltip=对象分割者 gregtech.machine.cutter.uiv.name=史诗切割机 III -gregtech.machine.cutter.uiv.tooltip=物品对象分割者 +gregtech.machine.cutter.uiv.tooltip=对象分割者 gregtech.machine.cutter.uxv.name=史诗切割机 IV -gregtech.machine.cutter.uxv.tooltip=物品对象分割者 +gregtech.machine.cutter.uxv.tooltip=对象分割者 gregtech.machine.cutter.opv.name=传奇切割机 -gregtech.machine.cutter.opv.tooltip=物品对象分割者 +gregtech.machine.cutter.opv.tooltip=对象分割者 # Distillery gregtech.machine.distillery.lv.name=基础蒸馏室 @@ -3370,17 +3370,17 @@ gregtech.machine.distillery.luv.tooltip=凝结物质分离器 gregtech.machine.distillery.zpm.name=精英蒸馏室 III gregtech.machine.distillery.zpm.tooltip=凝结物质分离器 gregtech.machine.distillery.uv.name=终极蒸馏室 -gregtech.machine.distillery.uv.tooltip=少数分流者 +gregtech.machine.distillery.uv.tooltip=馏分分离器 gregtech.machine.distillery.uhv.name=史诗蒸馏室 -gregtech.machine.distillery.uhv.tooltip=少数分流者 +gregtech.machine.distillery.uhv.tooltip=馏分分离器 gregtech.machine.distillery.uev.name=史诗蒸馏室 II -gregtech.machine.distillery.uev.tooltip=少数分流者 +gregtech.machine.distillery.uev.tooltip=馏分分离器 gregtech.machine.distillery.uiv.name=史诗蒸馏室 III -gregtech.machine.distillery.uiv.tooltip=少数分流者 +gregtech.machine.distillery.uiv.tooltip=馏分分离器 gregtech.machine.distillery.uxv.name=史诗蒸馏室 IV -gregtech.machine.distillery.uxv.tooltip=少数分流者 +gregtech.machine.distillery.uxv.tooltip=馏分分离器 gregtech.machine.distillery.opv.name=传奇蒸馏室 -gregtech.machine.distillery.opv.tooltip=少数分流者 +gregtech.machine.distillery.opv.tooltip=馏分分离器 # Electrolyzer gregtech.machine.electrolyzer.lv.name=基础电解机 @@ -3440,13 +3440,13 @@ gregtech.machine.electromagnetic_separator.opv.tooltip=电磁场驱离装置 # Extractor gregtech.machine.extractor.lv.name=基础提取机 -gregtech.machine.extractor.lv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.lv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.mv.name=进阶提取机 -gregtech.machine.extractor.mv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.mv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.hv.name=进阶提取机 II -gregtech.machine.extractor.hv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.hv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.ev.name=进阶提取机 III -gregtech.machine.extractor.ev.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.ev.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.iv.name=精英提取机 gregtech.machine.extractor.iv.tooltip=真空提炼机 gregtech.machine.extractor.luv.name=精英提取机 II @@ -3468,13 +3468,13 @@ gregtech.machine.extractor.opv.tooltip=液化吸取者 # Extruder gregtech.machine.extruder.lv.name=基础压模器 -gregtech.machine.extruder.lv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.lv.tooltip=通用型金属加工器 gregtech.machine.extruder.mv.name=进阶压模器 -gregtech.machine.extruder.mv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.mv.tooltip=通用型金属加工器 gregtech.machine.extruder.hv.name=进阶压模器 II -gregtech.machine.extruder.hv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.hv.tooltip=通用型金属加工器 gregtech.machine.extruder.ev.name=进阶压模器 III -gregtech.machine.extruder.ev.tooltip=通用的金属处理机器 +gregtech.machine.extruder.ev.tooltip=通用型金属加工器 gregtech.machine.extruder.iv.name=精英压模器 gregtech.machine.extruder.iv.tooltip=材料压出器 gregtech.machine.extruder.luv.name=精英压模器 II @@ -3503,11 +3503,11 @@ gregtech.machine.fermenter.hv.tooltip=发酵流体 gregtech.machine.fermenter.ev.name=进阶发酵槽 III gregtech.machine.fermenter.ev.tooltip=发酵流体 gregtech.machine.fermenter.iv.name=精英发酵槽 -gregtech.machine.fermenter.iv.tooltip=发酵催促器 +gregtech.machine.fermenter.iv.tooltip=发酵加速器 gregtech.machine.fermenter.luv.name=精英发酵槽 II -gregtech.machine.fermenter.luv.tooltip=发酵催促器 +gregtech.machine.fermenter.luv.tooltip=发酵加速器 gregtech.machine.fermenter.zpm.name=精英发酵槽 III -gregtech.machine.fermenter.zpm.tooltip=发酵催促器 +gregtech.machine.fermenter.zpm.tooltip=发酵加速器 gregtech.machine.fermenter.uv.name=终极发酵槽 gregtech.machine.fermenter.uv.tooltip=呼吸控制器 gregtech.machine.fermenter.uhv.name=史诗发酵槽 @@ -3523,41 +3523,41 @@ gregtech.machine.fermenter.opv.tooltip=呼吸控制器 # Fluid Heater gregtech.machine.fluid_heater.lv.name=基础流体加热器 -gregtech.machine.fluid_heater.lv.tooltip=加热流体 +gregtech.machine.fluid_heater.lv.tooltip=加热你的流体 gregtech.machine.fluid_heater.mv.name=进阶流体加热器 -gregtech.machine.fluid_heater.mv.tooltip=加热流体 +gregtech.machine.fluid_heater.mv.tooltip=加热你的流体 gregtech.machine.fluid_heater.hv.name=进阶流体加热器 II -gregtech.machine.fluid_heater.hv.tooltip=加热流体 +gregtech.machine.fluid_heater.hv.tooltip=加热你的流体 gregtech.machine.fluid_heater.ev.name=进阶流体加热器 III -gregtech.machine.fluid_heater.ev.tooltip=加热流体 +gregtech.machine.fluid_heater.ev.tooltip=加热你的流体 gregtech.machine.fluid_heater.iv.name=精英流体加热器 -gregtech.machine.fluid_heater.iv.tooltip=热量注入器 +gregtech.machine.fluid_heater.iv.tooltip=热量灌注器 gregtech.machine.fluid_heater.luv.name=精英流体加热器 II -gregtech.machine.fluid_heater.luv.tooltip=热量注入器 +gregtech.machine.fluid_heater.luv.tooltip=热量灌注器 gregtech.machine.fluid_heater.zpm.name=精英流体加热器 III -gregtech.machine.fluid_heater.zpm.tooltip=热量注入器 +gregtech.machine.fluid_heater.zpm.tooltip=热量灌注器 gregtech.machine.fluid_heater.uv.name=终极流体加热器 -gregtech.machine.fluid_heater.uv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uhv.name=史诗流体加热器 -gregtech.machine.fluid_heater.uhv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uhv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uev.name=史诗流体加热器 II -gregtech.machine.fluid_heater.uev.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uev.tooltip=热量灌输器 gregtech.machine.fluid_heater.uiv.name=史诗流体加热器 III -gregtech.machine.fluid_heater.uiv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uiv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uxv.name=史诗流体加热器 IV -gregtech.machine.fluid_heater.uxv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uxv.tooltip=热量灌输器 gregtech.machine.fluid_heater.opv.name=传奇流体加热器 -gregtech.machine.fluid_heater.opv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.opv.tooltip=热量灌输器 # Fluid Solidifier gregtech.machine.fluid_solidifier.lv.name=基础流体固化器 -gregtech.machine.fluid_solidifier.lv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.lv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.mv.name=进阶流体固化器 -gregtech.machine.fluid_solidifier.mv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.mv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.hv.name=进阶流体固化器 II -gregtech.machine.fluid_solidifier.hv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.hv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.ev.name=进阶流体固化器 III -gregtech.machine.fluid_solidifier.ev.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.ev.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.iv.name=精英流体固化器 gregtech.machine.fluid_solidifier.iv.tooltip=并不是制冰机 gregtech.machine.fluid_solidifier.luv.name=精英流体固化器 II @@ -3587,11 +3587,11 @@ gregtech.machine.forge_hammer.hv.tooltip=停,抡锤时间到! gregtech.machine.forge_hammer.ev.name=进阶锻造锤 III gregtech.machine.forge_hammer.ev.tooltip=停,抡锤时间到! gregtech.machine.forge_hammer.iv.name=精英锻造锤 -gregtech.machine.forge_hammer.iv.tooltip=板材锻造机 +gregtech.machine.forge_hammer.iv.tooltip=锻板机 gregtech.machine.forge_hammer.luv.name=精英锻造锤 II -gregtech.machine.forge_hammer.luv.tooltip=板材锻造机 +gregtech.machine.forge_hammer.luv.tooltip=锻板机 gregtech.machine.forge_hammer.zpm.name=精英锻造锤 III -gregtech.machine.forge_hammer.zpm.tooltip=板材锻造机 +gregtech.machine.forge_hammer.zpm.tooltip=锻板机 gregtech.machine.forge_hammer.uv.name=终极锻造锤 gregtech.machine.forge_hammer.uv.tooltip=冲击调制器 gregtech.machine.forge_hammer.uhv.name=史诗锻造锤 @@ -3607,13 +3607,13 @@ gregtech.machine.forge_hammer.opv.tooltip=冲击调制器 # Forming Press gregtech.machine.forming_press.lv.name=基础冲压机床 -gregtech.machine.forming_press.lv.tooltip=将印象压印为实际的存在 +gregtech.machine.forming_press.lv.tooltip=图像拓印者 gregtech.machine.forming_press.mv.name=进阶冲压机床 -gregtech.machine.forming_press.mv.tooltip=印象具现者 +gregtech.machine.forming_press.mv.tooltip=图像拓印者 gregtech.machine.forming_press.hv.name=进阶冲压机床 II -gregtech.machine.forming_press.hv.tooltip=印象具现者 +gregtech.machine.forming_press.hv.tooltip=图像拓印者 gregtech.machine.forming_press.ev.name=进阶冲压机床 III -gregtech.machine.forming_press.ev.tooltip=印象具现者 +gregtech.machine.forming_press.ev.tooltip=图像拓印者 gregtech.machine.forming_press.iv.name=精英冲压机床 gregtech.machine.forming_press.iv.tooltip=对象层化机 gregtech.machine.forming_press.luv.name=精英冲压机床 II @@ -3747,13 +3747,13 @@ gregtech.machine.packer.opv.tooltip=亚马逊仓库 # Polarizer gregtech.machine.polarizer.lv.name=基础两极磁化机 -gregtech.machine.polarizer.lv.tooltip=使磁体两极化 +gregtech.machine.polarizer.lv.tooltip=将你的磁体极化 gregtech.machine.polarizer.mv.name=进阶两极磁化机 -gregtech.machine.polarizer.mv.tooltip=使磁体两极化 +gregtech.machine.polarizer.mv.tooltip=将你的磁体极化 gregtech.machine.polarizer.hv.name=进阶两极磁化机 II -gregtech.machine.polarizer.hv.tooltip=使磁体两极化 +gregtech.machine.polarizer.hv.tooltip=将你的磁体极化 gregtech.machine.polarizer.ev.name=进阶两极磁化机 III -gregtech.machine.polarizer.ev.tooltip=使磁体两极化 +gregtech.machine.polarizer.ev.tooltip=将你的磁体极化 gregtech.machine.polarizer.iv.name=精英两极磁化机 gregtech.machine.polarizer.iv.tooltip=磁性引入机 gregtech.machine.polarizer.luv.name=精英两极磁化机 II @@ -3783,11 +3783,11 @@ gregtech.machine.laser_engraver.hv.tooltip=请勿直视激光 gregtech.machine.laser_engraver.ev.name=进阶精密激光蚀刻机 III gregtech.machine.laser_engraver.ev.tooltip=请勿直视激光 gregtech.machine.laser_engraver.iv.name=精英精密激光蚀刻机 -gregtech.machine.laser_engraver.iv.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.iv.tooltip=功率高达两百零四万瓦 gregtech.machine.laser_engraver.luv.name=精英精密激光蚀刻机 II -gregtech.machine.laser_engraver.luv.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.luv.tooltip=功率高达八百一十六万瓦 gregtech.machine.laser_engraver.zpm.name=精英精密激光蚀刻机 III -gregtech.machine.laser_engraver.zpm.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.zpm.tooltip=功率高达三千两百六十四万瓦 gregtech.machine.laser_engraver.uv.name=终极精密激光蚀刻机 gregtech.machine.laser_engraver.uv.tooltip=高精度光子加农炮 gregtech.machine.laser_engraver.uhv.name=史诗激光蚀刻机 @@ -3887,13 +3887,13 @@ gregtech.machine.wiremill.opv.tooltip=导线易形者 # Circuit Assembler gregtech.machine.circuit_assembler.lv.name=基础电路组装机 -gregtech.machine.circuit_assembler.lv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.lv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.mv.name=进阶电路组装机 -gregtech.machine.circuit_assembler.mv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.mv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.hv.name=进阶电路组装机 II -gregtech.machine.circuit_assembler.hv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.hv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.ev.name=进阶电路组装机 III -gregtech.machine.circuit_assembler.ev.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.ev.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.iv.name=精英电路组装机 gregtech.machine.circuit_assembler.iv.tooltip=电子厂 gregtech.machine.circuit_assembler.luv.name=精英电路组装机 II @@ -3901,17 +3901,17 @@ gregtech.machine.circuit_assembler.luv.tooltip=电子厂 gregtech.machine.circuit_assembler.zpm.name=精英电路组装机 III gregtech.machine.circuit_assembler.zpm.tooltip=电子厂 gregtech.machine.circuit_assembler.uv.name=终极电路组装机 -gregtech.machine.circuit_assembler.uv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uhv.name=史诗电路组装机 -gregtech.machine.circuit_assembler.uhv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uhv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uev.name=史诗电路组装机 II -gregtech.machine.circuit_assembler.uev.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uev.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uiv.name=史诗电路组装机 III -gregtech.machine.circuit_assembler.uiv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uiv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uxv.name=史诗电路组装机 IV -gregtech.machine.circuit_assembler.uxv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uxv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.opv.name=传奇电路组装机 -gregtech.machine.circuit_assembler.opv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.opv.tooltip=计算机工厂 # Mass Fabricator gregtech.machine.mass_fabricator.lv.name=基础质量发生器 @@ -3923,11 +3923,11 @@ gregtech.machine.mass_fabricator.hv.tooltip=UU物质 = “质量” * “发生 gregtech.machine.mass_fabricator.ev.name=进阶质量发生器 III gregtech.machine.mass_fabricator.ev.tooltip=UU物质 = “质量” * “发生”的平方 gregtech.machine.mass_fabricator.iv.name=精英质量发生器 -gregtech.machine.mass_fabricator.iv.tooltip=创世工坊 +gregtech.machine.mass_fabricator.iv.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.luv.name=精英质量发生器 II -gregtech.machine.mass_fabricator.luv.tooltip=创世工坊 +gregtech.machine.mass_fabricator.luv.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.zpm.name=精英质量发生器 III -gregtech.machine.mass_fabricator.zpm.tooltip=创世工坊 +gregtech.machine.mass_fabricator.zpm.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.uv.name=终极质量发生器 gregtech.machine.mass_fabricator.uv.tooltip=存在之源 gregtech.machine.mass_fabricator.uhv.name=史诗质量发生器 @@ -3943,13 +3943,13 @@ gregtech.machine.mass_fabricator.opv.tooltip=存在之源 # Replicator gregtech.machine.replicator.lv.name=基础复制机 -gregtech.machine.replicator.lv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.lv.tooltip=生产最纯净的元素 gregtech.machine.replicator.mv.name=进阶复制机 -gregtech.machine.replicator.mv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.mv.tooltip=生产最纯净的元素 gregtech.machine.replicator.hv.name=进阶复制机 II -gregtech.machine.replicator.hv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.hv.tooltip=生产最纯净的元素 gregtech.machine.replicator.ev.name=进阶复制机 III -gregtech.machine.replicator.ev.tooltip=生产出至纯的元素 +gregtech.machine.replicator.ev.tooltip=生产最纯净的元素 gregtech.machine.replicator.iv.name=精英复制机 gregtech.machine.replicator.iv.tooltip=物质粘贴机 gregtech.machine.replicator.luv.name=精英复制机 II @@ -4307,7 +4307,7 @@ gregtech.machine.quantum_tank.uv.name=量子缸 IV gregtech.machine.quantum_tank.uhv.name=量子缸 V #Buffers -gregtech.machine.buffer.tooltip=能够存储物品与流体的小型缓存器 +gregtech.machine.buffer.tooltip=用于存储物品和流体的小小缓冲器 gregtech.machine.buffer.lv.name=基础缓存器 gregtech.machine.buffer.mv.name=进阶缓存器 gregtech.machine.buffer.hv.name=进阶缓存器 II @@ -4325,31 +4325,31 @@ tile.hermetic_casing.hermetic_casing_uhv.name=密封机械方块 IX #Gas Collectors gregtech.machine.gas_collector.lv.name=基础集气室 -gregtech.machine.gas_collector.lv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.lv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.mv.name=进阶集气室 -gregtech.machine.gas_collector.mv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.mv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.hv.name=进阶集气室 II -gregtech.machine.gas_collector.hv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.hv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.ev.name=进阶集气室 III -gregtech.machine.gas_collector.ev.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.ev.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.iv.name=精英集气室 -gregtech.machine.gas_collector.iv.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.iv.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.luv.name=精英集气室 II -gregtech.machine.gas_collector.luv.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.luv.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.zpm.name=精英集气室 III -gregtech.machine.gas_collector.zpm.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.zpm.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.uv.name=终极集气室 -gregtech.machine.gas_collector.uv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uhv.name=史诗集气室 -gregtech.machine.gas_collector.uhv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uhv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uev.name=史诗集气室 II -gregtech.machine.gas_collector.uev.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uev.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uiv.name=史诗集气室 III -gregtech.machine.gas_collector.uiv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uiv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uxv.name=史诗集气室 IV -gregtech.machine.gas_collector.uxv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uxv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.opv.name=传说集气室 -gregtech.machine.gas_collector.opv.tooltip=从宇宙中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.opv.tooltip=依照维度从宇宙中收集种类各异的气体 #Rock Breakers gregtech.machine.rock_breaker.lv.name=基础碎岩机 @@ -4367,17 +4367,17 @@ gregtech.machine.rock_breaker.luv.tooltip=岩浆冷却固化器 R-9200 gregtech.machine.rock_breaker.zpm.name=精英碎岩机 III gregtech.machine.rock_breaker.zpm.tooltip=岩浆冷却固化器 R-10200 gregtech.machine.rock_breaker.uv.name=终极碎岩机 -gregtech.machine.rock_breaker.uv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uv.tooltip=火山成型室 gregtech.machine.rock_breaker.uhv.name=史诗碎岩机 -gregtech.machine.rock_breaker.uhv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uhv.tooltip=火山成型室 gregtech.machine.rock_breaker.uev.name=史诗碎岩机 II -gregtech.machine.rock_breaker.uev.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uev.tooltip=火山成型室 gregtech.machine.rock_breaker.uiv.name=史诗碎岩机 III -gregtech.machine.rock_breaker.uiv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uiv.tooltip=火山成型室 gregtech.machine.rock_breaker.uxv.name=史诗碎岩机 IV -gregtech.machine.rock_breaker.uxv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uxv.tooltip=火山成型室 gregtech.machine.rock_breaker.opv.name=传奇碎岩机 -gregtech.machine.rock_breaker.opv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.opv.tooltip=火山成型室 #Fisher gregtech.machine.fisher.lv.name=基础捕鱼机 @@ -4809,7 +4809,7 @@ gregtech.machine.power_substation.tooltip3=最多容许§f%d层电容§7。 gregtech.machine.power_substation.tooltip4=每§f24小时§7损失相当于总容量的§f1%%§7的能量。 gregtech.machine.power_substation.tooltip5=每个电容的损失上限为§f%,d EU/t§7。 gregtech.machine.power_substation.tooltip6=可以使用 -gregtech.machine.power_substation.tooltip6.5= 激光仓§7。 +gregtech.machine.power_substation.tooltip6.5=激光仓§7。 gregtech.multiblock.power_substation.description=蓄能变电站是一个用于储存大量能量的多方块结构,它最多可以容纳18层电容,每层都必须填充完整,这意味着你可以用空电容来填充空间。 gregtech.machine.active_transformer.name=有源变压器 @@ -5647,8 +5647,10 @@ gregtech.multiblock.computation.not_enough_computation=机器需要更多算力 gregtech.multiblock.power_substation.stored=存储:%s gregtech.multiblock.power_substation.capacity=容量:%s gregtech.multiblock.power_substation.passive_drain=被动损失:%s -gregtech.multiblock.power_substation.average_io=平均输入/输出:%s -gregtech.multiblock.power_substation.average_io_hover=蓄能变电站内部的平均能量变化 +gregtech.multiblock.power_substation.average_in=平均EU输入:%s +gregtech.multiblock.power_substation.average_out=平均EU输出:%s +gregtech.multiblock.power_substation.average_in_hover=蓄能变电站内部的平均功率输入 +gregtech.multiblock.power_substation.average_out_hover=蓄能变电站内部的平均功率输出 gregtech.multiblock.power_substation.time_to_fill=预计充满时间:%s gregtech.multiblock.power_substation.time_to_drain=预计耗空时间:%s gregtech.multiblock.power_substation.time_seconds=%s秒 From 754a636f0036c81b0f8d3f9951bcd284838a6042 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 1 Feb 2024 21:05:45 -0600 Subject: [PATCH 61/98] Clean up MetaTileEntities class formatting (#2371) --- .../metatileentities/MetaTileEntities.java | 140 ++++++------------ 1 file changed, 47 insertions(+), 93 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 28e89934d0e..31b6cc29edf 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -139,91 +139,65 @@ public class MetaTileEntities { + // spotless:off + // HULLS public static final MetaTileEntityHull[] HULL = new MetaTileEntityHull[GTValues.V.length]; - public static final MetaTileEntityTransformer[] TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no - // MAX - public static final MetaTileEntityTransformer[] HI_AMP_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - - 1]; /// no MAX - public static final MetaTileEntityTransformer[] POWER_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - - 1]; // no MAX + public static final MetaTileEntityTransformer[] TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no MAX + public static final MetaTileEntityTransformer[] HI_AMP_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; /// no MAX + public static final MetaTileEntityTransformer[] POWER_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no MAX public static final MetaTileEntityDiode[] DIODES = new MetaTileEntityDiode[GTValues.V.length]; public static final MetaTileEntityBatteryBuffer[][] BATTERY_BUFFER = new MetaTileEntityBatteryBuffer[3][GTValues.V.length]; public static final MetaTileEntityCharger[] CHARGER = new MetaTileEntityCharger[GTValues.V.length]; + // SIMPLE MACHINES SECTION - public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] MACERATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ALLOY_SMELTER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ARC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] AUTOCLAVE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] MACERATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ALLOY_SMELTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ARC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] AUTOCLAVE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] BENDER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] BREWERY = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] CANNER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] CHEMICAL_BATH = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] CHEMICAL_REACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] COMPRESSOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] CHEMICAL_BATH = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] CHEMICAL_REACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] COMPRESSOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] CUTTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] DISTILLERY = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ELECTROLYZER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ELECTROMAGNETIC_SEPARATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] EXTRACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] DISTILLERY = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTROLYZER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTROMAGNETIC_SEPARATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] EXTRACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] EXTRUDER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] FERMENTER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FLUID_HEATER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FLUID_SOLIDIFIER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FORGE_HAMMER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FORMING_PRESS = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] FERMENTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FLUID_HEATER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FLUID_SOLIDIFIER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FORGE_HAMMER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FORMING_PRESS = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] LATHE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] MIXER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] ORE_WASHER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] ORE_WASHER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] PACKER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] UNPACKER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] POLARIZER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] LASER_ENGRAVER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] POLARIZER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] LASER_ENGRAVER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] SIFTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] THERMAL_CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] THERMAL_CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] WIREMILL = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] CIRCUIT_ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - // TODO Replication system - // public static final SimpleMachineMetaTileEntity[] MASS_FABRICATOR = new - // SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - // public static final SimpleMachineMetaTileEntity[] REPLICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - // - 1]; + public static final SimpleMachineMetaTileEntity[] CIRCUIT_ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + // public static final SimpleMachineMetaTileEntity[] MASS_FABRICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; // TODO Replication + // public static final SimpleMachineMetaTileEntity[] REPLICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; // TODO Replication public static final SimpleMachineMetaTileEntity[] SCANNER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - 1]; public static final MetaTileEntityRockBreaker[] ROCK_BREAKER = new MetaTileEntityRockBreaker[GTValues.V.length - 1]; public static final MetaTileEntityMiner[] MINER = new MetaTileEntityMiner[GTValues.V.length - 1]; + // GENERATORS SECTION public static final SimpleGeneratorMetaTileEntity[] COMBUSTION_GENERATOR = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] STEAM_TURBINE = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] GAS_TURBINE = new SimpleGeneratorMetaTileEntity[4]; + // MULTIBLOCK PARTS SECTION public static final MetaTileEntityItemBus[] ITEM_IMPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; // ULV-UHV public static final MetaTileEntityItemBus[] ITEM_EXPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; @@ -234,39 +208,14 @@ public class MetaTileEntities { public static final MetaTileEntityMultiFluidHatch[] QUADRUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV public static final MetaTileEntityMultiFluidHatch[] NONUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, - // LuV, - // ZPM, - // UV, UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, - // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, - // ZPM, UV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, ZPM, UV public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV + 1]; // LV-UV public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; public static final MetaTileEntityQuantumChest[] QUANTUM_CHEST = new MetaTileEntityQuantumChest[10]; @@ -305,6 +254,7 @@ public class MetaTileEntities { // Used for addons if they wish to disable certain tiers of machines private static final Map MID_TIER = new HashMap<>(); private static final Map HIGH_TIER = new HashMap<>(); + // STEAM AGE SECTION public static SteamCoalBoiler STEAM_BOILER_COAL_BRONZE; public static SteamCoalBoiler STEAM_BOILER_COAL_STEEL; @@ -338,6 +288,7 @@ public class MetaTileEntities { public static MetaTileEntityMaintenanceHatch CONFIGURABLE_MAINTENANCE_HATCH; public static MetaTileEntityAutoMaintenanceHatch AUTO_MAINTENANCE_HATCH; public static MetaTileEntityCleaningMaintenanceHatch CLEANING_MAINTENANCE_HATCH; + // MULTIBLOCKS SECTION public static MetaTileEntityPrimitiveBlastFurnace PRIMITIVE_BLAST_FURNACE; public static MetaTileEntityCokeOven COKE_OVEN; @@ -398,6 +349,7 @@ public class MetaTileEntities { public static MetaTileEntityCrate STAINLESS_STEEL_CRATE; public static MetaTileEntityCrate TITANIUM_CRATE; public static MetaTileEntityCrate TUNGSTENSTEEL_CRATE; + // MISC MACHINES SECTION public static MetaTileEntityWorkbench WORKBENCH; public static MetaTileEntityCreativeEnergy CREATIVE_ENERGY; @@ -416,6 +368,8 @@ public class MetaTileEntities { public static MetaTileEntityConverter[][] ENERGY_CONVERTER = new MetaTileEntityConverter[4][GTValues.V.length]; + //spotless:on + public static void init() { GTLog.logger.info("Registering MetaTileEntities"); From ef0a5c6a9215b197c89774bb32e3172e3972bb8d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 4 Feb 2024 13:25:18 -0700 Subject: [PATCH 62/98] Set Hardness and Resistance to LDP Blocks (#2370) --- .../gregtech/api/pipenet/longdist/BlockLongDistancePipe.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java index 28339dd7ef2..2372a9792c8 100644 --- a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java +++ b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java @@ -35,6 +35,8 @@ public BlockLongDistancePipe(LongDistancePipeType pipeType) { setTranslationKey("long_distance_" + pipeType.getName() + "_pipeline"); setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setHarvestLevel(ToolClasses.WRENCH, 1); + setHardness(2f); + setResistance(10f); } @Override From be62b40def29bc463eced2a22337b89c37e6dc05 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 4 Feb 2024 14:27:09 -0600 Subject: [PATCH 63/98] Fix hasEnoughPower() check in ARL (#2365) --- .../capability/impl/AbstractRecipeLogic.java | 25 +++++-------------- .../capability/impl/PrimitiveRecipeLogic.java | 10 +++++--- .../api/capability/impl/RecipeLogicSteam.java | 17 +++++++++++++ .../impl/SteamMultiblockRecipeLogic.java | 17 +++++++++++++ 4 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index e00cdc21235..ce4eab33ac9 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -636,33 +636,20 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, * @param resultOverclock the overclock data to use. Format: {@code [EUt, duration]}. * @return true if there is enough energy to continue recipe progress */ - protected boolean hasEnoughPower(@NotNull int[] resultOverclock) { + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { // Format of resultOverclock: EU/t, duration - int totalEUt = resultOverclock[0] * resultOverclock[1]; + int recipeEUt = resultOverclock[0]; // RIP Ternary // Power Consumption case - if (totalEUt >= 0) { - int capacity; - // If the total consumed power is greater than half the internal capacity - if (totalEUt > getEnergyCapacity() / 2) { - // Only draw 1A of power from the internal buffer to allow for recharging of the internal buffer from - // external sources - capacity = resultOverclock[0]; - } else { - // If the total consumed power is less than half the capacity, just drain the whole thing - capacity = totalEUt; - } - - // Return true if we have enough energy stored to progress the recipe, either 1A or the whole amount - return getEnergyStored() >= capacity; + if (recipeEUt >= 0) { + // ensure it can run for at least 8 ticks. Arbitrary value, but should prevent instant failures + return getEnergyStored() >= ((long) recipeEUt << 3); } // Power Generation case else { - // This is the EU/t generated by the generator - int power = resultOverclock[0]; // Return true if we can fit at least 1A of energy into the energy output - return getEnergyStored() - (long) power <= getEnergyCapacity(); + return getEnergyStored() - (long) recipeEUt <= getEnergyCapacity(); } } diff --git a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java index 182b900ae3b..e3367929b06 100644 --- a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java @@ -38,15 +38,19 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) { return true; // spoof energy being drawn } + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + return true; + } + @Override public long getMaxVoltage() { return GTValues.LV; } - @NotNull @Override - protected int[] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, - long maxVoltage, int recipeDuration, int amountOC) { + protected int @NotNull [] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, + long maxVoltage, int recipeDuration, int amountOC) { return standardOverclockingLogic( 1, getMaxVoltage(), diff --git a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java index c5d7dcbb960..c1e4fc665a9 100644 --- a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java +++ b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java @@ -227,6 +227,23 @@ public long getMaxVoltage() { return GTValues.V[GTValues.LV]; } + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + int totalSteam = (int) (resultOverclock[0] * resultOverclock[1] / conversionRate); + if (totalSteam > 0) { + long steamStored = getEnergyStored(); + long steamCapacity = getEnergyCapacity(); + // if the required steam is larger than the full buffer, just require the full buffer + if (steamCapacity < totalSteam) { + return steamCapacity == steamStored; + } + // otherwise require the full amount of steam for the recipe + return steamStored >= totalSteam; + } + // generation case unchanged + return super.hasEnoughPower(resultOverclock); + } + @NotNull @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java index b227f3942c2..d649a7d6fa7 100644 --- a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java @@ -167,4 +167,21 @@ private void performVentingAnimation(BlockPos machinePos, EnumFacing ventingSide 1.0f); } } + + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + int totalSteam = (int) (resultOverclock[0] * resultOverclock[1] / conversionRate); + if (totalSteam > 0) { + long steamStored = getEnergyStored(); + long steamCapacity = getEnergyCapacity(); + // if the required steam is larger than the full buffer, just require the full buffer + if (steamCapacity < totalSteam) { + return steamCapacity == steamStored; + } + // otherwise require the full amount of steam for the recipe + return steamStored >= totalSteam; + } + // generation case unchanged + return super.hasEnoughPower(resultOverclock); + } } From 72954c46bca9e554123f2e1e0ff564da765502ae Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 4 Feb 2024 14:34:21 -0600 Subject: [PATCH 64/98] Use drain/extract for Recipe#matches (#2358) --- .../java/gregtech/api/recipes/Recipe.java | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/Recipe.java b/src/main/java/gregtech/api/recipes/Recipe.java index f52c3adc10e..d52be1bac09 100644 --- a/src/main/java/gregtech/api/recipes/Recipe.java +++ b/src/main/java/gregtech/api/recipes/Recipe.java @@ -191,8 +191,54 @@ public static Recipe trimRecipeOutputs(Recipe currentRecipe, RecipeMap recipe public final boolean matches(boolean consumeIfSuccessful, IItemHandlerModifiable inputs, IMultipleTankHandler fluidInputs) { - return matches(consumeIfSuccessful, GTUtility.itemHandlerToList(inputs), - GTUtility.fluidHandlerToList(fluidInputs)); + Pair fluids = null; + Pair items = null; + + if (fluidInputs.getFluidTanks().size() > 0) { + fluids = matchesFluid(GTUtility.fluidHandlerToList(fluidInputs)); + if (!fluids.getKey()) { + return false; + } + } + + if (inputs.getSlots() > 0) { + items = matchesItems(GTUtility.itemHandlerToList(inputs)); + if (!items.getKey()) { + return false; + } + } + + if (consumeIfSuccessful) { + if (fluids != null) { + int[] fluidAmountInTank = fluids.getValue(); + var backedList = fluidInputs.getFluidTanks(); + + for (int i = 0; i < fluidAmountInTank.length; i++) { + var tank = backedList.get(i); + FluidStack fluidStack = tank.getFluid(); + int fluidAmount = fluidAmountInTank[i]; + + if (fluidStack == null || fluidStack.amount == fluidAmount) { + continue; + } + tank.drain(Math.abs(fluidAmount - fluidStack.amount), true); + } + } + if (items != null) { + int[] itemAmountInSlot = items.getValue(); + for (int i = 0; i < itemAmountInSlot.length; i++) { + ItemStack itemInSlot = inputs.getStackInSlot(i); + int itemAmount = itemAmountInSlot[i]; + + if (itemInSlot.isEmpty() || itemInSlot.getCount() == itemAmount) { + continue; + } + inputs.extractItem(i, Math.abs(itemAmount - itemInSlot.getCount()), false); + } + } + } + + return true; } /** From 0bee7e1682131838304d0185b535320fff35fbd9 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 5 Feb 2024 13:14:48 -0600 Subject: [PATCH 65/98] Fix part sharing tooltip missing on some parts (#2375) --- .../MetaTileEntityComputationHatch.java | 10 ++++++++++ .../MetaTileEntityDataAccessHatch.java | 7 ++++++- .../MetaTileEntityObjectHolder.java | 15 +++++++++++++++ .../MetaTileEntityOpticalDataHatch.java | 11 +++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java index 850ea3730be..ae41352ceb2 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java @@ -13,10 +13,13 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.render.CCRenderState; @@ -166,4 +169,11 @@ public T getCapability(Capability capability, EnumFacing side) { } return super.getCapability(capability, side); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java index c925716144e..a50acc06ba0 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java @@ -175,6 +175,11 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List } else { tooltip.add(I18n.format("gregtech.machine.data_access_hatch.tooltip.2", getInventorySize())); } + if (canPartShare()) { + tooltip.add(I18n.format("gregtech.universal.enabled")); + } else { + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } @NotNull @@ -199,7 +204,7 @@ public List getDataInfo() { @Override public boolean canPartShare() { - return false; + return isCreative; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java index 5658841fcda..efb526a0616 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java @@ -18,6 +18,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -25,12 +26,14 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -207,6 +210,18 @@ public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { heldItems.removeNotifiableMetaTileEntity(controllerBase); } + @Override + public boolean canPartShare() { + return false; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } + private class ObjectHolderHandler extends NotifiableItemStackHandler { public ObjectHolderHandler(MetaTileEntity metaTileEntity) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java index ca4d8d8000c..054cbccfd19 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java @@ -14,16 +14,20 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; @@ -134,4 +138,11 @@ public MultiblockAbility getAbility() { public void registerAbilities(@NotNull List abilityList) { abilityList.add(this); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } From a7cf3c6c732961eb5cf879f7b5287896955d36ad Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Thu, 8 Feb 2024 18:00:35 +0000 Subject: [PATCH 66/98] re-enable sharing for laser hatches (#2376) --- .../multi/multiblockpart/MetaTileEntityLaserHatch.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java index 2f622588c7b..76acce75c33 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java @@ -72,11 +72,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - public boolean canPartShare() { - return false; - } - @Override public MultiblockAbility getAbility() { return isOutput ? MultiblockAbility.OUTPUT_LASER : MultiblockAbility.INPUT_LASER; @@ -114,7 +109,7 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip.add(I18n.format("gregtech.universal.tooltip.amperage_in_till", amperage)); } tooltip.add(I18n.format("gregtech.universal.tooltip.energy_storage_capacity", buffer.getEnergyCapacity())); - tooltip.add(I18n.format("gregtech.universal.disabled")); + tooltip.add(I18n.format("gregtech.universal.enabled")); } @NotNull From c6d494e30865317c7da37a741792f229aa358721 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 11 Feb 2024 01:59:21 -0600 Subject: [PATCH 67/98] Config and API for tick acceleration blocking (#2381) --- .../api/metatileentity/MetaTileEntity.java | 18 +++++++++++++++ .../java/gregtech/common/ConfigHolder.java | 5 +++++ .../MetaTileEntityWorldAccelerator.java | 22 +++++++++---------- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 2ba29cb597d..e1da60cdfbe 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -67,6 +67,7 @@ import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Optional.Method; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -152,6 +153,7 @@ public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, protected boolean muffled = false; private int playSoundCooldown = 0; + private int lastTick = 0; public MetaTileEntity(ResourceLocation metaTileEntityId) { this.metaTileEntityId = metaTileEntityId; @@ -809,6 +811,13 @@ private void updateLightValue() { } public void update() { + if (!allowTickAcceleration()) { + int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); + if (currentTick == lastTick) { + return; + } + lastTick = currentTick; + } for (MTETrait mteTrait : this.mteTraits.values()) { if (shouldUpdate(mteTrait)) { mteTrait.update(); @@ -824,6 +833,15 @@ public void update() { } } + /** + * @return Whether this machine is allowed to be tick accelerated by external means. This does NOT + * apply to World Accelerators from GT, those will never work on machines. This refers to effects + * like Time in a Bottle, or Torcherino, or similar. + */ + public boolean allowTickAcceleration() { + return ConfigHolder.machines.allowTickAcceleration; + } + protected boolean shouldUpdate(MTETrait trait) { return true; } diff --git a/src/main/java/gregtech/common/ConfigHolder.java b/src/main/java/gregtech/common/ConfigHolder.java index 54863fecb57..290fb9f7d64 100644 --- a/src/main/java/gregtech/common/ConfigHolder.java +++ b/src/main/java/gregtech/common/ConfigHolder.java @@ -156,6 +156,11 @@ public static class MachineOptions { "Default: false" }) @Config.RequiresMcRestart public boolean highTierContent = false; + + @Config.Comment({ "Whether tick acceleration effects are allowed to affect GT machines.", + "This does NOT apply to the World Accelerator, but to external effects like Time in a Bottle.", + "Default: true" }) + public boolean allowTickAcceleration = true; } public static class WorldGenOptions { diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java index 09c851400ce..861cdd4c9e9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java @@ -29,7 +29,6 @@ import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fml.common.FMLCommonHandler; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; @@ -57,7 +56,6 @@ public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity impleme private boolean tileMode = false; private boolean isActive = false; private boolean isPaused = false; - private int lastTick; // Variables for Random Tick mode optimization // limit = ((tier - min) / (max - min)) * 2^tier @@ -67,7 +65,6 @@ public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity impleme public MetaTileEntityWorldAccelerator(ResourceLocation metaTileEntityId, int tier) { super(metaTileEntityId, tier); - this.lastTick = 0; this.speed = (int) Math.pow(2, tier); this.successLimit = SUCCESS_LIMITS[tier - 1]; initializeInventory(); @@ -124,6 +121,11 @@ protected long getTEModeAmperage() { return 6L; } + @Override + public boolean allowTickAcceleration() { + return false; + } + @Override public void update() { super.update(); @@ -131,15 +133,11 @@ public void update() { if (isPaused && isActive) { setActive(false); } else if (!isPaused) { - int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); - if (currentTick != lastTick) { // Prevent other tick accelerators from accelerating us - lastTick = currentTick; - boolean wasSuccessful = isTEMode() ? handleTEMode() : handleRandomTickMode(); - if (!wasSuccessful) { - setActive(false); - } else if (!isActive) { - setActive(true); - } + boolean wasSuccessful = isTEMode() ? handleTEMode() : handleRandomTickMode(); + if (!wasSuccessful) { + setActive(false); + } else if (!isActive) { + setActive(true); } } } From 2539663222c1d0b01934cf016ee43b52d3e9acd3 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon, 12 Feb 2024 16:36:00 -0500 Subject: [PATCH 68/98] fix material tree crash (#2382) --- src/main/java/gregtech/integration/jei/basic/MaterialTree.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java index 3babd634779..d919ab41597 100644 --- a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java +++ b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java @@ -73,7 +73,7 @@ public MaterialTree(Material material) { } List matFluidsStack = new ArrayList<>(); - if (material.hasProperty(PropertyKey.FLUID)) { + if (material.getFluid() != null) { matFluidsStack.add(material.getFluid(1000)); } this.fluidInputs.add(matFluidsStack); From 729ff91d799f366a3f17da6cd1b2f5ab31afb583 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:52:44 -0500 Subject: [PATCH 69/98] fix #2382 (#2386) --- .../java/gregtech/integration/jei/basic/MaterialTree.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java index d919ab41597..82cc58d5dab 100644 --- a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java +++ b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java @@ -6,6 +6,7 @@ import gregtech.api.unification.ore.OrePrefix; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import com.google.common.collect.ImmutableList; @@ -73,8 +74,11 @@ public MaterialTree(Material material) { } List matFluidsStack = new ArrayList<>(); - if (material.getFluid() != null) { - matFluidsStack.add(material.getFluid(1000)); + if (material.hasProperty(PropertyKey.FLUID)) { + Fluid fluid = material.getFluid(); + if (fluid != null) { + matFluidsStack.add(new FluidStack(fluid, 1000)); + } } this.fluidInputs.add(matFluidsStack); From eb33b4d262ddbc7c3b3ba9e1711908d33259526e Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:59:12 -0600 Subject: [PATCH 70/98] Update build script version to 1707682661 (#2380) --- build.gradle | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index f4c0964bd89..8ea7b057a37 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1705076830 +//version: 1707682661 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -24,9 +24,9 @@ plugins { id 'eclipse' id 'maven-publish' id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7' - id 'com.gtnewhorizons.retrofuturagradle' version '1.3.28' - id 'net.darkhax.curseforgegradle' version '1.1.17' apply false - id 'com.modrinth.minotaur' version '2.8.6' apply false + id 'com.gtnewhorizons.retrofuturagradle' version '1.3.33' + id 'net.darkhax.curseforgegradle' version '1.1.18' apply false + id 'com.modrinth.minotaur' version '2.8.7' apply false id 'com.diffplug.spotless' version '6.13.0' apply false id 'com.palantir.git-version' version '3.0.0' apply false id 'com.github.johnrengelman.shadow' version '8.1.1' apply false @@ -446,6 +446,10 @@ repositories { name 'GTNH Maven' url 'https://nexus.gtnewhorizons.com/repository/public/' } + maven { + name 'GTCEu Maven' + url 'https://maven.gtceu.com' + } } if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) { // need to add this here even if we did not above @@ -473,9 +477,25 @@ configurations { config.extendsFrom(shadowCompile) } } + + create("runtimeOnlyNonPublishable") { + description = "Runtime only dependencies that are not published alongside the jar" + canBeConsumed = false + canBeResolved = false + } + create("devOnlyNonPublishable") { + description = "Runtime and compiletime dependencies that are not published alongside the jar (compileOnly + runtimeOnlyNonPublishable)" + canBeConsumed = false + canBeResolved = false + } + + compileOnly.extendsFrom(devOnlyNonPublishable) + runtimeOnlyNonPublishable.extendsFrom(devOnlyNonPublishable) + runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable) + testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable) } -String mixinProviderSpec = 'zone.rong:mixinbooter:8.9' +String mixinProviderSpec = 'zone.rong:mixinbooter:9.1' dependencies { if (usesMixins.toBoolean()) { annotationProcessor 'org.ow2.asm:asm-debug-all:5.2' @@ -493,7 +513,7 @@ dependencies { transitive = false } } else if (forceEnableMixins.toBoolean()) { - runtimeOnly(mixinProviderSpec) + runtimeOnlyNonPublishable(mixinProviderSpec) } if (enableJUnit.toBoolean()) { @@ -503,8 +523,8 @@ dependencies { } if (enableModernJavaSyntax.toBoolean()) { - annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0' - compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') { + annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.1' + compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.1') { transitive = false } // workaround for https://github.com/bsideup/jabel/issues/174 @@ -513,8 +533,8 @@ dependencies { patchedMinecraft 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0' // allow Jabel to work in tests - testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.0" - testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.0") { + testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.1" + testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.1") { transitive = false // We only care about the 1 annotation class } testCompileOnly "me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0" @@ -527,9 +547,13 @@ dependencies { } if (includeCommonDevEnvMods.toBoolean()) { - implementation 'mezz.jei:jei_1.12.2:4.16.1.302' - //noinspection DependencyNotationArgument - implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28 + if (!(modId.equals('jei'))) { + implementation 'mezz.jei:jei_1.12.2:4.16.1.302' + } + if (!(modId.equals('theoneprobe'))) { + //noinspection DependencyNotationArgument + implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28 + } } } From 9246b3832dc3597931dcc1ce97fd3d4c43fe36a4 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 16 Feb 2024 19:03:05 -0600 Subject: [PATCH 71/98] Use GTCEu maven (#2379) --- dependencies.gradle | 93 ++++++++++++++++++++++++++------------------- gradle.properties | 2 +- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 82ef07ce6a8..7f2d35d408a 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,58 +1,71 @@ //file:noinspection DependencyNotationArgument // TODO remove when fixed in RFG ^ /* - * Add your dependencies here. Common configurations: - * - implementation("group:name:version:classifier"): if you need this for internal implementation details of the mod. - * Available at compiletime and runtime for your environment. - * - * - compileOnlyApi("g:n:v:c"): if you need this for internal implementation details of the mod. - * Available at compiletime but not runtime for your environment. - * + * Add your dependencies here. Supported configurations: + * - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod + * Available at runtime and compiletime for mods depending on this mod + * - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API + * Available at runtime but not compiletime for mods depending on this mod + * - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods + * Not available at all for mods depending on this mod, only visible at compiletime for this mod + * - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod + * Available at compiletime but not runtime for mods depending on this mod + * - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency + * Not available at all for mods depending on this mod, only visible at runtime for this mod + * - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime, + * but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing + * - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime + * Available at runtime for mods depending on this mod * - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry + * - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main * - * - testCONFIG("g:n:v:c"): replace CONFIG by one of the above, same as above but for the test sources instead of main + * - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name + * Requires you to enable usesShadowedDependencies in gradle.properties + * For more info, see https://github.com/GregTechCEu/Buildscripts/blob/master/docs/shadow.md * - * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed. + * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed, + * but use this sparingly as it can break using your mod as another mod's dependency if you're not careful. + * + * To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven, + * or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file. * * To add a mod with CurseMaven, replace '("g:n:v:c")' in the above with 'rfg.deobf("curse.maven:project_slug-project_id:file_id")' - * Example: implementation rfg.deobf("curse.maven:gregtech-ce-unofficial-557242:4527757") + * Example: devOnlyNonPublishable(rfg.deobf("curse.maven:top-245211:2667280")) + * + * Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not. + * The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published. * - * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph + * For more details, see https://docs.gradle.org/8.4/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - // Hard Dependencies - - // the CCL deobf jar uses very old MCP mappings, making it error at runtime in runClient/runServer - // therefore we manually deobf the regular jar - implementation rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848") // CCL 3.2.3.358 - implementation("com.cleanroommc:modularui:2.4.1") { transitive = false } - - // Soft Dependencies - // Can change any of these from compileOnlyApi -> implementation to test them in-game. - - implementation "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684" - implementation rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - implementation("com.cleanroommc:groovyscript:0.7.1") { transitive = false } - implementation rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 + // Published dependencies + api("codechicken:codechickenlib:3.2.3.358") + api("com.cleanroommc:modularui:2.4.1") { transitive = false } + api("com.cleanroommc:groovyscript:0.7.3") { transitive = false } + api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684") + api rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 + api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - compileOnlyApi rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 - compileOnlyApi "curse.maven:journeymap-32274:2916002" // Journeymap 5.7.1 - compileOnlyApi "curse.maven:voxelmap-225179:3029445" // VoxelMap 1.9.28 - compileOnlyApi "curse.maven:xaeros-263420:4516832" // Xaero's Minimap 23.4.1 - compileOnlyApi rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 - compileOnlyApi rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 - compileOnlyApi rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 - compileOnlyApi rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 + // Non-published dependencies + // Change any to devOnlyNonPublishable to test them in-game. + compileOnly("curse.maven:journeymap-32274:2916002") // Journeymap 5.7.1 + compileOnly("curse.maven:voxelmap-225179:3029445") // VoxelMap 1.9.28 + compileOnly("curse.maven:xaeros-263420:4516832") // Xaero's Minimap 23.4.1 + compileOnly rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 + compileOnly rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 + compileOnly rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 + compileOnly rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 + compileOnly rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. - // runtimeOnly rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) - // runtimeOnly rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) - // runtimeOnly rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 - // runtimeOnly rfg.deobf("curse.maven:magic-bees-65764:2855061") // Magic Bees 3.2.25 - // runtimeOnly rfg.deobf("curse.maven:gendustry-70492:2516215") // Gendustry 1.6.5.8 - // runtimeOnly rfg.deobf("curse.maven:bdlib-70496:2518031") // BdLib 1.14.3.12 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:magic-bees-65764:2855061") // Magic Bees 3.2.25 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:gendustry-70492:2516215") // Gendustry 1.6.5.8 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:bdlib-70496:2518031") // BdLib 1.14.3.12 } minecraft { @@ -60,7 +73,7 @@ minecraft { } configurations { - implementation { + compileOnly { // exclude GNU trove, FastUtil is superior and still updated exclude group: "net.sf.trove4j", module: "trove4j" // exclude javax.annotation from findbugs, jetbrains annotations are superior diff --git a/gradle.properties b/gradle.properties index 4739812b018..ffc16b29370 100644 --- a/gradle.properties +++ b/gradle.properties @@ -145,7 +145,7 @@ noPublishedSources = false # For maven credentials: # Username is set with the 'MAVEN_USER' environment variable, default to "NONE" # Password is set with the 'MAVEN_PASSWORD' environment variable, default to "NONE" -customMavenPublishUrl= +customMavenPublishUrl= https://maven.gtceu.com # The group for maven artifacts. Defaults to the 'project.modGroup' until the last '.' (if any). # So 'mymod' becomes 'mymod' and 'com.myname.mymodid' 'becomes com.myname' mavenArtifactGroup= From 3f8d011beca3b4107b532877f4d0102c2818fc6e Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:26:20 -0600 Subject: [PATCH 72/98] Fix parallel overclocks using the wrong voltage for multiblocks (#2390) --- .../gregtech/api/capability/impl/MultiblockRecipeLogic.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index 1ebb3e73c82..b27685c6987 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -434,6 +434,11 @@ public long getMaxVoltage() { } } + @Override + protected long getMaxParallelVoltage() { + return getMaximumOverclockVoltage(); + } + @Nullable @Override public RecipeMap getRecipeMap() { From df3cf24e8fc2bf590d0a44ec0f29ecb8772d8937 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:37:35 -0600 Subject: [PATCH 73/98] Temporary hotfix for research ID lookup (#2391) --- .../gregtech/api/recipes/machines/RecipeMapAssemblyLine.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java index 28cd542d11d..7edeb9a7f62 100644 --- a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java +++ b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java @@ -63,6 +63,10 @@ public boolean removeRecipe(@NotNull Recipe recipe) { @Override public void addDataStickEntry(@NotNull String researchId, @NotNull Recipe recipe) { + if (researchId.contains("xmetaitem.")) { + // save compatibility with an issue in 2.8.6, causing research IDs to change + addDataStickEntry(researchId.replace("xmetaitem.", "xitem.meta_item."), recipe); + } Collection collection = researchEntries.computeIfAbsent(researchId, (k) -> new ObjectOpenHashSet<>()); collection.add(recipe); } From a4c1f07d967bdfcc995e4752f5b53d7a4e841d44 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:09:37 -0500 Subject: [PATCH 74/98] Use chestWood oredict for ULV and LV item buses (#2383) --- .../MetaTileEntityMachineRecipeLoader.java | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java index 8d5775942e6..013e759001f 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java @@ -1,8 +1,12 @@ package gregtech.loaders.recipe; import gregtech.api.GTValues; +import gregtech.api.items.OreDictNames; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.recipes.ModHandler; +import gregtech.api.recipes.ingredients.GTRecipeInput; +import gregtech.api.recipes.ingredients.GTRecipeItemInput; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.Mods; @@ -18,7 +22,6 @@ import static gregtech.common.blocks.MetaBlocks.LD_FLUID_PIPE; import static gregtech.common.blocks.MetaBlocks.LD_ITEM_PIPE; import static gregtech.common.items.MetaItems.*; -import static gregtech.common.items.MetaItems.SENSOR_UV; import static gregtech.common.metatileentities.MetaTileEntities.*; public class MetaTileEntityMachineRecipeLoader { @@ -242,8 +245,8 @@ public static void init() { .duration(300).EUt(VA[EV]).buildAndRegister(); // Item Buses - registerHatchBusRecipe(ULV, ITEM_IMPORT_BUS[ULV], ITEM_EXPORT_BUS[ULV], new ItemStack(Blocks.CHEST)); - registerHatchBusRecipe(LV, ITEM_IMPORT_BUS[LV], ITEM_EXPORT_BUS[LV], new ItemStack(Blocks.CHEST)); + registerHatchBusRecipe(ULV, ITEM_IMPORT_BUS[ULV], ITEM_EXPORT_BUS[ULV], OreDictNames.chestWood.toString()); + registerHatchBusRecipe(LV, ITEM_IMPORT_BUS[LV], ITEM_EXPORT_BUS[LV], OreDictNames.chestWood.toString()); registerHatchBusRecipe(MV, ITEM_IMPORT_BUS[MV], ITEM_EXPORT_BUS[MV], BRONZE_CRATE.getStackForm()); registerHatchBusRecipe(HV, ITEM_IMPORT_BUS[HV], ITEM_EXPORT_BUS[HV], STEEL_CRATE.getStackForm()); registerHatchBusRecipe(EV, ITEM_IMPORT_BUS[EV], ITEM_EXPORT_BUS[EV], ALUMINIUM_CRATE.getStackForm()); @@ -1025,7 +1028,16 @@ public static void init() { } private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, MetaTileEntity outputBus, - ItemStack extra) { + Object extraInput) { + GTRecipeInput extra; + if (extraInput instanceof ItemStack stack) { + extra = new GTRecipeItemInput(stack); + } else if (extraInput instanceof String oreName) { + extra = new GTRecipeOreInput(oreName); + } else { + throw new IllegalArgumentException("extraInput must be ItemStack or GTRecipeInput"); + } + // Glue recipe for ULV and LV // 250L for ULV, 500L for LV if (tier <= GTValues.LV) { @@ -1114,29 +1126,18 @@ private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, Me } private static int getFluidAmount(int offsetTier) { - switch (offsetTier) { - case 0: - return 4; - case 1: - return 9; - case 2: - return 18; - case 3: - return 36; - case 4: - return 72; - case 5: - return 144; - case 6: - return 288; - case 7: - return 432; - case 8: - return 576; - case 9: - default: - return 720; - } + return switch (offsetTier) { + case 0 -> 4; + case 1 -> 9; + case 2 -> 18; + case 3 -> 36; + case 4 -> 72; + case 5 -> 144; + case 6 -> 288; + case 7 -> 432; + case 8 -> 576; + default -> 720; + }; } // TODO clean this up with a CraftingComponent rework From f1b1d79a890808aa468cf919e684ff5ae73d8d53 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:14:55 -0600 Subject: [PATCH 75/98] add maven to GHA publish action --- .github/workflows/publish_project.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml index 2172ac6806e..69fb413604c 100644 --- a/.github/workflows/publish_project.yml +++ b/.github/workflows/publish_project.yml @@ -41,6 +41,12 @@ jobs: generate_release_notes: true fail_on_unmatched_files: true + - name: Publish to Maven + env: + MAVEN_USER: "${{ secrets.MAVEN_USER }}" + MAVEN:PASSWORD: "${{ secrets.MAVEN_PASSWORD }}" + run: ./gradlew publish + - name: Publish to Curseforge env: CURSEFORGE_API_KEY: "${{ secrets.CURSEFORGE_API_KEY }}" From 62ffdb22f85e2f73322db49abe14c3b88b804e26 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:23:20 -0600 Subject: [PATCH 76/98] 2.8.7 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ffc16b29370..9de88c6bf58 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 2.8.6-beta +modVersion = 2.8.7-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true From c8ab1a87ad532e2445c41c818944907129df1ce2 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:28:45 -0600 Subject: [PATCH 77/98] fix maven upload action --- .github/workflows/publish_project.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml index 69fb413604c..a6bb305d5bb 100644 --- a/.github/workflows/publish_project.yml +++ b/.github/workflows/publish_project.yml @@ -44,7 +44,7 @@ jobs: - name: Publish to Maven env: MAVEN_USER: "${{ secrets.MAVEN_USER }}" - MAVEN:PASSWORD: "${{ secrets.MAVEN_PASSWORD }}" + MAVEN_PASSWORD: "${{ secrets.MAVEN_PASSWORD }}" run: ./gradlew publish - name: Publish to Curseforge From 675efe0712af3a4dcdae53e3075a6dd45fc0c9c9 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 2 Mar 2024 21:32:27 -0500 Subject: [PATCH 78/98] fix quantum tank not always fully reading custom data (#2396) --- .../storage/MetaTileEntityQuantumTank.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java index 6e27064a4e3..d6624d95823 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java @@ -11,7 +11,14 @@ import gregtech.api.cover.CoverRayTracer; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.gui.widgets.AdvancedTextWidget; +import gregtech.api.gui.widgets.FluidContainerSlotWidget; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.PhantomTankWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.TankWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.IFastRenderMetaTileEntity; import gregtech.api.metatileentity.ITieredMetaTileEntity; @@ -443,14 +450,16 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { try { this.fluidTank.setFluid(FluidStack.loadFluidStackFromNBT(buf.readCompoundTag())); } catch (IOException ignored) { - GTLog.logger.warn("Failed to load fluid from NBT in a quantum tank at " + this.getPos() + - " on a routine fluid update"); + GTLog.logger.warn("Failed to load fluid from NBT in a quantum tank at {} on a routine fluid update", + this.getPos()); } scheduleRenderUpdate(); } else if (dataId == UPDATE_FLUID_AMOUNT) { + // amount must always be read even if it cannot be used to ensure the reader index advances + int amount = buf.readInt(); FluidStack stack = fluidTank.getFluid(); if (stack != null) { - stack.amount = Math.min(buf.readInt(), fluidTank.getCapacity()); + stack.amount = Math.min(amount, fluidTank.getCapacity()); scheduleRenderUpdate(); } } else if (dataId == UPDATE_IS_VOIDING) { From ae5ef986446366ccb7305bc946e5a01a7affaa92 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Sat, 2 Mar 2024 23:17:25 -0700 Subject: [PATCH 79/98] Fix NPE from facing being null when drawing grid overlays (#2401) --- src/main/java/gregtech/common/ToolEventHandlers.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/common/ToolEventHandlers.java b/src/main/java/gregtech/common/ToolEventHandlers.java index 65d407e9635..62195e49791 100644 --- a/src/main/java/gregtech/common/ToolEventHandlers.java +++ b/src/main/java/gregtech/common/ToolEventHandlers.java @@ -477,6 +477,8 @@ private static void drawGridOverlays(@NotNull AxisAlignedBB box) { @SideOnly(Side.CLIENT) private static void drawGridOverlays(EnumFacing facing, AxisAlignedBB box, Predicate test) { + if (facing == null) return; + Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); buffer.begin(3, DefaultVertexFormats.POSITION_COLOR); From 74272b220806d2268f3d5d33443a0e8340ef9d3d Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sun, 3 Mar 2024 02:08:27 -0700 Subject: [PATCH 80/98] Drain Tricorder energy only when in survival (#2402) --- .../gregtech/common/items/behaviors/TricorderBehavior.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java index 344b97231d3..82a2f46c854 100644 --- a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java @@ -63,7 +63,9 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPo List info = getScannerInfo(player, world, pos); if (player.isCreative() || drainEnergy(player.getHeldItem(hand), energyCost, true)) { - drainEnergy(player.getHeldItem(hand), energyCost, false); + if (!player.isCreative()) { + drainEnergy(player.getHeldItem(hand), energyCost, false); + } for (ITextComponent line : info) { player.sendMessage(line); } From db174d2d802cbf7b51bfb9553fc7ec4921fec569 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:14:43 -0600 Subject: [PATCH 81/98] Advanced Stocking Input Bus + Advanced Stocking Input Hatch (#2367) --- .../api/capability/GregtechDataCodes.java | 4 + .../java/gregtech/api/gui/GuiTextures.java | 6 + .../multiblock/IMultiblockPart.java | 3 + .../multiblock/MultiblockControllerBase.java | 2 +- .../RecipeMapMultiblockController.java | 1 + .../client/renderer/texture/Textures.java | 8 + .../gui/widget/appeng/AEConfigWidget.java | 45 +- .../widget/appeng/AEFluidConfigWidget.java | 40 +- .../gui/widget/appeng/AEItemConfigWidget.java | 40 +- .../gui/widget/appeng/slot/AEConfigSlot.java | 34 +- .../widget/appeng/slot/AEFluidConfigSlot.java | 91 +++- .../widget/appeng/slot/AEItemConfigSlot.java | 97 +++- .../gui/widget/appeng/slot/AmountSetSlot.java | 2 +- .../metatileentities/MetaTileEntities.java | 15 +- .../appeng/MetaTileEntityAEHostablePart.java | 93 ++-- .../appeng/MetaTileEntityMEInputBus.java | 424 +++++++----------- .../appeng/MetaTileEntityMEInputHatch.java | 318 ++++--------- .../appeng/MetaTileEntityMEOutputBus.java | 59 ++- .../appeng/MetaTileEntityMEOutputHatch.java | 63 ++- .../appeng/MetaTileEntityMEStockingBus.java | 414 +++++++++++++++++ .../appeng/MetaTileEntityMEStockingHatch.java | 375 ++++++++++++++++ .../appeng/slot/ExportOnlyAEFluidList.java | 64 +++ .../appeng/slot/ExportOnlyAEFluidSlot.java | 192 ++++++++ .../appeng/slot/ExportOnlyAEItemList.java | 126 ++++++ .../appeng/slot/ExportOnlyAEItemSlot.java | 138 ++++++ .../appeng/{ => slot}/ExportOnlyAESlot.java | 11 +- .../appeng/{ => slot}/IConfigurableSlot.java | 7 +- .../appeng/stack/WrappedItemStack.java | 10 +- .../MetaTileEntityMachineRecipeLoader.java | 19 + .../resources/assets/gregtech/lang/en_us.lang | 32 +- .../blocks/overlay/appeng/me_input_bus.png | Bin 154 -> 199 bytes .../overlay/appeng/me_input_bus_active.png | Bin 0 -> 196 bytes .../blocks/overlay/appeng/me_input_hatch.png | Bin 154 -> 199 bytes .../overlay/appeng/me_input_hatch_active.png | Bin 0 -> 196 bytes .../blocks/overlay/appeng/me_output_bus.png | Bin 154 -> 199 bytes .../overlay/appeng/me_output_bus_active.png | Bin 0 -> 195 bytes .../blocks/overlay/appeng/me_output_hatch.png | Bin 154 -> 199 bytes .../overlay/appeng/me_output_hatch_active.png | Bin 0 -> 195 bytes .../gregtech/textures/gui/base/slot_dark.png | Bin 0 -> 99 bytes .../textures/gui/widget/arrow_double.png | Bin 0 -> 215 bytes .../gui/widget/button_me_auto_pull.png | Bin 0 -> 273 bytes 41 files changed, 2004 insertions(+), 729 deletions(-) create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java rename src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/{ => slot}/ExportOnlyAESlot.java (94%) rename src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/{ => slot}/IConfigurableSlot.java (66%) create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus_active.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch_active.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus_active.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch_active.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/base/slot_dark.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/button_me_auto_pull.png diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index e425d3339e4..4fcead477d4 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -166,4 +166,8 @@ public static int assignId() { // Alarm public static final int UPDATE_SOUND = assignId(); public static final int UPDATE_RADIUS = assignId(); + + // ME Parts + public static final int UPDATE_AUTO_PULL = assignId(); + public static final int UPDATE_ONLINE_STATUS = assignId(); } diff --git a/src/main/java/gregtech/api/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index e85bffcfe97..e2b7afa929a 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -48,6 +48,9 @@ public class GuiTextures { public static final TextureArea FLUID_TANK_OVERLAY = TextureArea .fullImage("textures/gui/base/fluid_tank_overlay.png"); public static final TextureArea SLOT = AdoptableTextureArea.fullImage("textures/gui/base/slot.png", 18, 18, 1, 1); + public static final TextureArea SLOT_DARK = AdoptableTextureArea.fullImage("textures/gui/base/slot_dark.png", 18, + 18, 1, 1); + @Deprecated // idek what this texture is public static final TextureArea SLOT_DARKENED = TextureArea.fullImage("textures/gui/base/darkened_slot.png"); public static final SteamTexture SLOT_STEAM = SteamTexture.fullImage("textures/gui/base/slot_%s.png"); public static final TextureArea TOGGLE_BUTTON_BACK = TextureArea @@ -504,6 +507,9 @@ public class GuiTextures { public static final TextureArea CONFIG_ARROW_DARK = TextureArea .fullImage("textures/gui/widget/config_arrow_dark.png"); public static final TextureArea SELECT_BOX = TextureArea.fullImage("textures/gui/widget/select_box.png"); + public static final TextureArea BUTTON_AUTO_PULL = TextureArea + .fullImage("textures/gui/widget/button_me_auto_pull.png"); + public static final TextureArea ARROW_DOUBLE = TextureArea.fullImage("textures/gui/widget/arrow_double.png"); // Fusion Reactor custom images public static final TextureArea FUSION_REACTOR_MK1_TITLE = TextureArea diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java index dc6cb0e5d28..520a36dcebb 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java @@ -11,4 +11,7 @@ public interface IMultiblockPart { default boolean canPartShare() { return true; } + + /** Called when distinct mode is toggled on the controller that this part is attached to */ + default void onDistinctChange(boolean newValue) {} } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java index 933ec7b1259..54b5bd45b5c 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java @@ -343,9 +343,9 @@ public void checkStructurePattern() { abilityPart.registerAbilities(abilityInstancesList); } } - parts.forEach(part -> part.addToMultiBlock(this)); this.multiblockParts.addAll(parts); this.multiblockAbilities.putAll(abilities); + parts.forEach(part -> part.addToMultiBlock(this)); this.structureFormed = true; writeCustomData(STRUCTURE_FORMED, buf -> buf.writeBoolean(true)); formStructure(context); diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index 4301adbacce..d90c9b548db 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -246,6 +246,7 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { this.isDistinct = isDistinct; recipeMapWorkable.onDistinctChanged(); + getMultiblockParts().forEach(part -> part.onDistinctChange(isDistinct)); // mark buses as changed on distinct toggle if (this.isDistinct) { this.notifiedItemInputList.addAll(this.getAbilities(MultiblockAbility.IMPORT_ITEMS)); diff --git a/src/main/java/gregtech/client/renderer/texture/Textures.java b/src/main/java/gregtech/client/renderer/texture/Textures.java index 39db1d4f0e2..c007a6b13d6 100644 --- a/src/main/java/gregtech/client/renderer/texture/Textures.java +++ b/src/main/java/gregtech/client/renderer/texture/Textures.java @@ -497,10 +497,18 @@ public class Textures { public static final SimpleOverlayRenderer ME_OUTPUT_HATCH = new SimpleOverlayRenderer( "overlay/appeng/me_output_hatch"); + public static final SimpleOverlayRenderer ME_OUTPUT_HATCH_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_output_hatch_active"); public static final SimpleOverlayRenderer ME_INPUT_HATCH = new SimpleOverlayRenderer( "overlay/appeng/me_input_hatch"); + public static final SimpleOverlayRenderer ME_INPUT_HATCH_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_input_hatch_active"); public static final SimpleOverlayRenderer ME_OUTPUT_BUS = new SimpleOverlayRenderer("overlay/appeng/me_output_bus"); + public static final SimpleOverlayRenderer ME_OUTPUT_BUS_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_output_bus_active"); public static final SimpleOverlayRenderer ME_INPUT_BUS = new SimpleOverlayRenderer("overlay/appeng/me_input_bus"); + public static final SimpleOverlayRenderer ME_INPUT_BUS_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_input_bus_active"); public static final ResourceLocation ACE_CAPE_TEXTURE = gregtechId("textures/capes/acecape.png"); public static final ResourceLocation AGENDER_CAPE_TEXTURE = gregtechId("textures/capes/agendercape.png"); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java index 59005459893..1195fa8f34f 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java @@ -6,7 +6,7 @@ import gregtech.api.util.Size; import gregtech.common.gui.widget.appeng.slot.AEConfigSlot; import gregtech.common.gui.widget.appeng.slot.AmountSetSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import appeng.api.storage.data.IAEStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -26,26 +26,34 @@ public abstract class AEConfigWidget> extends AbstractWidg protected Int2ObjectMap> changeMap = new Int2ObjectOpenHashMap<>(); protected IConfigurableSlot[] displayList; protected AmountSetSlot amountSetWidget; + protected final boolean isStocking; protected final static int UPDATE_ID = 1000; - public AEConfigWidget(int x, int y, IConfigurableSlot[] config) { + public AEConfigWidget(int x, int y, IConfigurableSlot[] config, boolean isStocking) { super(new Position(x, y), new Size(config.length * 18, 18 * 2)); + this.isStocking = isStocking; this.config = config; this.init(); - this.amountSetWidget = new AmountSetSlot<>(80, -40, this); - this.addWidget(this.amountSetWidget); - this.addWidget(this.amountSetWidget.getText()); - this.amountSetWidget.setVisible(false); - this.amountSetWidget.getText().setVisible(false); + if (!isStocking()) { + this.amountSetWidget = new AmountSetSlot<>(80, -40, this); + this.addWidget(this.amountSetWidget); + this.addWidget(this.amountSetWidget.getText()); + this.amountSetWidget.setVisible(false); + this.amountSetWidget.getText().setVisible(false); + } } public void enableAmount(int slotIndex) { + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (isStocking()) return; this.amountSetWidget.setSlotIndex(slotIndex); this.amountSetWidget.setVisible(true); this.amountSetWidget.getText().setVisible(true); } public void disableAmount() { + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (isStocking()) return; this.amountSetWidget.setSlotIndex(-1); this.amountSetWidget.setVisible(false); this.amountSetWidget.getText().setVisible(false); @@ -53,22 +61,29 @@ public void disableAmount() { @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (this.amountSetWidget.isVisible()) { - if (this.amountSetWidget.getText().mouseClicked(mouseX, mouseY, button)) { - return true; + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (!isStocking()) { + if (this.amountSetWidget.isVisible()) { + if (this.amountSetWidget.getText().mouseClicked(mouseX, mouseY, button)) { + return true; + } } - } - for (Widget w : this.widgets) { - if (w instanceof AEConfigSlot) { - ((AEConfigSlot) w).setSelect(false); + for (Widget w : this.widgets) { + if (w instanceof AEConfigSlot) { + ((AEConfigSlot) w).setSelect(false); + } } + this.disableAmount(); } - this.disableAmount(); return super.mouseClicked(mouseX, mouseY, button); } abstract void init(); + public boolean isStocking() { + return isStocking; + } + @Override public void detectAndSendChanges() { super.detectAndSendChanges(); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java index 1599217290c..b5f709b0b86 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java @@ -1,39 +1,49 @@ package gregtech.common.gui.widget.appeng; import gregtech.common.gui.widget.appeng.slot.AEFluidConfigSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; import appeng.api.storage.data.IAEFluidStack; -/** - * @Author GlodBlock - * @Description Display {@link IAEFluidStack} config - * @Date 2023/4/21-1:45 - */ public class AEFluidConfigWidget extends AEConfigWidget { - public AEFluidConfigWidget(int x, int y, IConfigurableSlot[] config) { - super(x, y, config); + final ExportOnlyAEFluidList fluidList; + + public AEFluidConfigWidget(int x, int y, ExportOnlyAEFluidList fluidList) { + super(x, y, fluidList.getInventory(), fluidList.isStocking()); + this.fluidList = fluidList; } @Override @SuppressWarnings("unchecked") void init() { - int line; + final int size = (int) Math.sqrt(this.config.length); this.displayList = new IConfigurableSlot[this.config.length]; this.cached = new IConfigurableSlot[this.config.length]; - for (int index = 0; index < this.config.length; index++) { - this.displayList[index] = new MetaTileEntityMEInputHatch.ExportOnlyAEFluid(); - this.cached[index] = new MetaTileEntityMEInputHatch.ExportOnlyAEFluid(); - line = index / 8; - this.addWidget(new AEFluidConfigSlot((index - line * 8) * 18, line * (18 * 2 + 2), this, index)); + for (int h = 0; h < size; h++) { + for (int w = 0; w < size; w++) { + final int index = h * size + w; + this.displayList[index] = new ExportOnlyAEFluidSlot(); + this.cached[index] = new ExportOnlyAEFluidSlot(); + this.addWidget(new AEFluidConfigSlot(w * 18, h * 18, this, index)); + } } } + public boolean hasStackInConfig(FluidStack stack) { + return fluidList.hasStackInConfig(stack, true); + } + + public boolean isAutoPull() { + return fluidList.isAutoPull(); + } + @Override public void readUpdateInfo(int id, PacketBuffer buffer) { super.readUpdateInfo(id, buffer); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java index c3707d4afaf..0f2afe98235 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java @@ -1,39 +1,49 @@ package gregtech.common.gui.widget.appeng; import gregtech.common.gui.widget.appeng.slot.AEItemConfigSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputBus; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import appeng.api.storage.data.IAEItemStack; -/** - * @Author GlodBlock - * @Description Display {@link IAEItemStack} config - * @Date 2023/4/22-1:02 - */ public class AEItemConfigWidget extends AEConfigWidget { - public AEItemConfigWidget(int x, int y, IConfigurableSlot[] config) { - super(x, y, config); + final ExportOnlyAEItemList itemList; + + public AEItemConfigWidget(int x, int y, ExportOnlyAEItemList itemList) { + super(x, y, itemList.getInventory(), itemList.isStocking()); + this.itemList = itemList; } @Override @SuppressWarnings("unchecked") void init() { - int line; + final int size = (int) Math.sqrt(this.config.length); this.displayList = new IConfigurableSlot[this.config.length]; this.cached = new IConfigurableSlot[this.config.length]; - for (int index = 0; index < this.config.length; index++) { - this.displayList[index] = new MetaTileEntityMEInputBus.ExportOnlyAEItem(); - this.cached[index] = new MetaTileEntityMEInputBus.ExportOnlyAEItem(); - line = index / 8; - this.addWidget(new AEItemConfigSlot((index - line * 8) * 18, line * (18 * 2 + 2), this, index)); + for (int h = 0; h < size; h++) { + for (int w = 0; w < size; w++) { + final int index = h * size + w; + this.displayList[index] = new ExportOnlyAEItemSlot(); + this.cached[index] = new ExportOnlyAEItemSlot(); + this.addWidget(new AEItemConfigSlot(w * 18, h * 18, this, index)); + } } } + public boolean hasStackInConfig(ItemStack stack) { + return itemList.hasStackInConfig(stack, true); + } + + public boolean isAutoPull() { + return itemList.isAutoPull(); + } + @Override public void readUpdateInfo(int id, PacketBuffer buffer) { super.readUpdateInfo(id, buffer); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java index ed1b9145bd7..d663340a451 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java @@ -5,7 +5,7 @@ import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; @@ -17,13 +17,9 @@ import java.util.Collections; import java.util.List; -/** - * @Author GlodBlock - * @Description A configurable slot - * @Date 2023/4/22-0:30 - */ public class AEConfigSlot> extends Widget implements IGhostIngredientTarget { + protected static final int DISPLAY_X_OFFSET = 18 * 5; protected AEConfigWidget parentWidget; protected int index; protected final static int REMOVE_ID = 1000; @@ -43,14 +39,24 @@ public void drawInForeground(int mouseX, int mouseY) { IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); if (slot.getConfig() == null && mouseOverConfig(mouseX, mouseY)) { List hoverStringList = new ArrayList<>(); - hoverStringList.add(I18n.format("gregtech.gui.config_slot")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.set")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.scroll")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.remove")); - drawHoveringText(ItemStack.EMPTY, hoverStringList, -1, mouseX, mouseY); + addHoverText(hoverStringList); + if (!hoverStringList.isEmpty()) { + drawHoveringText(ItemStack.EMPTY, hoverStringList, -1, mouseX, mouseY); + } } } + protected void addHoverText(List hoverText) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + if (!parentWidget.isStocking()) { + hoverText.add(I18n.format("gregtech.gui.config_slot.set")); + hoverText.add(I18n.format("gregtech.gui.config_slot.scroll")); + } else { + hoverText.add(I18n.format("gregtech.gui.config_slot.set_only")); + } + hoverText.add(I18n.format("gregtech.gui.config_slot.remove")); + } + public void setSelect(boolean val) { this.select = val; } @@ -62,11 +68,15 @@ protected boolean mouseOverConfig(int mouseX, int mouseY) { protected boolean mouseOverStock(int mouseX, int mouseY) { Position position = getPosition(); - return isMouseOver(position.x, position.y + 18, 18, 18, mouseX, mouseY); + return isMouseOver(position.x + DISPLAY_X_OFFSET, position.y, 18, 18, mouseX, mouseY); } @Override public List> getPhantomTargets(Object ingredient) { return Collections.emptyList(); } + + public AEConfigWidget getParentWidget() { + return parentWidget; + } } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java index b4ab7e87beb..2b852fdeb14 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java @@ -7,10 +7,11 @@ import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.RenderUtil; -import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.gui.widget.appeng.AEFluidConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; +import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -34,27 +35,26 @@ import static gregtech.api.capability.GregtechDataCodes.LOAD_PHANTOM_FLUID_STACK_FROM_NBT; import static gregtech.api.util.GTUtility.getFluidFromContainer; -/** - * @Author GlodBlock - * @Description A configurable slot for {@link IAEFluidStack} - * @Date 2023/4/21-0:50 - */ public class AEFluidConfigSlot extends AEConfigSlot { - public AEFluidConfigSlot(int x, int y, AEConfigWidget widget, int index) { - super(new Position(x, y), new Size(18, 18 * 2), widget, index); + public AEFluidConfigSlot(int x, int y, AEFluidConfigWidget widget, int index) { + super(new Position(x, y), new Size(18 * 6, 18), widget, index); + } + + @Override + public AEFluidConfigWidget getParentWidget() { + return (AEFluidConfigWidget) super.getParentWidget(); } @Override public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { super.drawInBackground(mouseX, mouseY, partialTicks, context); + AEFluidConfigWidget pw = getParentWidget(); Position position = getPosition(); - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = pw.getDisplay(this.index); IAEFluidStack config = slot.getConfig(); IAEFluidStack stock = slot.getStock(); - GuiTextures.FLUID_SLOT.draw(position.x, position.y, 18, 18); - GuiTextures.FLUID_SLOT.draw(position.x, position.y + 18, 18, 18); - GuiTextures.CONFIG_ARROW.draw(position.x, position.y, 18, 18); + drawSlots(pw.isAutoPull(), position.x, position.y); if (this.select) { GuiTextures.SELECT_BOX.draw(position.x, position.y, 18, 18); } @@ -62,22 +62,35 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender int stackY = position.y + 1; if (config != null) { RenderUtil.drawFluidForGui(config.getFluidStack(), config.getFluidStack().amount, stackX, stackY, 17, 17); - String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4) + "L"; - drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + + if (!pw.isStocking()) { + String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4) + "L"; + drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + } } if (stock != null) { - RenderUtil.drawFluidForGui(stock.getFluidStack(), stock.getFluidStack().amount, stackX, stackY + 18, 17, - 17); + RenderUtil.drawFluidForGui(stock.getFluidStack(), stock.getFluidStack().amount, stackX + DISPLAY_X_OFFSET, + stackY, 17, 17); String amountStr = TextFormattingUtil.formatLongToCompactString(stock.getStackSize(), 4) + "L"; - drawStringFixedCorner(amountStr, stackX + 17, stackY + 18 + 17, 16777215, true, 0.5f); + drawStringFixedCorner(amountStr, stackX + DISPLAY_X_OFFSET + 17, stackY + 17, 16777215, true, 0.5f); } if (mouseOverConfig(mouseX, mouseY)) { drawSelectionOverlay(stackX, stackY, 16, 16); } else if (mouseOverStock(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY + 18, 16, 16); + drawSelectionOverlay(stackX + DISPLAY_X_OFFSET, stackY, 16, 16); } } + private void drawSlots(boolean autoPull, int x, int y) { + if (autoPull) { + GuiTextures.SLOT_DARK.draw(x, y, 18, 18); + } else { + GuiTextures.FLUID_SLOT.draw(x, y, 18, 18); + } + GuiTextures.SLOT_DARK.draw(x + DISPLAY_X_OFFSET, y, 18, 18); + GuiTextures.CONFIG_ARROW.draw(x, y, 18, 18); + } + @Override public void drawInForeground(int mouseX, int mouseY) { super.drawInForeground(mouseX, mouseY); @@ -107,13 +120,31 @@ public void drawInForeground(int mouseX, int mouseY) { } } + @Override + protected void addHoverText(List hoverText) { + if (getParentWidget().isAutoPull()) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + hoverText.add(I18n.format("gregtech.gui.config_slot.auto_pull_managed")); + } else { + super.addHoverText(hoverText); + } + } + @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { + AEFluidConfigWidget pw = getParentWidget(); + if (pw.isAutoPull()) { + return false; + } + if (mouseOverConfig(mouseX, mouseY)) { if (button == 1) { // Right click to clear - this.parentWidget.disableAmount(); writeClientAction(REMOVE_ID, buf -> {}); + + if (!pw.isStocking()) { + this.parentWidget.disableAmount(); + } } else if (button == 0) { // Left click to set/select ItemStack hold = this.gui.entityPlayer.inventory.getItemStack(); @@ -125,8 +156,11 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { buf.writeVarInt(fluid.amount); }); } - this.parentWidget.enableAmount(this.index); - this.select = true; + + if (!pw.isStocking()) { + this.parentWidget.enableAmount(this.index); + this.select = true; + } } return true; } @@ -145,6 +179,7 @@ public void handleClientAction(int id, PacketBuffer buffer) { if (id == UPDATE_ID) { FluidStack fluid = FluidRegistry.getFluidStack(buffer.readString(Integer.MAX_VALUE / 16), buffer.readVarInt()); + if (!isFluidValidForSlot(fluid)) return; slot.setConfig(WrappedFluidStack.fromFluidStack(fluid)); this.parentWidget.enableAmount(this.index); if (fluid != null) { @@ -198,13 +233,20 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { } } + private boolean isFluidValidForSlot(FluidStack stack) { + if (stack == null) return true; + AEFluidConfigWidget pw = getParentWidget(); + if (!pw.isStocking()) return true; + return !pw.hasStackInConfig(stack); + } + @Override public List> getPhantomTargets(Object ingredient) { if (getFluidFromContainer(ingredient) == null) { return Collections.emptyList(); } Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; return Lists.newArrayList(new IGhostIngredientHandler.Target<>() { @NotNull @@ -227,9 +269,10 @@ public void accept(@NotNull Object ingredient) { @SideOnly(Side.CLIENT) public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + if (parentWidget.isStocking()) return false; IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; if (slot.getConfig() == null || wheelDelta == 0 || !rectangle.contains(mouseX, mouseY)) { return false; } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java index 02cad40272b..3dff4140249 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java @@ -5,10 +5,11 @@ import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; -import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.gui.widget.appeng.AEItemConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; +import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.relauncher.Side; @@ -24,27 +25,26 @@ import java.util.Collections; import java.util.List; -/** - * @Author GlodBlock - * @Description A configurable slot for {@link IAEItemStack} - * @Date 2023/4/22-0:48 - */ public class AEItemConfigSlot extends AEConfigSlot { - public AEItemConfigSlot(int x, int y, AEConfigWidget widget, int index) { - super(new Position(x, y), new Size(18, 18 * 2), widget, index); + public AEItemConfigSlot(int x, int y, AEItemConfigWidget widget, int index) { + super(new Position(x, y), new Size(18 * 6, 18), widget, index); + } + + @Override + public AEItemConfigWidget getParentWidget() { + return (AEItemConfigWidget) super.getParentWidget(); } @Override public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { super.drawInBackground(mouseX, mouseY, partialTicks, context); + AEItemConfigWidget pw = getParentWidget(); Position position = getPosition(); - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = pw.getDisplay(this.index); IAEItemStack config = slot.getConfig(); IAEItemStack stock = slot.getStock(); - GuiTextures.SLOT.draw(position.x, position.y, 18, 18); - GuiTextures.SLOT.draw(position.x, position.y + 18, 18, 18); - GuiTextures.CONFIG_ARROW_DARK.draw(position.x, position.y, 18, 18); + drawSlots(pw.isAutoPull(), position.x, position.y); if (this.select) { GuiTextures.SELECT_BOX.draw(position.x, position.y, 18, 18); } @@ -54,28 +54,43 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender ItemStack stack = config.createItemStack(); stack.setCount(1); drawItemStack(stack, stackX, stackY, null); - String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4); - drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + + // Only draw the config amount if not stocking, as its meaningless when stocking + if (!pw.isStocking()) { + String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4); + drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + } } if (stock != null) { ItemStack stack = stock.createItemStack(); stack.setCount(1); - drawItemStack(stack, stackX, stackY + 18, null); + drawItemStack(stack, stackX + DISPLAY_X_OFFSET, stackY, null); String amountStr = TextFormattingUtil.formatLongToCompactString(stock.getStackSize(), 4); - drawStringFixedCorner(amountStr, stackX + 17, stackY + 18 + 17, 16777215, true, 0.5f); + drawStringFixedCorner(amountStr, stackX + DISPLAY_X_OFFSET + 17, stackY + 17, 16777215, true, 0.5f); } if (mouseOverConfig(mouseX, mouseY)) { drawSelectionOverlay(stackX, stackY, 16, 16); } else if (mouseOverStock(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY + 18, 16, 16); + drawSelectionOverlay(stackX + DISPLAY_X_OFFSET, stackY, 16, 16); } } + private void drawSlots(boolean autoPull, int x, int y) { + if (autoPull) { + GuiTextures.SLOT_DARK.draw(x, y, 18, 18); + GuiTextures.CONFIG_ARROW.draw(x, y, 18, 18); + } else { + GuiTextures.SLOT.draw(x, y, 18, 18); + GuiTextures.CONFIG_ARROW_DARK.draw(x, y, 18, 18); + } + GuiTextures.SLOT_DARK.draw(x + DISPLAY_X_OFFSET, y, 18, 18); + } + @Override public void drawInForeground(int mouseX, int mouseY) { super.drawInForeground(mouseX, mouseY); IAEItemStack item = null; - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = this.getParentWidget().getDisplay(this.index); if (mouseOverConfig(mouseX, mouseY)) { item = slot.getConfig(); } else if (mouseOverStock(mouseX, mouseY)) { @@ -86,22 +101,45 @@ public void drawInForeground(int mouseX, int mouseY) { } } + @Override + protected void addHoverText(List hoverText) { + if (getParentWidget().isAutoPull()) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + hoverText.add(I18n.format("gregtech.gui.config_slot.auto_pull_managed")); + } else { + super.addHoverText(hoverText); + } + } + @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { + AEItemConfigWidget pw = getParentWidget(); + // don't allow manual interaction with config slots when auto pull is enabled + if (pw.isAutoPull()) { + return false; + } + if (mouseOverConfig(mouseX, mouseY)) { if (button == 1) { // Right click to clear - this.parentWidget.disableAmount(); writeClientAction(REMOVE_ID, buf -> {}); + + if (!pw.isStocking()) { + pw.disableAmount(); + } } else if (button == 0) { // Left click to set/select ItemStack item = this.gui.entityPlayer.inventory.getItemStack(); if (!item.isEmpty()) { writeClientAction(UPDATE_ID, buf -> buf.writeItemStack(item)); + return true; + } + + if (!pw.isStocking()) { + pw.enableAmount(this.index); + this.select = true; } - this.parentWidget.enableAmount(this.index); - this.select = true; } return true; } @@ -120,6 +158,7 @@ public void handleClientAction(int id, PacketBuffer buffer) { if (id == UPDATE_ID) { try { ItemStack item = buffer.readItemStack(); + if (!isItemValidForSlot(item)) return; slot.setConfig(WrappedItemStack.fromItemStack(item)); this.parentWidget.enableAmount(this.index); if (!item.isEmpty()) { @@ -157,13 +196,21 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { } } + // Method for server-side validation of an attempted new configured item + private boolean isItemValidForSlot(ItemStack stack) { + if (stack == null || stack.isEmpty()) return true; + AEItemConfigWidget pw = getParentWidget(); + if (!pw.isStocking()) return true; + return !pw.hasStackInConfig(stack); + } + @Override public List> getPhantomTargets(Object ingredient) { if (!(ingredient instanceof ItemStack)) { return Collections.emptyList(); } Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; return Lists.newArrayList(new IGhostIngredientHandler.Target<>() { @NotNull @@ -183,9 +230,11 @@ public void accept(@NotNull Object ingredient) { @SideOnly(Side.CLIENT) public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + // Only allow the amount scrolling if not stocking, as amount is useless for stocking + if (parentWidget.isStocking()) return false; IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; if (slot.getConfig() == null || wheelDelta == 0 || !rectangle.contains(mouseX, mouseY)) { return false; } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java index ccec8521dd7..35063d5638b 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java @@ -6,7 +6,7 @@ import gregtech.api.gui.widgets.TextFieldWidget2; import gregtech.api.util.Position; import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import net.minecraft.network.PacketBuffer; diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 31b6cc29edf..9f01ef182e5 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -95,6 +95,8 @@ import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputHatch; import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputBus; import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEStockingBus; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEStockingHatch; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCABridge; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCAComputation; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCACooler; @@ -362,6 +364,8 @@ public class MetaTileEntities { public static MetaTileEntity ITEM_EXPORT_BUS_ME; public static MetaTileEntity FLUID_IMPORT_HATCH_ME; public static MetaTileEntity ITEM_IMPORT_BUS_ME; + public static MetaTileEntity STOCKING_BUS_ME; + public static MetaTileEntity STOCKING_HATCH_ME; public static MetaTileEntityLDItemEndpoint LONG_DIST_ITEM_ENDPOINT; public static MetaTileEntityLDFluidEndpoint LONG_DIST_FLUID_ENDPOINT; public static MetaTileEntityAlarm ALARM; @@ -1122,7 +1126,7 @@ public static void init() { // IDs 1730-1744 are taken by 4A <-> 16A Transformers. They are grouped with other transformers for // organization. - // ME Hatches, IDs 1745-1748 + // ME Hatches, IDs 1745-1748, 1752-1756 if (Mods.AppliedEnergistics2.isModLoaded()) { FLUID_EXPORT_HATCH_ME = registerMetaTileEntity(1745, new MetaTileEntityMEOutputHatch(gregtechId("me_export_fluid_hatch"))); @@ -1132,6 +1136,13 @@ public static void init() { new MetaTileEntityMEInputHatch(gregtechId("me_import_fluid_hatch"))); ITEM_IMPORT_BUS_ME = registerMetaTileEntity(1748, new MetaTileEntityMEInputBus(gregtechId("me_import_item_bus"))); + STOCKING_BUS_ME = registerMetaTileEntity(1752, + new MetaTileEntityMEStockingBus(gregtechId("me_stocking_item_bus"))); + STOCKING_HATCH_ME = registerMetaTileEntity(1753, + new MetaTileEntityMEStockingHatch(gregtechId("me_stocking_fluid_hatch"))); + // 1754: Crafting Input Bus + // 1755: Crafting Input Buffer + // 1756: Crafting Input Slave } LONG_DIST_ITEM_ENDPOINT = registerMetaTileEntity(1749, @@ -1142,6 +1153,8 @@ public static void init() { // Alarm, ID 1751 ALARM = registerMetaTileEntity(1751, new MetaTileEntityAlarm(gregtechId("alarm"))); + // IDs 1752-1756 are taken by AE2 parts + // Multi-Fluid Hatches, IDs 1190, 1191, 1205, 1206, 1780-1799 // EV hatches separate because of old names/IDs QUADRUPLE_IMPORT_HATCH[0] = registerMetaTileEntity(1190, diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java index 7f470e4d0ff..1c8f73e6837 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java @@ -1,10 +1,6 @@ package gregtech.common.metatileentities.multi.multiblockpart.appeng; -import gregtech.api.GTValues; import gregtech.api.capability.IControllable; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.client.renderer.ICubeRenderer; -import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; @@ -19,13 +15,12 @@ import appeng.api.networking.GridFlags; import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionSource; +import appeng.api.storage.IMEMonitor; import appeng.api.storage.IStorageChannel; -import appeng.api.storage.channels.IFluidStorageChannel; -import appeng.api.storage.channels.IItemStorageChannel; -import appeng.api.storage.data.IAEFluidStack; -import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; +import appeng.me.GridAccessException; import appeng.me.helpers.AENetworkProxy; import appeng.me.helpers.BaseActionSource; import appeng.me.helpers.IGridProxyable; @@ -36,28 +31,21 @@ import java.io.IOException; import java.util.EnumSet; -/** - * @Author GlodBlock - * @Description It can connect to ME network. - * @Date 2023/4/18-23:17 - */ -public abstract class MetaTileEntityAEHostablePart extends MetaTileEntityMultiblockNotifiablePart - implements IControllable { +import static gregtech.api.capability.GregtechDataCodes.UPDATE_ONLINE_STATUS; - protected static final IStorageChannel ITEM_NET = AEApi.instance().storage() - .getStorageChannel(IItemStorageChannel.class); - protected static final IStorageChannel FLUID_NET = AEApi.instance().storage() - .getStorageChannel(IFluidStorageChannel.class); +public abstract class MetaTileEntityAEHostablePart> extends MetaTileEntityMultiblockNotifiablePart + implements IControllable { - private final static int ME_UPDATE_INTERVAL = ConfigHolder.compat.ae2.updateIntervals; + private final Class> storageChannel; private AENetworkProxy aeProxy; private int meUpdateTick; protected boolean isOnline; - private final static int ONLINE_ID = 6666; - public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) { + public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch, + Class> storageChannel) { super(metaTileEntityId, tier, isExportHatch); this.meUpdateTick = 0; + this.storageChannel = storageChannel; } @Override @@ -73,9 +61,7 @@ public void update() { * So there is no need to drop them. */ @Override - public void clearMachineInventory(NonNullList itemBuffer) { - // NO-OP - } + public void clearMachineInventory(NonNullList itemBuffer) {} @Override public void writeInitialSyncData(PacketBuffer buf) { @@ -114,24 +100,9 @@ public void receiveInitialSyncData(PacketBuffer buf) { @Override public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); - if (dataId == ONLINE_ID) { + if (dataId == UPDATE_ONLINE_STATUS) { this.isOnline = buf.readBoolean(); - } - } - - @Override - public ICubeRenderer getBaseTexture() { - MultiblockControllerBase controller = getController(); - if (controller != null) { - return this.hatchTexture = controller.getBaseTexture(this); - } else if (this.hatchTexture != null) { - if (hatchTexture != Textures.getInactiveTexture(hatchTexture)) { - return this.hatchTexture = Textures.getInactiveTexture(hatchTexture); - } - return this.hatchTexture; - } else { - // Always display as EV casing - return Textures.VOLTAGE_CASINGS[GTValues.EV]; + scheduleRenderUpdate(); } } @@ -165,9 +136,7 @@ public void setFrontFacing(EnumFacing frontFacing) { } @Override - public void gridChanged() { - // NO-OP - } + public void gridChanged() {} /** * Update me network connection status. @@ -180,26 +149,27 @@ public boolean updateMEStatus() { } else { this.isOnline = false; } - writeCustomData(ONLINE_ID, buf -> buf.writeBoolean(this.isOnline)); + if (!getWorld().isRemote) { + writeCustomData(UPDATE_ONLINE_STATUS, buf -> buf.writeBoolean(this.isOnline)); + } return this.isOnline; } protected boolean shouldSyncME() { - return this.meUpdateTick % ME_UPDATE_INTERVAL == 0; + return this.meUpdateTick % ConfigHolder.compat.ae2.updateIntervals == 0; } protected IActionSource getActionSource() { - if (this.getHolder() instanceof IActionHost) { - return new MachineSource((IActionHost) this.getHolder()); + if (this.getHolder() instanceof IActionHost holder) { + return new MachineSource(holder); } return new BaseActionSource(); } @Nullable private AENetworkProxy createProxy() { - if (this.getHolder() instanceof IGridProxyable) { - AENetworkProxy proxy = new AENetworkProxy((IGridProxyable) this.getHolder(), "mte_proxy", - this.getStackForm(), true); + if (this.getHolder() instanceof IGridProxyable holder) { + AENetworkProxy proxy = new AENetworkProxy(holder, "mte_proxy", this.getStackForm(), true); proxy.setFlags(GridFlags.REQUIRE_CHANNEL); proxy.setIdlePowerUsage(ConfigHolder.compat.ae2.meHatchEnergyUsage); proxy.setValidSides(EnumSet.of(this.getFrontFacing())); @@ -207,4 +177,23 @@ private AENetworkProxy createProxy() { } return null; } + + @NotNull + protected IStorageChannel getStorageChannel() { + return AEApi.instance().storage().getStorageChannel(storageChannel); + } + + @Nullable + protected IMEMonitor getMonitor() { + AENetworkProxy proxy = getProxy(); + if (proxy == null) return null; + + IStorageChannel channel = getStorageChannel(); + + try { + return proxy.getStorage().getInventory(channel); + } catch (GridAccessException ignored) { + return null; + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index 18a81b7df3d..1076de705e9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -3,15 +3,25 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IGhostSlotConfigurable; +import gregtech.api.capability.INotifiableHandler; +import gregtech.api.capability.impl.GhostCircuitItemStackHandler; +import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.capability.impl.NotifiableItemStackHandler; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.GhostCircuitSlotWidget; +import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEItemConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; import net.minecraft.client.resources.I18n; @@ -23,117 +33,160 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; -import java.util.function.Consumer; -/** - * @Author GlodBlock - * @Description The Input Bus that can auto fetch item ME storage network. - * @Date 2023/4/22-13:34 - */ -public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart { +public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart + implements IMultiblockAbilityPart, + IGhostSlotConfigurable { public final static String ITEM_BUFFER_TAG = "ItemSlots"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; - private boolean workingEnabled; - private ExportOnlyAEItemList aeItemHandler; + private boolean workingEnabled = true; + protected ExportOnlyAEItemList aeItemHandler; + private GhostCircuitItemStackHandler circuitInventory; + private NotifiableItemStackHandler extraSlotInventory; + private ItemHandlerList actualImportItems; public MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, false); - this.workingEnabled = true; + this(metaTileEntityId, GTValues.EV); + } + + protected MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId, int tier) { + super(metaTileEntityId, tier, false, IItemStorageChannel.class); + } + + protected ExportOnlyAEItemList getAEItemHandler() { + if (aeItemHandler == null) { + aeItemHandler = new ExportOnlyAEItemList(this, CONFIG_SIZE, this.getController()); + } + return aeItemHandler; } @Override protected void initializeInventory() { - this.aeItemHandler = new ExportOnlyAEItemList(this, CONFIG_SIZE, this.getController()); super.initializeInventory(); - } - - protected IItemHandlerModifiable createImportItemHandler() { - return this.aeItemHandler; + this.aeItemHandler = getAEItemHandler(); + this.circuitInventory = new GhostCircuitItemStackHandler(this); + this.circuitInventory.addNotifiableMetaTileEntity(this); + this.extraSlotInventory = new NotifiableItemStackHandler(this, 1, this, false); + this.extraSlotInventory.addNotifiableMetaTileEntity(this); + this.actualImportItems = new ItemHandlerList( + Arrays.asList(this.aeItemHandler, this.circuitInventory, this.extraSlotInventory)); + this.importItems = this.actualImportItems; } public IItemHandlerModifiable getImportItems() { - this.importItems = this.aeItemHandler; - return super.getImportItems(); + return this.actualImportItems; } @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (ExportOnlyAEItem aeSlot : this.aeItemHandler.inventory) { - // Try to clear the wrong item - IAEItemStack exceedItem = aeSlot.exceedStack(); - if (exceedItem != null) { - long total = exceedItem.getStackSize(); - IAEItemStack notInserted = aeNetwork.injectItems(exceedItem, Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - aeSlot.extractItem(0, (int) (total - notInserted.getStackSize()), false); - continue; - } else { - aeSlot.extractItem(0, (int) total, false); - } - } - // Fill it - IAEItemStack reqItem = aeSlot.requestStack(); - if (reqItem != null) { - IAEItemStack extracted = aeNetwork.extractItems(reqItem, Actionable.MODULATE, - this.getActionSource()); - if (extracted != null) { - aeSlot.addStack(extracted); - } - } - } - } catch (GridAccessException ignore) {} - } + if (!getWorld().isRemote && this.workingEnabled && updateMEStatus() && shouldSyncME()) { + syncME(); } } - @Override - public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (ExportOnlyAEItem aeSlot : this.aeItemHandler.inventory) { - IAEItemStack stock = aeSlot.stock; - if (stock instanceof WrappedItemStack) { - stock = ((WrappedItemStack) stock).getAEStack(); + protected void syncME() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEItemSlot aeSlot : this.getAEItemHandler().getInventory()) { + // Try to clear the wrong item + IAEItemStack exceedItem = aeSlot.exceedStack(); + if (exceedItem != null) { + long total = exceedItem.getStackSize(); + IAEItemStack notInserted = monitor.injectItems(exceedItem, Actionable.MODULATE, this.getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + aeSlot.extractItem(0, (int) (total - notInserted.getStackSize()), false); + continue; + } else { + aeSlot.extractItem(0, (int) total, false); } - if (stock != null) { - aeNetwork.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + // Fill it + IAEItemStack reqItem = aeSlot.requestStack(); + if (reqItem != null) { + IAEItemStack extracted = monitor.extractItems(reqItem, Actionable.MODULATE, this.getActionSource()); + if (extracted != null) { + aeSlot.addStack(extracted); } } - } catch (GridAccessException ignore) {} + } + } + + @Override + public void onRemoval() { + flushInventory(); super.onRemoval(); } + protected void flushInventory() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEItemSlot aeSlot : this.getAEItemHandler().getInventory()) { + IAEItemStack stock = aeSlot.getStock(); + if (stock instanceof WrappedItemStack) { + stock = ((WrappedItemStack) stock).getAEStack(); + } + if (stock != null) { + monitor.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + } + } + @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { - return new MetaTileEntityMEInputBus(this.metaTileEntityId); + return new MetaTileEntityMEInputBus(metaTileEntityId); + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) { + notifiable.addNotifiableMetaTileEntity(controllerBase); + notifiable.addToNotifiedList(this, handler, false); + } + } } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + super.removeFromMultiBlock(controllerBase); + for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) { + notifiable.removeNotifiableMetaTileEntity(controllerBase); + } + } + } + + @Override + protected final ModularUI createUI(EntityPlayer player) { + ModularUI.Builder builder = createUITemplate(player); + return builder.build(this.getHolder(), player); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer player) { ModularUI.Builder builder = ModularUI .builder(GuiTextures.BACKGROUND, 176, 18 + 18 * 4 + 94) .label(10, 5, getMetaFullName()); @@ -141,13 +194,37 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); // Config slots - builder.widget(new AEItemConfigWidget(16, 25, this.aeItemHandler.inventory)); + builder.widget(new AEItemConfigWidget(7, 25, this.getAEItemHandler())); + + // Ghost circuit slot + SlotWidget circuitSlot = new GhostCircuitSlotWidget(circuitInventory, 0, 7 + 18 * 4, 25 + 18 * 3) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.INT_CIRCUIT_OVERLAY); + builder.widget(circuitSlot.setConsumer(w -> { + String configString; + if (circuitInventory == null || + circuitInventory.getCircuitValue() == GhostCircuitItemStackHandler.NO_CONFIG) { + configString = new TextComponentTranslation("gregtech.gui.configurator_slot.no_value") + .getFormattedText(); + } else { + configString = String.valueOf(circuitInventory.getCircuitValue()); + } + + w.setTooltipText("gregtech.gui.configurator_slot.tooltip", configString); + })); + + // Extra slot + builder.widget(new SlotWidget(extraSlotInventory, 0, 7 + 18 * 4, 25 + 18 * 2) + .setBackgroundTexture(GuiTextures.SLOT) + .setTooltipText("gregtech.gui.me_bus.extra_slot")); - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); - return builder.build(this.getHolder(), entityPlayer); + // Arrow image + builder.image(7 + 18 * 4, 25 + 18, 18, 18, GuiTextures.ARROW_DOUBLE); + + builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); + return builder; } @Override @@ -190,13 +267,16 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean(WORKING_TAG, this.workingEnabled); NBTTagList slots = new NBTTagList(); for (int i = 0; i < CONFIG_SIZE; i++) { - ExportOnlyAEItem slot = this.aeItemHandler.inventory[i]; + ExportOnlyAEItemSlot slot = this.getAEItemHandler().getInventory()[i]; NBTTagCompound slotTag = new NBTTagCompound(); slotTag.setInteger("slot", i); slotTag.setTag("stack", slot.serializeNBT()); slots.appendTag(slotTag); } data.setTag(ITEM_BUFFER_TAG, slots); + this.circuitInventory.write(data); + // Extra slot inventory + GTUtility.writeItems(this.extraSlotInventory, "ExtraInventory", data); return data; } @@ -210,10 +290,12 @@ public void readFromNBT(NBTTagCompound data) { NBTTagList slots = (NBTTagList) data.getTag(ITEM_BUFFER_TAG); for (NBTBase nbtBase : slots) { NBTTagCompound slotTag = (NBTTagCompound) nbtBase; - ExportOnlyAEItem slot = this.aeItemHandler.inventory[slotTag.getInteger("slot")]; + ExportOnlyAEItemSlot slot = this.getAEItemHandler().getInventory()[slotTag.getInteger("slot")]; slot.deserializeNBT(slotTag.getCompoundTag("stack")); } } + this.circuitInventory.read(data); + GTUtility.readItems(this.extraSlotInventory, "ExtraInventory", data); this.importItems = createImportItemHandler(); } @@ -221,7 +303,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_INPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_INPUT_BUS_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_INPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -231,6 +317,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -241,197 +328,22 @@ public MultiblockAbility getAbility() { @Override public void registerAbilities(List list) { - list.add(this.aeItemHandler); + list.add(this.actualImportItems); } - private static class ExportOnlyAEItemList extends NotifiableItemStackHandler { - - ExportOnlyAEItem[] inventory; - - public ExportOnlyAEItemList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { - super(holder, slots, entityToNotify, false); - this.inventory = new ExportOnlyAEItem[CONFIG_SIZE]; - for (int i = 0; i < CONFIG_SIZE; i++) { - this.inventory[i] = new ExportOnlyAEItem(null, null); - } - for (ExportOnlyAEItem slot : this.inventory) { - slot.trigger = this::onContentsChanged; - } - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - for (int index = 0; index < CONFIG_SIZE; index++) { - if (nbt.hasKey("#" + index)) { - NBTTagCompound slotTag = nbt.getCompoundTag("#" + index); - this.inventory[index].deserializeNBT(slotTag); - } - } - } - - @Override - public NBTTagCompound serializeNBT() { - NBTTagCompound nbt = new NBTTagCompound(); - for (int index = 0; index < CONFIG_SIZE; index++) { - NBTTagCompound slot = this.inventory[index].serializeNBT(); - nbt.setTag("#" + index, slot); - } - return nbt; - } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - // NO-OP - } - - @Override - public int getSlots() { - return MetaTileEntityMEInputBus.CONFIG_SIZE; - } - - @NotNull - @Override - public ItemStack getStackInSlot(int slot) { - if (slot >= 0 && slot < CONFIG_SIZE) { - return this.inventory[slot].getStackInSlot(0); - } - return ItemStack.EMPTY; - } - - @NotNull - @Override - public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - return stack; - } - - @NotNull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot >= 0 && slot < CONFIG_SIZE) { - return this.inventory[slot].extractItem(0, amount, simulate); - } - return ItemStack.EMPTY; - } - - @Override - public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; - } - - @Override - protected int getStackLimit(int slot, @NotNull ItemStack stack) { - return Integer.MAX_VALUE; - } + @Override + public boolean hasGhostCircuitInventory() { + return true; } - public static class ExportOnlyAEItem extends ExportOnlyAESlot implements IItemHandlerModifiable { - - private Consumer trigger; - - public ExportOnlyAEItem(IAEItemStack config, IAEItemStack stock) { - super(config, stock); - } - - public ExportOnlyAEItem() { - super(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - if (nbt.hasKey(CONFIG_TAG)) { - this.config = WrappedItemStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); - } - if (nbt.hasKey(STOCK_TAG)) { - this.stock = WrappedItemStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); - } - } - - @Override - public ExportOnlyAEItem copy() { - return new ExportOnlyAEItem( - this.config == null ? null : this.config.copy(), - this.stock == null ? null : this.stock.copy()); - } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - // NO-OP - } - - @Override - public int getSlots() { - return 1; - } - - @NotNull - @Override - public ItemStack getStackInSlot(int slot) { - if (slot == 0 && this.stock != null) { - return this.stock.getDefinition(); - } - return ItemStack.EMPTY; - } - - @NotNull - @Override - public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - return stack; - } - - @NotNull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot == 0 && this.stock != null) { - int extracted = (int) Math.min(this.stock.getStackSize(), amount); - ItemStack result = this.stock.createItemStack(); - result.setCount(extracted); - if (!simulate) { - this.stock.decStackSize(extracted); - if (this.stock.getStackSize() == 0) { - this.stock = null; - } - } - if (this.trigger != null) { - this.trigger.accept(0); - } - return result; - } - return ItemStack.EMPTY; - } - - @Override - public IAEItemStack requestStack() { - IAEItemStack result = super.requestStack(); - if (result instanceof WrappedItemStack) { - return ((WrappedItemStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public IAEItemStack exceedStack() { - IAEItemStack result = super.exceedStack(); - if (result instanceof WrappedItemStack) { - return ((WrappedItemStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public void addStack(IAEItemStack stack) { - if (this.stock == null) { - this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); - } else { - this.stock.add(stack); - } - this.trigger.accept(0); + @Override + public void setGhostCircuitConfig(int config) { + if (this.circuitInventory.getCircuitValue() == config) { + return; } - - @Override - public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; + this.circuitInventory.setCircuitValue(config); + if (!getWorld().isRemote) { + markDirty(); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java index 9a6dfa4f6aa..c864cecff64 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java @@ -3,16 +3,18 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; -import gregtech.api.capability.INotifiableHandler; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEFluidConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; import net.minecraft.client.resources.I18n; @@ -26,120 +28,126 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.FluidTankProperties; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.IFluidTankProperties; import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * @Author GlodBlock - * @Description The Input Hatch that can auto fetch fluid ME storage network. - * @Date 2023/4/20-21:21 - */ -public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String FLUID_BUFFER_TAG = "FluidTanks"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; - private boolean workingEnabled; - private ExportOnlyAEFluid[] aeFluidTanks; + private boolean workingEnabled = true; + protected ExportOnlyAEFluidList aeFluidHandler; public MetaTileEntityMEInputHatch(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, false); - this.workingEnabled = true; + this(metaTileEntityId, GTValues.EV); + } + + protected MetaTileEntityMEInputHatch(ResourceLocation metaTileEntityId, int tier) { + super(metaTileEntityId, tier, false, IFluidStorageChannel.class); + } + + protected ExportOnlyAEFluidList getAEFluidHandler() { + if (aeFluidHandler == null) { + aeFluidHandler = new ExportOnlyAEFluidList(this, CONFIG_SIZE, this.getController()); + } + return aeFluidHandler; } @Override protected void initializeInventory() { - this.aeFluidTanks = new ExportOnlyAEFluid[CONFIG_SIZE]; - for (int i = 0; i < CONFIG_SIZE; i++) { - this.aeFluidTanks[i] = new ExportOnlyAEFluid(this, null, null, this.getController()); - } + getAEFluidHandler(); // initialize it super.initializeInventory(); } @Override protected FluidTankList createImportFluidHandler() { - return new FluidTankList(false, this.aeFluidTanks); + return new FluidTankList(false, getAEFluidHandler().getInventory()); } @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (ExportOnlyAEFluid aeTank : this.aeFluidTanks) { - // Try to clear the wrong fluid - IAEFluidStack exceedFluid = aeTank.exceedStack(); - if (exceedFluid != null) { - long total = exceedFluid.getStackSize(); - IAEFluidStack notInserted = aeNetwork.injectItems(exceedFluid, Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - aeTank.drain((int) (total - notInserted.getStackSize()), true); - continue; - } else { - aeTank.drain((int) total, true); - } - } - // Fill it - IAEFluidStack reqFluid = aeTank.requestStack(); - if (reqFluid != null) { - IAEFluidStack extracted = aeNetwork.extractItems(reqFluid, Actionable.MODULATE, - this.getActionSource()); - if (extracted != null) { - aeTank.addStack(extracted); - } - } - } - } catch (GridAccessException ignore) {} - } + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && updateMEStatus()) { + syncME(); } } - @Override - public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (ExportOnlyAEFluid aeTank : this.aeFluidTanks) { - IAEFluidStack stock = aeTank.stock; - if (stock instanceof WrappedFluidStack) { - stock = ((WrappedFluidStack) stock).getAEStack(); + protected void syncME() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEFluidSlot aeTank : this.getAEFluidHandler().getInventory()) { + // Try to clear the wrong fluid + IAEFluidStack exceedFluid = aeTank.exceedStack(); + if (exceedFluid != null) { + long total = exceedFluid.getStackSize(); + IAEFluidStack notInserted = monitor.injectItems(exceedFluid, Actionable.MODULATE, + this.getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + aeTank.drain((int) (total - notInserted.getStackSize()), true); + continue; + } else { + aeTank.drain((int) total, true); } - if (stock != null) { - aeNetwork.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + // Fill it + IAEFluidStack reqFluid = aeTank.requestStack(); + if (reqFluid != null) { + IAEFluidStack extracted = monitor.extractItems(reqFluid, Actionable.MODULATE, this.getActionSource()); + if (extracted != null) { + aeTank.addStack(extracted); } } - } catch (GridAccessException ignore) {} + } + } + + @Override + public void onRemoval() { + flushInventory(); super.onRemoval(); } + protected void flushInventory() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEFluidSlot aeTank : this.getAEFluidHandler().getInventory()) { + IAEFluidStack stock = aeTank.getStock(); + if (stock instanceof WrappedFluidStack) { + stock = ((WrappedFluidStack) stock).getAEStack(); + } + if (stock != null) { + monitor.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + } + } + @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { return new MetaTileEntityMEInputHatch(this.metaTileEntityId); } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + protected final ModularUI createUI(EntityPlayer player) { + ModularUI.Builder builder = createUITemplate(player); + return builder.build(this.getHolder(), player); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer player) { ModularUI.Builder builder = ModularUI .builder(GuiTextures.BACKGROUND, 176, 18 + 18 * 4 + 94) .label(10, 5, getMetaFullName()); @@ -147,13 +155,21 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); // Config slots - builder.widget(new AEFluidConfigWidget(16, 25, this.aeFluidTanks)); + builder.widget(new AEFluidConfigWidget(7, 25, this.getAEFluidHandler())); - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); - return builder.build(this.getHolder(), entityPlayer); + // Arrow image + builder.image(7 + 18 * 4, 25 + 18, 18, 18, GuiTextures.ARROW_DOUBLE); + + // GT Logo, cause there's some free real estate + builder.widget(new ImageWidget(7 + 18 * 4, 25 + 18 * 3, 17, 17, + GTValues.XMAS.get() ? GuiTextures.GREGTECH_LOGO_XMAS : GuiTextures.GREGTECH_LOGO) + .setIgnoreColor(true)); + + builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); + return builder; } @Override @@ -196,7 +212,7 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean(WORKING_TAG, this.workingEnabled); NBTTagList tanks = new NBTTagList(); for (int i = 0; i < CONFIG_SIZE; i++) { - ExportOnlyAEFluid tank = this.aeFluidTanks[i]; + ExportOnlyAEFluidSlot tank = this.getAEFluidHandler().getInventory()[i]; NBTTagCompound tankTag = new NBTTagCompound(); tankTag.setInteger("slot", i); tankTag.setTag("tank", tank.serializeNBT()); @@ -216,7 +232,7 @@ public void readFromNBT(NBTTagCompound data) { NBTTagList tanks = (NBTTagList) data.getTag(FLUID_BUFFER_TAG); for (NBTBase nbtBase : tanks) { NBTTagCompound tankTag = (NBTTagCompound) nbtBase; - ExportOnlyAEFluid tank = this.aeFluidTanks[tankTag.getInteger("slot")]; + ExportOnlyAEFluidSlot tank = this.getAEFluidHandler().getInventory()[tankTag.getInteger("slot")]; tank.deserializeNBT(tankTag.getCompoundTag("tank")); } } @@ -226,7 +242,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_INPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_INPUT_HATCH_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_INPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -236,6 +256,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -246,157 +267,6 @@ public MultiblockAbility getAbility() { @Override public void registerAbilities(List list) { - list.addAll(Arrays.asList(this.aeFluidTanks)); - } - - public static class ExportOnlyAEFluid extends ExportOnlyAESlot - implements IFluidTank, INotifiableHandler, IFluidHandler { - - private final List notifiableEntities = new ArrayList<>(); - private MetaTileEntity holder; - - public ExportOnlyAEFluid(MetaTileEntity holder, IAEFluidStack config, IAEFluidStack stock, MetaTileEntity mte) { - super(config, stock); - this.holder = holder; - this.notifiableEntities.add(mte); - } - - public ExportOnlyAEFluid() { - super(); - } - - @Override - public IAEFluidStack requestStack() { - IAEFluidStack result = super.requestStack(); - if (result instanceof WrappedFluidStack) { - return ((WrappedFluidStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public IAEFluidStack exceedStack() { - IAEFluidStack result = super.exceedStack(); - if (result instanceof WrappedFluidStack) { - return ((WrappedFluidStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public void addStack(IAEFluidStack stack) { - if (this.stock == null) { - this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); - } else { - this.stock.add(stack); - } - trigger(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - if (nbt.hasKey(CONFIG_TAG)) { - this.config = WrappedFluidStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); - } - if (nbt.hasKey(STOCK_TAG)) { - this.stock = WrappedFluidStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); - } - } - - @Nullable - @Override - public FluidStack getFluid() { - if (this.stock != null && this.stock instanceof WrappedFluidStack) { - return ((WrappedFluidStack) this.stock).getDelegate(); - } - return null; - } - - @Override - public int getFluidAmount() { - return this.stock != null ? (int) this.stock.getStackSize() : 0; - } - - @Override - public int getCapacity() { - // Its capacity is always 0. - return 0; - } - - @Override - public FluidTankInfo getInfo() { - return new FluidTankInfo(this); - } - - @Override - public IFluidTankProperties[] getTankProperties() { - return new IFluidTankProperties[] { - new FluidTankProperties(this.getFluid(), 0) - }; - } - - @Override - public int fill(FluidStack resource, boolean doFill) { - return 0; - } - - @Nullable - @Override - public FluidStack drain(FluidStack resource, boolean doDrain) { - if (this.getFluid() != null && this.getFluid().isFluidEqual(resource)) { - return this.drain(resource.amount, doDrain); - } - return null; - } - - @Nullable - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - if (this.stock == null) { - return null; - } - int drained = (int) Math.min(this.stock.getStackSize(), maxDrain); - FluidStack result = new FluidStack(this.stock.getFluid(), drained); - if (doDrain) { - this.stock.decStackSize(drained); - if (this.stock.getStackSize() == 0) { - this.stock = null; - } - trigger(); - } - return result; - } - - @Override - public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { - this.notifiableEntities.add(metaTileEntity); - } - - @Override - public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { - this.notifiableEntities.remove(metaTileEntity); - } - - private void trigger() { - for (MetaTileEntity metaTileEntity : this.notifiableEntities) { - if (metaTileEntity != null && metaTileEntity.isValid()) { - this.addToNotifiedList(metaTileEntity, this, false); - } - } - if (holder != null) { - holder.markDirty(); - } - } - - @Override - public ExportOnlyAEFluid copy() { - return new ExportOnlyAEFluid( - this.holder, - this.config == null ? null : this.config.copy(), - this.stock == null ? null : this.stock.copy(), - null); - } + list.addAll(Arrays.asList(this.getAEFluidHandler().getInventory())); } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java index 92277985603..853321014f9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java @@ -30,9 +30,9 @@ import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IItemList; -import appeng.me.GridAccessException; import appeng.util.item.AEItemStack; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; @@ -43,22 +43,16 @@ import java.util.ArrayList; import java.util.List; -/** - * @Author GlodBlock - * @Description The Output Bus that can directly send its contents to ME storage network. - * @Date 2023/4/19-20:37 - */ -public class MetaTileEntityMEOutputBus extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEOutputBus extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String ITEM_BUFFER_TAG = "ItemBuffer"; public final static String WORKING_TAG = "WorkingEnabled"; - private boolean workingEnabled; + private boolean workingEnabled = true; private SerializableItemList internalBuffer; public MetaTileEntityMEOutputBus(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, true); - this.workingEnabled = true; + super(metaTileEntityId, GTValues.EV, true, IItemStorageChannel.class); } @Override @@ -70,21 +64,18 @@ protected void initializeInventory() { @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - if (!this.internalBuffer.isEmpty()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (IAEItemStack item : this.internalBuffer) { - IAEItemStack notInserted = aeNetwork.injectItems(item.copy(), Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - item.setStackSize(notInserted.getStackSize()); - } else { - item.reset(); - } - } - } catch (GridAccessException ignore) {} + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && this.updateMEStatus()) { + if (this.internalBuffer.isEmpty()) return; + + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEItemStack item : this.internalBuffer) { + IAEItemStack notInserted = monitor.injectItems(item.copy(), Actionable.MODULATE, getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + item.setStackSize(notInserted.getStackSize()); + } else { + item.reset(); } } } @@ -92,12 +83,12 @@ public void update() { @Override public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); + IMEMonitor monitor = getMonitor(); + if (monitor != null) { for (IAEItemStack item : this.internalBuffer) { - aeNetwork.injectItems(item.copy(), Actionable.MODULATE, this.getActionSource()); + monitor.injectItems(item.copy(), Actionable.MODULATE, this.getActionSource()); } - } catch (GridAccessException ignore) {} + } super.onRemoval(); } @@ -115,7 +106,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); builder.label(10, 25, "gregtech.gui.waiting_list", 0xFFFFFFFF); builder.widget(new AEItemGridWidget(10, 35, 3, this.internalBuffer)); @@ -180,7 +171,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_OUTPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_OUTPUT_BUS_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_OUTPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -190,7 +185,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.item_bus.export.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_export.tooltip")); - tooltip.add(I18n.format("gregtech.machine.me.export.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.item_export.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java index c19e7e1bb51..f22c489909b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java @@ -32,10 +32,10 @@ import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IItemList; import appeng.fluids.util.AEFluidStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; @@ -45,22 +45,16 @@ import java.util.ArrayList; import java.util.List; -/** - * @Author GlodBlock - * @Description The Output Hatch that can directly send its contents to ME storage network. - * @Date 2023/4/19-1:18 - */ -public class MetaTileEntityMEOutputHatch extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEOutputHatch extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String FLUID_BUFFER_TAG = "FluidBuffer"; public final static String WORKING_TAG = "WorkingEnabled"; - private boolean workingEnabled; + private boolean workingEnabled = true; private SerializableFluidList internalBuffer; public MetaTileEntityMEOutputHatch(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, true); - this.workingEnabled = true; + super(metaTileEntityId, GTValues.EV, true, IFluidStorageChannel.class); } @Override @@ -72,21 +66,18 @@ protected void initializeInventory() { @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - if (!this.internalBuffer.isEmpty()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (IAEFluidStack fluid : this.internalBuffer) { - IAEFluidStack notInserted = aeNetwork.injectItems(fluid.copy(), Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - fluid.setStackSize(notInserted.getStackSize()); - } else { - fluid.reset(); - } - } - } catch (GridAccessException ignore) {} + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && updateMEStatus()) { + if (this.internalBuffer.isEmpty()) return; + + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEFluidStack fluid : this.internalBuffer) { + IAEFluidStack notInserted = monitor.injectItems(fluid.copy(), Actionable.MODULATE, getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + fluid.setStackSize(notInserted.getStackSize()); + } else { + fluid.reset(); } } } @@ -94,12 +85,12 @@ public void update() { @Override public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (IAEFluidStack fluid : this.internalBuffer) { - aeNetwork.injectItems(fluid.copy(), Actionable.MODULATE, this.getActionSource()); - } - } catch (GridAccessException ignore) {} + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEFluidStack fluid : this.internalBuffer) { + monitor.injectItems(fluid.copy(), Actionable.MODULATE, this.getActionSource()); + } super.onRemoval(); } @@ -117,7 +108,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); builder.label(10, 25, "gregtech.gui.waiting_list", 0xFFFFFFFF); builder.widget(new AEFluidGridWidget(10, 35, 3, this.internalBuffer)); @@ -182,7 +173,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_OUTPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_OUTPUT_HATCH_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_OUTPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -192,7 +187,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fluid_hatch.export.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_export.tooltip")); - tooltip.add(I18n.format("gregtech.machine.me.export.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.fluid_export.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java new file mode 100644 index 00000000000..99928574f82 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java @@ -0,0 +1,414 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng; + +import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; + +import appeng.api.config.Actionable; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IItemList; +import codechicken.lib.raytracer.CuboidRayTraceResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; + +public class MetaTileEntityMEStockingBus extends MetaTileEntityMEInputBus { + + private static final int CONFIG_SIZE = 16; + private boolean autoPull; + private Predicate autoPullTest; + + public MetaTileEntityMEStockingBus(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, GTValues.LuV); + this.autoPullTest = $ -> false; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MetaTileEntityMEStockingBus(metaTileEntityId); + } + + @Override + protected ExportOnlyAEStockingItemList getAEItemHandler() { + if (this.aeItemHandler == null) { + this.aeItemHandler = new ExportOnlyAEStockingItemList(this, CONFIG_SIZE, getController()); + } + return (ExportOnlyAEStockingItemList) this.aeItemHandler; + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && isWorkingEnabled() && autoPull && getOffsetTimer() % 100 == 0) { + refreshList(); + syncME(); + } + } + + // Update the visual display for the fake items. This also is important for the item handler's + // getStackInSlot() method, as it uses the cached items set here. + @Override + protected void syncME() { + IMEMonitor monitor = super.getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEStockingItemSlot slot : this.getAEItemHandler().getInventory()) { + if (slot.getConfig() == null) { + slot.setStack(null); + } else { + // Try to fill the slot + IAEItemStack request; + if (slot.getConfig() instanceof WrappedItemStack wis) { + request = wis.getAEStack(); + } else { + request = slot.getConfig().copy(); + } + request.setStackSize(Integer.MAX_VALUE); + IAEItemStack result = monitor.extractItems(request, Actionable.SIMULATE, getActionSource()); + slot.setStack(result); + } + } + } + + @Override + protected void flushInventory() { + // no-op, nothing to send back to the network + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + // ensure that no other stocking bus on this multiblock is configured to hold the same item. + // that we have in our own bus. + this.autoPullTest = stack -> !this.testConfiguredInOtherBus(stack); + // also ensure that our current config is valid given other inputs + validateConfig(); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + // block auto-pull from working when not in a formed multiblock + this.autoPullTest = $ -> false; + if (this.autoPull) { + // may as well clear if we are auto-pull, no reason to preserve the config + this.getAEItemHandler().clearConfig(); + } + super.removeFromMultiBlock(controllerBase); + } + + @Override + public void onDistinctChange(boolean newValue) { + super.onDistinctChange(newValue); + if (!getWorld().isRemote && !newValue) { + // Ensure that our configured items won't match any other buses in the multiblock. + // Needed since we allow duplicates in distinct mode on, but not off + validateConfig(); + } + } + + /** + * Test for if any of our configured items are in another stocking bus on the multi + * we are attached to. Prevents dupes in certain situations. + */ + private void validateConfig() { + for (var slot : this.getAEItemHandler().getInventory()) { + if (slot.getConfig() != null) { + ItemStack configuredStack = slot.getConfig().createItemStack(); + if (testConfiguredInOtherBus(configuredStack)) { + slot.setConfig(null); + slot.setStock(null); + } + } + } + } + + /** + * @return True if the passed stack is found as a configuration in any other stocking buses on the multiblock. + */ + private boolean testConfiguredInOtherBus(ItemStack stack) { + if (stack == null || stack.isEmpty()) return false; + MultiblockControllerBase controller = getController(); + if (controller == null) return false; + + // In distinct mode, we don't need to check other buses since only one bus can run a recipe at a time. + if (!(controller instanceof RecipeMapMultiblockController rmmc) || !rmmc.isDistinct()) { + // Otherwise, we need to test for if the item is configured + // in any stocking bus in the multi (besides ourselves). + var abilityList = controller.getAbilities(MultiblockAbility.IMPORT_ITEMS); + for (var ability : abilityList) { + if (ability instanceof ExportOnlyAEStockingItemList aeList) { + // We don't need to check for ourselves, as this case is handled elsewhere. + if (aeList == this.aeItemHandler) continue; + if (aeList.hasStackInConfig(stack, false)) { + return true; + } + } + } + } + return false; + } + + private void setAutoPull(boolean autoPull) { + this.autoPull = autoPull; + markDirty(); + if (!getWorld().isRemote) { + if (!this.autoPull) { + this.getAEItemHandler().clearConfig(); + } else if (updateMEStatus()) { + this.refreshList(); + syncME(); + } + writeCustomData(UPDATE_AUTO_PULL, buf -> buf.writeBoolean(this.autoPull)); + } + } + + /** + * Refresh the configuration list in auto-pull mode. + * Sets the config to the first 16 valid items found in the network. + */ + private void refreshList() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) { + clearInventory(0); + return; + } + + IItemList storageList = monitor.getStorageList(); + if (storageList == null) { + clearInventory(0); + return; + } + + int index = 0; + for (IAEItemStack stack : storageList) { + if (index >= CONFIG_SIZE) break; + if (stack.getStackSize() == 0) continue; + stack = monitor.extractItems(stack, Actionable.SIMULATE, getActionSource()); + if (stack == null || stack.getStackSize() == 0) continue; + + ItemStack itemStack = stack.createItemStack(); + if (itemStack == null || itemStack.isEmpty()) continue; + // Ensure that it is valid to configure with this stack + if (autoPullTest != null && !autoPullTest.test(itemStack)) continue; + IAEItemStack selectedStack = WrappedItemStack.fromItemStack(itemStack); + if (selectedStack == null) continue; + IAEItemStack configStack = selectedStack.copy().setStackSize(1); + var slot = this.getAEItemHandler().getInventory()[index]; + slot.setConfig(configStack); + slot.setStack(selectedStack); + index++; + } + + clearInventory(index); + } + + private void clearInventory(int startIndex) { + for (int i = startIndex; i < CONFIG_SIZE; i++) { + var slot = this.getAEItemHandler().getInventory()[i]; + slot.setConfig(null); + slot.setStack(null); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == UPDATE_AUTO_PULL) { + this.autoPull = buf.readBoolean(); + } + } + + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = super.createUITemplate(player); + builder.widget(new ImageCycleButtonWidget(7 + 18 * 4 + 1, 26, 16, 16, GuiTextures.BUTTON_AUTO_PULL, + () -> autoPull, this::setAutoPull).setTooltipHoverString("gregtech.gui.me_bus.auto_pull_button")); + return builder; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + setAutoPull(!autoPull); + if (autoPull) { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_enabled"), false); + } else { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_disabled"), false); + } + } + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AutoPull", autoPull); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.autoPull = data.getBoolean("AutoPull"); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(autoPull); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.autoPull = buf.readBoolean(); + } + + private static class ExportOnlyAEStockingItemSlot extends ExportOnlyAEItemSlot { + + private final MetaTileEntityMEStockingBus holder; + + public ExportOnlyAEStockingItemSlot(IAEItemStack config, IAEItemStack stock, + MetaTileEntityMEStockingBus holder) { + super(config, stock); + this.holder = holder; + } + + public ExportOnlyAEStockingItemSlot(MetaTileEntityMEStockingBus holder) { + super(); + this.holder = holder; + } + + @Override + public ExportOnlyAEStockingItemSlot copy() { + return new ExportOnlyAEStockingItemSlot( + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + this.holder); + } + + @Override + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot == 0 && this.stock != null) { + if (this.config != null) { + // Extract the items from the real net to either validate (simulate) + // or extract (modulate) when this is called + IMEMonitor monitor = holder.getMonitor(); + if (monitor == null) return ItemStack.EMPTY; + + Actionable action = simulate ? Actionable.SIMULATE : Actionable.MODULATE; + IAEItemStack request; + if (this.config instanceof WrappedItemStack wis) { + request = wis.getAEStack(); + } else { + request = this.config.copy(); + } + request.setStackSize(amount); + + IAEItemStack result = monitor.extractItems(request, action, holder.getActionSource()); + if (result != null) { + int extracted = (int) Math.min(result.getStackSize(), amount); + this.stock.decStackSize(extracted); // may as well update the display here + if (this.trigger != null) { + this.trigger.accept(0); + } + if (extracted != 0) { + ItemStack resultStack = this.config.createItemStack(); + resultStack.setCount(extracted); + return resultStack; + } + } + } + } + return ItemStack.EMPTY; + } + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip.2")); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + private static class ExportOnlyAEStockingItemList extends ExportOnlyAEItemList { + + private final MetaTileEntityMEStockingBus holder; + + public ExportOnlyAEStockingItemList(MetaTileEntityMEStockingBus holder, int slots, + MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify); + this.holder = holder; + } + + @Override + protected void createInventory(MetaTileEntity holder) { + if (!(holder instanceof MetaTileEntityMEStockingBus stocking)) { + throw new IllegalArgumentException("Cannot create Stocking Item List for nonstocking MetaTileEntity!"); + } + this.inventory = new ExportOnlyAEStockingItemSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEStockingItemSlot(stocking); + } + for (ExportOnlyAEItemSlot slot : this.inventory) { + slot.setTrigger(this::onContentsChanged); + } + } + + @Override + public ExportOnlyAEStockingItemSlot[] getInventory() { + return (ExportOnlyAEStockingItemSlot[]) super.getInventory(); + } + + @Override + public boolean isStocking() { + return true; + } + + @Override + public boolean isAutoPull() { + return holder.autoPull; + } + + @Override + public boolean hasStackInConfig(ItemStack stack, boolean checkExternal) { + boolean inThisBus = super.hasStackInConfig(stack, false); + if (inThisBus) return true; + if (checkExternal) { + return holder.testConfiguredInOtherBus(stack); + } + return false; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java new file mode 100644 index 00000000000..1693ece229b --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java @@ -0,0 +1,375 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng; + +import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; + +import appeng.api.config.Actionable; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import codechicken.lib.raytracer.CuboidRayTraceResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; + +public class MetaTileEntityMEStockingHatch extends MetaTileEntityMEInputHatch { + + private static final int CONFIG_SIZE = 16; + private boolean autoPull; + private Predicate autoPullTest; + + public MetaTileEntityMEStockingHatch(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, GTValues.LuV); + this.autoPullTest = $ -> false; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MetaTileEntityMEStockingHatch(metaTileEntityId); + } + + @Override + protected ExportOnlyAEStockingFluidList getAEFluidHandler() { + if (this.aeFluidHandler == null) { + this.aeFluidHandler = new ExportOnlyAEStockingFluidList(this, CONFIG_SIZE, getController()); + } + return (ExportOnlyAEStockingFluidList) this.aeFluidHandler; + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && isWorkingEnabled() && autoPull && getOffsetTimer() % 100 == 0) { + refreshList(); + syncME(); + } + } + + @Override + protected void syncME() { + IMEMonitor monitor = super.getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEStockingFluidSlot slot : this.getAEFluidHandler().getInventory()) { + if (slot.getConfig() == null) { + slot.setStack(null); + } else { + // Try to fill the slot + IAEFluidStack request; + if (slot.getConfig() instanceof WrappedFluidStack wfs) { + request = wfs.getAEStack(); + } else { + request = slot.getConfig().copy(); + } + request.setStackSize(Integer.MAX_VALUE); + IAEFluidStack result = monitor.extractItems(request, Actionable.SIMULATE, getActionSource()); + slot.setStack(result); + } + } + } + + @Override + protected void flushInventory() { + // no-op, nothing to send back to the network + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + this.autoPullTest = stack -> !this.testConfiguredInOtherHatch(stack); + validateConfig(); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + this.autoPullTest = $ -> false; + if (this.autoPull) { + this.getAEFluidHandler().clearConfig(); + } + super.removeFromMultiBlock(controllerBase); + } + + private void validateConfig() { + for (var slot : this.getAEFluidHandler().getInventory()) { + if (slot.getConfig() != null) { + FluidStack configuredStack = slot.getConfig().getFluidStack(); + if (testConfiguredInOtherHatch(configuredStack)) { + slot.setConfig(null); + slot.setStock(null); + } + } + } + } + + private boolean testConfiguredInOtherHatch(FluidStack stack) { + if (stack == null) return false; + MultiblockControllerBase controller = getController(); + if (controller == null) return false; + + var abilityList = controller.getAbilities(MultiblockAbility.IMPORT_FLUIDS); + for (var ability : abilityList) { + if (ability instanceof ExportOnlyAEStockingFluidSlot aeSlot) { + if (aeSlot.getConfig() == null) continue; + if (getAEFluidHandler().ownsSlot(aeSlot)) continue; + if (aeSlot.getConfig().getFluid().equals(stack.getFluid())) { + return true; + } + } + } + return false; + } + + private void setAutoPull(boolean autoPull) { + this.autoPull = autoPull; + markDirty(); + if (!getWorld().isRemote) { + if (!this.autoPull) { + this.getAEFluidHandler().clearConfig(); + } else if (updateMEStatus()) { + this.refreshList(); + syncME(); + } + writeCustomData(UPDATE_AUTO_PULL, buf -> buf.writeBoolean(this.autoPull)); + } + } + + private void refreshList() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) { + clearInventory(0); + return; + } + + IItemList storageList = monitor.getStorageList(); + if (storageList == null) { + clearInventory(0); + return; + } + + int index = 0; + for (IAEFluidStack stack : storageList) { + if (index >= CONFIG_SIZE) break; + if (stack.getStackSize() == 0) continue; + stack = monitor.extractItems(stack, Actionable.SIMULATE, getActionSource()); + if (stack == null || stack.getStackSize() == 0) continue; + + FluidStack fluidStack = stack.getFluidStack(); + if (fluidStack == null) continue; + if (autoPullTest != null && !autoPullTest.test(fluidStack)) continue; + IAEFluidStack selectedStack = WrappedFluidStack.fromFluidStack(fluidStack); + IAEFluidStack configStack = selectedStack.copy().setStackSize(1); + var slot = this.getAEFluidHandler().getInventory()[index]; + slot.setConfig(configStack); + slot.setStack(selectedStack); + index++; + } + + clearInventory(index); + } + + private void clearInventory(int startIndex) { + for (int i = startIndex; i < CONFIG_SIZE; i++) { + var slot = this.getAEFluidHandler().getInventory()[i]; + slot.setConfig(null); + slot.setStack(null); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == UPDATE_AUTO_PULL) { + this.autoPull = buf.readBoolean(); + } + } + + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = super.createUITemplate(player); + builder.widget(new ImageCycleButtonWidget(7 + 18 * 4 + 1, 26, 16, 16, GuiTextures.BUTTON_AUTO_PULL, + () -> autoPull, this::setAutoPull).setTooltipHoverString("gregtech.gui.me_bus.auto_pull_button")); + return builder; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + setAutoPull(!autoPull); + if (autoPull) { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_enabled"), false); + } else { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_disabled"), false); + } + } + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AutoPull", autoPull); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.autoPull = data.getBoolean("AutoPull"); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(autoPull); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.autoPull = buf.readBoolean(); + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip.2")); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + private static class ExportOnlyAEStockingFluidSlot extends ExportOnlyAEFluidSlot { + + public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, IAEFluidStack config, + IAEFluidStack stock, MetaTileEntity entityToNotify) { + super(holder, config, stock, entityToNotify); + } + + public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, MetaTileEntity entityToNotify) { + super(holder, entityToNotify); + } + + @Override + protected MetaTileEntityMEStockingHatch getHolder() { + return (MetaTileEntityMEStockingHatch) super.getHolder(); + } + + @Override + public ExportOnlyAEFluidSlot copy() { + return new ExportOnlyAEStockingFluidSlot( + this.getHolder(), + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + null); + } + + @Override + public @Nullable FluidStack drain(int maxDrain, boolean doDrain) { + if (this.stock == null) { + return null; + } + if (this.config != null) { + IMEMonitor monitor = getHolder().getMonitor(); + if (monitor == null) return null; + + Actionable action = doDrain ? Actionable.MODULATE : Actionable.SIMULATE; + IAEFluidStack request; + if (this.config instanceof WrappedFluidStack wfs) { + request = wfs.getAEStack(); + } else { + request = this.config.copy(); + } + request.setStackSize(maxDrain); + + IAEFluidStack result = monitor.extractItems(request, action, getHolder().getActionSource()); + if (result != null) { + int extracted = (int) Math.min(result.getStackSize(), maxDrain); + this.stock.decStackSize(extracted); + trigger(); + if (extracted != 0) { + FluidStack resultStack = this.config.getFluidStack(); + resultStack.amount = extracted; + return resultStack; + } + } + } + return null; + } + } + + private static class ExportOnlyAEStockingFluidList extends ExportOnlyAEFluidList { + + private final MetaTileEntityMEStockingHatch holder; + + public ExportOnlyAEStockingFluidList(MetaTileEntityMEStockingHatch holder, int slots, + MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify); + this.holder = holder; + } + + @Override + protected void createInventory(MetaTileEntity holder, MetaTileEntity entityToNotify) { + if (!(holder instanceof MetaTileEntityMEStockingHatch stocking)) { + throw new IllegalArgumentException("Cannot create Stocking Fluid List for nonstocking MetaTileEntity!"); + } + this.inventory = new ExportOnlyAEStockingFluidSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEStockingFluidSlot(stocking, entityToNotify); + } + } + + @Override + public ExportOnlyAEStockingFluidSlot[] getInventory() { + return (ExportOnlyAEStockingFluidSlot[]) super.getInventory(); + } + + @Override + public boolean isStocking() { + return true; + } + + @Override + public boolean isAutoPull() { + return holder.autoPull; + } + + @Override + public boolean hasStackInConfig(FluidStack stack, boolean checkExternal) { + boolean inThisHatch = super.hasStackInConfig(stack, false); + if (inThisHatch) return true; + if (checkExternal) { + return holder.testConfiguredInOtherHatch(stack); + } + return false; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java new file mode 100644 index 00000000000..fd4b40ea7e5 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java @@ -0,0 +1,64 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraftforge.fluids.FluidStack; + +import appeng.api.storage.data.IAEFluidStack; + +public class ExportOnlyAEFluidList { + + protected final int size; + protected ExportOnlyAEFluidSlot[] inventory; + + public ExportOnlyAEFluidList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { + this.size = slots; + createInventory(holder, entityToNotify); + } + + protected void createInventory(MetaTileEntity holder, MetaTileEntity entityToNotify) { + this.inventory = new ExportOnlyAEFluidSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEFluidSlot(holder, entityToNotify); + } + } + + public ExportOnlyAEFluidSlot[] getInventory() { + return inventory; + } + + public void clearConfig() { + for (var slot : inventory) { + slot.setConfig(null); + slot.setStock(null); + } + } + + public boolean hasStackInConfig(FluidStack stack, boolean checkExternal) { + if (stack == null) return false; + for (ExportOnlyAEFluidSlot slot : inventory) { + IAEFluidStack config = slot.getConfig(); + if (config != null && config.getFluid().equals(stack.getFluid())) { + return true; + } + } + return false; + } + + public boolean isAutoPull() { + return false; + } + + public boolean isStocking() { + return false; + } + + public boolean ownsSlot(ExportOnlyAEFluidSlot testSlot) { + for (var slot : inventory) { + if (slot == testSlot) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java new file mode 100644 index 00000000000..73ad45f9ac4 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java @@ -0,0 +1,192 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.capability.INotifiableHandler; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.FluidTankProperties; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; + +import appeng.api.storage.data.IAEFluidStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class ExportOnlyAEFluidSlot extends ExportOnlyAESlot + implements IFluidTank, INotifiableHandler, IFluidHandler { + + private final List notifiableEntities = new ArrayList<>(); + private MetaTileEntity holder; + + public ExportOnlyAEFluidSlot(MetaTileEntity holder, IAEFluidStack config, IAEFluidStack stock, MetaTileEntity mte) { + super(config, stock); + this.holder = holder; + this.notifiableEntities.add(mte); + } + + public ExportOnlyAEFluidSlot(MetaTileEntity holder, MetaTileEntity entityToNotify) { + this(holder, null, null, entityToNotify); + } + + public ExportOnlyAEFluidSlot() { + super(); + } + + @Override + public IAEFluidStack requestStack() { + IAEFluidStack result = super.requestStack(); + if (result instanceof WrappedFluidStack) { + return ((WrappedFluidStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public IAEFluidStack exceedStack() { + IAEFluidStack result = super.exceedStack(); + if (result instanceof WrappedFluidStack) { + return ((WrappedFluidStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public void addStack(IAEFluidStack stack) { + if (this.stock == null) { + this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); + } else { + this.stock.add(stack); + } + trigger(); + } + + @Override + public void setStack(IAEFluidStack stack) { + if (this.stock == null && stack == null) { + return; + } else if (stack == null) { + this.stock = null; + } else if (this.stock == null || this.stock.getFluid() != stack.getFluid()) { + this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); + } else if (this.stock.getStackSize() != stack.getStackSize()) { + this.stock.setStackSize(stack.getStackSize()); + } else return; + trigger(); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(CONFIG_TAG)) { + this.config = WrappedFluidStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); + } + if (nbt.hasKey(STOCK_TAG)) { + this.stock = WrappedFluidStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); + } + } + + @Nullable + @Override + public FluidStack getFluid() { + if (this.stock != null && this.stock instanceof WrappedFluidStack) { + return ((WrappedFluidStack) this.stock).getDelegate(); + } + return null; + } + + @Override + public int getFluidAmount() { + return this.stock != null ? (int) this.stock.getStackSize() : 0; + } + + @Override + public int getCapacity() { + // Its capacity is always 0. + return 0; + } + + @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(this); + } + + @Override + public IFluidTankProperties[] getTankProperties() { + return new IFluidTankProperties[] { + new FluidTankProperties(this.getFluid(), 0) + }; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return 0; + } + + @Nullable + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + if (this.getFluid() != null && this.getFluid().isFluidEqual(resource)) { + return this.drain(resource.amount, doDrain); + } + return null; + } + + @Nullable + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (this.stock == null) { + return null; + } + int drained = (int) Math.min(this.stock.getStackSize(), maxDrain); + FluidStack result = new FluidStack(this.stock.getFluid(), drained); + if (doDrain) { + this.stock.decStackSize(drained); + if (this.stock.getStackSize() == 0) { + this.stock = null; + } + trigger(); + } + return result; + } + + @Override + public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.add(metaTileEntity); + } + + @Override + public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.remove(metaTileEntity); + } + + protected void trigger() { + for (MetaTileEntity metaTileEntity : this.notifiableEntities) { + if (metaTileEntity != null && metaTileEntity.isValid()) { + this.addToNotifiedList(metaTileEntity, this, false); + } + } + if (holder != null) { + holder.markDirty(); + } + } + + @Override + public ExportOnlyAEFluidSlot copy() { + return new ExportOnlyAEFluidSlot( + this.holder, + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + null); + } + + protected MetaTileEntity getHolder() { + return holder; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java new file mode 100644 index 00000000000..995670eff15 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java @@ -0,0 +1,126 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import appeng.api.storage.data.IAEItemStack; +import org.jetbrains.annotations.NotNull; + +public class ExportOnlyAEItemList extends NotifiableItemStackHandler { + + protected final int size; + protected ExportOnlyAEItemSlot[] inventory; + + public ExportOnlyAEItemList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify, false); + this.size = slots; + createInventory(holder); + } + + protected void createInventory(MetaTileEntity holder) { + this.inventory = new ExportOnlyAEItemSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEItemSlot(); + } + for (ExportOnlyAEItemSlot slot : this.inventory) { + slot.setTrigger(this::onContentsChanged); + } + } + + public ExportOnlyAEItemSlot[] getInventory() { + return inventory; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + for (int index = 0; index < size; index++) { + if (nbt.hasKey("#" + index)) { + NBTTagCompound slotTag = nbt.getCompoundTag("#" + index); + this.inventory[index].deserializeNBT(slotTag); + } + } + } + + @Override + public NBTTagCompound serializeNBT() { + NBTTagCompound nbt = new NBTTagCompound(); + for (int index = 0; index < size; index++) { + NBTTagCompound slot = this.inventory[index].serializeNBT(); + nbt.setTag("#" + index, slot); + } + return nbt; + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) { + // NO-OP + } + + @Override + public int getSlots() { + return size; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (slot >= 0 && slot < size) { + return this.inventory[slot].getStackInSlot(0); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot >= 0 && slot < size) { + return this.inventory[slot].extractItem(0, amount, simulate); + } + return ItemStack.EMPTY; + } + + @Override + public int getSlotLimit(int slot) { + return Integer.MAX_VALUE; + } + + @Override + protected int getStackLimit(int slot, @NotNull ItemStack stack) { + return Integer.MAX_VALUE; + } + + public void clearConfig() { + for (var slot : inventory) { + slot.setConfig(null); + slot.setStock(null); + } + } + + public boolean hasStackInConfig(ItemStack stack, boolean checkExternal) { + if (stack == null || stack.isEmpty()) return false; + for (ExportOnlyAEItemSlot slot : inventory) { + IAEItemStack config = slot.getConfig(); + if (config != null && config.isSameType(stack)) { + return true; + } + } + return false; + } + + public boolean isAutoPull() { + return false; + } + + public boolean isStocking() { + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java new file mode 100644 index 00000000000..1408d77ad49 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java @@ -0,0 +1,138 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.items.IItemHandlerModifiable; + +import appeng.api.storage.data.IAEItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public class ExportOnlyAEItemSlot extends ExportOnlyAESlot implements IItemHandlerModifiable { + + protected Consumer trigger; + + public ExportOnlyAEItemSlot(IAEItemStack config, IAEItemStack stock) { + super(config, stock); + } + + public ExportOnlyAEItemSlot() { + super(); + } + + public void setTrigger(Consumer trigger) { + this.trigger = trigger; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(CONFIG_TAG)) { + this.config = WrappedItemStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); + } + if (nbt.hasKey(STOCK_TAG)) { + this.stock = WrappedItemStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); + } + } + + @Override + public ExportOnlyAEItemSlot copy() { + return new ExportOnlyAEItemSlot( + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy()); + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) {} + + @Override + public int getSlots() { + return 1; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (slot == 0 && this.stock != null) { + return this.stock.getDefinition(); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot == 0 && this.stock != null) { + int extracted = (int) Math.min(this.stock.getStackSize(), amount); + ItemStack result = this.stock.createItemStack(); + result.setCount(extracted); + if (!simulate) { + this.stock.decStackSize(extracted); + if (this.stock.getStackSize() == 0) { + this.stock = null; + } + } + if (this.trigger != null) { + this.trigger.accept(0); + } + return result; + } + return ItemStack.EMPTY; + } + + @Override + public IAEItemStack requestStack() { + IAEItemStack result = super.requestStack(); + if (result instanceof WrappedItemStack) { + return ((WrappedItemStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public IAEItemStack exceedStack() { + IAEItemStack result = super.exceedStack(); + if (result instanceof WrappedItemStack) { + return ((WrappedItemStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public void addStack(IAEItemStack stack) { + if (this.stock == null) { + this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); + } else { + this.stock.add(stack); + } + this.trigger.accept(0); + } + + @Override + public void setStack(IAEItemStack stack) { + if (this.stock == null && stack == null) { + return; + } else if (stack == null) { + this.stock = null; + } else { + // todo this could maybe be improved with better comparison check + this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); + } + this.trigger.accept(0); + } + + @Override + public int getSlotLimit(int slot) { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java similarity index 94% rename from src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java rename to src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java index 8d5027add51..316a76e422b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java @@ -1,4 +1,4 @@ -package gregtech.common.metatileentities.multi.multiblockpart.appeng; +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.INBTSerializable; @@ -6,11 +6,6 @@ import appeng.api.storage.data.IAEStack; import org.jetbrains.annotations.Nullable; -/** - * @author GlodBlock - * @Description A export only slot to hold {@link IAEStack} - * @date 2023/4/22-13:42 - */ public abstract class ExportOnlyAESlot> implements IConfigurableSlot, INBTSerializable { @@ -64,7 +59,9 @@ public T exceedStack() { return null; } - abstract void addStack(T stack); + public abstract void addStack(T stack); + + public abstract void setStack(T stack); @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java similarity index 66% rename from src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java rename to src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java index 6cc3a48771d..9e4532c8f19 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java @@ -1,10 +1,5 @@ -package gregtech.common.metatileentities.multi.multiblockpart.appeng; +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; -/** - * @Author GlodBlock - * @Description A slot that can be set to keep requesting. - * @Date 2023/4/21-0:34 - */ public interface IConfigurableSlot { T getConfig(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java index 854996b0db4..274d4aac26c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java @@ -191,12 +191,18 @@ public boolean sameOre(IAEItemStack iaeItemStack) { @Override public boolean isSameType(IAEItemStack iaeItemStack) { - return false; + if (iaeItemStack == null) return false; + IAEItemStack aeStack = AEItemStack.fromItemStack(this.delegate); + if (aeStack == null) return false; + return aeStack.isSameType(iaeItemStack); } @Override public boolean isSameType(ItemStack itemStack) { - return false; + if (this.delegate.isEmpty()) return itemStack.isEmpty(); + IAEItemStack aeStack = AEItemStack.fromItemStack(this.delegate); + if (aeStack == null) return false; + return aeStack.isSameType(itemStack); } @Override diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java index 013e759001f..39e12fe8af3 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java @@ -8,6 +8,7 @@ import gregtech.api.recipes.ingredients.GTRecipeItemInput; import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.GTUtility; import gregtech.api.util.Mods; import net.minecraft.init.Blocks; @@ -1024,6 +1025,24 @@ public static void init() { .inputs(accelerationCard.copy()) .output(ITEM_IMPORT_BUS_ME) .duration(300).EUt(VA[HV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(ITEM_IMPORT_BUS[IV]) + .inputs(normalInterface.copy()) + .input(CONVEYOR_MODULE_IV) + .input(SENSOR_IV) + .inputs(GTUtility.copy(4, accelerationCard)) + .output(STOCKING_BUS_ME) + .duration(300).EUt(VA[IV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(FLUID_IMPORT_HATCH[IV]) + .inputs(fluidInterface.copy()) + .input(ELECTRIC_PUMP_IV) + .input(SENSOR_IV) + .inputs(GTUtility.copy(4, accelerationCard)) + .output(STOCKING_HATCH_ME) + .duration(300).EUt(VA[IV]).buildAndRegister(); } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 38436e8da3d..0dea6d1ea4b 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5254,15 +5254,27 @@ gregtech.machine.laser_hatch.tooltip2=§cLaser Cables must be in a straight line gregtech.machine.fluid_tank.max_multiblock=Max Multiblock Size: %,dx%,dx%,d gregtech.machine.fluid_tank.fluid=Contains %s L of %s -gregtech.machine.me_export_fluid_hatch.name=ME Output Hatch +# ME Parts +gregtech.machine.me_import_item_bus.name=ME Input Bus +gregtech.machine.me.item_import.tooltip=Extracts specified items from the ME network +gregtech.machine.me_stocking_item_bus.name=ME Stocking Input Bus +gregtech.machine.me.stocking_item.tooltip=Retrieves items directly from the ME network +gregtech.machine.me.stocking_item.tooltip.2=Auto-Pull from ME mode will automatically stock the first 16 items in the ME system, updated every 5 seconds. +gregtech.machine.me_import_item_hatch.configs.tooltip=Keeps 16 item types in stock +gregtech.machine.me_import_fluid_hatch.name=ME Input Hatch +gregtech.machine.me.fluid_import.tooltip=Extracts specified fluids from ME network +gregtech.machine.me_stocking_fluid_hatch.name=ME Stocking Input Hatch +gregtech.machine.me.stocking_fluid.tooltip=Retrieves fluids directly from the ME network +gregtech.machine.me.stocking_fluid.tooltip.2=Auto-Pull from ME mode will automatically stock the first 16 fluids in the ME system, updated every 5 seconds. +gregtech.machine.me_import_fluid_hatch.configs.tooltip=Keeps 16 fluid types in stock gregtech.machine.me_export_item_bus.name=ME Output Bus -gregtech.machine.me_import_fluid_hatch.name=ME Stocking Input Hatch -gregtech.machine.me_import_item_bus.name=ME Stocking Input Bus -gregtech.machine.me.fluid_export.tooltip=Stores fluid directly into ME network. -gregtech.machine.me.item_export.tooltip=Stores item directly into ME network. -gregtech.machine.me.fluid_import.tooltip=Fetch fluids from ME network automatically. -gregtech.machine.me.item_import.tooltip=Fetch items from ME network automatically. -gregtech.machine.me.export.tooltip=It has infinite capacity before connecting to ME network. +gregtech.machine.me.item_export.tooltip=Stores items directly into the ME network +gregtech.machine.me.item_export.tooltip.2=Can cache an infinite amount of items +gregtech.machine.me_export_fluid_hatch.name=ME Output Hatch +gregtech.machine.me.fluid_export.tooltip=Stores fluids directly into the ME network +gregtech.machine.me.fluid_export.tooltip.2=Can cache an infinite amount of fluid +gregtech.machine.me.stocking_auto_pull_enabled=Auto-Pull Enabled +gregtech.machine.me.stocking_auto_pull_disabled=Auto-Pull Disabled # Universal tooltips gregtech.universal.tooltip.voltage_in=§aVoltage IN: §f%,d EU/t (%s§f) @@ -5403,8 +5415,12 @@ gregtech.gui.me_network.offline=Network Status: §4Offline§r gregtech.gui.waiting_list=Sending Queue: gregtech.gui.config_slot=§fConfig Slot§r gregtech.gui.config_slot.set=§7Click to §bset/select§7 config slot.§r +gregtech.gui.config_slot.set_only=§7Click to §bset§7 config slot.§r gregtech.gui.config_slot.scroll=§7Scroll wheel to §achange§7 config amount.§r gregtech.gui.config_slot.remove=§7Right click to §4clear§7 config slot.§r +gregtech.gui.config_slot.auto_pull_managed=§4Disabled:§7 Managed by Auto-Pull +gregtech.gui.me_bus.extra_slot=Extra Slot/n§7Put extra items for recipes here, like Molds or Lenses +gregtech.gui.me_bus.auto_pull_button=Click to toggle automatic item pulling from ME gregtech.gui.alarm.radius=Radius: diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png index 76486f57cddf495f9f58ce74646a9ccc9c56afac..dd3d1f12037c5f85d9801b81d745aaba4be77205 100644 GIT binary patch delta 182 zcmbQmc${&9WIZzj1A~Sxe=v|@EDmyaVpw-h<|UBBlJ4m1$iT3%pZiZDE0E70;1lBN z;NY-g#fp@al=qcFKrvINS%G|>0G|+72M34ul|m^gDL{b*R@%2f>PmwAg8%>j&)}f7@(Ym9S>O>_%)r36 z41^im@2t!R3L1L4IEH8hCnvZu-(ZoLz@W$Irs2S0(8yTF=q7MXyI~=#F9X*DCXR+! g2GIqa2FA<`&n7T#e60KB6HqgQr>mdKI;Vst00y5j5C8xG literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png index f19def26e3015ebd2d36784d2b2bde5fee921cfa..a2644c44b468a44e4f7e1ca4a5dcd2d60a61fbd7 100644 GIT binary patch delta 182 zcmbQmc${&9WIZzj1A~Sxe=v|@EDmyaVpw-h<|UBBlJ4m1$iT3%pZiZDE0E70;1lBN z;NY-g#fp@a6kf+gK(R-gdM*Je){-E<;Qv6t@Ov8{$RN%FkH}&M2EM}}%y>M1MG8>R zz|+MsL?bvk!IAj}i^K#5Jw`VT2M&FMM#ehEv@|CsiKq)K3mEho7;dlzFwSD&=4Mcf WXVOgk77sLufx*+&&t;ucLK6TwcQV}o delta 137 zcmX@kIE!(DWIY=L1B3kM|A{~<(bL5-#G*G@qTm2W@qsQ;?SGRW&FJXh*bpa{a_~zj zcgH0gV-3c0X^TuaA~tXqRo+ev{geAzk;kwrw&6NMUaYBs+HHm;hHC~5jq9i93z{^U p=^YTe^`(%ph)Y_jp|O#XA=p>Y;#2yGSfFJLp00i_>ztSpngHZNS%G|>0G|+72L}gU$3-bADL{ck%Ukb*)RhGJ1^@s5pTR+EF)x7&9|Go4~m7vF?{oK+O!Eu6{1-oD!M|L rG=erRz!uu{aRG7)8zO*#fdK%QvJtvQCq}~n0000NS%G|>0G|-o_mx5p4h|_PDL{ch?|Z92>PmwAg8%>j&)}f7@(Ym9S>O>_%)r36 z41^im@2t!R3L1F2IEH8hCnvZu-(ZoLz~Is#$XCE^(8yTF$j0WxBoTFiC4pf&gAfDv f0wxp2v^0kA6BsWl@3ayJ>SgeB^>bP0l+XkK$uBR{ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png index 313e4fdbeb65f380306ed3f8419c5833ecfb1f13..e13a7f0fb7c07ebb8cfc5a6491eb8989871c2c4c 100644 GIT binary patch delta 182 zcmbQmc${&9WIZzj1A~Sxe=v|@EDmyaVpw-h<|UBBlJ4m1$iT3%pZiZDE0E70;1lAy zV#Nvv2ZxlD6kf+gKry+kcb5Vw){-E<;Qv6t@Ov8{$RN%FkH}&M2EM}}%y>M1MG8>R zz|+MsL?bvk!IAj}i^K#5mj*$;0&abSM#ehEv@|CsiKq)K2@KO2gc!INFqtrli7{B# WGx=_re=Y&2nZeW5&t;ucLK6V{)G|{5 delta 137 zcmV;40CxY!0h$4j8Gi-<001BJ|6u?C0AWc)K~y-6V;FG22y?)S6)XOe;+Tkt2(Vrj zWWltG=|pLs)sYEjGf^4@EZ77&gjBIA{_*ZMh8V>zz-s`Xq9YiSZ2&ONS%G|>0G|+7UdKfa4h|_PDL{djyOQ>T)RhGJ1^@s5pTR+E%w=boFyt=akR{0PuevF#rGn literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png b/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png new file mode 100644 index 0000000000000000000000000000000000000000..5613c4a37856c9ea6bddc0ad15a7d8852e8734d8 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!V2-DYV~B-+vIJ{EKuE|J`BN^8J^`~-CQO*n zkSL)%g^f98n__eM`+JU&JUrZDIt{Pg3k5v{6?vHTDllUs+WpRATAquubtu zi!_ITX!eaHPFaB-(;; zJ)TjhjZtxT&VSn(K#iOQ9+AZi419+{nDKc2iWHz=uBVG*h{pNk1|~N)H%9}3L#GAI z49$30j4$2hS>7c1_Vk`|b|y)sNYQHvZ3WemA*XIgE}FqHxpj&{1EZI=k%rR}mJdb_ z?<_ge815FcpUH@S_Whm01jdqn*%^#Q{4QKC<~6hMv>37+Sa|3F1B3oGmCT044tYR} O89ZJ6T-G@yGywpki&`)M literal 0 HcmV?d00001 From 4e47ef8e75cab83ffa25dc90b80adf37add2cafd Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:15:00 -0600 Subject: [PATCH 82/98] Electric Wirecutter (#2404) --- .../java/gregtech/common/items/ToolItems.java | 33 ++++++++++++++++++ .../recipe/handlers/ToolRecipeHandler.java | 19 ++++++++++ .../resources/assets/gregtech/lang/en_us.lang | 3 ++ .../dull/tool_head_wirecutter.json | 6 ++++ .../models/item/tools/wire_cutter_hv.json | 7 ++++ .../models/item/tools/wire_cutter_iv.json | 7 ++++ .../models/item/tools/wire_cutter_lv.json | 7 ++++ .../tools/handle_electric_wire_cutter_hv.png | Bin 0 -> 2552 bytes .../tools/handle_electric_wire_cutter_iv.png | Bin 0 -> 2532 bytes .../tools/handle_electric_wire_cutter_lv.png | Bin 0 -> 2508 bytes .../items/tools/wire_cutter_electric.png | Bin 0 -> 1786 bytes 11 files changed, 82 insertions(+) create mode 100644 src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json create mode 100644 src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json create mode 100644 src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json create mode 100644 src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json create mode 100644 src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png create mode 100644 src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png create mode 100644 src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png create mode 100644 src/main/resources/assets/gregtech/textures/items/tools/wire_cutter_electric.png diff --git a/src/main/java/gregtech/common/items/ToolItems.java b/src/main/java/gregtech/common/items/ToolItems.java index 05e2453846b..5545387ef7c 100644 --- a/src/main/java/gregtech/common/items/ToolItems.java +++ b/src/main/java/gregtech/common/items/ToolItems.java @@ -55,6 +55,9 @@ public final class ToolItems { public static IGTTool BUZZSAW; public static IGTTool SCREWDRIVER_LV; public static IGTTool PLUNGER; + public static IGTTool WIRECUTTER_LV; + public static IGTTool WIRECUTTER_HV; + public static IGTTool WIRECUTTER_IV; private ToolItems() {/**/} @@ -319,6 +322,36 @@ public static void init() { .oreDict(ToolOreDict.toolPlunger) .toolClasses(ToolClasses.PLUNGER) .markerItem(() -> ToolHelper.getAndSetToolData(PLUNGER, Materials.Rubber, 255, 1, 4F, 0F))); + WIRECUTTER_LV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_lv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(2.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.LV)); + WIRECUTTER_HV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_hv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(3.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.HV)); + WIRECUTTER_IV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_iv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(4.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.IV)); } public static IGTTool register(@NotNull ToolBuilder builder) { diff --git a/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java index 4b6ec9210b2..1997631a38c 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java @@ -287,6 +287,10 @@ private static void processElectricTool(OrePrefix prefix, Material material, Too .EUt(8 * voltageMultiplier) .buildAndRegister(); } + + // wirecutter + addElectricWirecutterRecipe(material, + new IGTTool[] { ToolItems.WIRECUTTER_LV, ToolItems.WIRECUTTER_HV, ToolItems.WIRECUTTER_IV }); } // screwdriver @@ -316,6 +320,21 @@ public static void addElectricToolRecipe(OrePrefix toolHead, Material material, } } + public static void addElectricWirecutterRecipe(Material material, IGTTool[] toolItems) { + for (IGTTool toolItem : toolItems) { + int tier = toolItem.getElectricTier(); + ItemStack powerUnitStack = powerUnitItems.get(tier).getStackForm(); + IElectricItem powerUnit = powerUnitStack.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, null); + ItemStack tool = toolItem.get(material, 0, powerUnit.getMaxCharge()); + ModHandler.addShapedEnergyTransferRecipe(String.format("%s_%s", toolItem.getToolId(), material), tool, + Ingredient.fromStacks(powerUnitStack), true, true, + "PfP", "hPd", "RUR", + 'P', new UnificationEntry(OrePrefix.plate, material), + 'U', powerUnitStack, + 'R', new UnificationEntry(OrePrefix.stick, material)); + } + } + public static void addToolRecipe(@NotNull Material material, @NotNull IGTTool tool, boolean mirrored, Object... recipe) { if (mirrored) { diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 0dea6d1ea4b..6fc2ebe2f39 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -1008,6 +1008,9 @@ item.gt.tool.screwdriver_lv.name=%s Screwdriver (LV) item.gt.tool.screwdriver_lv.tooltip=§8Adjusts Covers and Machines item.gt.tool.plunger.name=%s Plunger item.gt.tool.plunger.tooltip=§8Removes Fluids from Machines +item.gt.tool.wire_cutter_lv.name=%s Wire Cutter (LV) +item.gt.tool.wire_cutter_hv.name=%s Wire Cutter (HV) +item.gt.tool.wire_cutter_iv.name=%s Wire Cutter (IV) item.gt.tool.tooltip.crafting_uses=§a%s Crafting Uses diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json new file mode 100644 index 00000000000..92690c87e45 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/tool_head_wire_cutter" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json new file mode 100644 index 00000000000..60a5a9255c1 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_hv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json new file mode 100644 index 00000000000..6a7f378d8a9 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_iv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json new file mode 100644 index 00000000000..406df61785c --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_lv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png new file mode 100644 index 0000000000000000000000000000000000000000..b54d8d136c2f0e8692327d3b940f495d641295d2 GIT binary patch literal 2552 zcmcIm+i%-c7No;Jl zNj9`;z3kq#qXTv+($GMvP?Em;lr~tGYhk)FD@)xzHs5asp+$hGkNgf@yW^g<0sxc zGq*T5w>UksU|EL`9XdTd{raiX=QnQLxOMB+GqV?q#iQBm!CdY&+ny|yj$vQcuV24u z)28h^b{v_UpO}~#+h1yEXlU8c($&?K$rOA(Ut3!n*-bVzHFb1!VEiR85W|nKn;05d z`4<<_%q+i*iJGl}7afAw^0aq1T?Bgo+Ag$RSrH zi@9vxQHo)zOswGV-Zn##Wr#Z#rXt>n@#gdN`8)p002^w{bC@1G$`&OIlyrY z5E&rTKvFnP;bgLUQTRNP4B2{0NyMJ5o`+XqD&xAA!Z3wG!C&D0rk!S3S(X{VF&sx@ z1nrdau3Dt?&bA6kl_rK9Xd9Mmn0eBpRW)ZRE*0DHU@pv7+CT%WPM>}r+1oo&J;F@SBS+Wq5K#n%*vRq>151%#8Lmb9*w2+*+_LwJ87EPTE&KIEF{PK1+r(Kk=MIFdsfC@B@1);01`Zq9}WPu{$QVV|po4S!IJrJrx zC1u(<6=%uFscFPm`E>cTcw8CGJFc3CXfPJ0u&aK<(3OCuLz$I%I=~{97Jwkpnk);n zrU{w`cuftYf;Ib?3CFz(*6ej`52aK<)exiw83pN-B#5-e2UMDs051SthkQz{*}q^L zxR=!Iqw~}&r1Y6t(~g@u&N5#UF_v*zPRfAc;F^`n4N~cra+{2xS66LSMV~duvZ@pn zdcqG=(5pDosp__|M$#TG=n8EigD~lRlu&^=X38z7Hj1Qif*-6j<{<)c)QS6t!RY}p zrSUQiMNXm-CjdGqvmBj*f(SG%$V$9eOT*n^@CqAH0AJJSBZW~hf*CcRM)=)|`}{u% z?BPVcW_|8%zW*Vx5aYdGSIaTPtgYP89mUtWCW1TIlee=<0%dte)%2>Zy1aK+29Rz- z+^%=%f;5ZA7Q{U-3LK65UZf%9Asdi@AnU1$pIPG{(8@d~c@(q;bU?GLpwY4< zrD$1&K;%&{D6!HSw3V&Z5rmjKzTPYJiq)#IRd%$pi)SKU;k?!+vbU;Fb(F_)v+>N{ za_fgPc-~J8#v;j{5%^)GadR^O(H_w3+k11@GTF7``i)y(eD!6ke%)6re){`w>wIUg zH8r0)e)7cgWal$Gx6|9cKGHV7u&*tVOdM@mTKazJm-ojq`;ESv-+X)fJDkVI1|zLv ufW0j>I_k&gUmE>ss?!?#V7dF+Y%B5WlR{(ryZ)T_mt(MhD0Vga%H*FW_%)RP literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png new file mode 100644 index 0000000000000000000000000000000000000000..303fea217f6ee5fa49bdbbc901d221d81931c863 GIT binary patch literal 2532 zcmcImTWs4@7LU+qY?_2LAx%6m9ySTIO@py_UO@1~D@aJ?IJXtnU6{a<8%s#VRI;+c zFzKw1R9hK0HGv?dl+>3eCY)z8Cv>?eA3Ub=7-`2RCS6@ANh7aokmz#hkiNWY*RFm0 z_N7o+1*SOsnlyThp1)(qj=sLW1H;4exFH^RrK6*xduR9H;GnSo{jB2<(ed3t9TU6Fv-c9XW(TLvL-3oPKx{O%da@rwo=>?B?oif6e-!WCw;PXaz2kw zE@R!|CMSBjlQl#cDkL=6TBYm+sFvdD#E5>6wt0@NL&D`0myS+kkLDKGDc2{g78e1A z5VD#cS5%dlSQ%$UD2hB(c&G!YAyGu4&NeTOp2xCD-zuQR>~qcY=qkmP!q7uJU#(W- zRVnWJMPAT#orfYXihv?Ou;zqD4LHI621%19O9JfMUTC`x8_^o3yAq~2>T)BNir40L zf@Z>K>iC-B@j@I%vDJYVZsWWazg+jg!aOOH3UR`KVud!ArYo0g!?&cZRNCkuoL;3K zH3Qrd9pu+M!Y`7*UGXuQUZp4QZ#m|b+|Uh5?mgmY|J;toLsLF6Lf6l`Zn;&lg%%4d zN^zMTIbu7OTMb5|QyQS~^8Qk~Rht2*L(5M+IRSq45u}kQX3Q zXsPADfnCcktUVBFVN`Jaib1nvSBxUzJ*QYdEtf-cP7oRnCUe;oM_rBEwuMyF!n&YK zKoy7pWGHLE)O8t{rfix}G7YtmXxV37yb@KgWp7b?tQAzlBpAp#Nq~YTE5MXg0|*+F zWN2AfDi|&M7k!)dl2Lwio_2-Mlv{TFoNLi6ODz#o8Q0~6X6=C1Y^~lPjc%#8$r3rS zX{#yvvdz|2g$x`CKgHpw;>6;b+x8Yod$^z*wAB)!r1w!m0~WZ2uxj`uU8D(qu+sR4 z2qZ98?;nO}sY=0=bbu9614NV|Na%tH3RqU4X(j|sQd()aI}8a4DuPl=qmL9u!w8oQ zr%33#mG=3664=9uddvFU-F*K;U`alDy>6CclHXdn$vcW~bxoRfa3t?wlLYGW&KSi_ zTWxtyGzO66V%n~E=n@i6=%kxJAEusJ> zv>*@!*#x?#6@YGFs7NG{&;)G@+Q!!A2$K9AU+)!q!)nvmsyo`)r8AMPXkJ?rIa;-+ zI&rAnd^)rD-uUG`I`3EKvg!QD5{5I|_H;p*8G&7~!`H^ovxCEzuip6jn=3um5t#H$3D2&+4b(*@0@;t9XL38W$gMhr+R<<=;OW*k1V{^IWoF_ZuZP)XV0F?T)TPm zhwp#B{oVGtbkFTu+D$bU7+*X&uwFVf;4SB_vllPv%%?x`=ij(>97KOP=BDSf7c$4* F{0pFb6#oDK literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png new file mode 100644 index 0000000000000000000000000000000000000000..c45bffa43605a2c3858313c423a5ef2d17126870 GIT binary patch literal 2508 zcmcImYitx%7~O)c6=*C3OQSRlLs3*_=e@Ht?1H7+(i#^^S)r&uI&nLs*zLnyE>}@)O`sm#i=C^m0DX_^>zC0j&#Ip>-PN^s>`!QLQ@A2n z;c{($cKDxiJ{sQ=ubFSTTqWhsmACe`&qljkH}~tI2D>5nfCP-FTUHGPx|7j3Lc3hP zY00<@7C;+QU|5g&@pIifa7=>lNv~-);hgrFA<(`6h$=p9YSA!XQbG(- zXvGAy|i18YaX9H$wo5qA)>p^BxaW06!UH zD25>^o}@&A5+sI^7!k{SaI_zW`Ak)l>I2o8{m{sdH`#VvBFRJ|;ZCq_!wi$OD2gP- zkPJg01YxzsY&l89tO;q73{3!9z|`ZmZp1K$R#uD_+mEA=(^{hO9CyshBn+jFOv-VR zc2kbF6i@{@T)f4Mq#{rO2_rBHW448`bPkKs6%6L!gVIK$IkaV0wW5eJ0tZD~p|&_A z>!D?|m;hF_q8%q>1B*8qwqZ3HSJ09BJEtZtRhm$?4KrjIk!;24vMd%8|D%qXPG+cB{_2AJh=)NW&~cvlFrjE5azj*LE6t9YQR* z_3APh)x&EFD-wWb1OhS~MR-M;AvD18l%jZPf#tJlxLgJ+(H@CnvmU)68R7c)(Q7 z-c!>DkZJ(bu9xV%Ebxj@^AMEcMLo}R41xNdCjejp?GY$WRJC-R5&d7#iYy~I6of*l z6hYIRLWqK(5uywzo`qhoKnsJ=rl$rf@R65dy^{3wssYDVD$w*SIup?dg+5WFK?-;hsWbjckWK?8_`od^5Up5r}}!%-|Bkt z)GIxw_a}WD4mG!QEv`O0YWELJA4~7>s?l^YBmO5Lz-(Ga=x4yDf_fP!AH)dCF zvGw?h>hQb9(N%lSA%&uA^gJ;YRPy zgS*!6{Q1K6_ga2^*< z6g18+X_3mdmyLKeAeUkzhI~79WqI$yZ}Ns7;CQpQd+7I1eN_I(!=-rP^!$dy&-do9 z(Kdb2+_`7u@3USwaejGad)?a87uMwEovohGcd)Q?+?#ci>Rzi~x+rQb?pXa*^%?Cc m*Sn#~B^`vd=4gL$Z`u1(zMk^vR$FpjscNfc2D+vK+Ik`9XCMQdB zdv80%54usc17+wa^T+nXiThE}NkLlZ27bWorda&7Kb@1QjIn_~rW7_$?nltsZexLy zoa8+3^L{*U-nR$(ds~_xYo;iwCEb@AB+pI$+VCK`Kl$fPNFEQ_eY;(XdgLj8HKYf( zUZbc7=8epVH=^v6RcwZ!hO;PCHf@5YsLrmk4b@TP(OHx;tORp)evzRKEx`;&6`G9fUL2kEj|uw1#EU@E*a+54Y4hOR)o(FD`&JETXH z0Xm5tM8`t{s{#P%xD<-UVkoOdJ7@t20tccTkXR6x1wj@hx^^+douldUU}{Ir8F@=E zdC#+Djw_W)p;9=6ogBwYlEeXl69kqZSa;m=V41btEp>(za#hE$Jp)^`&j_=)=p`5u zYBdMb4rnd6Rwq(1t_*FC4*@@?3Q$u6oLzJZ73Z4Dp#n0I<+%jQ2Ut=jMG4?*(wb&~ zcDYL;HPLQn+(z6Wa&gg7QO_9hxTPMLoyQ(_^LU*+g5w|?TTVI%df3TeT&OEG zP-mfqa414QJ#1JSF1c;Kmzn`eK@TMuqFRIn0?UI8ku1u~Ahr#NG5}SmLK;DX9{fKz zEb}p$m;M9BnxT*15vr-OjvW({Dj6osAo|nr!CimmWtA;1Vcg%8HOh7FdUAl zVUdkUS%Ho4kvJ<#YK+zOm-H}?2Kj|x;of-yh2$hIU`N3ksdCuw-%20JeTGZK8n68kLuhYpS1{;G z>&Q^`yF0~PG@7PY3e;dqG@)AsBWD#nI z%-izUyAP3B{e3#soe>XSd7rl?w?EvoIQ&&(-_f1DFZ7<}#rv98I$oNbpFV!<=>7v% z=iI{C9cT2WwogwkoRzZ zN;}-Ja&h119q(RQ?WayHWp;hAf7A5LAI;Z(J+<^> Date: Wed, 6 Mar 2024 21:33:51 -0600 Subject: [PATCH 83/98] Allow PSS to display on CM (#2405) --- .../common/covers/CoverDigitalInterface.java | 71 ++++++++++++++----- .../MetaTileEntityMonitorScreen.java | 65 ++++++++++++++--- 2 files changed, 111 insertions(+), 25 deletions(-) diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java index 7455688d164..d4950ca4ac7 100644 --- a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java +++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java @@ -19,6 +19,7 @@ import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.RenderUtil; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityPowerSubstation; import gregtech.common.terminal.app.prospector.widget.WidgetOreList; import net.minecraft.client.Minecraft; @@ -228,7 +229,7 @@ public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFaci } else if (getItemCapability() != null) { items = new ItemStack[getItemCapability().getSlots()]; this.mode = MODE.ITEM; - } else if (getEnergyCapability() != null) { + } else if (getEnergyCapability() != null || getCoverableView() instanceof MetaTileEntityPowerSubstation) { this.mode = MODE.ENERGY; } else if (getMachineCapability() != null) { this.mode = MODE.MACHINE; @@ -579,22 +580,19 @@ private void syncAllInfo() { } } if (this.mode == MODE.ENERGY || (mode == MODE.PROXY && proxyMode[2] > 0)) { - IEnergyContainer energyContainer = this.getEnergyCapability(); - if (energyContainer != null) { - // TODO, figure out what to do when values exceed Long.MAX_VALUE, ie with multiple Ultimate batteries - if (energyStored != energyContainer.getEnergyStored() || - energyCapability != energyContainer.getEnergyCapacity()) { - energyStored = energyContainer.getEnergyStored(); - energyCapability = energyContainer.getEnergyCapacity(); + if (getCoverableView() instanceof MetaTileEntityPowerSubstation pss) { + if (energyStored != pss.getStoredLong() || energyCapability != pss.getCapacityLong()) { + energyStored = pss.getStoredLong(); + energyCapability = pss.getCapacityLong(); writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { packetBuffer.writeLong(energyStored); packetBuffer.writeLong(energyCapability); }); } - if (this.getOffsetTimer() % 20 == 0) { // per second + if (this.getOffsetTimer() % 20 == 0) { writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { - packetBuffer.writeLong(energyContainer.getInputPerSec()); - packetBuffer.writeLong(energyContainer.getOutputPerSec()); + packetBuffer.writeLong(pss.getAverageInLastSec() * 20L); + packetBuffer.writeLong(pss.getAverageOutLastSec() * 20L); inputEnergyList.add(energyInputPerDur); outputEnergyList.add(energyOutputPerDur); if (inputEnergyList.size() > 13) { @@ -603,6 +601,33 @@ private void syncAllInfo() { } }); } + } else { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + // TODO, figure out what to do when values exceed Long.MAX_VALUE, ie with multiple Ultimate + // batteries + if (energyStored != energyContainer.getEnergyStored() || + energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + if (this.getOffsetTimer() % 20 == 0) { // per second + writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { + packetBuffer.writeLong(energyContainer.getInputPerSec()); + packetBuffer.writeLong(energyContainer.getOutputPerSec()); + inputEnergyList.add(energyInputPerDur); + outputEnergyList.add(energyOutputPerDur); + if (inputEnergyList.size() > 13) { + inputEnergyList.remove(0); + outputEnergyList.remove(0); + } + }); + } + } } } if (this.mode == MODE.MACHINE || (mode == MODE.PROXY && proxyMode[3] > 0)) { @@ -626,17 +651,28 @@ private void syncAllInfo() { }); } if (this.getOffsetTimer() % 20 == 0) { - IEnergyContainer energyContainer = this.getEnergyCapability(); - if (energyContainer != null) { - if (energyStored != energyContainer.getEnergyStored() || - energyCapability != energyContainer.getEnergyCapacity()) { - energyStored = energyContainer.getEnergyStored(); - energyCapability = energyContainer.getEnergyCapacity(); + if (getCoverableView() instanceof MetaTileEntityPowerSubstation pss) { + if (energyStored != pss.getStoredLong() || energyCapability != pss.getCapacityLong()) { + energyStored = pss.getStoredLong(); + energyCapability = pss.getCapacityLong(); writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { packetBuffer.writeLong(energyStored); packetBuffer.writeLong(energyCapability); }); } + } else { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + if (energyStored != energyContainer.getEnergyStored() || + energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + } } } } @@ -861,6 +897,7 @@ public boolean canCapabilityAttach() { return getFluidCapability() != null || getItemCapability() != null || getEnergyCapability() != null || + getCoverableView() instanceof MetaTileEntityPowerSubstation || getMachineCapability() != null; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java index a5d37f33c41..46bcafb51d5 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java @@ -202,20 +202,69 @@ private void updateProxyPlugin() { } public int getX() { - if (this.getController() != null) { - if (this.getController().getPos().getX() - this.getPos().getX() != 0) { - return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; - } else { - return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + MultiblockControllerBase controller = this.getController(); + if (controller != null) { + EnumFacing spin = controller.getUpwardsFacing(); + switch (controller.getFrontFacing().getAxis()) { + case Y -> { + if (spin.getAxis() == EnumFacing.Axis.X) + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + else + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + } + case X -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + else + return Math.abs(this.getController().getPos().getY() - this.getPos().getY()) - 1; + } + default -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + else + return Math.abs(this.getController().getPos().getY() - this.getPos().getY()) - 1; + } } } return -1; } public int getY() { - if (this.getController() != null) { - return ((MetaTileEntityCentralMonitor) this.getController()).height - - (this.getPos().getY() + 1 - this.getController().getPos().getY()) - 1; + MultiblockControllerBase controller = this.getController(); + if (controller != null) { + EnumFacing spin = controller.getUpwardsFacing(); + EnumFacing facing = controller.getFrontFacing(); + int height = ((MetaTileEntityCentralMonitor) this.getController()).height; + switch (facing.getAxis()) { + case Y -> { + if (spin.getAxis() == EnumFacing.Axis.X) + return height - + (Math.abs(controller.getPos().getX() - spin.getXOffset() - this.getPos().getX())) - 1; + else + return height - + (Math.abs(controller.getPos().getZ() - spin.getZOffset() - this.getPos().getZ())) - 1; + } + case X -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return height - + (Math.abs(controller.getPos().getY() + spin.getZOffset() - this.getPos().getY())) - 1; + else + return height - (Math.abs( + controller.getPos().getZ() + spin.getXOffset() * facing.rotateY().getZOffset() - + this.getPos().getZ())) - + 1; + } + default -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return height - + (Math.abs(controller.getPos().getY() + spin.getZOffset() - this.getPos().getY())) - 1; + else + return height - (Math.abs( + controller.getPos().getX() + spin.getXOffset() * facing.rotateY().getXOffset() - + this.getPos().getX())) - + 1; + } + } } return -1; } From 77ed2e04876c133c8d09ac42ef8a46922c9bd6a2 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Sun, 10 Mar 2024 17:23:35 -0500 Subject: [PATCH 84/98] Fix server crashes with alarms (#2411) --- .../electric/MetaTileEntityAlarm.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java index cadf9768286..67751f893e9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java @@ -76,15 +76,17 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { return ModularUI.builder(GuiTextures.BACKGROUND, 240, 86) .widget(new LabelWidget(10, 5, getMetaFullName())) .widget(new SelectorWidget(10, 20, 220, 20, - getSounds().stream().map((event) -> event.getSoundName().toString()) + getSounds().stream().map(this::getNameOfSound) .collect(Collectors.toList()), - 0x555555, () -> this.selectedSound.getSoundName().toString(), true).setOnChanged((v) -> { - GregTechAPI.soundManager.stopTileSound(getPos()); + 0x555555, () -> getNameOfSound(this.selectedSound), true).setOnChanged((v) -> { + if (this.getWorld().isRemote) + GregTechAPI.soundManager.stopTileSound(getPos()); SoundEvent newSound = SoundEvent.REGISTRY.getObject(new ResourceLocation(v)); if (this.selectedSound != newSound) { this.selectedSound = SoundEvent.REGISTRY.getObject(new ResourceLocation(v)); this.writeCustomData(GregtechDataCodes.UPDATE_SOUND, - (writer) -> writer.writeResourceLocation(this.selectedSound.getSoundName())); + (writer) -> writer + .writeResourceLocation(getResourceLocationOfSound(this.selectedSound))); } })) .widget(new ImageWidget(10, 54, 220, 20, GuiTextures.DISPLAY)) @@ -168,14 +170,14 @@ public void receiveInitialSyncData(PacketBuffer buf) { public void writeInitialSyncData(PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeBoolean(this.isActive); - buf.writeResourceLocation(this.selectedSound.getSoundName()); + buf.writeResourceLocation(getResourceLocationOfSound(this.selectedSound)); buf.writeInt(this.radius); } @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean("isActive", this.isActive); - data.setString("selectedSound", this.selectedSound.getSoundName().toString()); + data.setString("selectedSound", getNameOfSound(this.selectedSound)); data.setInteger("radius", this.radius); return super.writeToNBT(data); } @@ -187,4 +189,12 @@ public void readFromNBT(NBTTagCompound data) { this.radius = data.getInteger("radius"); super.readFromNBT(data); } + + public String getNameOfSound(SoundEvent sound) { + return getResourceLocationOfSound(sound).toString(); + } + + public ResourceLocation getResourceLocationOfSound(SoundEvent sound) { + return SoundEvent.REGISTRY.getNameForObject(sound); + } } From e85169eb34a849d1b56514d4b090cda9080b5bfe Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:21:43 -0400 Subject: [PATCH 85/98] fix pipe capability retrieval logic (#2415) --- .../api/pipenet/tile/TileEntityPipeBase.java | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index 84897a022e8..7d4fc9015ef 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -335,24 +335,28 @@ public T getCapabilityInternal(Capability capability, @Nullable EnumFacin @Nullable @Override public final T getCapability(@NotNull Capability capability, @Nullable EnumFacing facing) { - boolean isCoverable = capability == GregtechTileCapabilities.CAPABILITY_COVER_HOLDER; - Cover cover = facing == null ? null : coverableImplementation.getCoverAtSide(facing); - T defaultValue; - if (getPipeBlock() == null) - defaultValue = null; - else - defaultValue = getCapabilityInternal(capability, facing); + T pipeCapability = getPipeBlock() == null ? null : getCapabilityInternal(capability, facing); - if (isCoverable) { - return defaultValue; + if (capability == GregtechTileCapabilities.CAPABILITY_COVER_HOLDER) { + return pipeCapability; } - if (cover == null && facing != null) { - return isConnected(facing) ? defaultValue : null; + + Cover cover = facing == null ? null : coverableImplementation.getCoverAtSide(facing); + if (cover == null) { + if (facing == null || isConnected(facing)) { + return pipeCapability; + } + return null; } - if (cover != null) { - return cover.getCapability(capability, defaultValue); + + T coverCapability = cover.getCapability(capability, pipeCapability); + if (coverCapability == pipeCapability) { + if (isConnected(facing)) { + return pipeCapability; + } + return null; } - return defaultValue; + return coverCapability; } @Override From fea6440e9852c1e44a88332b568981d2d19c3b7b Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:21:58 -0400 Subject: [PATCH 86/98] fix solar panels not outputting to cables (#2416) --- src/main/java/gregtech/common/covers/CoverSolarPanel.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/covers/CoverSolarPanel.java b/src/main/java/gregtech/common/covers/CoverSolarPanel.java index 7e2e750439a..e972ef560ad 100644 --- a/src/main/java/gregtech/common/covers/CoverSolarPanel.java +++ b/src/main/java/gregtech/common/covers/CoverSolarPanel.java @@ -13,7 +13,6 @@ import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -50,10 +49,9 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra public void update() { CoverableView coverable = getCoverableView(); World world = coverable.getWorld(); - BlockPos blockPos = coverable.getPos(); - if (GTUtility.canSeeSunClearly(world, blockPos)) { + if (GTUtility.canSeeSunClearly(world, coverable.getPos())) { IEnergyContainer energyContainer = coverable.getCapability(GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, - null); + getAttachedSide()); if (energyContainer != null) { energyContainer.acceptEnergyFromNetwork(null, EUt, 1); } From dc389f8f66475dd741ac96138f926e7f94cb0f70 Mon Sep 17 00:00:00 2001 From: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Sun, 17 Mar 2024 17:12:12 +0100 Subject: [PATCH 87/98] Update GroovyScript & improve material API for groovy (#2389) --- dependencies.gradle | 2 +- .../material/properties/BlastProperty.java | 14 +++-- .../material/CTMaterialHelpers.java | 5 +- .../integration/groovy/GroovyExpansions.java | 42 ++++++++++++++ .../GroovyMaterialBuilderExpansion.java | 36 ++++++++---- .../groovy/GroovyRecipeBuilderExpansion.java | 16 ----- .../groovy/GroovyScriptModule.java | 58 ++++++++++++++++++- 7 files changed, 136 insertions(+), 37 deletions(-) create mode 100644 src/main/java/gregtech/integration/groovy/GroovyExpansions.java delete mode 100644 src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java diff --git a/dependencies.gradle b/dependencies.gradle index 7f2d35d408a..445b5e3963b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -41,7 +41,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") api("com.cleanroommc:modularui:2.4.1") { transitive = false } - api("com.cleanroommc:groovyscript:0.7.3") { transitive = false } + api("com.cleanroommc:groovyscript:0.8.0") { transitive = false } api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684") api rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 diff --git a/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java b/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java index 172e0981ac7..61670ea18f9 100644 --- a/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java @@ -1,17 +1,18 @@ package gregtech.api.unification.material.properties; +import gregtech.integration.groovy.GroovyScriptModule; + import crafttweaker.CraftTweakerAPI; import org.jetbrains.annotations.NotNull; public class BlastProperty implements IMaterialProperty { /** - * Blast Furnace Temperature of this Material. - * If below 1000K, Primitive Blast Furnace recipes will be also added. + * Blast Furnace Temperature of this Material. If below 1000K, Primitive Blast Furnace recipes will be also added. * If above 1750K, a Hot Ingot and its Vacuum Freezer recipe will be also added. *

- * If a Material with this Property has a Fluid, its temperature - * will be set to this if it is the default Fluid temperature. + * If a Material with this Property has a Fluid, its temperature will be set to this if it is the default Fluid + * temperature. */ private int blastTemperature; @@ -132,7 +133,10 @@ public void verifyProperty(MaterialProperties properties) { public static GasTier validateGasTier(String gasTierName) { if (gasTierName == null) return null; - else if ("LOW".equalsIgnoreCase(gasTierName)) return GasTier.LOW; + if (GroovyScriptModule.isCurrentlyRunning()) { + return GroovyScriptModule.parseAndValidateEnumValue(GasTier.class, gasTierName, "gas tier"); + } + if ("LOW".equalsIgnoreCase(gasTierName)) return GasTier.LOW; else if ("MID".equalsIgnoreCase(gasTierName)) return GasTier.MID; else if ("HIGH".equalsIgnoreCase(gasTierName)) return GasTier.HIGH; else if ("HIGHER".equalsIgnoreCase(gasTierName)) return GasTier.HIGHER; diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java index ca5d08a1efa..ed66c077a40 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java @@ -4,6 +4,7 @@ import gregtech.api.fluids.FluidState; import gregtech.api.unification.material.Material; import gregtech.api.unification.stack.MaterialStack; +import gregtech.integration.groovy.GroovyScriptModule; import com.google.common.collect.ImmutableList; import crafttweaker.CraftTweakerAPI; @@ -17,7 +18,9 @@ protected static ImmutableList validateComponentList(MaterialStac protected static FluidState validateFluidState(String fluidTypeName) { if (fluidTypeName == null || fluidTypeName.equals("fluid")) return FluidState.LIQUID; - + if (GroovyScriptModule.isCurrentlyRunning()) { + return GroovyScriptModule.parseAndValidateEnumValue(FluidState.class, fluidTypeName, "fluid type"); + } if (fluidTypeName.equals("liquid")) return FluidState.LIQUID; if (fluidTypeName.equals("gas")) return FluidState.GAS; if (fluidTypeName.equals("plasma")) return FluidState.PLASMA; diff --git a/src/main/java/gregtech/integration/groovy/GroovyExpansions.java b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java new file mode 100644 index 00000000000..8c23fdf270f --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java @@ -0,0 +1,42 @@ +package gregtech.integration.groovy; + +import gregtech.api.recipes.RecipeBuilder; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.event.MaterialEvent; + +import net.minecraft.util.ResourceLocation; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; + +public class GroovyExpansions { + + public static > RecipeBuilder property(RecipeBuilder builder, String key, + Object value) { + if (!builder.applyProperty(key, value)) { + GroovyLog.get().error("Failed to add property '{}' with '{}' to recipe", key, value); + } + return builder; + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, ResourceLocation resourceLocation) { + return new Material.Builder(id, resourceLocation); + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, String domain, String path) { + return materialBuilder(event, id, domain, path); + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, String s) { + String domain, path; + if (s.contains(":")) { + String[] parts = s.split(":", 2); + domain = parts[0]; + path = parts[1]; + } else { + domain = GroovyScript.getRunConfig().getPackId(); + path = s; + } + return materialBuilder(event, id, new ResourceLocation(domain, path)); + } +} diff --git a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java index 3f5ea4873f4..f4e30273435 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java +++ b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java @@ -8,9 +8,13 @@ import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.stack.MaterialStack; import net.minecraft.util.ResourceLocation; +import com.cleanroommc.groovyscript.api.GroovyLog; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + import java.util.ArrayList; import java.util.List; @@ -85,22 +89,30 @@ public static Material.Builder blastTemp(Material.Builder builder, int temp, Str public static Material.Builder blastTemp(Material.Builder builder, int temp, String raw, int eutOverride, int durationOverride, int vacuumEUtOverride, int vacuumDurationOverride) { - BlastProperty.GasTier gasTier = null; - String name = raw.toUpperCase(); - for (BlastProperty.GasTier gasTier1 : BlastProperty.GasTier.VALUES) { - if (gasTier1.name().equals(name)) { - gasTier = gasTier1; - break; - } - } - final BlastProperty.GasTier finalGasTier = gasTier; - if (GroovyScriptModule.validateNonNull(gasTier, () -> "Can't find gas tier for " + name + - " in material builder. Valid values are 'low', 'mid', 'high', 'higher', 'highest'!")) { + BlastProperty.GasTier gasTier = GroovyScriptModule.parseAndValidateEnumValue(BlastProperty.GasTier.class, raw, + "gas tier"); + if (gasTier != null) { return builder.blast(b -> b - .temp(temp, finalGasTier) + .temp(temp, gasTier) .blastStats(eutOverride, durationOverride) .vacuumStats(vacuumEUtOverride, vacuumDurationOverride)); } return builder; } + + public static Material.Builder components(Material.Builder builder, Object... objects) { + ObjectArrayList materialStacks = new ObjectArrayList<>(); + for (Object o : objects) { + if (o instanceof MaterialStack materialStack) { + materialStacks.add(materialStack); + } else if (o instanceof Material material) { + materialStacks.add(new MaterialStack(material, 1)); + } else { + GroovyLog.get() + .error("Material components must be of type Material or MaterialStack, but was of type {}", + o == null ? null : o.getClass()); + } + } + return builder.components(materialStacks.toArray(new MaterialStack[0])); + } } diff --git a/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java deleted file mode 100644 index 90a0dc3753b..00000000000 --- a/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java +++ /dev/null @@ -1,16 +0,0 @@ -package gregtech.integration.groovy; - -import gregtech.api.recipes.RecipeBuilder; - -import com.cleanroommc.groovyscript.api.GroovyLog; - -public class GroovyRecipeBuilderExpansion { - - public static > RecipeBuilder property(RecipeBuilder builder, String key, - Object value) { - if (!builder.applyProperty(key, value)) { - GroovyLog.get().error("Failed to add property '{}' with '{}' to recipe", key, value); - } - return builder; - } -} diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index b6b603bb07e..571261241b2 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -8,6 +8,8 @@ import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.event.PostMaterialEvent; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.Mods; @@ -35,13 +37,20 @@ import com.cleanroommc.groovyscript.api.GroovyPlugin; import com.cleanroommc.groovyscript.api.IGameObjectHandler; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.event.EventBusType; +import com.cleanroommc.groovyscript.event.GroovyEventManager; import com.cleanroommc.groovyscript.gameobjects.GameObjectHandlerManager; +import com.cleanroommc.groovyscript.helper.EnumHelper; +import com.cleanroommc.groovyscript.sandbox.LoadStage; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; import com.google.common.collect.ImmutableList; +import groovy.lang.Closure; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; @@ -77,6 +86,18 @@ public static boolean isCurrentlyRunning() { GroovyScript.getSandbox().isRunning(); } + public static > T parseAndValidateEnumValue(Class clazz, String raw, String type) { + T t = EnumHelper.valueOfNullable(clazz, raw, false); + if (t == null) { + GroovyLog.get().error("Can't find {} for {} in material builder. Valid values are {};", + type, + raw, + Arrays.toString(clazz.getEnumConstants())); + return null; + } + return t; + } + public static GroovyContainer getInstance() { return modSupportContainer; } @@ -191,10 +212,42 @@ public static void loadMetaItemBracketHandler() { } @Override - public @NotNull String getModName() { + public @NotNull String getContainerName() { return "GregTech"; } + @Override + public @Nullable ModPropertyContainer createModPropertyContainer() { + return new ModPropertyContainer() { + + public void materialEvent(EventPriority priority, Closure eventListener) { + if (isCurrentlyRunning() && GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + GroovyEventManager.INSTANCE.listen(priority, EventBusType.FORGE, MaterialEvent.class, + eventListener); + } + + public void materialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } + + public void lateMaterialEvent(EventPriority priority, Closure eventListener) { + if (isCurrentlyRunning() && GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + GroovyEventManager.INSTANCE.listen(priority, EventBusType.FORGE, PostMaterialEvent.class, + eventListener); + } + + public void lateMaterialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } + }; + } + @Override public void onCompatLoaded(GroovyContainer groovyContainer) { modSupportContainer = groovyContainer; @@ -213,6 +266,7 @@ public void onCompatLoaded(GroovyContainer groovyContainer) { ExpansionHelper.mixinClass(Material.class, MaterialExpansion.class); ExpansionHelper.mixinClass(Material.class, MaterialPropertyExpansion.class); ExpansionHelper.mixinClass(Material.Builder.class, GroovyMaterialBuilderExpansion.class); - ExpansionHelper.mixinClass(RecipeBuilder.class, GroovyRecipeBuilderExpansion.class); + ExpansionHelper.mixinMethod(RecipeBuilder.class, GroovyExpansions.class, "property"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "materialBuilder"); } } From c2f681f69f7b61c76e4b113263474133993ad056 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sun, 24 Mar 2024 10:41:14 -0400 Subject: [PATCH 88/98] allow SMD diodes in low tier diode block recipes (#2423) --- .../java/gregtech/loaders/recipe/MetaTileEntityLoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java index 9cb0e321a0e..192c35d1d16 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java @@ -898,7 +898,8 @@ public static void init() { ROTOR); registerMachineRecipe(ArrayUtils.subarray(MetaTileEntities.DIODES, GTValues.ULV, GTValues.HV), "CDC", "DHD", - "PDP", 'H', HULL, 'D', MetaItems.DIODE, 'P', PLATE, 'C', CABLE_QUAD); + "PDP", 'H', HULL, 'D', new UnificationEntry(OrePrefix.component, MarkerMaterials.Component.Diode), 'P', + PLATE, 'C', CABLE_QUAD); registerMachineRecipe(ArrayUtils.subarray(MetaTileEntities.DIODES, GTValues.HV, GTValues.LuV), "CDC", "DHD", "PDP", 'H', HULL, 'D', MetaItems.SMD_DIODE, 'P', PLATE, 'C', CABLE_QUAD); registerMachineRecipe( From ba69a484403b01e3d87703546c582b61bfe0d596 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sun, 24 Mar 2024 22:10:19 -0400 Subject: [PATCH 89/98] check for a valid MTE before rendering (#2424) --- .../client/renderer/handler/MetaTileEntityRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java index 846bcc08860..8e0fe1f6962 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java @@ -94,7 +94,7 @@ public void renderItem(ItemStack rawStack, TransformType transformType) { @Override public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, BufferBuilder buffer) { MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(world, pos); - if (metaTileEntity == null) { + if (metaTileEntity == null || !metaTileEntity.isValid()) { return false; } CCRenderState renderState = CCRenderState.instance(); From 20e61ca2cac5bde02d56827e7a019aa21cb69f5a Mon Sep 17 00:00:00 2001 From: froot <66188216+kumquat-ir@users.noreply.github.com> Date: Wed, 27 Mar 2024 00:16:28 -0700 Subject: [PATCH 90/98] Fix link to GT IMPACT in readme (#2427) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5876b6d1b60..8a4fcfa7209 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Anything else? Sure come to [Discord](https://discord.gg/bWSWuYvURP). ## Credited Works Heating Coil Textures, Wooden Forms, World Accelerators, and the Extreme Combustion Engine are from the **[GregTech: New Horizons Modpack](https://www.curseforge.com/minecraft/modpacks/gt-new-horizons)**. -Primitive Water Pump and Super Tank GUI Textures are from the **[IMPACT: GREGTECH EDITION Modpack](https://gtimpact.space/)**. +Primitive Water Pump and Super Tank GUI Textures are from the **[IMPACT: GREGTECH EDITION Modpack](https://gt-impact.github.io/)**. Ender Fluid Link Cover, Auto-Maintenance Hatch, Optical Fiber, and Data Bank Textures are from **[TecTech](https://github.com/Technus/TecTech)**. From ad8275f17f3f735867f65ed40ec5c09b76d4309b Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:16:49 -0600 Subject: [PATCH 91/98] Fix fluid drilling rig display units (#2417) --- .../multi/electric/MetaTileEntityFluidDrill.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java index a1501dd6f65..dca07a39e5f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java @@ -184,7 +184,7 @@ protected void addDisplayText(List textList) { TextFormatting.BLUE, TextFormattingUtil.formatNumbers( minerLogic.getFluidToProduce() * 20L / FluidDrillLogic.MAX_PROGRESS) + - " L/t"); + " L/s"); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, "gregtech.multiblock.fluid_rig.fluid_amount", From db02d99d491e35d00740e338e1feda5046ca7458 Mon Sep 17 00:00:00 2001 From: iouter <62897714+iouter@users.noreply.github.com> Date: Wed, 27 Mar 2024 15:17:15 +0800 Subject: [PATCH 92/98] Update zh_cn.lang (#2413) --- .../resources/assets/gregtech/lang/zh_cn.lang | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang index 60613d04a2c..67437657210 100644 --- a/src/main/resources/assets/gregtech/lang/zh_cn.lang +++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang @@ -112,7 +112,7 @@ gregtech.waila.progress_computation=计算进度:%s / %s gregtech.multiblock.title=多方块结构 gregtech.multiblock.primitive_blast_furnace.bronze.description=土高炉是(PBF)是个多方块结构。尽管它不是很快,却能在游戏前期为你的发展提供钢材。 -gregtech.multiblock.coke_oven.description=焦炉是个多方块结构,用于在早期生产焦炭和杂酚油。无需燃料即可工作,内部至多可容纳32桶杂酚油。其存储可通过焦炉仓进行访问。 +gregtech.multiblock.coke_oven.description=焦炉是一种多方块结构,用于在早期生产焦煤和杂酚油,无需燃料即可工作,内部至多可容纳 32 桶杂酚油。其存储可通过焦炉仓进行访问。 gregtech.multiblock.vacuum_freezer.description=真空冷冻机是个多方块结构,主要用于热锭冷却。此外,它还可以冻结水等其他物质。 gregtech.multiblock.implosion_compressor.description=聚爆压缩机是个多方块结构,能够借助炸药将宝石粉转化为相应的宝石。 gregtech.multiblock.pyrolyse_oven.description=热解炉是种用于将原木处理为木炭、杂酚油、灰烬或重油的多方块结构。 @@ -852,7 +852,7 @@ metaitem.cover.item.voiding.advanced.tooltip=作§f覆盖板§7时允许按数 metaitem.cover.storage.name=存储覆盖板 metaitem.cover.storage.tooltip=给零碎的小玩意准备的小型存储空间 metaitem.cover.maintenance.detector.name=维护需求覆盖板 -metaitem.cover.maintenance.detector.tooltip=作§f覆盖板§7时在机器§f需要维护§7输出红石信号。 +metaitem.cover.maintenance.detector.tooltip=作§f覆盖板§7时在机器§f需要维护§7时发出红石信号。 metaitem.cover.facade.name=%s伪装板 metaitem.cover.facade.tooltip=可作为§f覆盖板§7加装装饰性套壳。 @@ -1008,6 +1008,9 @@ item.gt.tool.screwdriver_lv.name=%s螺丝刀(LV) item.gt.tool.screwdriver_lv.tooltip=§8调整覆盖板和机器 item.gt.tool.plunger.name=%s搋子 item.gt.tool.plunger.tooltip=§8从机器中抽除流体 +item.gt.tool.wire_cutter_lv.name=%s剪线钳(LV) +item.gt.tool.wire_cutter_hv.name=%s剪线钳(HV) +item.gt.tool.wire_cutter_iv.name=%s剪线钳(IV) item.gt.tool.tooltip.crafting_uses=§a合成耐久度:%s @@ -2348,6 +2351,17 @@ tile.treated_wood_fence.name=防腐木栅栏 tile.rubber_wood_fence_gate.name=橡胶木栅栏门 tile.treated_wood_fence_gate.name=防腐木栅栏门 +tile.gt_explosive.breaking_tooltip=破坏它会引爆火药,潜行挖掘以重新拾取 +tile.gt_explosive.lighting_tooltip=无法用红石信号引爆 + +tile.powderbarrel.name=火药桶 +tile.powderbarrel.drops_tooltip=爆炸范围略大于TNT,所有被摧毁的方块都会掉落 +entity.Powderbarrel.name=火药桶 + +tile.itnt.name=工业TNT +tile.itnt.drops_tooltip=爆炸范围比TNT大得多,所有被摧毁的方块都会掉落 +entity.ITNT.name=工业TNT + tile.brittle_charcoal.name=脆木炭块 tile.brittle_charcoal.tooltip.1=产自木炭堆点火器。 tile.brittle_charcoal.tooltip.2=采掘可掉落木炭。 @@ -4405,7 +4419,7 @@ gregtech.machine.world_accelerator.zpm.name=精英世界加速器 III gregtech.machine.world_accelerator.zpm.tooltip=“时间之§m瓶§r”§7方块 gregtech.machine.world_accelerator.uv.name=终极世界加速器 gregtech.machine.world_accelerator.uv.tooltip=时间扭曲者 -gregtech.machine.world_accelerator.description=使用§f螺丝刀§7在§f方块实体§r或§f随机刻§7模式中切换。 +gregtech.machine.world_accelerator.description=使用§f螺丝刀§7在§f方块实体§7或§f随机刻§7模式中切换。 gregtech.machine.world_accelerator.power_usage=§7在随机刻模式下最多使用§f%dA,§7在方块实体模式下最多使用§f%dA 。 gregtech.machine.world_accelerator.acceleration=§d加速倍率: §f%dx gregtech.machine.world_accelerator.working_area=§b作用范围: @@ -5243,15 +5257,27 @@ gregtech.machine.laser_hatch.tooltip2=§c激光传导线缆必须直线摆放! gregtech.machine.fluid_tank.max_multiblock=多方块结构最大尺寸:%,dx%,dx%,d gregtech.machine.fluid_tank.fluid=含有%s mB%s -gregtech.machine.me_export_fluid_hatch.name=ME输出仓 +# ME Parts +gregtech.machine.me_import_item_bus.name=ME输入总线 +gregtech.machine.me.item_import.tooltip=从ME网络提取指定物品 +gregtech.machine.me_stocking_item_bus.name=ME库存输入总线 +gregtech.machine.me.stocking_item.tooltip=直接从ME网络抽取物品 +gregtech.machine.me.stocking_item.tooltip.2=ME自动拉取模式将自动标记ME网络中的前16种物品,每5秒更新一次。 +gregtech.machine.me_import_item_hatch.configs.tooltip=可标记16种物品 +gregtech.machine.me_import_fluid_hatch.name=ME输入仓 +gregtech.machine.me.fluid_import.tooltip=从ME网络提取指定流体 +gregtech.machine.me_stocking_fluid_hatch.name=ME库存输入仓 +gregtech.machine.me.stocking_fluid.tooltip=直接从ME网络抽取流体 +gregtech.machine.me.stocking_fluid.tooltip.2=ME自动拉取模式将自动标记ME网络中的前16种流体,每5秒更新一次。 +gregtech.machine.me_import_fluid_hatch.configs.tooltip=可标记16种流体 gregtech.machine.me_export_item_bus.name=ME输出总线 -gregtech.machine.me_import_fluid_hatch.name=ME库存输入仓 -gregtech.machine.me_import_item_bus.name=ME库存输入总线 -gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中。 -gregtech.machine.me.item_export.tooltip=将物品直接存储到ME网络中。 -gregtech.machine.me.fluid_import.tooltip=自动从ME网络获取流体。 -gregtech.machine.me.item_import.tooltip=自动从ME网络获取物品。 -gregtech.machine.me.export.tooltip=在连接到ME网络之前,它具有无限容量。 +gregtech.machine.me.item_export.tooltip=将物品直接存储到ME网络中 +gregtech.machine.me.item_export.tooltip.2=可以缓存无限数量的物品 +gregtech.machine.me_export_fluid_hatch.name=ME输出仓 +gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中 +gregtech.machine.me.fluid_export.tooltip.2=可以缓存无限数量的流体 +gregtech.machine.me.stocking_auto_pull_enabled=ME自动拉取已启用 +gregtech.machine.me.stocking_auto_pull_disabled=ME自动拉取已禁用 # Universal tooltips gregtech.universal.tooltip.voltage_in=§a输入电压:§f%,d EU/t(%s§f) @@ -5274,7 +5300,7 @@ gregtech.universal.tooltip.item_stored=§d内含物品:§f%2$,d + %3$,d 个%1$ gregtech.universal.tooltip.item_transfer_rate=§b传输速率:§f%,d件物品/s gregtech.universal.tooltip.item_transfer_rate_stacks=§b传输速率:§f%,d组物品/s gregtech.universal.tooltip.fluid_storage_capacity=§9流体容量:§f%,d L -gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:§r共§f%d§7个流体槽,每个§f%dL§7 +gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:§7共§f%d§7个流体槽,每个§f%dL§7 gregtech.universal.tooltip.fluid_stored=§d内含流体:§f%2$,d L %1$s gregtech.universal.tooltip.fluid_transfer_rate=§b传输速率:§f%,d L/t gregtech.universal.tooltip.parallel=§d最大并行:§f%d @@ -5392,8 +5418,12 @@ gregtech.gui.me_network.offline=网络状态:§4离线§r gregtech.gui.waiting_list=发送队列: gregtech.gui.config_slot=§f配置槽位§r gregtech.gui.config_slot.set=§7点击§b设置/选择§7配置槽位。§r +gregtech.gui.config_slot.set_only=§7点击§b设置§7配置槽位。§r gregtech.gui.config_slot.scroll=§7使用滚轮§a切换§7配置数。§r gregtech.gui.config_slot.remove=§7右击§4清除§7配置槽位。§r +gregtech.gui.config_slot.auto_pull_managed=§4禁用:§7由ME自动拉取管理 +gregtech.gui.me_bus.extra_slot=额外槽位/n§7在这里放置配方的额外物品,例如模具或透镜 +gregtech.gui.me_bus.auto_pull_button=单击以切换ME自动拉取模式 gregtech.gui.alarm.radius=半径: From bf9ce4d91b60643f2579b698e3414c119ecdc7a4 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:08:03 -0600 Subject: [PATCH 93/98] Generify DimensionProperty (#2414) --- .../capability/impl/AbstractRecipeLogic.java | 9 +- .../gregtech/api/recipes/RecipeBuilder.java | 50 ++++++++++- .../java/gregtech/api/recipes/RecipeMaps.java | 5 +- .../builders/GasCollectorRecipeBuilder.java | 82 ----------------- .../recipeproperties/DimensionProperty.java | 87 +++++++++++++++++++ .../GasCollectorDimensionProperty.java | 48 ---------- .../electric/MetaTileEntityGasCollector.java | 31 +------ .../resources/assets/gregtech/lang/en_us.lang | 1 + 8 files changed, 148 insertions(+), 165 deletions(-) delete mode 100644 src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java create mode 100644 src/main/java/gregtech/api/recipes/recipeproperties/DimensionProperty.java delete mode 100644 src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index ce4eab33ac9..6d8877ff1dc 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -16,6 +16,7 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.logic.IParallelableRecipeLogic; import gregtech.api.recipes.recipeproperties.CleanroomProperty; +import gregtech.api.recipes.recipeproperties.DimensionProperty; import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; @@ -407,7 +408,7 @@ protected boolean checkPreviousRecipe() { * @return true if the recipe is allowed to be used, else false */ public boolean checkRecipe(@NotNull Recipe recipe) { - return checkCleanroomRequirement(recipe); + return checkCleanroomRequirement(recipe) && checkDimensionRequirement(recipe); } /** @@ -431,6 +432,12 @@ protected boolean checkCleanroomRequirement(@NotNull Recipe recipe) { return false; } + protected boolean checkDimensionRequirement(@NotNull Recipe recipe) { + if (!recipe.hasProperty(DimensionProperty.getInstance())) return true; + return recipe.getProperty(DimensionProperty.getInstance(), DimensionProperty.DimensionPropertyList.EMPTY_LIST) + .checkDimension(this.getMetaTileEntity().getWorld().provider.getDimension()); + } + /** * Prepares the recipe to be run. *

    diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index 87175224c5d..1b59129381a 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -13,6 +13,7 @@ import gregtech.api.recipes.ingredients.nbtmatch.NBTCondition; import gregtech.api.recipes.ingredients.nbtmatch.NBTMatcher; import gregtech.api.recipes.recipeproperties.CleanroomProperty; +import gregtech.api.recipes.recipeproperties.DimensionProperty; import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; import gregtech.api.recipes.recipeproperties.RecipeProperty; import gregtech.api.recipes.recipeproperties.RecipePropertyStorage; @@ -39,6 +40,8 @@ import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; import crafttweaker.CraftTweakerAPI; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntLists; import org.apache.commons.lang3.builder.ToStringBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -137,8 +140,51 @@ public R cleanroom(@Nullable CleanroomType cleanroom) { return (R) this; } + public R dimension(int dimensionID) { + return dimension(dimensionID, false); + } + + public R dimension(int dimensionID, boolean toBlackList) { + DimensionProperty.DimensionPropertyList dimensionIDs = getCompleteDimensionIDs(); + if (dimensionIDs == DimensionProperty.DimensionPropertyList.EMPTY_LIST) { + dimensionIDs = new DimensionProperty.DimensionPropertyList(); + this.applyProperty(DimensionProperty.getInstance(), dimensionIDs); + } + dimensionIDs.add(dimensionID, toBlackList); + return (R) this; + } + + public DimensionProperty.DimensionPropertyList getCompleteDimensionIDs() { + return this.recipePropertyStorage == null ? DimensionProperty.DimensionPropertyList.EMPTY_LIST : + this.recipePropertyStorage.getRecipePropertyValue(DimensionProperty.getInstance(), + DimensionProperty.DimensionPropertyList.EMPTY_LIST); + } + + public IntList getDimensionIDs() { + return this.recipePropertyStorage == null ? IntLists.EMPTY_LIST : + this.recipePropertyStorage.getRecipePropertyValue(DimensionProperty.getInstance(), + DimensionProperty.DimensionPropertyList.EMPTY_LIST).whiteListDimensions; + } + + public IntList getBlockedDimensionIDs() { + return this.recipePropertyStorage == null ? IntLists.EMPTY_LIST : + this.recipePropertyStorage.getRecipePropertyValue(DimensionProperty.getInstance(), + DimensionProperty.DimensionPropertyList.EMPTY_LIST).whiteListDimensions; + } + public boolean applyProperty(@NotNull String key, @Nullable Object value) { - if (key.equals(CleanroomProperty.KEY)) { + if (key.equals(DimensionProperty.KEY)) { + if (value instanceof DimensionProperty.DimensionPropertyList list) { + DimensionProperty.DimensionPropertyList dimensionIDs = getCompleteDimensionIDs(); + if (dimensionIDs == DimensionProperty.DimensionPropertyList.EMPTY_LIST) { + dimensionIDs = new DimensionProperty.DimensionPropertyList(); + this.applyProperty(DimensionProperty.getInstance(), dimensionIDs); + } + dimensionIDs.merge(list); + return true; + } + return false; + } else if (key.equals(CleanroomProperty.KEY)) { if (value instanceof CleanroomType) { this.cleanroom((CleanroomType) value); } else if (value instanceof String) { @@ -976,6 +1022,8 @@ public String toString() { .append("EUt", EUt) .append("hidden", hidden) .append("cleanroom", getCleanroom()) + .append("dimensions", getDimensionIDs().toString()) + .append("dimensions_blocked", getBlockedDimensionIDs().toString()) .append("recipeStatus", recipeStatus) .toString(); } diff --git a/src/main/java/gregtech/api/recipes/RecipeMaps.java b/src/main/java/gregtech/api/recipes/RecipeMaps.java index e61261ddd09..9cd9547457f 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipes/RecipeMaps.java @@ -11,7 +11,6 @@ import gregtech.api.recipes.builders.ComputationRecipeBuilder; import gregtech.api.recipes.builders.FuelRecipeBuilder; import gregtech.api.recipes.builders.FusionRecipeBuilder; -import gregtech.api.recipes.builders.GasCollectorRecipeBuilder; import gregtech.api.recipes.builders.ImplosionRecipeBuilder; import gregtech.api.recipes.builders.PrimitiveRecipeBuilder; import gregtech.api.recipes.builders.SimpleRecipeBuilder; @@ -982,8 +981,8 @@ public final class RecipeMaps { .build(); @ZenProperty - public static final RecipeMap GAS_COLLECTOR_RECIPES = new RecipeMapBuilder<>( - "gas_collector", new GasCollectorRecipeBuilder()) + public static final RecipeMap GAS_COLLECTOR_RECIPES = new RecipeMapBuilder<>( + "gas_collector", new SimpleRecipeBuilder()) .itemInputs(1) .fluidOutputs(1) .itemSlotOverlay(GuiTextures.INT_CIRCUIT_OVERLAY, false, true) diff --git a/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java deleted file mode 100644 index fe3bb345305..00000000000 --- a/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java +++ /dev/null @@ -1,82 +0,0 @@ -package gregtech.api.recipes.builders; - -import gregtech.api.recipes.Recipe; -import gregtech.api.recipes.RecipeBuilder; -import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.GasCollectorDimensionProperty; - -import crafttweaker.CraftTweakerAPI; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.ints.IntLists; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class GasCollectorRecipeBuilder extends RecipeBuilder { - - public GasCollectorRecipeBuilder() {} - - public GasCollectorRecipeBuilder(Recipe recipe, RecipeMap recipeMap) { - super(recipe, recipeMap); - } - - public GasCollectorRecipeBuilder(RecipeBuilder recipeBuilder) { - super(recipeBuilder); - } - - @Override - public GasCollectorRecipeBuilder copy() { - return new GasCollectorRecipeBuilder(this); - } - - @Override - public boolean applyProperty(@NotNull String key, Object value) { - if (key.equals(GasCollectorDimensionProperty.KEY)) { - if (value instanceof Integer) { - this.dimension((Integer) value); - } else if (value instanceof List && !((List) value).isEmpty() && - ((List) value).get(0) instanceof Integer) { - IntList dimensionIDs = getDimensionIDs(); - if (dimensionIDs == IntLists.EMPTY_LIST) { - dimensionIDs = new IntArrayList(); - this.applyProperty(GasCollectorDimensionProperty.getInstance(), dimensionIDs); - } - dimensionIDs.addAll((List) value); - } else { - if (isCTRecipe) { - CraftTweakerAPI.logError("Dimension for Gas Collector needs to be a Integer"); - return false; - } - throw new IllegalArgumentException("Invalid Dimension Property Type!"); - } - return true; - } - return super.applyProperty(key, value); - } - - public GasCollectorRecipeBuilder dimension(int dimensionID) { - IntList dimensionIDs = getDimensionIDs(); - if (dimensionIDs == IntLists.EMPTY_LIST) { - dimensionIDs = new IntArrayList(); - this.applyProperty(GasCollectorDimensionProperty.getInstance(), dimensionIDs); - } - dimensionIDs.add(dimensionID); - return this; - } - - public IntList getDimensionIDs() { - return this.recipePropertyStorage == null ? IntLists.EMPTY_LIST : - this.recipePropertyStorage.getRecipePropertyValue(GasCollectorDimensionProperty.getInstance(), - IntLists.EMPTY_LIST); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .appendSuper(super.toString()) - .append(GasCollectorDimensionProperty.getInstance().getKey(), getDimensionIDs().toString()) - .toString(); - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/DimensionProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/DimensionProperty.java new file mode 100644 index 00000000000..f233e7cd7f3 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/recipeproperties/DimensionProperty.java @@ -0,0 +1,87 @@ +package gregtech.api.recipes.recipeproperties; + +import gregtech.api.worldgen.config.WorldGenRegistry; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; + +public class DimensionProperty extends RecipeProperty { + + public static final String KEY = "dimension"; + + private static DimensionProperty INSTANCE; + + private DimensionProperty() { + super(KEY, DimensionPropertyList.class); + } + + public static DimensionProperty getInstance() { + if (INSTANCE == null) + INSTANCE = new DimensionProperty(); + return INSTANCE; + } + + @Override + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { + DimensionPropertyList list = castValue(value); + + if (list.whiteListDimensions.size() > 0) + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions", + getDimensionsForRecipe(castValue(value).whiteListDimensions)), x, y, color); + if (list.blackListDimensions.size() > 0) + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions_blocked", + getDimensionsForRecipe(castValue(value).blackListDimensions)), x, y, color); + } + + private static String getDimensionsForRecipe(IntList value) { + Int2ObjectMap dimNames = WorldGenRegistry.getNamedDimensions(); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < value.size(); i++) { + builder.append(dimNames.getOrDefault(value.getInt(i), String.valueOf(value.getInt(i)))); + if (i != value.size() - 1) + builder.append(", "); + } + String str = builder.toString(); + + if (str.length() >= 13) { + str = str.substring(0, 10) + ".."; + } + return str; + } + + // It would've been better to have one list and swap between blacklist and whitelist, but that would've been + // a bit awkward to apply to the property in practice. + public static class DimensionPropertyList { + + public static DimensionPropertyList EMPTY_LIST = new DimensionPropertyList(); + + public IntList whiteListDimensions = new IntArrayList(); + public IntList blackListDimensions = new IntArrayList(); + + public void add(int key, boolean toBlacklist) { + if (toBlacklist) { + blackListDimensions.add(key); + whiteListDimensions.rem(key); + } else { + whiteListDimensions.add(key); + blackListDimensions.rem(key); + } + } + + public void merge(DimensionPropertyList list) { + this.whiteListDimensions.addAll(list.whiteListDimensions); + this.blackListDimensions.addAll(list.blackListDimensions); + } + + public boolean checkDimension(int dim) { + boolean valid = true; + if (this.blackListDimensions.size() > 0) valid = !this.blackListDimensions.contains(dim); + if (this.whiteListDimensions.size() > 0) valid = this.whiteListDimensions.contains(dim); + return valid; + } + } +} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java deleted file mode 100644 index 94bb810e3b1..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java +++ /dev/null @@ -1,48 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import gregtech.api.worldgen.config.WorldGenRegistry; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.IntList; - -public class GasCollectorDimensionProperty extends RecipeProperty { - - public static final String KEY = "dimension"; - - private static GasCollectorDimensionProperty INSTANCE; - - private GasCollectorDimensionProperty() { - super(KEY, IntList.class); - } - - public static GasCollectorDimensionProperty getInstance() { - if (INSTANCE == null) - INSTANCE = new GasCollectorDimensionProperty(); - return INSTANCE; - } - - @Override - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions", - getDimensionsForRecipe(castValue(value))), x, y, color); - } - - private static String getDimensionsForRecipe(IntList value) { - Int2ObjectMap dimNames = WorldGenRegistry.getNamedDimensions(); - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < value.size(); i++) { - builder.append(dimNames.getOrDefault(value.getInt(i), String.valueOf(value.getInt(i)))); - if (i != value.size() - 1) - builder.append(", "); - } - String str = builder.toString(); - - if (str.length() >= 13) { - str = str.substring(0, 10) + ".."; - } - return str; - } -} diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java index 77bdd3b0485..8300d2b5fc9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java @@ -1,24 +1,17 @@ package gregtech.common.metatileentities.electric; -import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.impl.RecipeLogicEnergy; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.SimpleMachineMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.recipes.recipeproperties.GasCollectorDimensionProperty; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import net.minecraft.util.ResourceLocation; -import it.unimi.dsi.fastutil.ints.IntLists; -import org.jetbrains.annotations.NotNull; - import java.util.function.Function; -import java.util.function.Supplier; public class MetaTileEntityGasCollector extends SimpleMachineMetaTileEntity { @@ -36,28 +29,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { @Override protected RecipeLogicEnergy createWorkable(RecipeMap recipeMap) { - return new GasCollectorRecipeLogic(this, recipeMap, () -> energyContainer); - } - - protected boolean checkRecipe(@NotNull Recipe recipe) { - for (int dimension : recipe.getProperty(GasCollectorDimensionProperty.getInstance(), IntLists.EMPTY_LIST)) { - if (dimension == this.getWorld().provider.getDimension()) { - return true; - } - } - return false; - } - - private static class GasCollectorRecipeLogic extends RecipeLogicEnergy { - - public GasCollectorRecipeLogic(MetaTileEntity metaTileEntity, RecipeMap recipeMap, - Supplier energyContainer) { - super(metaTileEntity, recipeMap, energyContainer); - } - - @Override - public boolean checkRecipe(@NotNull Recipe recipe) { - return ((MetaTileEntityGasCollector) metaTileEntity).checkRecipe(recipe) && super.checkRecipe(recipe); - } + return new RecipeLogicEnergy(this, recipeMap, () -> energyContainer); } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 6fc2ebe2f39..42c4c0ac26c 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5337,6 +5337,7 @@ gregtech.recipe.temperature=Temperature: %,dK (%s) gregtech.recipe.explosive=Explosive: %s gregtech.recipe.eu_to_start=Energy To Start: %sEU gregtech.recipe.dimensions=Dimensions: %s +gregtech.recipe.dimensions_blocked=Blocked Dimensions: %s gregtech.recipe.cleanroom=Requires %s gregtech.recipe.cleanroom.display_name=Cleanroom gregtech.recipe.cleanroom_sterile.display_name=Sterile Cleanroom From 111326a1222de0cd03b18f1cd8a73163110f88cc Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Wed, 27 Mar 2024 21:08:12 -0500 Subject: [PATCH 94/98] Allow Data Stick to copy-paste ME bus settings (#2419) --- .../api/capability/IDataStickIntractable.java | 11 ++++ .../api/metatileentity/MetaTileEntity.java | 17 ++++- .../appeng/MetaTileEntityMEInputBus.java | 65 ++++++++++++++++++- .../appeng/MetaTileEntityMEInputHatch.java | 58 ++++++++++++++++- .../appeng/MetaTileEntityMEStockingBus.java | 28 ++++++++ .../appeng/MetaTileEntityMEStockingHatch.java | 26 ++++++++ .../resources/assets/gregtech/lang/en_us.lang | 5 ++ 7 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 src/main/java/gregtech/api/capability/IDataStickIntractable.java diff --git a/src/main/java/gregtech/api/capability/IDataStickIntractable.java b/src/main/java/gregtech/api/capability/IDataStickIntractable.java new file mode 100644 index 00000000000..4b9d36ee6ff --- /dev/null +++ b/src/main/java/gregtech/api/capability/IDataStickIntractable.java @@ -0,0 +1,11 @@ +package gregtech.api.capability; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public interface IDataStickIntractable { + + void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick); + + boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick); +} diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index e1da60cdfbe..a1ca10b2af0 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -6,6 +6,7 @@ import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.impl.AbstractRecipeLogic; import gregtech.api.capability.impl.FluidHandlerProxy; @@ -35,6 +36,7 @@ import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; import gregtech.common.creativetab.GTCreativeTabs; +import gregtech.common.items.MetaItems; import net.minecraft.block.Block; import net.minecraft.block.state.BlockFaceShape; @@ -487,6 +489,12 @@ public final void onCoverLeftClick(EntityPlayer playerIn, CuboidRayTraceResult r public boolean onRightClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { ItemStack heldStack = playerIn.getHeldItem(hand); + if (this instanceof IDataStickIntractable dsi) { + if (MetaItems.TOOL_DATA_STICK.isItemEqual(heldStack) && dsi.onDataStickRightClick(playerIn, heldStack)) { + return true; + } + } + if (!playerIn.isSneaking() && openGUIOnRightClick()) { if (getWorld() != null && !getWorld().isRemote) { if (usesMui2()) { @@ -642,7 +650,14 @@ public boolean onHardHammerClick(EntityPlayer playerIn, EnumHand hand, EnumFacin return true; } - public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) {} + public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (this instanceof IDataStickIntractable dsi) { + ItemStack stack = player.getHeldItemMainhand(); + if (MetaItems.TOOL_DATA_STICK.isItemEqual(stack)) { + dsi.onDataStickLeftClick(player, stack); + } + } + } /** * @return true if the player must sneak to rotate this metatileentity, otherwise false diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index 1076de705e9..3d4fea9abc0 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.IGhostSlotConfigurable; import gregtech.api.capability.INotifiableHandler; import gregtech.api.capability.impl.GhostCircuitItemStackHandler; @@ -54,15 +55,15 @@ public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart, - IGhostSlotConfigurable { + IGhostSlotConfigurable, IDataStickIntractable { public final static String ITEM_BUFFER_TAG = "ItemSlots"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; private boolean workingEnabled = true; protected ExportOnlyAEItemList aeItemHandler; - private GhostCircuitItemStackHandler circuitInventory; - private NotifiableItemStackHandler extraSlotInventory; + protected GhostCircuitItemStackHandler circuitInventory; + protected NotifiableItemStackHandler extraSlotInventory; private ItemHandlerList actualImportItems; public MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId) { @@ -318,6 +319,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -346,4 +348,61 @@ public void setGhostCircuitConfig(int config) { markDirty(); } } + + @Override + public final void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("MEInputBus", writeConfigToTag()); + dataStick.setTagCompound(tag); + dataStick.setTranslatableName("gregtech.machine.me.item_import.data_stick.name"); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_copy_settings"), true); + } + + protected NBTTagCompound writeConfigToTag() { + NBTTagCompound tag = new NBTTagCompound(); + NBTTagCompound configStacks = new NBTTagCompound(); + tag.setTag("ConfigStacks", configStacks); + for (int i = 0; i < CONFIG_SIZE; i++) { + var slot = this.aeItemHandler.getInventory()[i]; + IAEItemStack config = slot.getConfig(); + if (config == null) { + continue; + } + NBTTagCompound stackNbt = new NBTTagCompound(); + config.getDefinition().writeToNBT(stackNbt); + configStacks.setTag(Integer.toString(i), stackNbt); + } + tag.setByte("GhostCircuit", (byte) this.circuitInventory.getCircuitValue()); + return tag; + } + + @Override + public final boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = dataStick.getTagCompound(); + if (tag == null || !tag.hasKey("MEInputBus")) { + return false; + } + readConfigFromTag(tag.getCompoundTag("MEInputBus")); + syncME(); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_paste_settings"), true); + return true; + } + + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.hasKey("ConfigStacks")) { + NBTTagCompound configStacks = tag.getCompoundTag("ConfigStacks"); + for (int i = 0; i < CONFIG_SIZE; i++) { + String key = Integer.toString(i); + if (configStacks.hasKey(key)) { + NBTTagCompound configTag = configStacks.getCompoundTag(key); + this.aeItemHandler.getInventory()[i].setConfig(WrappedItemStack.fromNBT(configTag)); + } else { + this.aeItemHandler.getInventory()[i].setConfig(null); + } + } + } + if (tag.hasKey("GhostCircuit")) { + this.setGhostCircuitConfig(tag.getByte("GhostCircuit")); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java index c864cecff64..4e510077787 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; @@ -26,6 +27,7 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.IFluidTank; @@ -44,7 +46,7 @@ import java.util.List; public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart { + implements IMultiblockAbilityPart, IDataStickIntractable { public final static String FLUID_BUFFER_TAG = "FluidTanks"; public final static String WORKING_TAG = "WorkingEnabled"; @@ -257,6 +259,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -269,4 +272,57 @@ public MultiblockAbility getAbility() { public void registerAbilities(List list) { list.addAll(Arrays.asList(this.getAEFluidHandler().getInventory())); } + + @Override + public final void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("MEInputHatch", writeConfigToTag()); + dataStick.setTagCompound(tag); + dataStick.setTranslatableName("gregtech.machine.me.fluid_import.data_stick.name"); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_copy_settings"), true); + } + + protected NBTTagCompound writeConfigToTag() { + NBTTagCompound tag = new NBTTagCompound(); + NBTTagCompound configStacks = new NBTTagCompound(); + tag.setTag("ConfigStacks", configStacks); + for (int i = 0; i < CONFIG_SIZE; i++) { + var slot = this.aeFluidHandler.getInventory()[i]; + IAEFluidStack config = slot.getConfig(); + if (config == null) { + continue; + } + NBTTagCompound stackNbt = new NBTTagCompound(); + config.writeToNBT(stackNbt); + configStacks.setTag(Integer.toString(i), stackNbt); + } + return tag; + } + + @Override + public final boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = dataStick.getTagCompound(); + if (tag == null || !tag.hasKey("MEInputHatch")) { + return false; + } + readConfigFromTag(tag.getCompoundTag("MEInputHatch")); + syncME(); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_paste_settings"), true); + return true; + } + + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.hasKey("ConfigStacks")) { + NBTTagCompound configStacks = tag.getCompoundTag("ConfigStacks"); + for (int i = 0; i < CONFIG_SIZE; i++) { + String key = Integer.toString(i); + if (configStacks.hasKey(key)) { + NBTTagCompound configTag = configStacks.getCompoundTag(key); + this.aeFluidHandler.getInventory()[i].setConfig(WrappedFluidStack.fromNBT(configTag)); + } else { + this.aeFluidHandler.getInventory()[i].setConfig(null); + } + } + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java index 99928574f82..f8bd7a5850a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java @@ -358,10 +358,38 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip")); tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } + @Override + protected NBTTagCompound writeConfigToTag() { + if (!autoPull) { + NBTTagCompound tag = super.writeConfigToTag(); + tag.setBoolean("AutoPull", false); + return tag; + } + // if in auto-pull, no need to write actual configured slots, but still need to write the ghost circuit + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("AutoPull", true); + tag.setByte("GhostCircuit", (byte) this.circuitInventory.getCircuitValue()); + return tag; + } + + @Override + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.getBoolean("AutoPull")) { + // if being set to auto-pull, no need to read the configured slots + this.setAutoPull(true); + this.setGhostCircuitConfig(tag.getByte("GhostCircuit")); + return; + } + // set auto pull first to avoid issues with clearing the config after reading from the data stick + this.setAutoPull(false); + super.readConfigFromTag(tag); + } + private static class ExportOnlyAEStockingItemList extends ExportOnlyAEItemList { private final MetaTileEntityMEStockingBus holder; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java index 1693ece229b..fcc9e1e7d12 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java @@ -263,10 +263,36 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip")); tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } + @Override + protected NBTTagCompound writeConfigToTag() { + if (!autoPull) { + NBTTagCompound tag = super.writeConfigToTag(); + tag.setBoolean("AutoPull", false); + return tag; + } + // if in auto-pull, no need to write actual configured slots, but still need to write the ghost circuit + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("AutoPull", true); + return tag; + } + + @Override + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.getBoolean("AutoPull")) { + // if being set to auto-pull, no need to read the configured slots + this.setAutoPull(true); + return; + } + // set auto pull first to avoid issues with clearing the config after reading from the data stick + this.setAutoPull(false); + super.readConfigFromTag(tag); + } + private static class ExportOnlyAEStockingFluidSlot extends ExportOnlyAEFluidSlot { public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, IAEFluidStack config, diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 42c4c0ac26c..5d1adf35389 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5278,6 +5278,11 @@ gregtech.machine.me.fluid_export.tooltip=Stores fluids directly into the ME netw gregtech.machine.me.fluid_export.tooltip.2=Can cache an infinite amount of fluid gregtech.machine.me.stocking_auto_pull_enabled=Auto-Pull Enabled gregtech.machine.me.stocking_auto_pull_disabled=Auto-Pull Disabled +gregtech.machine.me.copy_paste.tooltip=Left-click with Data Stick to copy settings, right-click to apply +gregtech.machine.me.import_copy_settings=Saved settings to Data Stick +gregtech.machine.me.import_paste_settings=Applied settings from Data Stick +gregtech.machine.me.item_import.data_stick.name=§oME Input Bus Configuration Data +gregtech.machine.me.fluid_import.data_stick.name=§oME Input Hatch Configuration Data # Universal tooltips gregtech.universal.tooltip.voltage_in=§aVoltage IN: §f%,d EU/t (%s§f) From aff043cfaa43f8dd44c45fb5de602fa2d3b56282 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:09:13 -0700 Subject: [PATCH 95/98] Fix LCE/ECE from parallelizing too much (#2426) --- .../api/capability/impl/MultiblockFuelRecipeLogic.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java index 9f93440025c..168ed40c67c 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java @@ -78,6 +78,11 @@ public int getParallelLimit() { return Integer.MAX_VALUE; } + @Override + protected long getMaxParallelVoltage() { + return getMaxVoltage(); + } + /** * Boost the energy production. * Should not change the state of the workable logic. Only read current values. From edbdaf4871412c59c30bf9fdb9daf6a7c1b438eb Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Wed, 27 Mar 2024 22:47:23 -0400 Subject: [PATCH 96/98] allow multiple build actions per recipemap (#2278) --- .../api/recipes/RecipeBuildAction.java | 17 +++++ .../gregtech/api/recipes/RecipeBuilder.java | 46 ++++++++----- .../java/gregtech/api/recipes/RecipeMap.java | 55 +++++++++++++--- .../api/recipes/RecipeMapBuilder.java | 26 ++++++++ .../java/gregtech/api/recipes/RecipeMaps.java | 66 +++++++++---------- 5 files changed, 150 insertions(+), 60 deletions(-) create mode 100644 src/main/java/gregtech/api/recipes/RecipeBuildAction.java diff --git a/src/main/java/gregtech/api/recipes/RecipeBuildAction.java b/src/main/java/gregtech/api/recipes/RecipeBuildAction.java new file mode 100644 index 00000000000..f7310129276 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/RecipeBuildAction.java @@ -0,0 +1,17 @@ +package gregtech.api.recipes; + +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface RecipeBuildAction> { + + /** + * Process a RecipeBuilder to perform an action with. + *

    + * Do not call {@link RecipeBuilder#buildAndRegister()} on the passed builder. + * It is safe to do so only on other builders, i.e. created through {@link RecipeBuilder#copy()}. + * + * @param builder the builder to utilize + */ + void accept(@NotNull R builder); +} diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index 1b59129381a..3ff85e2ce99 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -9,7 +9,11 @@ import gregtech.api.recipes.chance.output.ChancedOutputLogic; import gregtech.api.recipes.chance.output.impl.ChancedFluidOutput; import gregtech.api.recipes.chance.output.impl.ChancedItemOutput; -import gregtech.api.recipes.ingredients.*; +import gregtech.api.recipes.ingredients.GTRecipeFluidInput; +import gregtech.api.recipes.ingredients.GTRecipeInput; +import gregtech.api.recipes.ingredients.GTRecipeItemInput; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; +import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.recipes.ingredients.nbtmatch.NBTCondition; import gregtech.api.recipes.ingredients.nbtmatch.NBTMatcher; import gregtech.api.recipes.recipeproperties.CleanroomProperty; @@ -43,11 +47,17 @@ import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntLists; import org.apache.commons.lang3.builder.ToStringBuilder; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; -import java.util.function.Consumer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; /** * @see Recipe @@ -74,9 +84,8 @@ public class RecipeBuilder> { protected GTRecipeCategory category; protected boolean isCTRecipe = false; protected int parallel = 0; - protected Consumer onBuildAction = null; protected EnumValidationResult recipeStatus = EnumValidationResult.VALID; - protected IRecipePropertyStorage recipePropertyStorage = null; + protected @Nullable IRecipePropertyStorage recipePropertyStorage = null; protected boolean recipePropertyStorageErrored = false; protected RecipeBuilder() { @@ -125,8 +134,8 @@ protected RecipeBuilder(RecipeBuilder recipeBuilder) { this.EUt = recipeBuilder.EUt; this.hidden = recipeBuilder.hidden; this.category = recipeBuilder.category; - this.onBuildAction = recipeBuilder.onBuildAction; - this.recipePropertyStorage = recipeBuilder.recipePropertyStorage; + this.recipePropertyStorage = recipeBuilder.recipePropertyStorage == null ? null : + recipeBuilder.recipePropertyStorage.copy(); if (this.recipePropertyStorage != null) { this.recipePropertyStorage = this.recipePropertyStorage.copy(); } @@ -933,19 +942,26 @@ protected static String getRequiredString(int max, int actual, @NotNull String t return out; } - protected R onBuild(Consumer consumer) { - this.onBuildAction = consumer; - return (R) this; - } - + /** + * @deprecated Obsolete. Does not need calling. + */ + @ApiStatus.Obsolete + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + @Deprecated protected R invalidateOnBuildAction() { - this.onBuildAction = null; return (R) this; } + /** + * Build and register the recipe, if valid. + * Do not call outside of the + * {@link net.minecraftforge.event.RegistryEvent.Register} event for recipes. + * + */ + @MustBeInvokedByOverriders public void buildAndRegister() { - if (onBuildAction != null) { - onBuildAction.accept((R) this); + for (RecipeBuildAction action : recipeMap.getBuildActions()) { + action.accept((R) this); } ValidationResult validationResult = build(); recipeMap.addRecipe(validationResult); diff --git a/src/main/java/gregtech/api/recipes/RecipeMap.java b/src/main/java/gregtech/api/recipes/RecipeMap.java index 1103deef462..218489f1c1d 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMap.java +++ b/src/main/java/gregtech/api/recipes/RecipeMap.java @@ -39,6 +39,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.Optional.Method; @@ -59,6 +60,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; import stanhebben.zenscript.annotations.Optional; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenGetter; @@ -75,9 +77,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; -import java.util.function.Consumer; import java.util.function.DoubleSupplier; -import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -124,9 +124,9 @@ public class RecipeMap> { private final Map> recipeByCategory = new Object2ObjectOpenHashMap<>(); - private Consumer onRecipeBuildAction; - protected SoundEvent sound; - private RecipeMap smallRecipeMap; + private final Map> recipeBuildActions = new Object2ObjectOpenHashMap<>(); + protected @Nullable SoundEvent sound; + private @Nullable RecipeMap smallRecipeMap; /** * Create and register new instance of RecipeMap with specified properties. All @@ -140,7 +140,7 @@ public class RecipeMap> { * @param defaultRecipeBuilder the default RecipeBuilder for the RecipeMap * @param isHidden if the RecipeMap should have a category in JEI * - * @deprecated {@link #RecipeMap(String, RecipeBuilder, Function, int, int, int, int)} + * @deprecated {@link RecipeMap#RecipeMap(String, R, RecipeMapUIFunction, int, int, int, int)} */ @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @Deprecated @@ -169,7 +169,7 @@ public RecipeMap(@NotNull String unlocalizedName, * @param defaultRecipeBuilder the default RecipeBuilder for the RecipeMap * @param isHidden if the RecipeMap should have a category in JEI * - * @deprecated {@link #RecipeMap(String, RecipeBuilder, Function, int, int, int, int)} + * @deprecated {@link RecipeMap#RecipeMap(String, R, RecipeMapUIFunction, int, int, int, int)} */ @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @Deprecated @@ -311,11 +311,46 @@ public RecipeMap setChanceFunction(@NotNull ChanceBoostFunction function) { return this; } - public RecipeMap onRecipeBuild(Consumer consumer) { - onRecipeBuildAction = consumer; + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param name the unique name of the action + * @param action the action to perform + * @return this + */ + public RecipeMap onRecipeBuild(@NotNull ResourceLocation name, @NotNull RecipeBuildAction action) { + if (recipeBuildActions.containsKey(name)) { + throw new IllegalArgumentException("Cannot register RecipeBuildAction with duplicate name: " + name); + } + recipeBuildActions.put(name, action); return this; } + /** + * @param name the name of the build action to remove + */ + public void removeBuildAction(@NotNull ResourceLocation name) { + recipeBuildActions.remove(name); + } + + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param actions the actions to perform + */ + @ApiStatus.Internal + protected void onRecipeBuild(@NotNull Map> actions) { + recipeBuildActions.putAll(actions); + } + + /** + * @return the build actions for this RecipeMap's default RecipeBuilder + */ + @ApiStatus.Internal + protected @UnmodifiableView @NotNull Collection<@NotNull RecipeBuildAction> getBuildActions() { + return this.recipeBuildActions.values(); + } + public RecipeMap allowEmptyOutput() { this.allowEmptyOutput = true; return this; @@ -1326,7 +1361,7 @@ public String getUnlocalizedName() { } public R recipeBuilder() { - return recipeBuilderSample.copy().onBuild(onRecipeBuildAction); + return recipeBuilderSample.copy(); } /** diff --git a/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java b/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java index 2d6e810cac8..8995cf529aa 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java @@ -5,13 +5,17 @@ import gregtech.api.recipes.ui.RecipeMapUI; import gregtech.api.recipes.ui.RecipeMapUIFunction; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap; import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; + import static gregtech.api.recipes.ui.RecipeMapUI.computeOverlayKey; public class RecipeMapBuilder> { @@ -41,6 +45,8 @@ public class RecipeMapBuilder> { private SoundEvent sound; private boolean allowEmptyOutputs; + private @Nullable Map> buildActions; + /** * @param unlocalizedName the name of the recipemap * @param defaultRecipeBuilder the default recipe builder of the recipemap @@ -247,6 +253,23 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip return this; } + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param name the unique name of the action + * @param action the action to perform + * @return this + */ + public @NotNull RecipeMapBuilder onBuild(@NotNull ResourceLocation name, @NotNull RecipeBuildAction action) { + if (buildActions == null) { + buildActions = new Object2ObjectOpenHashMap<>(); + } else if (buildActions.containsKey(name)) { + throw new IllegalArgumentException("Cannot register RecipeBuildAction with duplicate name: " + name); + } + buildActions.put(name, action); + return this; + } + /** * Do not call this twice. RecipeMapBuilders are not re-usable. * @@ -260,6 +283,9 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip if (allowEmptyOutputs) { recipeMap.allowEmptyOutput(); } + if (buildActions != null) { + recipeMap.onRecipeBuild(buildActions); + } return recipeMap; } } diff --git a/src/main/java/gregtech/api/recipes/RecipeMaps.java b/src/main/java/gregtech/api/recipes/RecipeMaps.java index 9cd9547457f..b5bdde0fa94 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipes/RecipeMaps.java @@ -43,6 +43,7 @@ import stanhebben.zenscript.annotations.ZenProperty; import static gregtech.api.GTValues.*; +import static gregtech.api.util.GTUtility.gregtechId; /** * Notes: @@ -122,13 +123,12 @@ public final class RecipeMaps { .fluidOutputs(1) .progressBar(GuiTextures.PROGRESS_BAR_ARC_FURNACE) .sound(GTSoundEvents.ARC) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("arc_furnace_oxygen"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { recipeBuilder.fluidInputs(Materials.Oxygen.getFluid(recipeBuilder.getDuration())); } - }); + }) + .build(); /** * Example: @@ -151,9 +151,7 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false) .progressBar(GuiTextures.PROGRESS_BAR_CIRCUIT) .sound(GTSoundEvents.ASSEMBLER) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("assembler_solder"), recipeBuilder -> { var fluidInputs = recipeBuilder.getFluidInputs(); if (fluidInputs.size() == 1 && fluidInputs.get(0).getInputFluidStack().getFluid() == Materials.SolderingAlloy.getFluid()) { @@ -162,7 +160,8 @@ public final class RecipeMaps { recipeBuilder.copy().clearFluidInputs().fluidInputs(Materials.Tin.getFluid(amount * 2)) .buildAndRegister(); } - + }) + .onBuild(gregtechId("assembler_recycling"), recipeBuilder -> { if (recipeBuilder.isWithRecycling()) { // ignore input fluids for recycling ItemStack outputStack = recipeBuilder.getOutputs().get(0); @@ -172,7 +171,8 @@ public final class RecipeMaps { OreDictUnifier.registerOre(outputStack, info); } } - }); + }) + .build(); /** * Example: @@ -191,12 +191,14 @@ public final class RecipeMaps { * .duration(600).EUt(6000).buildAndRegister(); *

* - * The Assembly Line Recipe Builder has no special properties/build actions yet, but will in the future + * The Assembly Line Recipe Builder creates additional Research Recipes for its outputs in the Scanner or Research + * Station when specified. */ @ZenProperty public static final RecipeMap ASSEMBLY_LINE_RECIPES = new RecipeMapAssemblyLine<>( "assembly_line", new AssemblyLineRecipeBuilder(), AssemblyLineUI::new) - .onRecipeBuild(AssemblyLineManager::createDefaultResearchRecipe); + .onRecipeBuild(gregtechId("default_research_recipe"), + AssemblyLineManager::createDefaultResearchRecipe); /** * Example: @@ -436,21 +438,18 @@ public final class RecipeMaps { .fluidSlotOverlay(GuiTextures.VIAL_OVERLAY_2, true) .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) .sound(GTValues.FOOLS.get() ? GTSoundEvents.SCIENCE : GTSoundEvents.CHEMICAL_REACTOR) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); - RecipeMaps.LARGE_CHEMICAL_RECIPES.recipeBuilder() - .inputs(recipeBuilder.getInputs().toArray(new GTRecipeInput[0])) - .fluidInputs(recipeBuilder.getFluidInputs()) - .outputs(recipeBuilder.getOutputs()) - .chancedOutputs(recipeBuilder.getChancedOutputs()) - .fluidOutputs(recipeBuilder.getFluidOutputs()) - .chancedFluidOutputs(recipeBuilder.getChancedFluidOutputs()) - .cleanroom(recipeBuilder.getCleanroom()) - .duration(recipeBuilder.getDuration()) - .EUt(recipeBuilder.getEUt()) - .buildAndRegister(); - }); + .onBuild(gregtechId("lcr_copy"), recipeBuilder -> RecipeMaps.LARGE_CHEMICAL_RECIPES.recipeBuilder() + .inputs(recipeBuilder.getInputs().toArray(new GTRecipeInput[0])) + .fluidInputs(recipeBuilder.getFluidInputs()) + .outputs(recipeBuilder.getOutputs()) + .chancedOutputs(recipeBuilder.getChancedOutputs()) + .fluidOutputs(recipeBuilder.getFluidOutputs()) + .chancedFluidOutputs(recipeBuilder.getChancedFluidOutputs()) + .cleanroom(recipeBuilder.getCleanroom()) + .duration(recipeBuilder.getDuration()) + .EUt(recipeBuilder.getEUt()) + .buildAndRegister()) + .build(); /** * Example: @@ -488,9 +487,7 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false) .progressBar(GuiTextures.PROGRESS_BAR_CIRCUIT_ASSEMBLER) .sound(GTSoundEvents.ASSEMBLER) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("circuit_assembler_solder"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { recipeBuilder.copy() .fluidInputs(Materials.SolderingAlloy.getFluid(Math.max(1, @@ -503,7 +500,8 @@ public final class RecipeMaps { recipeBuilder.fluidInputs(Materials.Tin.getFluid(Math.max(1, GTValues.L * recipeBuilder.getSolderMultiplier()))); } - }); + }) + .build(); /** * Example: @@ -611,11 +609,8 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true, true) .progressBar(GuiTextures.PROGRESS_BAR_SLICE) .sound(GTSoundEvents.CUT) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("cutter_fluid"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { - int duration = recipeBuilder.getDuration(); int eut = recipeBuilder.getEUt(); recipeBuilder @@ -641,7 +636,8 @@ public final class RecipeMaps { .duration(Math.max(1, duration)); } - }); + }) + .build(); /** * Examples: From e6cc4930ca204be09d0721198b274f344c0add4e Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:00:13 -0400 Subject: [PATCH 97/98] add ItemStack inputNBT method (#2431) --- .../gregtech/api/recipes/RecipeBuilder.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index 3ff85e2ce99..7f73f62f32f 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -331,20 +331,20 @@ public R inputNBT(OrePrefix orePrefix, Material material, int count, NBTMatcher } public R inputNBT(Item item, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item)), matcher, condition); + return inputNBT(new ItemStack(item), matcher, condition); } public R inputNBT(Item item, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item), count), matcher, condition); + return inputNBT(new ItemStack(item, count), matcher, condition); } public R inputNBT(Item item, int count, int meta, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item, count, meta)), matcher, condition); + return inputNBT(new ItemStack(item, count, meta), matcher, condition); } public R inputNBT(Item item, int count, @SuppressWarnings("unused") boolean wild, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item, count, GTValues.W)), matcher, condition); + return inputNBT(new ItemStack(item, count, GTValues.W), matcher, condition); } public R inputNBT(Block block, NBTMatcher matcher, NBTCondition condition) { @@ -352,28 +352,40 @@ public R inputNBT(Block block, NBTMatcher matcher, NBTCondition condition) { } public R inputNBT(Block block, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(block, count)), matcher, condition); + return inputNBT(new ItemStack(block, count), matcher, condition); } public R inputNBT(Block block, int count, @SuppressWarnings("unused") boolean wild, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(block, count, GTValues.W)), matcher, condition); + return inputNBT(new ItemStack(block, count, GTValues.W), matcher, condition); } public R inputNBT(MetaItem.MetaValueItem item, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(item.getStackForm(count)), matcher, condition); + return inputNBT(item.getStackForm(count), matcher, condition); } public R inputNBT(MetaItem.MetaValueItem item, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(item.getStackForm()), matcher, condition); + return inputNBT(item.getStackForm(), matcher, condition); } public R inputNBT(MetaTileEntity mte, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(mte.getStackForm()), matcher, condition); + return inputNBT(mte.getStackForm(), matcher, condition); } public R inputNBT(MetaTileEntity mte, int amount, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(mte.getStackForm(amount)), matcher, condition); + return inputNBT(mte.getStackForm(amount), matcher, condition); + } + + /** + * NBT tags are stripped from the input stack and are not automatically checked. + * + * @param stack the itemstack to input. + * @param matcher the matcher for the stack's nbt + * @param condition the condition for the stack's nbt + * @return this + */ + public R inputNBT(@NotNull ItemStack stack, NBTMatcher matcher, NBTCondition condition) { + return inputNBT(new GTRecipeItemInput(stack), matcher, condition); } public R inputs(ItemStack... inputs) { From 456c1aed15f41d05beb5d05423713880c00ea946 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sun, 31 Mar 2024 13:01:26 -0400 Subject: [PATCH 98/98] Reduce allocations in RecipeBuilder (#2434) --- .../gregtech/api/recipes/RecipeBuilder.java | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index 7f73f62f32f..74357bd8130 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -57,7 +57,6 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Objects; /** * @see Recipe @@ -388,10 +387,21 @@ public R inputNBT(@NotNull ItemStack stack, NBTMatcher matcher, NBTCondition con return inputNBT(new GTRecipeItemInput(stack), matcher, condition); } + public R inputs(ItemStack input) { + if (input == null || input.isEmpty()) { + GTLog.logger.error("Input cannot be null or empty. Input: {}", input); + GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + recipeStatus = EnumValidationResult.INVALID; + } else { + this.inputs.add(new GTRecipeItemInput(input)); + } + return (R) this; + } + public R inputs(ItemStack... inputs) { for (ItemStack input : inputs) { if (input == null || input.isEmpty()) { - GTLog.logger.error("Input cannot contain null or empty ItemStacks. Inputs: {}", input); + GTLog.logger.error("Inputs cannot contain null or empty ItemStacks. Inputs: {}", input); GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); recipeStatus = EnumValidationResult.INVALID; continue; @@ -414,10 +424,21 @@ public R inputStacks(Collection inputs) { return (R) this; } + public R inputs(GTRecipeInput input) { + if (input.getAmount() < 0) { + GTLog.logger.error("Input count cannot be less than 0. Actual: {}.", input.getAmount()); + GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + recipeStatus = EnumValidationResult.INVALID; + } else { + this.inputs.add(input); + } + return (R) this; + } + public R inputs(GTRecipeInput... inputs) { for (GTRecipeInput input : inputs) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); + GTLog.logger.error("Input count cannot be less than 0. Actual: {}.", input.getAmount()); GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); recipeStatus = EnumValidationResult.INVALID; continue; @@ -532,6 +553,13 @@ public R output(MetaTileEntity mte, int amount) { return outputs(mte.getStackForm(amount)); } + public R outputs(ItemStack output) { + if (output != null && !output.isEmpty()) { + this.outputs.add(output); + } + return (R) this; + } + public R outputs(ItemStack... outputs) { return outputs(Arrays.asList(outputs)); } @@ -558,13 +586,25 @@ public R fluidInputs(GTRecipeInput fluidIngredient) { return (R) this; } + public R fluidInputs(FluidStack input) { + if (input != null && input.amount > 0) { + this.fluidInputs.add(new GTRecipeFluidInput(input)); + } else if (input != null) { + GTLog.logger.error("Fluid Input count cannot be less than 0. Actual: {}.", input.amount); + GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + } else { + GTLog.logger.error("FluidStack cannot be null."); + } + return (R) this; + } + public R fluidInputs(FluidStack... fluidStacks) { ArrayList fluidIngredients = new ArrayList<>(); for (FluidStack fluidStack : fluidStacks) { if (fluidStack != null && fluidStack.amount > 0) { fluidIngredients.add(new GTRecipeFluidInput(fluidStack)); } else if (fluidStack != null) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", fluidStack.amount); + GTLog.logger.error("Fluid Input count cannot be less than 0. Actual: {}.", fluidStack.amount); GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); } else { GTLog.logger.error("FluidStack cannot be null."); @@ -579,13 +619,20 @@ public R clearFluidInputs() { return (R) this; } + public R fluidOutputs(FluidStack output) { + if (output != null && output.amount > 0) { + this.fluidOutputs.add(output); + } + return (R) this; + } + public R fluidOutputs(FluidStack... outputs) { return fluidOutputs(Arrays.asList(outputs)); } public R fluidOutputs(Collection outputs) { outputs = new ArrayList<>(outputs); - outputs.removeIf(Objects::isNull); + outputs.removeIf(o -> o == null || o.amount <= 0); this.fluidOutputs.addAll(outputs); return (R) this; }