From 195bed9d68077d0ae9cc5b6284027725ff7b4f2e Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk
Date: Wed, 21 Jan 2026 10:34:03 +0100
Subject: [PATCH 01/78] Add check to not cache invalid recipes (#4486)
---
.../com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java
index 2b97ff75302..1483937c722 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java
@@ -344,6 +344,10 @@ protected void handleSearchingRecipes(@NotNull Iterator matches) {
if (checkMatchedRecipeAvailable(match))
return;
+ if (!matchRecipe(match).isSuccess()) {
+ continue;
+ }
+
// cache matching recipes.
if (lastFailedMatches == null) {
lastFailedMatches = new ArrayList<>();
From 02bfeb48bfc73640c274b6582529ca7236402d91 Mon Sep 17 00:00:00 2001
From: lilpaladin1
Date: Sat, 24 Jan 2026 08:23:15 -0600
Subject: [PATCH 02/78] Remove BlockEntity Check in MinerLogic (#4488)
---
.../gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java
index d9a4e62ea21..688d4a5df17 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java
@@ -551,7 +551,6 @@ private LinkedList getBlocksToMine() {
BlockPos blockPos = new BlockPos(x, y, z);
BlockState state = level.getBlockState(blockPos);
if (state.getDestroySpeed(level, blockPos) >= 0 &&
- level.getBlockEntity(blockPos) == null &&
state.is(Tags.Blocks.ORES)) {
blocks.addLast(blockPos);
}
From 29dfe0335bc80acb2b3e5eb6500be5b558c68f68 Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk
Date: Sun, 25 Jan 2026 18:18:42 +0100
Subject: [PATCH 03/78] Fix autogenerating mortar recipes (#4498)
---
docs/content/Modpacks/Changes/v7.5.0.md | 3 +++
.../data/recipe/generated/ToolRecipeHandler.java | 12 +++++++++---
.../gtceu/data/recipe/misc/CustomToolRecipes.java | 15 ---------------
3 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/docs/content/Modpacks/Changes/v7.5.0.md b/docs/content/Modpacks/Changes/v7.5.0.md
index 898852884bc..5be1593ff4b 100644
--- a/docs/content/Modpacks/Changes/v7.5.0.md
+++ b/docs/content/Modpacks/Changes/v7.5.0.md
@@ -23,3 +23,6 @@ You also need to adjust the generics of `getType()` and `createTemplate()` to ma
## Machine & Cover Copy/Paste System
A new system for copying machines using the Machine Memory Card has been added, see [this page](../Other-Topics/Cover-Machine-Copy-Paste-Support.md) if you want to add extra copy/paste behaviour to your own machines and covers.
+
+## Mortar Recipe Fix
+Previously, adding GTToolType.MORTAR to your tool did not automatically generate the recipe. This has been fixed. If you previously generated a recipe using this, you need to remove your manual recipe.
\ No newline at end of file
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java
index 2139209ef0b..79f2bf28a5a 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java
@@ -25,6 +25,7 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.Ingredient;
+import net.minecraft.world.level.block.Blocks;
import com.tterrag.registrate.util.entry.ItemEntry;
import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
@@ -63,14 +64,19 @@ public static void run(@NotNull Consumer provider, @NotNull Mate
}
private static void processTool(@NotNull Consumer provider, @NotNull Material material) {
+ ItemStack stick = new ItemStack(Items.STICK);
+ MaterialEntry ingot = new MaterialEntry(
+ material.hasProperty(PropertyKey.GEM) ? TagPrefix.gem : TagPrefix.ingot, material);
+ addToolRecipe(provider, material, GTToolType.MORTAR, false,
+ " I ", "SIS", "SSS",
+ 'I', ingot,
+ 'S', new ItemStack(Blocks.STONE));
+
if (!material.shouldGenerateRecipesFor(plate)) {
return;
}
- ItemStack stick = new ItemStack(Items.STICK);
MaterialEntry plate = new MaterialEntry(TagPrefix.plate, material);
- MaterialEntry ingot = new MaterialEntry(
- material.hasProperty(PropertyKey.GEM) ? TagPrefix.gem : TagPrefix.ingot, material);
if (material.hasFlag(GENERATE_PLATE)) {
addToolRecipe(provider, material, GTToolType.MINING_HAMMER, true,
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CustomToolRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CustomToolRecipes.java
index 2d94a1c84ca..a5510ac10c5 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CustomToolRecipes.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CustomToolRecipes.java
@@ -130,7 +130,6 @@ private static void registerPowerUnitRecipes(@NotNull Consumer p
private static void registerCustomToolRecipes(@NotNull Consumer provider) {
registerFlintToolRecipes(provider);
- registerMortarRecipes(provider);
registerSoftToolRecipes(provider);
registerElectricRecipes(provider);
@@ -178,20 +177,6 @@ private static void registerFlintToolRecipes(@NotNull Consumer p
'S', stick);
}
- private static void registerMortarRecipes(@NotNull Consumer provider) {
- for (Material material : new Material[] {
- GTMaterials.Bronze, GTMaterials.Iron, GTMaterials.Invar, GTMaterials.Steel,
- GTMaterials.DamascusSteel, GTMaterials.CobaltBrass, GTMaterials.WroughtIron }) {
-
- addToolRecipe(provider, material, GTToolType.MORTAR, false,
- " I ", "SIS", "SSS",
- 'I',
- new MaterialEntry(material.hasProperty(PropertyKey.GEM) ? TagPrefix.gem : TagPrefix.ingot,
- material),
- 'S', new ItemStack(Blocks.STONE));
- }
- }
-
private static void registerSoftToolRecipes(@NotNull Consumer provider) {
final ItemStack stick = new ItemStack(Items.STICK);
From 258f72b6aaa0ef95d5755fa294ac43b12b660263 Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk
Date: Mon, 26 Jan 2026 16:21:08 +0100
Subject: [PATCH 04/78] Add testing mention to github template (#4503)
---
.github/pull_request_template.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 34fece61126..4132c1a42cb 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -9,6 +9,9 @@ _Any implementations in this PR that should be carefully looked over, or that co
_A short description of what this PR added/fixed/changed/removed._
_For correct linking of issues please use any of the Closes/Fixes/Resolves keywords. Example: When a PR is fixing a bug use "Fixes: #number-of-bug"_
+## How Was This Tested
+_This section is for screenshots, code snippets or descriptions of how the PR was tested in code or in game to ensure correctness._
+
## Additional Information
_This section is for screenshots to demonstrate any GUI or rendering changes, or any other additional information that reviewers should be aware of._
From 388e46897fddd80672e4d49b430b4a2ad96ce6c0 Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk
Date: Mon, 26 Jan 2026 21:50:00 +0100
Subject: [PATCH 05/78] Replace mandatory air with any in blast chiler
structure (#4502)
---
.../gregtechceu/gtceu/common/data/machines/GCYMMachines.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
index 8ece01ec0cb..e793954c8f5 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
@@ -923,7 +923,7 @@ public static void init() {}
.pattern(definition -> FactoryBlockPattern.start()
.aisle("XXXXXXX#KKK", "XXXXXXX#KVK", "XXXXXXX#KVK", "XXXXXXX#KVK", "XXXXXXX#KKK", "XXXXXXX####", "XXXXXXX####")
.aisle("XXXXXXX#KVK", "XPPPPPPPPPV", "XPAPAPX#VPV", "XPPPPPPPPPV", "XPAPAPX#KVK", "XPPPPPX####", "XXXXXXX####")
- .aisle("XXXXXXX#KVK", "XPAPAPXAVPV", "XAAAAAX#VPV", "XPAAAPX#VPV", "XAAAAAX#KVK", "XPAPAPX####", "XXXXXXX####")
+ .aisle("XXXXXXX#KVK", "XPAPAPX#VPV", "XAAAAAX#VPV", "XPAAAPX#VPV", "XAAAAAX#KVK", "XPAPAPX####", "XXXXXXX####")
.aisle("XXXXXXX#KVK", "XPAPAPPPPPV", "XAAAAAX#VPV", "XPAAAPPPPPV", "XAAAAAX#KVK", "XPAPAPX####", "XXXXXXX####")
.aisle("XXXXXXX#KKK", "XPPPPPX#KVK", "XPA#APX#KVK", "XPAAAPX#KVK", "XPAAAPX#KKK", "XPPPPPX####", "XXXXXXX####")
.aisle("#XXXXX#####", "#XXSXX#####", "#XGGGX#####", "#XGGGX#####", "#XGGGX#####", "#XXXXX#####", "###########")
From 0dfe9b9556604ee70aaad07e41fe4cbab7fdd565 Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk
Date: Mon, 26 Jan 2026 21:50:16 +0100
Subject: [PATCH 06/78] Fix CME with parts and partpositions when calling
getParts in addedToController (#4505)
---
.../api/machine/multiblock/MultiblockControllerMachine.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java
index cc5535e2fbb..44a162c65a0 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java
@@ -187,13 +187,13 @@ public void onStructureFormed() {
}
}
this.parts.sort(getPartSorter());
+ updatePartPositions();
for (var part : parts) {
if (part instanceof IParallelHatch pHatch) {
parallelHatch = pHatch;
}
part.addedToController(this);
}
- updatePartPositions();
}
@Override
From 97847f73e68b6c2b14b020fe7d8cd3f7c66b4448 Mon Sep 17 00:00:00 2001
From: Phoenixvine <82596737+Phoenixvine32908@users.noreply.github.com>
Date: Tue, 27 Jan 2026 09:09:38 -0500
Subject: [PATCH 07/78] Rename method for adding tool enchantments (#4510)
---
docs/content/Modpacks/Materials-and-Elements/Tool-Creation.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/content/Modpacks/Materials-and-Elements/Tool-Creation.md b/docs/content/Modpacks/Materials-and-Elements/Tool-Creation.md
index cd5a6dac2ab..55bc0cc865f 100644
--- a/docs/content/Modpacks/Materials-and-Elements/Tool-Creation.md
+++ b/docs/content/Modpacks/Materials-and-Elements/Tool-Creation.md
@@ -59,7 +59,7 @@ The builder has the same arguments as the constructor, and can have chained meth
- `ignoreCraftingTools()`
- Disable crafting tools being made from this Material.
-- `addEnchantmentForTools(Enchantment enchantment, int level)`
+- `.enchantment(Enchantment enchantment, int level)`
- Enchantment is the default enchantment applied on tool creation.
Level is the level of said enchantment.
- `enchantability(int enchantability)`
@@ -82,7 +82,7 @@ Here is an example of using the builder in a material:
]
)
.unbreakable()
- .addEnchantmentForTools(silk_touch, 1)
+ .enchantment(SILK_TOUCH, 1)
.build()
)
});
From 3f7e588f6704e09b42e27d8767fc06d46413cb35 Mon Sep 17 00:00:00 2001
From: Phoenixvine <82596737+Phoenixvine32908@users.noreply.github.com>
Date: Wed, 28 Jan 2026 11:18:10 -0500
Subject: [PATCH 08/78] Lamp predicates. (#4511)
Co-authored-by: Ghostipedia / Caitlynn <46772882+Ghostipedia@users.noreply.github.com>
Co-authored-by: Jurre Groenendijk
Co-authored-by: Gustavo <77560533+gustovafing@users.noreply.github.com>
---
docs/content/Modpacks/Changes/v7.5.0.md | 7 ++++-
.../gtceu/api/pattern/Predicates.java | 31 +++++++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/docs/content/Modpacks/Changes/v7.5.0.md b/docs/content/Modpacks/Changes/v7.5.0.md
index 5be1593ff4b..8480fd6014d 100644
--- a/docs/content/Modpacks/Changes/v7.5.0.md
+++ b/docs/content/Modpacks/Changes/v7.5.0.md
@@ -25,4 +25,9 @@ You also need to adjust the generics of `getType()` and `createTemplate()` to ma
A new system for copying machines using the Machine Memory Card has been added, see [this page](../Other-Topics/Cover-Machine-Copy-Paste-Support.md) if you want to add extra copy/paste behaviour to your own machines and covers.
## Mortar Recipe Fix
-Previously, adding GTToolType.MORTAR to your tool did not automatically generate the recipe. This has been fixed. If you previously generated a recipe using this, you need to remove your manual recipe.
\ No newline at end of file
+Previously, adding GTToolType.MORTAR to your tool did not automatically generate the recipe. This has been fixed. If you previously generated a recipe using this, you need to remove your manual recipe.
+
+## Lamp Predicates
+Previously, lamps were not useable with the terminal in multiblocks. There are new lamp predicates that will help solve this problem.
+The predicate to use all lamps is: `Predicates.anyLamp()`
+The predicate to use a specific color is: `Predicates.lampsByColor(DyeColor.DYE_COLOR)`. Where DYE_COLOR is the name of the color you want.
\ No newline at end of file
diff --git a/src/main/java/com/gregtechceu/gtceu/api/pattern/Predicates.java b/src/main/java/com/gregtechceu/gtceu/api/pattern/Predicates.java
index 413a17137ee..962b35c3579 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/pattern/Predicates.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/pattern/Predicates.java
@@ -17,6 +17,7 @@
import com.gregtechceu.gtceu.api.recipe.GTRecipeType;
import com.gregtechceu.gtceu.common.block.BatteryBlock;
import com.gregtechceu.gtceu.common.block.CoilBlock;
+import com.gregtechceu.gtceu.common.block.LampBlock;
import com.gregtechceu.gtceu.common.data.GTMaterialBlocks;
import com.gregtechceu.gtceu.common.machine.multiblock.electric.PowerSubstationMachine;
import com.gregtechceu.gtceu.config.ConfigHolder;
@@ -25,11 +26,13 @@
import net.minecraft.network.chat.Component;
import net.minecraft.tags.TagKey;
+import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
+import com.tterrag.registrate.util.entry.BlockEntry;
import com.tterrag.registrate.util.entry.RegistryEntry;
import org.apache.commons.lang3.ArrayUtils;
@@ -38,6 +41,8 @@
import java.util.function.Supplier;
import static com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties.ACTIVE;
+import static com.gregtechceu.gtceu.common.data.GTBlocks.BORDERLESS_LAMPS;
+import static com.gregtechceu.gtceu.common.data.GTBlocks.LAMPS;
import static com.gregtechceu.gtceu.common.machine.multiblock.electric.PowerSubstationMachine.PMC_BATTERY_HEADER;
public class Predicates {
@@ -100,6 +105,32 @@ public static TraceabilityPredicate air() {
return new TraceabilityPredicate(SimplePredicate.AIR);
}
+ @SafeVarargs
+ public static TraceabilityPredicate lamps(BlockEntry... lampEntries) {
+ return new TraceabilityPredicate(blockWorldState -> {
+ BlockState state = blockWorldState.getBlockState();
+ for (BlockEntry entry : lampEntries) {
+ if (state.is(entry.get())) return true;
+ }
+ return false;
+ }, () -> Arrays.stream(lampEntries)
+ .map(entry -> new BlockInfo(entry.get().defaultBlockState(), null))
+ .toArray(BlockInfo[]::new));
+ }
+
+ public static TraceabilityPredicate anyLamp() {
+ List> all = new ArrayList<>();
+ all.addAll(LAMPS.values());
+ all.addAll(BORDERLESS_LAMPS.values());
+ return lamps(all.toArray(BlockEntry[]::new));
+ }
+
+ private static final Map LAMPS_BY_COLOR = new EnumMap<>(DyeColor.class);
+
+ public static TraceabilityPredicate lampsByColor(DyeColor color) {
+ return LAMPS_BY_COLOR.computeIfAbsent(color, c -> lamps(LAMPS.get(c), BORDERLESS_LAMPS.get(c)));
+ }
+
public static TraceabilityPredicate abilities(PartAbility... abilities) {
return blocks(Arrays.stream(abilities).map(PartAbility::getAllBlocks).flatMap(Collection::stream)
.toArray(Block[]::new));
From de443c19bba82ce68168d43a3c27272b34c065a6 Mon Sep 17 00:00:00 2001
From: remakefactory <215389873+remakefactory@users.noreply.github.com>
Date: Thu, 29 Jan 2026 18:48:04 +0800
Subject: [PATCH 09/78] fix Same uuid (#4483)
---
.../gtceu/api/item/armor/ArmorComponentItem.java | 4 +---
.../gtceu/api/item/armor/IArmorLogic.java | 12 ++++++------
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/armor/ArmorComponentItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/armor/ArmorComponentItem.java
index 428b2a658df..5579e039564 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/item/armor/ArmorComponentItem.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/item/armor/ArmorComponentItem.java
@@ -28,9 +28,7 @@
import org.jetbrains.annotations.NotNullByDefault;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
import java.util.function.Consumer;
@NotNullByDefault
diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/armor/IArmorLogic.java b/src/main/java/com/gregtechceu/gtceu/api/item/armor/IArmorLogic.java
index c67bb1ca296..3ae5f075c83 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/item/armor/IArmorLogic.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/item/armor/IArmorLogic.java
@@ -26,13 +26,13 @@
public interface IArmorLogic {
- UUID ATTACK_DAMAGE_MODIFIER = UUID.fromString("648D7064-6A60-4F59-8ABE-C2C23A6DD7A9");
- UUID ATTACK_SPEED_MODIFIER = UUID.fromString("FA233E1C-4180-4288-B05C-BCCE9785ACA3");
+ UUID ATTACK_DAMAGE_MODIFIER = UUID.fromString("2adb6ae9-df4d-4a45-bb07-8553dd4b6832");
+ UUID ATTACK_SPEED_MODIFIER = UUID.fromString("876a7cd1-aec0-4ae5-ae3f-e951d5f1965a");
EnumMap ARMOR_MODIFIER_UUID_PER_TYPE = Util.make(new EnumMap<>(ArmorItem.Type.class), map -> {
- map.put(ArmorItem.Type.BOOTS, UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"));
- map.put(ArmorItem.Type.LEGGINGS, UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"));
- map.put(ArmorItem.Type.CHESTPLATE, UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"));
- map.put(ArmorItem.Type.HELMET, UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150"));
+ map.put(ArmorItem.Type.BOOTS, UUID.fromString("be2b5c6e-bb5d-4675-a6be-c6c488a437f5"));
+ map.put(ArmorItem.Type.LEGGINGS, UUID.fromString("435c34aa-0c5b-442d-abb0-d1c984c894f9"));
+ map.put(ArmorItem.Type.CHESTPLATE, UUID.fromString("77d81693-63cc-4593-977d-8e0391d94a77"));
+ map.put(ArmorItem.Type.HELMET, UUID.fromString("cc839692-3a33-4907-a114-21fa0a18184c"));
});
default void addToolComponents(ArmorComponentItem item) {}
From 5ad5f7cb9fc1a9fe9c60b54b8c90cff1f87c5564 Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk
Date: Thu, 29 Jan 2026 20:26:01 +0100
Subject: [PATCH 10/78] Fix invalid comparison in dimension condition (#4518)
---
.../gtceu/common/recipe/condition/DimensionCondition.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java
index 84b2f9d86c8..d046376bdd0 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java
@@ -82,7 +82,7 @@ public SlotWidget setupDimensionMarkers(int xOffset, int yOffset) {
@Override
public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) {
Level level = recipeLogic.machine.self().getLevel();
- return level != null && dimension.equals(level.dimension().location());
+ return level != null && dimension.location().equals(level.dimension().location());
}
@Override
From f21fd8be6eda2e97555e782b5b90559a233f6ded Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Thu, 29 Jan 2026 23:05:33 +0200
Subject: [PATCH 11/78] Fix LWJGL and FastUtil sources (#4520)
---
gradle/scripts/repositories.gradle | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/gradle/scripts/repositories.gradle b/gradle/scripts/repositories.gradle
index 0b84ea42783..d0546c95ce2 100644
--- a/gradle/scripts/repositories.gradle
+++ b/gradle/scripts/repositories.gradle
@@ -1,6 +1,14 @@
repositories {
mavenLocal()
mavenCentral()
+ // force gradle to download FastUtil & LWJGL from the central maven so we can get source artifacts
+ exclusiveContent { // Force
+ forRepository { mavenCentral() }
+ filter {
+ includeGroup("it.unimi.dsi")
+ includeGroup("org.lwjgl")
+ }
+ }
maven { // JEI
name = "Jared's Maven"
From c04379a94b3a69891a8fc20c1764dbc63d72f9f0 Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Thu, 29 Jan 2026 23:10:09 +0200
Subject: [PATCH 12/78] Fix wireless_transmitter_cover_test not working on
systems where the decimal separator isn't a dot (#4521)
---
.../com/gregtechceu/gtceu/common/data/GTPlaceholders.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTPlaceholders.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTPlaceholders.java
index 35a707c549c..78df4b96671 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/GTPlaceholders.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTPlaceholders.java
@@ -711,10 +711,11 @@ public MultiLineComponent apply(PlaceholderContext ctx,
1000000000L, "B",
1000000000000L, "T");
long max = 1;
- for (Long i : suffixes.keySet()) {
+ for (long i : suffixes.keySet()) {
if (n >= i && max < i) max = i;
}
- return MultiLineComponent.literal("%.2f%s".formatted(((double) n) / max, suffixes.get(max)));
+ return MultiLineComponent.literal(String.format(Locale.ROOT, "%.2f%s",
+ ((double) n) / max, suffixes.get(max)));
}
});
PlaceholderHandler.addPlaceholder(new Placeholder("click") {
From 7b7ac4420db2050b3b06743fc79c427415b6be20 Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Sun, 1 Feb 2026 00:22:48 +0200
Subject: [PATCH 13/78] Pipe model rework (#4283)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Gustavo <77560533+gustovafing@users.noreply.github.com>
---
docs/content/Modpacks/Changes/v7.4.0.md | 1 -
docs/content/Modpacks/Changes/v7.5.0.md | 55 +-
.../gtceu/blockstates/huge_duct_pipe.json | 7 +
.../gtceu/blockstates/large_duct_pipe.json | 7 +
.../gtceu/blockstates/normal_duct_pipe.json | 7 +
.../gtceu/blockstates/normal_laser_pipe.json | 10 +
.../blockstates/normal_optical_pipe.json | 10 +
.../gtceu/blockstates/small_duct_pipe.json | 7 +
.../gtceu/models/block/huge_duct_pipe.json | 55 ++
.../gtceu/models/block/large_duct_pipe.json | 55 ++
.../gtceu/models/block/normal_duct_pipe.json | 55 ++
.../gtceu/models/block/normal_laser_pipe.json | 55 ++
.../block/normal_laser_pipe_active.json | 55 ++
.../models/block/normal_optical_pipe.json | 55 ++
.../block/normal_optical_pipe_active.json | 55 ++
.../block/pipe/huge_duct_pipe/center.json | 47 ++
.../block/pipe/huge_duct_pipe/connection.json | 48 ++
.../block/pipe/large_duct_pipe/center.json | 47 ++
.../pipe/large_duct_pipe/connection.json | 48 ++
.../block/pipe/normal_duct_pipe/center.json | 47 ++
.../pipe/normal_duct_pipe/connection.json | 48 ++
.../block/pipe/normal_laser_pipe/center.json | 86 ++++
.../pipe/normal_laser_pipe/center_active.json | 6 +
.../pipe/normal_laser_pipe/connection.json | 79 +++
.../normal_laser_pipe/connection_active.json | 6 +
.../pipe/normal_optical_pipe/center.json | 86 ++++
.../normal_optical_pipe/center_active.json | 6 +
.../pipe/normal_optical_pipe/connection.json | 79 +++
.../connection_active.json | 6 +
.../pipe/restrictor/down/thickness_12.0.json | 33 ++
.../pipe/restrictor/down/thickness_14.0.json | 33 ++
.../pipe/restrictor/down/thickness_6.0.json | 33 ++
.../pipe/restrictor/down/thickness_8.0.json | 33 ++
.../pipe/restrictor/east/thickness_12.0.json | 33 ++
.../pipe/restrictor/east/thickness_14.0.json | 33 ++
.../pipe/restrictor/east/thickness_6.0.json | 33 ++
.../pipe/restrictor/east/thickness_8.0.json | 33 ++
.../pipe/restrictor/north/thickness_12.0.json | 33 ++
.../pipe/restrictor/north/thickness_14.0.json | 33 ++
.../pipe/restrictor/north/thickness_6.0.json | 33 ++
.../pipe/restrictor/north/thickness_8.0.json | 33 ++
.../pipe/restrictor/south/thickness_12.0.json | 33 ++
.../pipe/restrictor/south/thickness_14.0.json | 33 ++
.../pipe/restrictor/south/thickness_6.0.json | 33 ++
.../pipe/restrictor/south/thickness_8.0.json | 33 ++
.../pipe/restrictor/up/thickness_12.0.json | 33 ++
.../pipe/restrictor/up/thickness_14.0.json | 33 ++
.../pipe/restrictor/up/thickness_6.0.json | 33 ++
.../pipe/restrictor/up/thickness_8.0.json | 33 ++
.../pipe/restrictor/west/thickness_12.0.json | 33 ++
.../pipe/restrictor/west/thickness_14.0.json | 33 ++
.../pipe/restrictor/west/thickness_6.0.json | 33 ++
.../pipe/restrictor/west/thickness_8.0.json | 33 ++
.../block/pipe/small_duct_pipe/center.json | 47 ++
.../pipe/small_duct_pipe/connection.json | 48 ++
.../gtceu/models/block/small_duct_pipe.json | 55 ++
.../gtceu/models/item/huge_duct_pipe.json | 49 ++
.../gtceu/models/item/large_duct_pipe.json | 49 ++
.../gtceu/models/item/normal_duct_pipe.json | 49 ++
.../gtceu/models/item/normal_laser_pipe.json | 80 +++
.../models/item/normal_optical_pipe.json | 80 +++
.../gtceu/models/item/small_duct_pipe.json | 49 ++
.../java/com/gregtechceu/gtceu/GTCEu.java | 2 +
.../gtceu/api/block/MaterialPipeBlock.java | 18 -
.../gtceu/api/block/PipeBlock.java | 46 +-
.../blockentity/MetaMachineBlockEntity.java | 6 +-
.../gtceu/api/item/DuctPipeBlockItem.java | 30 --
.../gtceu/api/item/LampBlockItem.java | 80 ++-
.../gtceu/api/item/LaserPipeBlockItem.java | 15 +-
.../gtceu/api/item/MaterialPipeBlockItem.java | 13 +-
.../gtceu/api/item/OpticalPipeBlockItem.java | 29 --
.../api/machine/IMachineBlockEntity.java | 5 -
.../registry/registrate/GTBlockBuilder.java | 9 +
.../registry/registrate/MachineBuilder.java | 7 +-
.../provider/GTBlockstateProvider.java | 11 +-
.../gregtechceu/gtceu/client/ClientProxy.java | 59 +++
.../gtceu/client/model/BaseBakedModel.java | 6 +-
.../gtceu/client/model/GTModelProperties.java | 16 +
.../model/IBlockEntityRendererBakedModel.java | 8 +-
.../gtceu/client/model/PipeModel.java | 357 -------------
.../client/model/machine/MachineModel.java | 46 +-
.../model/machine/MachineModelLoader.java | 2 +-
.../multipart/MultiPartBakedModel.java | 15 +-
.../machine/variant/MultiVariantModel.java | 4 +-
.../client/model/pipe/ActivablePipeModel.java | 169 +++++++
.../client/model/pipe/BakedPipeModel.java | 152 ++++++
.../gtceu/client/model/pipe/PipeModel.java | 377 ++++++++++++++
.../client/model/pipe/PipeModelLoader.java | 62 +++
.../client/model/pipe/UnbakedPipeModel.java | 71 +++
.../gtceu/client/model/pipe/package-info.java | 7 +
.../BlockEntityWithBERModelRenderer.java | 6 +-
.../renderer/block/LampItemRenderer.java | 54 ++
.../client/renderer/block/LampRenderer.java | 49 --
.../renderer/block/OreBlockRenderer.java | 12 +-
.../renderer/block/PipeBlockRenderer.java | 149 ------
.../gtceu/common/block/CableBlock.java | 9 +-
.../gtceu/common/block/DuctPipeBlock.java | 19 +-
.../gtceu/common/block/FluidPipeBlock.java | 7 +-
.../gtceu/common/block/ItemPipeBlock.java | 7 +-
.../gtceu/common/block/LampBlock.java | 26 +-
.../gtceu/common/block/LaserPipeBlock.java | 39 +-
.../gtceu/common/block/OpticalPipeBlock.java | 43 +-
.../common/blockentity/CableBlockEntity.java | 4 -
.../blockentity/DuctPipeBlockEntity.java | 6 +-
.../blockentity/ItemPipeBlockEntity.java | 4 -
.../blockentity/LaserPipeBlockEntity.java | 69 +--
.../blockentity/OpticalPipeBlockEntity.java | 39 +-
.../gtceu/common/commands/GTCommands.java | 2 +-
.../gtceu/common/data/GTBlockEntities.java | 8 +-
.../gtceu/common/data/GTBlocks.java | 10 +-
.../gtceu/common/data/models/GTModels.java | 8 +
.../common/pipelike/cable/Insulation.java | 34 +-
.../common/pipelike/duct/DuctPipeType.java | 7 -
.../pipelike/fluidpipe/FluidPipeType.java | 30 +-
.../common/pipelike/item/ItemPipeType.java | 29 +-
.../core/mixins/client/ModelManagerMixin.java | 22 +-
.../data/model/builder/PipeModelBuilder.java | 477 ++++++++++++++++++
.../gtceu/data/pack/GTDynamicDataPack.java | 2 +-
.../data/pack/GTDynamicResourcePack.java | 116 ++---
.../event/RegisterDynamicResourcesEvent.java | 12 +
.../integration/kjs/GregTechKubeJSPlugin.java | 16 -
.../com/gregtechceu/gtceu/utils/GTMath.java | 67 +++
.../com/gregtechceu/gtceu/utils/GTUtil.java | 2 +
...er.java => RuntimeBlockstateProvider.java} | 20 +-
.../gtceu/utils/memoization/GTMemoizer.java | 42 +-
.../function/MemoizedBiFunction.java | 11 +
.../function/MemoizedFunction.java | 9 +
.../function/MemoizedTriFunction.java | 11 +
.../textures/block/pipe/pipe_optical_side.png | Bin 280 -> 298 bytes
.../block/pipe/pipe_optical_side_overlay.png | Bin 0 -> 113 bytes
.../pipe/pipe_optical_side_overlay_active.png | Bin 0 -> 197 bytes
...ipe_optical_side_overlay_active.png.mcmeta | 5 +
132 files changed, 4422 insertions(+), 1108 deletions(-)
create mode 100644 src/generated/resources/assets/gtceu/blockstates/huge_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/blockstates/large_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/blockstates/normal_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/blockstates/normal_laser_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/blockstates/normal_optical_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/blockstates/small_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/huge_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/large_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/normal_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/normal_laser_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/normal_laser_pipe_active.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/normal_optical_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/normal_optical_pipe_active.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_12.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_14.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_6.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_8.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_12.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_14.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_6.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_8.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_12.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_14.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_6.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_8.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_12.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_14.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_6.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_8.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_12.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_14.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_6.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_8.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_12.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_14.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_6.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_8.0.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
create mode 100644 src/generated/resources/assets/gtceu/models/block/small_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/item/huge_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/item/large_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/item/normal_duct_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/item/normal_laser_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/item/normal_optical_pipe.json
create mode 100644 src/generated/resources/assets/gtceu/models/item/small_duct_pipe.json
delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/item/DuctPipeBlockItem.java
delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/item/OpticalPipeBlockItem.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java
delete mode 100644 src/main/java/com/gregtechceu/gtceu/client/model/PipeModel.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModelLoader.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/model/pipe/UnbakedPipeModel.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/model/pipe/package-info.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/renderer/block/LampItemRenderer.java
delete mode 100644 src/main/java/com/gregtechceu/gtceu/client/renderer/block/LampRenderer.java
delete mode 100644 src/main/java/com/gregtechceu/gtceu/client/renderer/block/PipeBlockRenderer.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/data/pack/event/RegisterDynamicResourcesEvent.java
rename src/main/java/com/gregtechceu/gtceu/utils/data/{RuntimeBlockStateProvider.java => RuntimeBlockstateProvider.java} (64%)
create mode 100644 src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedBiFunction.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedFunction.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedTriFunction.java
create mode 100644 src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side_overlay.png
create mode 100644 src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side_overlay_active.png
create mode 100644 src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side_overlay_active.png.mcmeta
diff --git a/docs/content/Modpacks/Changes/v7.4.0.md b/docs/content/Modpacks/Changes/v7.4.0.md
index 766793617d0..b12d7e98444 100644
--- a/docs/content/Modpacks/Changes/v7.4.0.md
+++ b/docs/content/Modpacks/Changes/v7.4.0.md
@@ -24,4 +24,3 @@ to
`roll(RecipeCapability> cap, List chancedEntries, ChanceBoostFunction boostFunction, int recipeTier, int chanceTier, Object2IntMap> cache, int times)`
(The chance roll function now also requires the RecipeCapability that is currently being processed to be passed in.)
-
diff --git a/docs/content/Modpacks/Changes/v7.5.0.md b/docs/content/Modpacks/Changes/v7.5.0.md
index 8480fd6014d..efe36c8eadb 100644
--- a/docs/content/Modpacks/Changes/v7.5.0.md
+++ b/docs/content/Modpacks/Changes/v7.5.0.md
@@ -4,9 +4,11 @@ title: "Version 7.5.0"
# Updating from `7.4.1` to `7.5.0`
+## Machine Builder Generics
+We have added a second Generic argument to our (Multiblock)MachineBuilder. This effectively means that anywhere where you used to store a partially finished `MachineBuilder>`, you now need to store a `MachineBuilder, ?>`. The same holds for `MultiblockMachineBuilder, ?>`.
-## MachineBuilder Generics
-We have added a second Generic argument to our (Multiblock)MachineBuilder. This effectively means that anywhere where you used to store a partially finished `MachineBuilder>`, you now need to store a `MachineBuilder, ?>`. The same holds for `MultiblockMachineBuilder,?>`.
+## Machine & Cover Copy/Paste System
+A new system for copying machines using the Machine Memory Card has been added, see [this page](../Other-Topics/Cover-Machine-Copy-Paste-Support.md) if you want to add extra copy/paste behaviour to your own machines and covers.
## RecipeCondition Generics
We have added a Generic argument to `RecipeCondition` describing the condition.
@@ -20,14 +22,53 @@ You also need to adjust the generics of `getType()` and `createTemplate()` to ma
- public RecipeCondition createTemplate() {
+ public ExampleCondition createTemplate() {
```
-
-## Machine & Cover Copy/Paste System
-A new system for copying machines using the Machine Memory Card has been added, see [this page](../Other-Topics/Cover-Machine-Copy-Paste-Support.md) if you want to add extra copy/paste behaviour to your own machines and covers.
-
## Mortar Recipe Fix
Previously, adding GTToolType.MORTAR to your tool did not automatically generate the recipe. This has been fixed. If you previously generated a recipe using this, you need to remove your manual recipe.
+## Pipe rendering changes
+_This is only relevant to add-on mods with custom pipe types._
+Addons with custom pipe implementations will have to tweak their code slightly to function with the new rendering code (see example below).
+
+```patch
+-public final PipeModel model = new PipeModel(pipeType.getThickness(), () -> [side texture], () -> [end texture], null, null);
+-@Getter
+-private final PipeBlockRenderer renderer = new PipeBlockRenderer(model);
+
+ ...
+
+ @Override
+-public PipeModel getPipeModel() {
+- return model;
++public PipeModel createPipeModel(GTBlockstateProvider provider) {
++ return new PipeModel(this, pipeType.getThickness(), [side texture], [end texture], provider);
+ }
+```
+If your pipe is generated from a material property (or equivalent), you should also call `PipeModel#dynamicModel()`
+to have models be generated at runtime.
+If so, must also add a **Mod bus** event listener for `RegisterDynamicResourcesEvent`, like so:
+```java
+@SubscribeEvent
+public static void registerDynamicResources(RegisterDynamicResourcesEvent event) {
+ for (var block : MyBlocks.MY_PIPE_BLOCKS) block.get().createPipeModel(RuntimeExistingFileHelper.INSTANCE).dynamicModel();
+}
+```
+Replace `MyBlocks.MY_PIPE_BLOCKS` with a reference to your pipe block array/map value collection.
+
+
+Conversely, if the pipe is **not** generated, but has a constant set of variants (such as optical fiber cables or laser pipes),
+you should **NOT** use `PipeModel#dynamicModel()` and instead set the model with `GTBlockBuilder#gtBlockstate` as such:
+```java
+ // on your pipe block builder
+ ... = REGISTRATE.block(...)
+ .properties(...)
+ .gtBlockstate(GTModels::createPipeBlockModel)
+ ...more builder things...
+ .item(...)
+ .model(NonNullBiConsumer.noop())
+ ...more builder things...
+```
+
## Lamp Predicates
Previously, lamps were not useable with the terminal in multiblocks. There are new lamp predicates that will help solve this problem.
The predicate to use all lamps is: `Predicates.anyLamp()`
-The predicate to use a specific color is: `Predicates.lampsByColor(DyeColor.DYE_COLOR)`. Where DYE_COLOR is the name of the color you want.
\ No newline at end of file
+The predicate to use a specific color is: `Predicates.lampsByColor(DyeColor.DYE_COLOR)`. Where DYE_COLOR is the name of the color you want.
diff --git a/src/generated/resources/assets/gtceu/blockstates/huge_duct_pipe.json b/src/generated/resources/assets/gtceu/blockstates/huge_duct_pipe.json
new file mode 100644
index 00000000000..583340f5ea7
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/blockstates/huge_duct_pipe.json
@@ -0,0 +1,7 @@
+{
+ "variants": {
+ "": {
+ "model": "gtceu:block/huge_duct_pipe"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/blockstates/large_duct_pipe.json b/src/generated/resources/assets/gtceu/blockstates/large_duct_pipe.json
new file mode 100644
index 00000000000..8ddcee59f5a
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/blockstates/large_duct_pipe.json
@@ -0,0 +1,7 @@
+{
+ "variants": {
+ "": {
+ "model": "gtceu:block/large_duct_pipe"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/blockstates/normal_duct_pipe.json b/src/generated/resources/assets/gtceu/blockstates/normal_duct_pipe.json
new file mode 100644
index 00000000000..c12030e7f2f
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/blockstates/normal_duct_pipe.json
@@ -0,0 +1,7 @@
+{
+ "variants": {
+ "": {
+ "model": "gtceu:block/normal_duct_pipe"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/blockstates/normal_laser_pipe.json b/src/generated/resources/assets/gtceu/blockstates/normal_laser_pipe.json
new file mode 100644
index 00000000000..7b77d7b3adb
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/blockstates/normal_laser_pipe.json
@@ -0,0 +1,10 @@
+{
+ "variants": {
+ "active=false": {
+ "model": "gtceu:block/normal_laser_pipe"
+ },
+ "active=true": {
+ "model": "gtceu:block/normal_laser_pipe_active"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/blockstates/normal_optical_pipe.json b/src/generated/resources/assets/gtceu/blockstates/normal_optical_pipe.json
new file mode 100644
index 00000000000..dcda4258ec6
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/blockstates/normal_optical_pipe.json
@@ -0,0 +1,10 @@
+{
+ "variants": {
+ "active=false": {
+ "model": "gtceu:block/normal_optical_pipe"
+ },
+ "active=true": {
+ "model": "gtceu:block/normal_optical_pipe_active"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/blockstates/small_duct_pipe.json b/src/generated/resources/assets/gtceu/blockstates/small_duct_pipe.json
new file mode 100644
index 00000000000..146f5c42cfb
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/blockstates/small_duct_pipe.json
@@ -0,0 +1,7 @@
+{
+ "variants": {
+ "": {
+ "model": "gtceu:block/small_duct_pipe"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/huge_duct_pipe.json b/src/generated/resources/assets/gtceu/models/block/huge_duct_pipe.json
new file mode 100644
index 00000000000..e737cf69235
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/huge_duct_pipe.json
@@ -0,0 +1,55 @@
+{
+ "parent": "gtceu:block/pipe/huge_duct_pipe/center",
+ "loader": "gtceu:pipe",
+ "parts": {
+ "center": {
+ "model": "gtceu:block/pipe/huge_duct_pipe/center"
+ },
+ "down": {
+ "model": "gtceu:block/pipe/huge_duct_pipe/connection"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/huge_duct_pipe/connection",
+ "x": 90,
+ "y": 270
+ },
+ "north": {
+ "model": "gtceu:block/pipe/huge_duct_pipe/connection",
+ "x": 90,
+ "y": 180
+ },
+ "south": {
+ "model": "gtceu:block/pipe/huge_duct_pipe/connection",
+ "x": 90
+ },
+ "up": {
+ "model": "gtceu:block/pipe/huge_duct_pipe/connection",
+ "x": 180
+ },
+ "west": {
+ "model": "gtceu:block/pipe/huge_duct_pipe/connection",
+ "x": 90,
+ "y": 90
+ }
+ },
+ "restrictors": {
+ "down": {
+ "model": "gtceu:block/pipe/restrictor/down/thickness_14.0"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/restrictor/east/thickness_14.0"
+ },
+ "north": {
+ "model": "gtceu:block/pipe/restrictor/north/thickness_14.0"
+ },
+ "south": {
+ "model": "gtceu:block/pipe/restrictor/south/thickness_14.0"
+ },
+ "up": {
+ "model": "gtceu:block/pipe/restrictor/up/thickness_14.0"
+ },
+ "west": {
+ "model": "gtceu:block/pipe/restrictor/west/thickness_14.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/large_duct_pipe.json b/src/generated/resources/assets/gtceu/models/block/large_duct_pipe.json
new file mode 100644
index 00000000000..a988ebb1438
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/large_duct_pipe.json
@@ -0,0 +1,55 @@
+{
+ "parent": "gtceu:block/pipe/large_duct_pipe/center",
+ "loader": "gtceu:pipe",
+ "parts": {
+ "center": {
+ "model": "gtceu:block/pipe/large_duct_pipe/center"
+ },
+ "down": {
+ "model": "gtceu:block/pipe/large_duct_pipe/connection"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/large_duct_pipe/connection",
+ "x": 90,
+ "y": 270
+ },
+ "north": {
+ "model": "gtceu:block/pipe/large_duct_pipe/connection",
+ "x": 90,
+ "y": 180
+ },
+ "south": {
+ "model": "gtceu:block/pipe/large_duct_pipe/connection",
+ "x": 90
+ },
+ "up": {
+ "model": "gtceu:block/pipe/large_duct_pipe/connection",
+ "x": 180
+ },
+ "west": {
+ "model": "gtceu:block/pipe/large_duct_pipe/connection",
+ "x": 90,
+ "y": 90
+ }
+ },
+ "restrictors": {
+ "down": {
+ "model": "gtceu:block/pipe/restrictor/down/thickness_12.0"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/restrictor/east/thickness_12.0"
+ },
+ "north": {
+ "model": "gtceu:block/pipe/restrictor/north/thickness_12.0"
+ },
+ "south": {
+ "model": "gtceu:block/pipe/restrictor/south/thickness_12.0"
+ },
+ "up": {
+ "model": "gtceu:block/pipe/restrictor/up/thickness_12.0"
+ },
+ "west": {
+ "model": "gtceu:block/pipe/restrictor/west/thickness_12.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/normal_duct_pipe.json b/src/generated/resources/assets/gtceu/models/block/normal_duct_pipe.json
new file mode 100644
index 00000000000..c17c8d7154b
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/normal_duct_pipe.json
@@ -0,0 +1,55 @@
+{
+ "parent": "gtceu:block/pipe/normal_duct_pipe/center",
+ "loader": "gtceu:pipe",
+ "parts": {
+ "center": {
+ "model": "gtceu:block/pipe/normal_duct_pipe/center"
+ },
+ "down": {
+ "model": "gtceu:block/pipe/normal_duct_pipe/connection"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/normal_duct_pipe/connection",
+ "x": 90,
+ "y": 270
+ },
+ "north": {
+ "model": "gtceu:block/pipe/normal_duct_pipe/connection",
+ "x": 90,
+ "y": 180
+ },
+ "south": {
+ "model": "gtceu:block/pipe/normal_duct_pipe/connection",
+ "x": 90
+ },
+ "up": {
+ "model": "gtceu:block/pipe/normal_duct_pipe/connection",
+ "x": 180
+ },
+ "west": {
+ "model": "gtceu:block/pipe/normal_duct_pipe/connection",
+ "x": 90,
+ "y": 90
+ }
+ },
+ "restrictors": {
+ "down": {
+ "model": "gtceu:block/pipe/restrictor/down/thickness_8.0"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/restrictor/east/thickness_8.0"
+ },
+ "north": {
+ "model": "gtceu:block/pipe/restrictor/north/thickness_8.0"
+ },
+ "south": {
+ "model": "gtceu:block/pipe/restrictor/south/thickness_8.0"
+ },
+ "up": {
+ "model": "gtceu:block/pipe/restrictor/up/thickness_8.0"
+ },
+ "west": {
+ "model": "gtceu:block/pipe/restrictor/west/thickness_8.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/normal_laser_pipe.json b/src/generated/resources/assets/gtceu/models/block/normal_laser_pipe.json
new file mode 100644
index 00000000000..164e2ac6fe6
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/normal_laser_pipe.json
@@ -0,0 +1,55 @@
+{
+ "parent": "gtceu:block/pipe/normal_laser_pipe/center",
+ "loader": "gtceu:pipe",
+ "parts": {
+ "center": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/center"
+ },
+ "down": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection",
+ "x": 90,
+ "y": 270
+ },
+ "north": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection",
+ "x": 90,
+ "y": 180
+ },
+ "south": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection",
+ "x": 90
+ },
+ "up": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection",
+ "x": 180
+ },
+ "west": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection",
+ "x": 90,
+ "y": 90
+ }
+ },
+ "restrictors": {
+ "down": {
+ "model": "gtceu:block/pipe/restrictor/down/thickness_6.0"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/restrictor/east/thickness_6.0"
+ },
+ "north": {
+ "model": "gtceu:block/pipe/restrictor/north/thickness_6.0"
+ },
+ "south": {
+ "model": "gtceu:block/pipe/restrictor/south/thickness_6.0"
+ },
+ "up": {
+ "model": "gtceu:block/pipe/restrictor/up/thickness_6.0"
+ },
+ "west": {
+ "model": "gtceu:block/pipe/restrictor/west/thickness_6.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/normal_laser_pipe_active.json b/src/generated/resources/assets/gtceu/models/block/normal_laser_pipe_active.json
new file mode 100644
index 00000000000..ac6d70b010c
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/normal_laser_pipe_active.json
@@ -0,0 +1,55 @@
+{
+ "parent": "gtceu:block/pipe/normal_laser_pipe/center_active",
+ "loader": "gtceu:pipe",
+ "parts": {
+ "center": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/center_active"
+ },
+ "down": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection_active"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection_active",
+ "x": 90,
+ "y": 270
+ },
+ "north": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection_active",
+ "x": 90,
+ "y": 180
+ },
+ "south": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection_active",
+ "x": 90
+ },
+ "up": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection_active",
+ "x": 180
+ },
+ "west": {
+ "model": "gtceu:block/pipe/normal_laser_pipe/connection_active",
+ "x": 90,
+ "y": 90
+ }
+ },
+ "restrictors": {
+ "down": {
+ "model": "gtceu:block/pipe/restrictor/down/thickness_6.0"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/restrictor/east/thickness_6.0"
+ },
+ "north": {
+ "model": "gtceu:block/pipe/restrictor/north/thickness_6.0"
+ },
+ "south": {
+ "model": "gtceu:block/pipe/restrictor/south/thickness_6.0"
+ },
+ "up": {
+ "model": "gtceu:block/pipe/restrictor/up/thickness_6.0"
+ },
+ "west": {
+ "model": "gtceu:block/pipe/restrictor/west/thickness_6.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/normal_optical_pipe.json b/src/generated/resources/assets/gtceu/models/block/normal_optical_pipe.json
new file mode 100644
index 00000000000..e03e782ac34
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/normal_optical_pipe.json
@@ -0,0 +1,55 @@
+{
+ "parent": "gtceu:block/pipe/normal_optical_pipe/center",
+ "loader": "gtceu:pipe",
+ "parts": {
+ "center": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/center"
+ },
+ "down": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection",
+ "x": 90,
+ "y": 270
+ },
+ "north": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection",
+ "x": 90,
+ "y": 180
+ },
+ "south": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection",
+ "x": 90
+ },
+ "up": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection",
+ "x": 180
+ },
+ "west": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection",
+ "x": 90,
+ "y": 90
+ }
+ },
+ "restrictors": {
+ "down": {
+ "model": "gtceu:block/pipe/restrictor/down/thickness_6.0"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/restrictor/east/thickness_6.0"
+ },
+ "north": {
+ "model": "gtceu:block/pipe/restrictor/north/thickness_6.0"
+ },
+ "south": {
+ "model": "gtceu:block/pipe/restrictor/south/thickness_6.0"
+ },
+ "up": {
+ "model": "gtceu:block/pipe/restrictor/up/thickness_6.0"
+ },
+ "west": {
+ "model": "gtceu:block/pipe/restrictor/west/thickness_6.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/normal_optical_pipe_active.json b/src/generated/resources/assets/gtceu/models/block/normal_optical_pipe_active.json
new file mode 100644
index 00000000000..2a727149bb7
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/normal_optical_pipe_active.json
@@ -0,0 +1,55 @@
+{
+ "parent": "gtceu:block/pipe/normal_optical_pipe/center_active",
+ "loader": "gtceu:pipe",
+ "parts": {
+ "center": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/center_active"
+ },
+ "down": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection_active"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection_active",
+ "x": 90,
+ "y": 270
+ },
+ "north": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection_active",
+ "x": 90,
+ "y": 180
+ },
+ "south": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection_active",
+ "x": 90
+ },
+ "up": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection_active",
+ "x": 180
+ },
+ "west": {
+ "model": "gtceu:block/pipe/normal_optical_pipe/connection_active",
+ "x": 90,
+ "y": 90
+ }
+ },
+ "restrictors": {
+ "down": {
+ "model": "gtceu:block/pipe/restrictor/down/thickness_6.0"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/restrictor/east/thickness_6.0"
+ },
+ "north": {
+ "model": "gtceu:block/pipe/restrictor/north/thickness_6.0"
+ },
+ "south": {
+ "model": "gtceu:block/pipe/restrictor/south/thickness_6.0"
+ },
+ "up": {
+ "model": "gtceu:block/pipe/restrictor/up/thickness_6.0"
+ },
+ "west": {
+ "model": "gtceu:block/pipe/restrictor/west/thickness_6.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
new file mode 100644
index 00000000000..6318ac6c5b3
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
@@ -0,0 +1,47 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 1,
+ 1,
+ 1
+ ],
+ "to": [
+ 15,
+ 15,
+ 15
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
new file mode 100644
index 00000000000..b5f34317735
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
@@ -0,0 +1,48 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "cullface": "down",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 1,
+ 0,
+ 1
+ ],
+ "to": [
+ 15,
+ 1,
+ 15
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
new file mode 100644
index 00000000000..26aeac6acf3
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
@@ -0,0 +1,47 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 2,
+ 2,
+ 2
+ ],
+ "to": [
+ 14,
+ 14,
+ 14
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
new file mode 100644
index 00000000000..e5504c54c2b
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
@@ -0,0 +1,48 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "cullface": "down",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 2,
+ 0,
+ 2
+ ],
+ "to": [
+ 14,
+ 2,
+ 14
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
new file mode 100644
index 00000000000..55bac017a34
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
@@ -0,0 +1,47 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 4,
+ 4,
+ 4
+ ],
+ "to": [
+ 12,
+ 12,
+ 12
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
new file mode 100644
index 00000000000..c004f0de717
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
@@ -0,0 +1,48 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "cullface": "down",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 4,
+ 0,
+ 4
+ ],
+ "to": [
+ 12,
+ 4,
+ 12
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
new file mode 100644
index 00000000000..0cc3032c0e5
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
@@ -0,0 +1,86 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 5,
+ 5
+ ],
+ "to": [
+ 11,
+ 11,
+ 11
+ ]
+ },
+ {
+ "faces": {
+ "down": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "east": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "north": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "south": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "up": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ 4.998,
+ 4.998
+ ],
+ "to": [
+ 11.002,
+ 11.002,
+ 11.002
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_laser_in",
+ "side": "gtceu:block/pipe/pipe_laser_side",
+ "side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
new file mode 100644
index 00000000000..18781c339d2
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
@@ -0,0 +1,6 @@
+{
+ "parent": "gtceu:block/pipe/normal_laser_pipe/center",
+ "textures": {
+ "side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay_emissive"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
new file mode 100644
index 00000000000..7dc25d11fdd
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
@@ -0,0 +1,79 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "cullface": "down",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 0,
+ 5
+ ],
+ "to": [
+ 11,
+ 5,
+ 11
+ ]
+ },
+ {
+ "faces": {
+ "east": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "north": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "south": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ -0.002,
+ 4.998
+ ],
+ "to": [
+ 11.002,
+ 5.002,
+ 11.002
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_laser_in",
+ "side": "gtceu:block/pipe/pipe_laser_side",
+ "side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
new file mode 100644
index 00000000000..a9170249dab
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
@@ -0,0 +1,6 @@
+{
+ "parent": "gtceu:block/pipe/normal_laser_pipe/connection",
+ "textures": {
+ "side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay_emissive"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
new file mode 100644
index 00000000000..c5356268055
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
@@ -0,0 +1,86 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 5,
+ 5
+ ],
+ "to": [
+ 11,
+ 11,
+ 11
+ ]
+ },
+ {
+ "faces": {
+ "down": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "east": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "north": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "south": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "up": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ 4.998,
+ 4.998
+ ],
+ "to": [
+ 11.002,
+ 11.002,
+ 11.002
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_optical_in",
+ "side": "gtceu:block/pipe/pipe_optical_side",
+ "side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
new file mode 100644
index 00000000000..ac513d036e5
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
@@ -0,0 +1,6 @@
+{
+ "parent": "gtceu:block/pipe/normal_optical_pipe/center",
+ "textures": {
+ "side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay_active"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
new file mode 100644
index 00000000000..b7ee34bd7f4
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
@@ -0,0 +1,79 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "cullface": "down",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 0,
+ 5
+ ],
+ "to": [
+ 11,
+ 5,
+ 11
+ ]
+ },
+ {
+ "faces": {
+ "east": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "north": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "south": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ -0.002,
+ 4.998
+ ],
+ "to": [
+ 11.002,
+ 5.002,
+ 11.002
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_optical_in",
+ "side": "gtceu:block/pipe/pipe_optical_side",
+ "side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
new file mode 100644
index 00000000000..224c446f985
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
@@ -0,0 +1,6 @@
+{
+ "parent": "gtceu:block/pipe/normal_optical_pipe/connection",
+ "textures": {
+ "side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay_active"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_12.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_12.0.json
new file mode 100644
index 00000000000..5b9c48b1c26
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_12.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "east": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 1.997,
+ 0,
+ 1.997
+ ],
+ "to": [
+ 14.002999,
+ 1.997,
+ 14.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_14.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_14.0.json
new file mode 100644
index 00000000000..416426ed097
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_14.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "east": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 0.997,
+ 0,
+ 0.997
+ ],
+ "to": [
+ 15.002999,
+ 0.997,
+ 15.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_6.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_6.0.json
new file mode 100644
index 00000000000..f4b1b636e25
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_6.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "east": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 4.997,
+ 0,
+ 4.997
+ ],
+ "to": [
+ 11.002999,
+ 4.997,
+ 11.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_8.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_8.0.json
new file mode 100644
index 00000000000..a3d058279fb
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/down/thickness_8.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "east": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 3.997,
+ 0,
+ 3.997
+ ],
+ "to": [
+ 12.002999,
+ 3.997,
+ 12.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_12.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_12.0.json
new file mode 100644
index 00000000000..2da815fb976
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_12.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 14.002999,
+ 1.997,
+ 1.997
+ ],
+ "to": [
+ 16,
+ 14.002999,
+ 14.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_14.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_14.0.json
new file mode 100644
index 00000000000..37f0d67af2b
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_14.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 15.002999,
+ 0.997,
+ 0.997
+ ],
+ "to": [
+ 16,
+ 15.002999,
+ 15.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_6.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_6.0.json
new file mode 100644
index 00000000000..ec6b20399be
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_6.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 11.002999,
+ 4.997,
+ 4.997
+ ],
+ "to": [
+ 16,
+ 11.002999,
+ 11.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_8.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_8.0.json
new file mode 100644
index 00000000000..1d959d45a40
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/east/thickness_8.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 12.002999,
+ 3.997,
+ 3.997
+ ],
+ "to": [
+ 16,
+ 12.002999,
+ 12.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_12.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_12.0.json
new file mode 100644
index 00000000000..8868df86dae
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_12.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "east": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 1.997,
+ 1.997,
+ 0
+ ],
+ "to": [
+ 14.002999,
+ 14.002999,
+ 1.997
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_14.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_14.0.json
new file mode 100644
index 00000000000..4cd0913b8d2
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_14.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "east": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 0.997,
+ 0.997,
+ 0
+ ],
+ "to": [
+ 15.002999,
+ 15.002999,
+ 0.997
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_6.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_6.0.json
new file mode 100644
index 00000000000..c3e00fbaf0b
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_6.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "east": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 4.997,
+ 4.997,
+ 0
+ ],
+ "to": [
+ 11.002999,
+ 11.002999,
+ 4.997
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_8.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_8.0.json
new file mode 100644
index 00000000000..5b9a9154025
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/north/thickness_8.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "east": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 3.997,
+ 3.997,
+ 0
+ ],
+ "to": [
+ 12.002999,
+ 12.002999,
+ 3.997
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_12.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_12.0.json
new file mode 100644
index 00000000000..cbdb82d87be
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_12.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "east": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 1.997,
+ 1.997,
+ 14.002999
+ ],
+ "to": [
+ 14.002999,
+ 14.002999,
+ 16
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_14.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_14.0.json
new file mode 100644
index 00000000000..83a2616c294
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_14.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "east": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 0.997,
+ 0.997,
+ 15.002999
+ ],
+ "to": [
+ 15.002999,
+ 15.002999,
+ 16
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_6.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_6.0.json
new file mode 100644
index 00000000000..eaa3a5d4466
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_6.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "east": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 4.997,
+ 4.997,
+ 11.002999
+ ],
+ "to": [
+ 11.002999,
+ 11.002999,
+ 16
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_8.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_8.0.json
new file mode 100644
index 00000000000..4c807280980
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/south/thickness_8.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "east": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 3.997,
+ 3.997,
+ 12.002999
+ ],
+ "to": [
+ 12.002999,
+ 12.002999,
+ 16
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_12.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_12.0.json
new file mode 100644
index 00000000000..258ac3ed5c5
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_12.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "east": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 1.997,
+ 14.002999,
+ 1.997
+ ],
+ "to": [
+ 14.002999,
+ 16,
+ 14.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_14.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_14.0.json
new file mode 100644
index 00000000000..8b6bee1a4e7
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_14.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "east": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 0.997,
+ 15.002999,
+ 0.997
+ ],
+ "to": [
+ 15.002999,
+ 16,
+ 15.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_6.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_6.0.json
new file mode 100644
index 00000000000..4d07bcf8535
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_6.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "east": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 4.997,
+ 11.002999,
+ 4.997
+ ],
+ "to": [
+ 11.002999,
+ 16,
+ 11.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_8.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_8.0.json
new file mode 100644
index 00000000000..9269e828d47
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/up/thickness_8.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "east": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "west": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 3.997,
+ 12.002999,
+ 3.997
+ ],
+ "to": [
+ 12.002999,
+ 16,
+ 12.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_12.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_12.0.json
new file mode 100644
index 00000000000..84b76eea7fa
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_12.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 0,
+ 1.997,
+ 1.997
+ ],
+ "to": [
+ 1.997,
+ 14.002999,
+ 14.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_14.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_14.0.json
new file mode 100644
index 00000000000..b0d3d796931
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_14.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 0,
+ 0.997,
+ 0.997
+ ],
+ "to": [
+ 0.997,
+ 15.002999,
+ 15.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_6.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_6.0.json
new file mode 100644
index 00000000000..61dcdbf9677
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_6.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 0,
+ 4.997,
+ 4.997
+ ],
+ "to": [
+ 4.997,
+ 11.002999,
+ 11.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_8.0.json b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_8.0.json
new file mode 100644
index 00000000000..cca985d934d
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/restrictor/west/thickness_8.0.json
@@ -0,0 +1,33 @@
+{
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#restrictor"
+ },
+ "north": {
+ "texture": "#restrictor"
+ },
+ "south": {
+ "texture": "#restrictor"
+ },
+ "up": {
+ "texture": "#restrictor"
+ }
+ },
+ "from": [
+ 0,
+ 3.997,
+ 3.997
+ ],
+ "to": [
+ 3.997,
+ 12.002999,
+ 12.002999
+ ]
+ }
+ ],
+ "textures": {
+ "restrictor": "gtceu:block/pipe/blocked/pipe_blocked"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
new file mode 100644
index 00000000000..98a31bc47ef
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
@@ -0,0 +1,47 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 5,
+ 5
+ ],
+ "to": [
+ 11,
+ 11,
+ 11
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
new file mode 100644
index 00000000000..569180a1fba
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
@@ -0,0 +1,48 @@
+{
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "cullface": "down",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 0,
+ 5
+ ],
+ "to": [
+ 11,
+ 5,
+ 11
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/small_duct_pipe.json b/src/generated/resources/assets/gtceu/models/block/small_duct_pipe.json
new file mode 100644
index 00000000000..bf4e30317f4
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/block/small_duct_pipe.json
@@ -0,0 +1,55 @@
+{
+ "parent": "gtceu:block/pipe/small_duct_pipe/center",
+ "loader": "gtceu:pipe",
+ "parts": {
+ "center": {
+ "model": "gtceu:block/pipe/small_duct_pipe/center"
+ },
+ "down": {
+ "model": "gtceu:block/pipe/small_duct_pipe/connection"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/small_duct_pipe/connection",
+ "x": 90,
+ "y": 270
+ },
+ "north": {
+ "model": "gtceu:block/pipe/small_duct_pipe/connection",
+ "x": 90,
+ "y": 180
+ },
+ "south": {
+ "model": "gtceu:block/pipe/small_duct_pipe/connection",
+ "x": 90
+ },
+ "up": {
+ "model": "gtceu:block/pipe/small_duct_pipe/connection",
+ "x": 180
+ },
+ "west": {
+ "model": "gtceu:block/pipe/small_duct_pipe/connection",
+ "x": 90,
+ "y": 90
+ }
+ },
+ "restrictors": {
+ "down": {
+ "model": "gtceu:block/pipe/restrictor/down/thickness_6.0"
+ },
+ "east": {
+ "model": "gtceu:block/pipe/restrictor/east/thickness_6.0"
+ },
+ "north": {
+ "model": "gtceu:block/pipe/restrictor/north/thickness_6.0"
+ },
+ "south": {
+ "model": "gtceu:block/pipe/restrictor/south/thickness_6.0"
+ },
+ "up": {
+ "model": "gtceu:block/pipe/restrictor/up/thickness_6.0"
+ },
+ "west": {
+ "model": "gtceu:block/pipe/restrictor/west/thickness_6.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/item/huge_duct_pipe.json b/src/generated/resources/assets/gtceu/models/item/huge_duct_pipe.json
new file mode 100644
index 00000000000..6446bb669a9
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/item/huge_duct_pipe.json
@@ -0,0 +1,49 @@
+{
+ "parent": "gtceu:block/pipe/huge_duct_pipe/center",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "cullface": "north",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "south": {
+ "cullface": "south",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 1,
+ 1,
+ 0
+ ],
+ "to": [
+ 15,
+ 15,
+ 16
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/item/large_duct_pipe.json b/src/generated/resources/assets/gtceu/models/item/large_duct_pipe.json
new file mode 100644
index 00000000000..8ce685ee51f
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/item/large_duct_pipe.json
@@ -0,0 +1,49 @@
+{
+ "parent": "gtceu:block/pipe/large_duct_pipe/center",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "cullface": "north",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "south": {
+ "cullface": "south",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 2,
+ 2,
+ 0
+ ],
+ "to": [
+ 14,
+ 14,
+ 16
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/item/normal_duct_pipe.json b/src/generated/resources/assets/gtceu/models/item/normal_duct_pipe.json
new file mode 100644
index 00000000000..3b362236c0f
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/item/normal_duct_pipe.json
@@ -0,0 +1,49 @@
+{
+ "parent": "gtceu:block/pipe/normal_duct_pipe/center",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "cullface": "north",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "south": {
+ "cullface": "south",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 4,
+ 4,
+ 0
+ ],
+ "to": [
+ 12,
+ 12,
+ 16
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/item/normal_laser_pipe.json b/src/generated/resources/assets/gtceu/models/item/normal_laser_pipe.json
new file mode 100644
index 00000000000..112eb3bf581
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/item/normal_laser_pipe.json
@@ -0,0 +1,80 @@
+{
+ "parent": "gtceu:block/pipe/normal_laser_pipe/center",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "cullface": "north",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "south": {
+ "cullface": "south",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 5,
+ 0
+ ],
+ "to": [
+ 11,
+ 11,
+ 16
+ ]
+ },
+ {
+ "faces": {
+ "down": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "east": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "up": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ 4.998,
+ -0.002
+ ],
+ "to": [
+ 11.002,
+ 11.002,
+ 16.002
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_laser_in",
+ "side": "gtceu:block/pipe/pipe_laser_side",
+ "side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/item/normal_optical_pipe.json b/src/generated/resources/assets/gtceu/models/item/normal_optical_pipe.json
new file mode 100644
index 00000000000..d57881dac07
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/item/normal_optical_pipe.json
@@ -0,0 +1,80 @@
+{
+ "parent": "gtceu:block/pipe/normal_optical_pipe/center",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "cullface": "north",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "south": {
+ "cullface": "south",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 5,
+ 0
+ ],
+ "to": [
+ 11,
+ 11,
+ 16
+ ]
+ },
+ {
+ "faces": {
+ "down": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "east": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "up": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ 4.998,
+ -0.002
+ ],
+ "to": [
+ 11.002,
+ 11.002,
+ 16.002
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_optical_in",
+ "side": "gtceu:block/pipe/pipe_optical_side",
+ "side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/item/small_duct_pipe.json b/src/generated/resources/assets/gtceu/models/item/small_duct_pipe.json
new file mode 100644
index 00000000000..52c2a00a7ee
--- /dev/null
+++ b/src/generated/resources/assets/gtceu/models/item/small_duct_pipe.json
@@ -0,0 +1,49 @@
+{
+ "parent": "gtceu:block/pipe/small_duct_pipe/center",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "cullface": "north",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "south": {
+ "cullface": "south",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 5,
+ 0
+ ],
+ "to": [
+ 11,
+ 11,
+ 16
+ ]
+ }
+ ],
+ "textures": {
+ "end": "gtceu:block/pipe/pipe_duct_in",
+ "side": "gtceu:block/pipe/pipe_duct_side"
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gregtechceu/gtceu/GTCEu.java b/src/main/java/com/gregtechceu/gtceu/GTCEu.java
index fee2fc2b308..e7b1de43d39 100644
--- a/src/main/java/com/gregtechceu/gtceu/GTCEu.java
+++ b/src/main/java/com/gregtechceu/gtceu/GTCEu.java
@@ -32,6 +32,8 @@ public class GTCEu {
public static final String NAME = "GregTechCEu";
public static final Logger LOGGER = LogManager.getLogger(NAME);
+ public static final Path GTCEU_FOLDER = getGameDir().resolve("gtceu");
+
public GTCEu() {
GTCEu.init();
GTCEuAPI.instance = this;
diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/MaterialPipeBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/MaterialPipeBlock.java
index 07d640a090f..e47f1e862ec 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/block/MaterialPipeBlock.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/block/MaterialPipeBlock.java
@@ -3,8 +3,6 @@
import com.gregtechceu.gtceu.api.blockentity.IPaintable;
import com.gregtechceu.gtceu.api.data.chemical.material.Material;
import com.gregtechceu.gtceu.api.pipenet.*;
-import com.gregtechceu.gtceu.client.model.PipeModel;
-import com.gregtechceu.gtceu.client.renderer.block.PipeBlockRenderer;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.color.block.BlockColor;
@@ -28,14 +26,10 @@ public abstract class MaterialPipeBlock<
extends PipeBlock {
public final Material material;
- public final PipeBlockRenderer renderer;
- public final PipeModel model;
public MaterialPipeBlock(Properties properties, PipeType pipeType, Material material) {
super(properties, pipeType);
this.material = material;
- this.model = createPipeModel();
- this.renderer = new PipeBlockRenderer(this.model);
}
@OnlyIn(Dist.CLIENT)
@@ -57,11 +51,6 @@ public int tinted(BlockState blockState, @Nullable BlockAndTintGetter level, @Nu
return index == 0 || index == 1 ? material.getMaterialRGB() : -1;
}
- @Override
- protected PipeModel getPipeModel() {
- return model;
- }
-
@Override
public final NodeDataType createRawData(BlockState pState, @Nullable ItemStack pStack) {
return createMaterialData();
@@ -80,11 +69,6 @@ public NodeDataType createProperties(IPipeNode pipeTile)
protected abstract NodeDataType createProperties(PipeType pipeType, Material material);
- @Override
- public @Nullable PipeBlockRenderer getRenderer(BlockState state) {
- return renderer;
- }
-
@Override
public final NodeDataType getFallbackType() {
return createMaterialData();
@@ -92,8 +76,6 @@ public final NodeDataType getFallbackType() {
protected abstract NodeDataType createMaterialData();
- protected abstract PipeModel createPipeModel();
-
@Override
public String getDescriptionId() {
return pipeType.getTagPrefix().getUnlocalizedName(material);
diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java
index c4079b9f324..a77fbb5cc62 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java
@@ -13,17 +13,16 @@
import com.gregtechceu.gtceu.api.pipenet.IPipeType;
import com.gregtechceu.gtceu.api.pipenet.LevelPipeNet;
import com.gregtechceu.gtceu.api.pipenet.PipeNet;
-import com.gregtechceu.gtceu.client.model.PipeModel;
-import com.gregtechceu.gtceu.client.renderer.block.PipeBlockRenderer;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
import com.gregtechceu.gtceu.common.data.GTItems;
import com.gregtechceu.gtceu.common.data.GTMaterialBlocks;
import com.gregtechceu.gtceu.common.item.CoverPlaceBehavior;
import com.gregtechceu.gtceu.config.ConfigHolder;
import com.gregtechceu.gtceu.data.recipe.VanillaRecipeHelper;
+import com.gregtechceu.gtceu.utils.GTMath;
import com.gregtechceu.gtceu.utils.GTUtil;
-import com.lowdragmc.lowdraglib.client.renderer.IBlockRendererProvider;
-
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -62,10 +61,9 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.joml.Vector3f;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import javax.annotation.ParametersAreNonnullByDefault;
@@ -74,19 +72,32 @@
@MethodsReturnNonnullByDefault
public abstract class PipeBlock & IPipeType, NodeDataType,
WorldPipeNetType extends LevelPipeNet>> extends Block
- implements EntityBlock, IBlockRendererProvider, SimpleWaterloggedBlock {
+ implements EntityBlock, SimpleWaterloggedBlock {
public final PipeType pipeType;
+ protected final Map shapes = new IdentityHashMap<>();
+
public PipeBlock(Properties properties, PipeType pipeType) {
super(properties);
this.pipeType = pipeType;
registerDefaultState(defaultBlockState().setValue(BlockStateProperties.WATERLOGGED, false));
+
+ float min = (16 - pipeType.getThickness() * 16) / 2f;
+ float max = min + pipeType.getThickness() * 16;
+ shapes.put(null, Block.box(min, min, min, max, max, max));
+ for (Direction dir : GTUtil.DIRECTIONS) {
+ var coords = GTMath.getCoordinates(dir, min, max);
+ Vector3f minCoord = coords.getLeft();
+ Vector3f maxCoord = coords.getRight();
+ shapes.put(dir, Block.box(minCoord.x, minCoord.y, minCoord.z, maxCoord.x, maxCoord.y, maxCoord.z));
+ }
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder builder) {
- super.createBlockStateDefinition(builder.add(BlockStateProperties.WATERLOGGED));
+ super.createBlockStateDefinition(builder);
+ builder.add(BlockStateProperties.WATERLOGGED);
}
@Override
@@ -129,11 +140,7 @@ public NodeDataType createProperties(BlockState state, @Nullable ItemStack stack
*/
public abstract NodeDataType getFallbackType();
- @Nullable
- @Override
- public abstract PipeBlockRenderer getRenderer(BlockState state);
-
- protected abstract PipeModel getPipeModel();
+ public abstract PipeModel createPipeModel(GTBlockstateProvider provider);
public void updateActiveNodeStatus(@NotNull Level worldIn, BlockPos pos,
IPipeNode pipeTile) {
@@ -400,7 +407,7 @@ public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos,
return Shapes.block();
}
connections = pipeNode.getVisualConnections();
- VoxelShape shape = getPipeModel().getShapes(connections);
+ VoxelShape shape = getShapes(connections);
shape = Shapes.or(shape, pipeNode.getCoverContainer().addCoverCollisionBoundingBox());
if (context instanceof EntityCollisionContext entityCtx && entityCtx.getEntity() instanceof Player player) {
@@ -424,7 +431,7 @@ public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos,
}
return shape;
}
- return getPipeModel().getShapes(connections);
+ return getShapes(connections);
}
@Nullable
@@ -475,4 +482,11 @@ public List getDrops(BlockState state, LootParams.Builder builder) {
public GTToolType getPipeTuneTool() {
return GTToolType.WRENCH;
}
+
+ public VoxelShape getShapes(int connections) {
+ return this.shapes.entrySet().stream()
+ .filter(entry -> entry.getKey() == null || PipeBlockEntity.isConnected(connections, entry.getKey()))
+ .map(Map.Entry::getValue)
+ .reduce(Shapes.empty(), Shapes::or);
+ }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java
index db0589bd9c4..380debf6782 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java
@@ -314,9 +314,9 @@ public AABB getRenderBoundingBox() {
BlockRenderDispatcher blockRenderDispatcher = Minecraft.getInstance().getBlockRenderer();
BakedModel model = blockRenderDispatcher.getBlockModel(this.getBlockState());
- if (model instanceof IBlockEntityRendererBakedModel> modelWithBER) {
- if (modelWithBER.getBlockEntityType() == this.getType()) {
- return ((IBlockEntityRendererBakedModel) modelWithBER)
+ if (model instanceof IBlockEntityRendererBakedModel> berModel) {
+ if (berModel.getBlockEntityType() != null && berModel.getBlockEntityType() == this.getType()) {
+ return ((IBlockEntityRendererBakedModel) berModel)
.getRenderBoundingBox(this);
}
}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/DuctPipeBlockItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/DuctPipeBlockItem.java
deleted file mode 100644
index 5563d6a4097..00000000000
--- a/src/main/java/com/gregtechceu/gtceu/api/item/DuctPipeBlockItem.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.gregtechceu.gtceu.api.item;
-
-import com.gregtechceu.gtceu.common.block.DuctPipeBlock;
-
-import com.lowdragmc.lowdraglib.client.renderer.IItemRendererProvider;
-import com.lowdragmc.lowdraglib.client.renderer.IRenderer;
-
-import net.minecraft.world.item.ItemStack;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class DuctPipeBlockItem extends PipeBlockItem implements IItemRendererProvider {
-
- public DuctPipeBlockItem(DuctPipeBlock block, Properties properties) {
- super(block, properties);
- }
-
- @Override
- @NotNull
- public DuctPipeBlock getBlock() {
- return (DuctPipeBlock) super.getBlock();
- }
-
- @Nullable
- @Override
- public IRenderer getRenderer(ItemStack stack) {
- return getBlock().getRenderer(getBlock().defaultBlockState());
- }
-}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/LampBlockItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/LampBlockItem.java
index f56af127f4a..d07587b9b57 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/item/LampBlockItem.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/item/LampBlockItem.java
@@ -1,20 +1,29 @@
package com.gregtechceu.gtceu.api.item;
+import com.gregtechceu.gtceu.GTCEu;
+import com.gregtechceu.gtceu.client.renderer.block.LampItemRenderer;
+import com.gregtechceu.gtceu.client.util.ModelUtils;
import com.gregtechceu.gtceu.common.block.LampBlock;
-import com.lowdragmc.lowdraglib.client.renderer.IItemRendererProvider;
-import com.lowdragmc.lowdraglib.client.renderer.IRenderer;
-
+import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
+import net.minecraft.client.resources.model.BakedModel;
+import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.core.NonNullList;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.state.BlockState;
+import net.minecraftforge.client.extensions.common.IClientItemExtensions;
+import net.minecraftforge.client.model.BakedModelWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.function.Consumer;
+
import javax.annotation.ParametersAreNonnullByDefault;
import static com.gregtechceu.gtceu.common.block.LampBlock.isBloomEnabled;
@@ -22,10 +31,14 @@
import static com.gregtechceu.gtceu.common.block.LampBlock.isLightEnabled;
@ParametersAreNonnullByDefault
-public class LampBlockItem extends BlockItem implements IItemRendererProvider {
+public class LampBlockItem extends BlockItem {
public LampBlockItem(LampBlock block, Properties properties) {
super(block, properties);
+
+ if (GTCEu.isClientSide()) {
+ ClientCallWrapper.registerEventListener(this);
+ }
}
@NotNull
@@ -37,16 +50,19 @@ public LampBlock getBlock() {
@Nullable
@Override
protected BlockState getPlacementState(BlockPlaceContext context) {
- BlockState returnValue = super.getPlacementState(context);
- ItemStack handItem = context.getItemInHand();
- if (returnValue != null && handItem.hasTag()) {
- var tag = handItem.getTag();
- returnValue = returnValue
- .setValue(LampBlock.INVERTED, isInverted(tag))
- .setValue(LampBlock.BLOOM, isBloomEnabled(tag))
- .setValue(LampBlock.LIGHT, isLightEnabled(tag));
+ BlockState state = super.getPlacementState(context);
+ return getStateFromStack(context.getItemInHand(), state);
+ }
+
+ public BlockState getStateFromStack(ItemStack stack, @Nullable BlockState baseState) {
+ if (!stack.hasTag() || !stack.is(this)) {
+ return baseState;
}
- return returnValue;
+ var tag = stack.getTag();
+ return (baseState != null ? baseState : getBlock().defaultBlockState())
+ .setValue(LampBlock.INVERTED, isInverted(tag))
+ .setValue(LampBlock.BLOOM, isBloomEnabled(tag))
+ .setValue(LampBlock.LIGHT, isLightEnabled(tag));
}
public void fillItemCategory(CreativeModeTab category, NonNullList items) {
@@ -55,17 +71,35 @@ public void fillItemCategory(CreativeModeTab category, NonNullList it
}
}
- @Nullable
@Override
- public IRenderer getRenderer(ItemStack stack) {
- BlockState state = getBlock().defaultBlockState();
- if (stack.hasTag()) {
- var tag = stack.getTag();
- state = state
- .setValue(LampBlock.INVERTED, isInverted(tag))
- .setValue(LampBlock.BLOOM, isBloomEnabled(tag))
- .setValue(LampBlock.LIGHT, isLightEnabled(tag));
+ public void initializeClient(Consumer consumer) {
+ consumer.accept(new IClientItemExtensions() {
+
+ @Override
+ public BlockEntityWithoutLevelRenderer getCustomRenderer() {
+ return LampItemRenderer.INSTANCE;
+ }
+ });
+ }
+
+ private static class ClientCallWrapper {
+
+ private static void registerEventListener(LampBlockItem item) {
+ ModelUtils.registerBakeEventListener(false, event -> {
+ ResourceLocation model = BuiltInRegistries.ITEM.getKey(item).withPrefix("item/");
+ BakedModel original = event.getModels().get(model);
+ if (original == null) {
+ model = new ModelResourceLocation(model, "inventory");
+ original = event.getModels().get(model);
+ }
+ event.getModels().put(model, new BakedModelWrapper<>(original) {
+
+ @Override
+ public boolean isCustomRenderer() {
+ return true;
+ }
+ });
+ });
}
- return getBlock().getRenderer(state);
}
}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/LaserPipeBlockItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/LaserPipeBlockItem.java
index dfaef338c15..3f34616dc3c 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/item/LaserPipeBlockItem.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/item/LaserPipeBlockItem.java
@@ -3,20 +3,14 @@
import com.gregtechceu.gtceu.api.block.PipeBlock;
import com.gregtechceu.gtceu.common.block.LaserPipeBlock;
-import com.lowdragmc.lowdraglib.client.renderer.IItemRendererProvider;
-import com.lowdragmc.lowdraglib.client.renderer.IRenderer;
-
import net.minecraft.client.color.item.ItemColor;
-import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
-import org.jetbrains.annotations.Nullable;
-
import javax.annotation.ParametersAreNonnullByDefault;
@ParametersAreNonnullByDefault
-public class LaserPipeBlockItem extends PipeBlockItem implements IItemRendererProvider {
+public class LaserPipeBlockItem extends PipeBlockItem {
public LaserPipeBlockItem(PipeBlock block, Properties properties) {
super(block, properties);
@@ -37,11 +31,4 @@ public static ItemColor tintColor() {
return -1;
};
}
-
- @Nullable
- @Override
- @OnlyIn(Dist.CLIENT)
- public IRenderer getRenderer(ItemStack stack) {
- return getBlock().getRenderer(getBlock().defaultBlockState());
- }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/MaterialPipeBlockItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/MaterialPipeBlockItem.java
index 97851db6697..22f63a6cf8f 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/item/MaterialPipeBlockItem.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/item/MaterialPipeBlockItem.java
@@ -2,9 +2,6 @@
import com.gregtechceu.gtceu.api.block.MaterialPipeBlock;
-import com.lowdragmc.lowdraglib.client.renderer.IItemRendererProvider;
-import com.lowdragmc.lowdraglib.client.renderer.IRenderer;
-
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.network.chat.Component;
@@ -13,13 +10,12 @@
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
-public class MaterialPipeBlockItem extends PipeBlockItem implements IItemRendererProvider {
+public class MaterialPipeBlockItem extends PipeBlockItem {
public MaterialPipeBlockItem(MaterialPipeBlock block, Properties properties) {
super(block, properties);
@@ -42,13 +38,6 @@ public static ItemColor tintColor() {
};
}
- @Nullable
- @Override
- @OnlyIn(Dist.CLIENT)
- public IRenderer getRenderer(ItemStack stack) {
- return getBlock().getRenderer(getBlock().defaultBlockState());
- }
-
@Override
public Component getDescription() {
return this.getBlock().getName();
diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/OpticalPipeBlockItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/OpticalPipeBlockItem.java
deleted file mode 100644
index ed59e05ded9..00000000000
--- a/src/main/java/com/gregtechceu/gtceu/api/item/OpticalPipeBlockItem.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.gregtechceu.gtceu.api.item;
-
-import com.gregtechceu.gtceu.common.block.OpticalPipeBlock;
-
-import com.lowdragmc.lowdraglib.client.renderer.IItemRendererProvider;
-import com.lowdragmc.lowdraglib.client.renderer.IRenderer;
-
-import net.minecraft.world.item.ItemStack;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
-
-import org.jetbrains.annotations.Nullable;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
-@ParametersAreNonnullByDefault
-public class OpticalPipeBlockItem extends PipeBlockItem implements IItemRendererProvider {
-
- public OpticalPipeBlockItem(OpticalPipeBlock block, Properties properties) {
- super(block, properties);
- }
-
- @Nullable
- @Override
- @OnlyIn(Dist.CLIENT)
- public IRenderer getRenderer(ItemStack stack) {
- return getBlock().getRenderer(getBlock().defaultBlockState());
- }
-}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/IMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/machine/IMachineBlockEntity.java
index df3ff0930d0..187fe5df909 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/machine/IMachineBlockEntity.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/machine/IMachineBlockEntity.java
@@ -13,12 +13,10 @@
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
-import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.client.model.data.ModelData;
-import net.minecraftforge.client.model.data.ModelProperty;
import net.minecraftforge.common.extensions.IForgeBlockEntity;
import org.jetbrains.annotations.NotNull;
@@ -31,9 +29,6 @@
public interface IMachineBlockEntity extends IToolGridHighlight, IAsyncAutoSyncBlockEntity, IRPCBlockEntity,
IAutoPersistBlockEntity, IPaintable, IForgeBlockEntity {
- ModelProperty MODEL_DATA_LEVEL = new ModelProperty<>();
- ModelProperty MODEL_DATA_POS = new ModelProperty<>();
-
default BlockEntity self() {
return (BlockEntity) this;
}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTBlockBuilder.java b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTBlockBuilder.java
index c1ba8744fb0..17dfee8d336 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTBlockBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTBlockBuilder.java
@@ -38,6 +38,10 @@ public GTBlockBuilder exBlockstate(NonNullBiConsumer cons.accept(ctx, (GTBlockstateProvider) prov));
}
+ public GTBlockBuilder gtBlockstate(NonNullBiConsumer, GTBlockstateProvider> cons) {
+ return setData(ProviderType.BLOCKSTATE, (ctx, prov) -> cons.accept(ctx, (GTBlockstateProvider) prov));
+ }
+
// region default overrides
@Override
@@ -122,6 +126,11 @@ public GTBlockBuilder setDataGeneric(Provid
return this;
}
+ @Override
+ public GTBlockBuilder setData(ProviderType extends D> type, NonNullBiConsumer, D> cons) {
+ return (GTBlockBuilder) super.setData(type, cons);
+ }
+
// spotless:on
// endregion
}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java
index b676b92f0cb..ee9020c53fc 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java
@@ -27,6 +27,7 @@
import com.gregtechceu.gtceu.common.data.models.GTMachineModels;
import com.gregtechceu.gtceu.config.ConfigHolder;
import com.gregtechceu.gtceu.data.model.builder.MachineModelBuilder;
+import com.gregtechceu.gtceu.utils.data.RuntimeBlockstateProvider;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.renderer.RenderType;
@@ -76,7 +77,6 @@
import javax.annotation.ParametersAreNonnullByDefault;
import static com.gregtechceu.gtceu.common.data.models.GTMachineModels.*;
-import static com.gregtechceu.gtceu.integration.kjs.GregTechKubeJSPlugin.RUNTIME_BLOCKSTATE_PROVIDER;
@SuppressWarnings("unused")
@ParametersAreNonnullByDefault
@@ -818,9 +818,10 @@ public static void generateAssetJsons(@Nullable As
// Fake a data provider for the GT model builders
var context = new DataGenContext<>(definition::getBlock, definition.getName(), id);
if (builder.blockModel() != null) {
- builder.blockModel().accept(context, RUNTIME_BLOCKSTATE_PROVIDER);
+ builder.blockModel().accept(context, RuntimeBlockstateProvider.INSTANCE);
} else {
- GTMachineModels.createMachineModel(builder.model()).accept(context, RUNTIME_BLOCKSTATE_PROVIDER);
+ GTMachineModels.createMachineModel(builder.model())
+ .accept(context, RuntimeBlockstateProvider.INSTANCE);
}
} else {
generator.itemModel(id, gen -> gen.parent(id.withPrefix("block/machine/").toString()));
diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/provider/GTBlockstateProvider.java b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/provider/GTBlockstateProvider.java
index 40bf8542286..6b7789b5159 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/provider/GTBlockstateProvider.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/provider/GTBlockstateProvider.java
@@ -78,14 +78,17 @@ public MultiVariantGenerator multiVariantGenerator(Block block) {
public MultiVariantGenerator multiVariantGenerator(Block block, Variant baseVariant) {
var multiVariant = MultiVariantGenerator.multiVariant(block, baseVariant);
- registeredBlocks.put(block, new BlockStateGeneratorWrapper(multiVariant));
- return multiVariant;
+ return addVanillaGenerator(block, multiVariant);
}
public MultiPartGenerator multiPartGenerator(Block block) {
var multiPart = MultiPartGenerator.multiPart(block);
- registeredBlocks.put(block, new BlockStateGeneratorWrapper(multiPart));
- return multiPart;
+ return addVanillaGenerator(block, multiPart);
+ }
+
+ public T addVanillaGenerator(Block block, T generator) {
+ registeredBlocks.put(block, new BlockStateGeneratorWrapper(generator));
+ return generator;
}
public static @Nullable PropertyDispatch createFacingDispatch(MachineDefinition definition) {
diff --git a/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java b/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java
index 0f3b72535e4..c4bc0f934da 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java
@@ -13,10 +13,18 @@
import com.gregtechceu.gtceu.api.item.QuantumTankMachineItem;
import com.gregtechceu.gtceu.client.model.item.FacadeUnbakedModel;
import com.gregtechceu.gtceu.client.model.machine.MachineModelLoader;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModelLoader;
import com.gregtechceu.gtceu.client.particle.HazardParticle;
import com.gregtechceu.gtceu.client.particle.MufflerParticle;
+import com.gregtechceu.gtceu.client.renderer.block.MaterialBlockRenderer;
+import com.gregtechceu.gtceu.client.renderer.block.OreBlockRenderer;
+import com.gregtechceu.gtceu.client.renderer.block.SurfaceRockRenderer;
import com.gregtechceu.gtceu.client.renderer.entity.GTBoatRenderer;
import com.gregtechceu.gtceu.client.renderer.entity.GTExplosiveRenderer;
+import com.gregtechceu.gtceu.client.renderer.item.ArmorItemRenderer;
+import com.gregtechceu.gtceu.client.renderer.item.TagPrefixItemRenderer;
+import com.gregtechceu.gtceu.client.renderer.item.ToolItemRenderer;
import com.gregtechceu.gtceu.client.renderer.item.decorator.GTComponentItemDecorator;
import com.gregtechceu.gtceu.client.renderer.item.decorator.GTLampItemOverlayRenderer;
import com.gregtechceu.gtceu.client.renderer.item.decorator.GTTankItemFluidPreview;
@@ -27,17 +35,23 @@
import com.gregtechceu.gtceu.common.CommonProxy;
import com.gregtechceu.gtceu.common.data.GTBlockEntities;
import com.gregtechceu.gtceu.common.data.GTEntityTypes;
+import com.gregtechceu.gtceu.common.data.GTMaterialBlocks;
import com.gregtechceu.gtceu.common.data.GTParticleTypes;
+import com.gregtechceu.gtceu.common.data.models.GTModels;
import com.gregtechceu.gtceu.common.entity.GTBoat;
import com.gregtechceu.gtceu.common.machine.owner.MachineOwner;
import com.gregtechceu.gtceu.config.ConfigHolder;
+import com.gregtechceu.gtceu.data.model.builder.PipeModelBuilder;
+import com.gregtechceu.gtceu.data.pack.event.RegisterDynamicResourcesEvent;
import com.gregtechceu.gtceu.forge.ForgeCommonEventListener;
+import com.gregtechceu.gtceu.integration.kjs.GregTechKubeJSPlugin;
import com.gregtechceu.gtceu.integration.map.ClientCacheManager;
import com.gregtechceu.gtceu.integration.map.cache.client.GTClientCache;
import com.gregtechceu.gtceu.integration.map.ftbchunks.FTBChunksPlugin;
import com.gregtechceu.gtceu.integration.map.layer.Layers;
import com.gregtechceu.gtceu.integration.map.layer.builtin.FluidRenderLayer;
import com.gregtechceu.gtceu.integration.map.layer.builtin.OreRenderLayer;
+import com.gregtechceu.gtceu.utils.data.RuntimeBlockstateProvider;
import com.gregtechceu.gtceu.utils.input.SyncedKeyMapping;
import net.minecraft.client.model.BoatModel;
@@ -49,6 +63,7 @@
import net.minecraft.world.item.Item;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.event.*;
+import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.registries.ForgeRegistries;
@@ -158,6 +173,50 @@ public static void initializeDynamicRenders() {
@SubscribeEvent
public void onRegisterModelLoaders(ModelEvent.RegisterGeometryLoaders event) {
event.register(MachineModelLoader.ID.getPath(), MachineModelLoader.INSTANCE);
+ event.register(PipeModelLoader.ID.getPath(), PipeModelLoader.INSTANCE);
event.register("facade", FacadeUnbakedModel.Loader.INSTANCE);
}
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void preRegisterDynamicAssets(RegisterDynamicResourcesEvent event) {
+ PipeModel.DYNAMIC_MODELS.clear();
+ }
+
+ @SubscribeEvent
+ public void registerDynamicAssets(RegisterDynamicResourcesEvent event) {
+ // regenerate all pipe models in case their textures changed
+ // cables may do this, others too if something's removed
+ for (var block : GTMaterialBlocks.CABLE_BLOCKS.values()) {
+ if (block == null) continue;
+ block.get().createPipeModel(RuntimeBlockstateProvider.INSTANCE).dynamicModel();
+ }
+ for (var block : GTMaterialBlocks.FLUID_PIPE_BLOCKS.values()) {
+ if (block == null) continue;
+ block.get().createPipeModel(RuntimeBlockstateProvider.INSTANCE).dynamicModel();
+ }
+ for (var block : GTMaterialBlocks.ITEM_PIPE_BLOCKS.values()) {
+ if (block == null) continue;
+ block.get().createPipeModel(RuntimeBlockstateProvider.INSTANCE).dynamicModel();
+ }
+
+ MaterialBlockRenderer.reinitModels();
+ TagPrefixItemRenderer.reinitModels();
+ OreBlockRenderer.reinitModels();
+ ToolItemRenderer.reinitModels();
+ ArmorItemRenderer.reinitModels();
+ SurfaceRockRenderer.reinitModels();
+ GTModels.registerMaterialFluidModels();
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOWEST)
+ public void postRegisterDynamicAssets(RegisterDynamicResourcesEvent event) {
+ // do this last so addons can easily add new variants to the registered model set
+ PipeModel.initDynamicModels();
+
+ if (GTCEu.Mods.isKubeJSLoaded()) {
+ GregTechKubeJSPlugin.generateMachineBlockModels();
+ }
+ RuntimeBlockstateProvider.INSTANCE.run();
+ PipeModelBuilder.clearRestrictorModelCache();
+ }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/BaseBakedModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/BaseBakedModel.java
index f91a52c0b2a..484ee5656e2 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/BaseBakedModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/BaseBakedModel.java
@@ -9,8 +9,6 @@
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.IDynamicBakedModel;
-import org.jetbrains.annotations.NotNull;
-
public abstract class BaseBakedModel implements IDynamicBakedModel {
public BaseBakedModel() {}
@@ -37,13 +35,13 @@ public boolean isCustomRenderer() {
@Override
@OnlyIn(Dist.CLIENT)
- public @NotNull ItemOverrides getOverrides() {
+ public ItemOverrides getOverrides() {
return ItemOverrides.EMPTY;
}
@Override
@OnlyIn(Dist.CLIENT)
- public @NotNull TextureAtlasSprite getParticleIcon() {
+ public TextureAtlasSprite getParticleIcon() {
return Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS)
.apply(MissingTextureAtlasSprite.getLocation());
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java b/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java
new file mode 100644
index 00000000000..2f58894072b
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java
@@ -0,0 +1,16 @@
+package com.gregtechceu.gtceu.client.model;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.BlockAndTintGetter;
+import net.minecraftforge.client.model.data.ModelProperty;
+
+public class GTModelProperties {
+
+ public static final ModelProperty LEVEL = new ModelProperty<>();
+ public static final ModelProperty POS = new ModelProperty<>();
+
+ public static final ModelProperty PIPE_CONNECTION_MASK = new ModelProperty<>();
+ public static final ModelProperty PIPE_BLOCKED_MASK = new ModelProperty<>();
+
+ public static final ModelProperty PIPE_ACTIVE = new ModelProperty<>();
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/IBlockEntityRendererBakedModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/IBlockEntityRendererBakedModel.java
index 6a59d976574..001442720cc 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/IBlockEntityRendererBakedModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/IBlockEntityRendererBakedModel.java
@@ -12,21 +12,21 @@
import net.minecraftforge.client.model.IDynamicBakedModel;
import com.mojang.blaze3d.vertex.PoseStack;
-import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public interface IBlockEntityRendererBakedModel
extends IDynamicBakedModel, BlockEntityRenderer {
+ @Nullable
BlockEntityType extends T> getBlockEntityType();
- void render(@NotNull T blockEntity, float partialTick,
- @NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer,
+ void render(T blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource buffer,
int packedLight, int packedOverlay);
default void renderByItem(ItemStack stack, ItemDisplayContext displayContext,
PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) {}
- default boolean shouldRender(T blockEntity, @NotNull Vec3 cameraPos) {
+ default boolean shouldRender(T blockEntity, Vec3 cameraPos) {
return Vec3.atCenterOf(blockEntity.getBlockPos()).closerThan(cameraPos, this.getViewDistance());
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/PipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/PipeModel.java
deleted file mode 100644
index efdff6bb28b..00000000000
--- a/src/main/java/com/gregtechceu/gtceu/client/model/PipeModel.java
+++ /dev/null
@@ -1,357 +0,0 @@
-package com.gregtechceu.gtceu.client.model;
-
-import com.gregtechceu.gtceu.GTCEu;
-import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
-import com.gregtechceu.gtceu.client.util.ModelUtils;
-import com.gregtechceu.gtceu.common.data.models.GTModels;
-import com.gregtechceu.gtceu.utils.GTUtil;
-import com.gregtechceu.gtceu.utils.memoization.GTMemoizer;
-import com.gregtechceu.gtceu.utils.memoization.MemoizedSupplier;
-
-import com.lowdragmc.lowdraglib.client.bakedpipeline.FaceQuad;
-import com.lowdragmc.lowdraglib.client.renderer.IItemRendererProvider;
-
-import net.minecraft.Util;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.MultiBufferSource;
-import net.minecraft.client.renderer.block.model.BakedQuad;
-import net.minecraft.client.renderer.texture.TextureAtlas;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.core.Direction;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.world.inventory.InventoryMenu;
-import net.minecraft.world.item.ItemDisplayContext;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.phys.AABB;
-import net.minecraft.world.phys.shapes.Shapes;
-import net.minecraft.world.phys.shapes.VoxelShape;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
-
-import com.mojang.blaze3d.vertex.PoseStack;
-import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
-import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
-import lombok.Setter;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-public class PipeModel {
-
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY = GTCEu.id("block/pipe/blocked/pipe_blocked");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_UP = GTCEu.id("block/pipe/blocked/pipe_blocked_up");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_DOWN = GTCEu.id("block/pipe/blocked/pipe_blocked_down");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_LEFT = GTCEu.id("block/pipe/blocked/pipe_blocked_left");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_RIGHT = GTCEu.id("block/pipe/blocked/pipe_blocked_right");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_NU = GTCEu.id("block/pipe/blocked/pipe_blocked_nu");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_ND = GTCEu.id("block/pipe/blocked/pipe_blocked_nd");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_NL = GTCEu.id("block/pipe/blocked/pipe_blocked_nl");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_NR = GTCEu.id("block/pipe/blocked/pipe_blocked_nr");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_UD = GTCEu.id("block/pipe/blocked/pipe_blocked_ud");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_UL = GTCEu.id("block/pipe/blocked/pipe_blocked_ul");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_UR = GTCEu.id("block/pipe/blocked/pipe_blocked_ur");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_DL = GTCEu.id("block/pipe/blocked/pipe_blocked_dl");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_DR = GTCEu.id("block/pipe/blocked/pipe_blocked_dr");
- public static final ResourceLocation PIPE_BLOCKED_OVERLAY_LR = GTCEu.id("block/pipe/blocked/pipe_blocked_lr");
- private static final Int2ObjectMap RESTRICTOR_MAP = new Int2ObjectOpenHashMap<>();
- private static boolean isRestrictorInitialized;
-
- protected static void initializeRestrictor(Function atlas) {
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_UP), Border.TOP);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_DOWN), Border.BOTTOM);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_UD), Border.TOP, Border.BOTTOM);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_LEFT), Border.LEFT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_UL), Border.TOP, Border.LEFT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_DL), Border.BOTTOM, Border.LEFT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_NR), Border.TOP, Border.BOTTOM, Border.LEFT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_RIGHT), Border.RIGHT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_UR), Border.TOP, Border.RIGHT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_DR), Border.BOTTOM, Border.RIGHT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_NL), Border.TOP, Border.BOTTOM, Border.RIGHT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_LR), Border.LEFT, Border.RIGHT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_ND), Border.TOP, Border.LEFT, Border.RIGHT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY_NU), Border.BOTTOM, Border.LEFT, Border.RIGHT);
- addRestrictor(atlas.apply(PIPE_BLOCKED_OVERLAY), Border.TOP, Border.BOTTOM, Border.LEFT, Border.RIGHT);
- }
-
- private static final EnumMap> FACE_BORDER_MAP = Util.make(() -> {
- EnumMap> map = new EnumMap<>(Direction.class);
-
- map.put(Direction.DOWN, borderMap(Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST));
- map.put(Direction.UP, borderMap(Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST));
- map.put(Direction.NORTH, borderMap(Direction.DOWN, Direction.UP, Direction.WEST, Direction.EAST));
- map.put(Direction.SOUTH, borderMap(Direction.DOWN, Direction.UP, Direction.WEST, Direction.EAST));
- map.put(Direction.WEST, borderMap(Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH));
- map.put(Direction.EAST, borderMap(Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH));
-
- return map;
- });
-
- public final static int ITEM_CONNECTIONS = 0b001100;
- public final float thickness;
- public final AABB coreCube;
- public final Map sideCubes;
-
- public MemoizedSupplier sideTexture, endTexture;
- @Nullable
- public MemoizedSupplier secondarySideTexture, secondaryEndTexture;
- @Setter
- public @Nullable ResourceLocation sideOverlayTexture, endOverlayTexture;
-
- @OnlyIn(Dist.CLIENT)
- private @Nullable TextureAtlasSprite sideSprite, endSprite;
- @OnlyIn(Dist.CLIENT)
- private @Nullable TextureAtlasSprite secondarySideSprite, secondaryEndSprite;
- @OnlyIn(Dist.CLIENT)
- private @Nullable TextureAtlasSprite sideOverlaySprite, endOverlaySprite;
-
- public PipeModel(float thickness, Supplier sideTexture, Supplier endTexture,
- @Nullable Supplier secondarySideTexture,
- @Nullable Supplier secondaryEndTexture) {
- this.sideTexture = GTMemoizer.memoize(sideTexture);
- this.endTexture = GTMemoizer.memoize(endTexture);
- this.secondarySideTexture = secondarySideTexture != null ? GTMemoizer.memoize(secondarySideTexture) :
- null;
- this.secondaryEndTexture = secondaryEndTexture != null ? GTMemoizer.memoize(secondaryEndTexture) : null;
- this.thickness = thickness;
- double min = (1d - thickness) / 2;
- double max = min + thickness;
- this.coreCube = new AABB(min, min, min, max, max, max);
- this.sideCubes = new EnumMap<>(Direction.class);
- for (Direction side : GTUtil.DIRECTIONS) {
- var normal = side.getNormal();
- sideCubes.put(side, new AABB(
- normal.getX() == 0 ? min : normal.getX() > 0 ? max : 0,
- normal.getY() == 0 ? min : normal.getY() > 0 ? max : 0,
- normal.getZ() == 0 ? min : normal.getZ() > 0 ? max : 0,
- normal.getX() == 0 ? max : normal.getX() > 0 ? 1 : min,
- normal.getY() == 0 ? max : normal.getY() > 0 ? 1 : min,
- normal.getZ() == 0 ? max : normal.getZ() > 0 ? 1 : min));
- }
-
- if (!isRestrictorInitialized) {
- ModelUtils.registerAtlasStitchedEventListener(false, InventoryMenu.BLOCK_ATLAS, event -> {
- initializeRestrictor(event.getAtlas()::getSprite);
- });
-
- isRestrictorInitialized = true;
- }
- ModelUtils.registerAtlasStitchedEventListener(false, InventoryMenu.BLOCK_ATLAS, event -> {
- TextureAtlas atlas = event.getAtlas();
-
- sideSprite = atlas.getSprite(sideTexture.get());
- endSprite = atlas.getSprite(endTexture.get());
- if (secondarySideTexture != null) {
- secondarySideSprite = atlas.getSprite(secondarySideTexture.get());
- }
- if (secondaryEndTexture != null) {
- secondaryEndSprite = atlas.getSprite(secondaryEndTexture.get());
- }
- if (sideOverlayTexture != null) {
- sideOverlaySprite = atlas.getSprite(sideOverlayTexture);
- }
- if (endOverlayTexture != null) {
- endOverlaySprite = atlas.getSprite(endOverlayTexture);
- }
- });
- }
-
- public VoxelShape getShapes(int connections) {
- var shapes = new ArrayList(7);
- shapes.add(Shapes.create(coreCube));
- for (Direction side : GTUtil.DIRECTIONS) {
- if (PipeBlockEntity.isConnected(connections, side)) {
- shapes.add(Shapes.create(sideCubes.get(side)));
- }
- }
- return shapes.stream().reduce(Shapes.empty(), Shapes::or);
- }
-
- @OnlyIn(Dist.CLIENT)
- public List bakeQuads(@Nullable Direction side, int connections, int blockedConnections) {
- if (side != null) {
- if (thickness == 1) { // full block
- List quads = new LinkedList<>();
- quads.add(FaceQuad.builder(side, sideSprite).cube(coreCube).cubeUV().tintIndex(0).bake());
- if (secondarySideSprite != null) {
- quads.add(FaceQuad.builder(side, secondarySideSprite).cube(coreCube).cubeUV().tintIndex(0).bake());
- }
- return quads;
- }
-
- if (PipeBlockEntity.isConnected(connections, side)) { // side connected
- List quads = new LinkedList<>();
- quads.add(FaceQuad.builder(side, endSprite).cube(sideCubes.get(side).inflate(-0.001)).cubeUV()
- .tintIndex(1).bake());
- if (secondaryEndSprite != null) {
- quads.add(FaceQuad.builder(side, secondaryEndSprite).cube(sideCubes.get(side)).cubeUV().tintIndex(1)
- .bake());
- }
- if (endOverlaySprite != null) {
- quads.add(FaceQuad.builder(side, endOverlaySprite).cube(sideCubes.get(side)).cubeUV().tintIndex(0)
- .bake());
- }
- if (sideOverlaySprite != null) {
- for (Direction face : GTUtil.DIRECTIONS) {
- if (face.getAxis() != side.getAxis()) {
- quads.add(FaceQuad.builder(face, sideOverlaySprite).cube(sideCubes.get(side)).cubeUV()
- .tintIndex(2).bake());
- }
- }
- }
- int borderMask = computeBorderMask(blockedConnections, connections, side);
- if (borderMask != 0) {
- quads.add(FaceQuad.builder(side, RESTRICTOR_MAP.get(borderMask)).cube(sideCubes.get(side)).cubeUV()
- .bake());
- }
- return quads;
- }
-
- return Collections.emptyList();
- }
-
- List quads = new LinkedList<>();
- if (thickness < 1) { // non full block
- // render core cube
- for (Direction face : GTUtil.DIRECTIONS) {
- if (!PipeBlockEntity.isConnected(connections, face)) {
- quads.add(FaceQuad.builder(face, sideSprite).cube(coreCube).cubeUV().tintIndex(0).bake());
- if (secondarySideSprite != null) {
- quads.add(FaceQuad.builder(face, secondarySideSprite).cube(coreCube).cubeUV().tintIndex(0)
- .bake());
- }
- }
- // render each connected side
- for (Direction facing : GTUtil.DIRECTIONS) {
- if (facing.getAxis() != face.getAxis()) {
- if (PipeBlockEntity.isConnected(connections, facing)) {
- quads.add(FaceQuad.builder(face, sideSprite).cube(sideCubes.get(facing)).cubeUV()
- .tintIndex(0).bake());
- if (secondarySideSprite != null) {
- quads.add(FaceQuad.builder(face, secondarySideSprite).cube(sideCubes.get(facing))
- .cubeUV().tintIndex(0).bake());
- }
- if (sideOverlaySprite != null) {
- quads.add(FaceQuad.builder(face, sideOverlaySprite)
- .cube(sideCubes.get(facing).inflate(0.001)).cubeUV().tintIndex(2).bake());
- }
- int borderMask = computeBorderMask(blockedConnections, connections, face);
- if (borderMask != 0) {
- quads.add(FaceQuad.builder(face, RESTRICTOR_MAP.get(borderMask))
- .cube(coreCube).cubeUV().bake());
- quads.add(FaceQuad.builder(face, RESTRICTOR_MAP.get(borderMask))
- .cube(sideCubes.get(facing)).cubeUV().bake());
- }
- }
- }
- }
- }
- }
- return quads;
- }
-
- @SuppressWarnings("DataFlowIssue")
- @OnlyIn(Dist.CLIENT)
- public @NotNull TextureAtlasSprite getParticleTexture() {
- return sideSprite;
- }
-
- private final Map, List> itemModelCache = new ConcurrentHashMap<>();
-
- @OnlyIn(Dist.CLIENT)
- public void renderItem(ItemStack stack, ItemDisplayContext transformType, boolean leftHand, PoseStack matrixStack,
- MultiBufferSource buffer, int combinedLight, int combinedOverlay, BakedModel model) {
- IItemRendererProvider.disabled.set(true);
- Minecraft.getInstance().getItemRenderer().render(stack, transformType, leftHand, matrixStack, buffer,
- combinedLight, combinedOverlay,
- (ItemBakedModel) (state, direction, random) -> itemModelCache.computeIfAbsent(
- Optional.ofNullable(direction),
- direction1 -> bakeQuads(direction1.orElse(null), ITEM_CONNECTIONS, 0)));
- IItemRendererProvider.disabled.set(false);
- }
-
- @OnlyIn(Dist.CLIENT)
- public void registerTextureAtlas(Consumer register) {
- itemModelCache.clear();
- sideTexture.invalidate();
- register.accept(sideTexture.get());
- endTexture.invalidate();
- register.accept(endTexture.get());
- if (secondarySideTexture != null) {
- secondarySideTexture.invalidate();
- if (secondarySideTexture.get() != GTModels.BLANK_TEXTURE) {
- register.accept(secondarySideTexture.get());
- }
- }
- if (secondaryEndTexture != null) {
- secondaryEndTexture.invalidate();
- if (secondaryEndTexture.get() != GTModels.BLANK_TEXTURE) {
- register.accept(secondaryEndTexture.get());
- }
- }
- if (sideOverlayTexture != null) register.accept(sideOverlayTexture);
- if (endOverlayTexture != null) register.accept(endOverlayTexture);
- sideSprite = null;
- endSprite = null;
- endOverlaySprite = null;
- }
-
- private static EnumMap borderMap(Direction topSide, Direction bottomSide, Direction leftSide,
- Direction rightSide) {
- EnumMap sideMap = new EnumMap<>(Border.class);
- sideMap.put(Border.TOP, topSide);
- sideMap.put(Border.BOTTOM, bottomSide);
- sideMap.put(Border.LEFT, leftSide);
- sideMap.put(Border.RIGHT, rightSide);
- return sideMap;
- }
-
- private static void addRestrictor(TextureAtlasSprite sprite, Border... borders) {
- int mask = 0;
- for (Border border : borders) {
- mask |= border.mask;
- }
- RESTRICTOR_MAP.put(mask, sprite);
- }
-
- protected static Direction getSideAtBorder(Direction side, Border border) {
- return FACE_BORDER_MAP.get(side).get(border);
- }
-
- protected static int computeBorderMask(int blockedConnections, int connections, Direction side) {
- int borderMask = 0;
- if (blockedConnections != 0) {
- for (Border border : Border.VALUES) {
- Direction borderSide = getSideAtBorder(side, border);
- if (PipeBlockEntity.isFaceBlocked(blockedConnections, borderSide) &&
- PipeBlockEntity.isConnected(connections, borderSide)) {
- // only render when the side is blocked *and* connected
- borderMask |= border.mask;
- }
- }
- }
- return borderMask;
- }
-
- public enum Border {
-
- TOP,
- BOTTOM,
- LEFT,
- RIGHT;
-
- public static final Border[] VALUES = values();
-
- public final int mask;
-
- Border() {
- mask = 1 << this.ordinal();
- }
- }
-}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java
index c20eb618e68..0b765ceba79 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java
@@ -9,6 +9,7 @@
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController;
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart;
import com.gregtechceu.gtceu.client.model.BaseBakedModel;
+import com.gregtechceu.gtceu.client.model.GTModelProperties;
import com.gregtechceu.gtceu.client.model.IBlockEntityRendererBakedModel;
import com.gregtechceu.gtceu.client.model.TextureOverrideModel;
import com.gregtechceu.gtceu.client.model.machine.multipart.MultiPartBakedModel;
@@ -52,15 +53,12 @@
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
-import static com.gregtechceu.gtceu.api.machine.IMachineBlockEntity.*;
-
public final class MachineModel extends BaseBakedModel implements ICoverableRenderer,
IBlockEntityRendererBakedModel {
@@ -138,7 +136,7 @@ public static void initSprites(TextureAtlas atlas) {
@SuppressWarnings("deprecation")
@Override
- public @NotNull TextureAtlasSprite getParticleIcon() {
+ public TextureAtlasSprite getParticleIcon() {
if (particleIcon != null) {
return particleIcon;
} else if (multiPart != null) {
@@ -152,9 +150,9 @@ public static void initSprites(TextureAtlas atlas) {
}
@Override
- public TextureAtlasSprite getParticleIcon(@NotNull ModelData modelData) {
- BlockAndTintGetter level = modelData.get(MODEL_DATA_LEVEL);
- BlockPos pos = modelData.get(MODEL_DATA_POS);
+ public TextureAtlasSprite getParticleIcon(ModelData modelData) {
+ BlockAndTintGetter level = modelData.get(GTModelProperties.LEVEL);
+ BlockPos pos = modelData.get(GTModelProperties.POS);
MetaMachine machine = (level == null || pos == null) ? null : MetaMachine.getMachine(level, pos);
MachineRenderState renderState = machine != null ? machine.getRenderState() :
@@ -171,11 +169,11 @@ public TextureAtlasSprite getParticleIcon(@NotNull ModelData modelData) {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
- public @NotNull ModelData getModelData(@NotNull BlockAndTintGetter level, @NotNull BlockPos pos,
- @NotNull BlockState state, @NotNull ModelData modelData) {
+ public ModelData getModelData(BlockAndTintGetter level, BlockPos pos,
+ BlockState state, ModelData modelData) {
ModelData.Builder builder = modelData.derive()
- .with(MODEL_DATA_LEVEL, level)
- .with(MODEL_DATA_POS, pos);
+ .with(GTModelProperties.LEVEL, level)
+ .with(GTModelProperties.POS, pos);
MetaMachine machine = MetaMachine.getMachine(level, pos);
MachineRenderState renderState = machine == null ? definition.defaultRenderState() : machine.getRenderState();
@@ -193,9 +191,9 @@ public TextureAtlasSprite getParticleIcon(@NotNull ModelData modelData) {
}
@Override
- public @NotNull List getQuads(@Nullable BlockState state, @Nullable Direction side,
- @NotNull RandomSource rand,
- @NotNull ModelData modelData, @Nullable RenderType renderType) {
+ public List getQuads(@Nullable BlockState state, @Nullable Direction side,
+ RandomSource rand,
+ ModelData modelData, @Nullable RenderType renderType) {
// If there is a root transform, undo the ModelState transform, apply it,
// then re-apply the ModelState transform.
// This is necessary because of things like UV locking, which should only respond to the ModelState,
@@ -206,7 +204,7 @@ public TextureAtlasSprite getParticleIcon(@NotNull ModelData modelData) {
}
List quads;
- if (modelData.has(MODEL_DATA_LEVEL) && modelData.has(MODEL_DATA_POS)) {
+ if (modelData.has(GTModelProperties.LEVEL) && modelData.has(GTModelProperties.POS)) {
quads = getMachineQuads(state, side, rand, modelData, renderType);
} else {
// if it doesn't have either of those properties, we're rendering an item.
@@ -217,10 +215,10 @@ public TextureAtlasSprite getParticleIcon(@NotNull ModelData modelData) {
}
public List getMachineQuads(@Nullable BlockState blockState, @Nullable Direction side,
- @NotNull RandomSource rand, @NotNull ModelData modelData,
+ RandomSource rand, ModelData modelData,
@Nullable RenderType renderType) {
- BlockAndTintGetter level = modelData.get(MODEL_DATA_LEVEL);
- BlockPos pos = modelData.get(MODEL_DATA_POS);
+ BlockAndTintGetter level = modelData.get(GTModelProperties.LEVEL);
+ BlockPos pos = modelData.get(GTModelProperties.POS);
MetaMachine machine = (level == null || pos == null) ? null : MetaMachine.getMachine(level, pos);
// render machine quads
@@ -261,7 +259,7 @@ public List getMachineQuads(@Nullable BlockState blockState, @Nullabl
public List renderMachine(@Nullable MetaMachine machine, @Nullable BlockAndTintGetter level,
@Nullable BlockPos pos, @Nullable BlockState blockState,
@Nullable Direction side, RandomSource rand,
- @NotNull ModelData modelData, @Nullable RenderType renderType) {
+ ModelData modelData, @Nullable RenderType renderType) {
List quads = new LinkedList<>();
MachineRenderState renderState = machine != null ? machine.getRenderState() : definition.defaultRenderState();
@@ -283,9 +281,9 @@ public List renderMachine(@Nullable MetaMachine machine, @Nullable Bl
return quads;
}
- public void renderBaseModel(List quads, @NotNull MachineRenderState renderState,
+ public void renderBaseModel(List quads, MachineRenderState renderState,
@Nullable BlockState blockState, @Nullable Direction side, RandomSource rand,
- @NotNull ModelData modelData, @Nullable RenderType renderType) {
+ ModelData modelData, @Nullable RenderType renderType) {
if (multiPart != null) {
quads.addAll(multiPart.getMachineQuads(definition, renderState, blockState,
side, rand, modelData, renderType));
@@ -387,8 +385,8 @@ public boolean isCustomRenderer() {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
- public void render(@NotNull BlockEntity blockEntity, float partialTick,
- @NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer,
+ public void render(BlockEntity blockEntity, float partialTick,
+ PoseStack poseStack, MultiBufferSource buffer,
int packedLight, int packedOverlay) {
if (!(blockEntity instanceof IMachineBlockEntity machineBE)) return;
if (machineBE.getDefinition() != getDefinition()) return;
@@ -449,7 +447,7 @@ public boolean shouldRenderOffScreen(BlockEntity blockEntity) {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
- public boolean shouldRender(BlockEntity blockEntity, @NotNull Vec3 cameraPos) {
+ public boolean shouldRender(BlockEntity blockEntity, Vec3 cameraPos) {
if (!(blockEntity instanceof IMachineBlockEntity machineBE)) return false;
if (machineBE.getDefinition() != getDefinition()) return false;
if (machineBE.getMetaMachine().getCoverContainer().hasDynamicCovers()) return true;
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModelLoader.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModelLoader.java
index 934b511a0ea..9dc6e3e532a 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModelLoader.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModelLoader.java
@@ -63,7 +63,7 @@ public class MachineModelLoader implements IGeometryLoader
private static final Splitter COMMA_SPLITTER = Splitter.on(',');
private static final Splitter EQUAL_SPLITTER = Splitter.on('=').limit(2);
- private static final UnbakedModel MISSING_MARKER = new BasicUnbakedModel();
+ public static final UnbakedModel MISSING_MARKER = new BasicUnbakedModel();
private MachineModelLoader() {}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/multipart/MultiPartBakedModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/multipart/MultiPartBakedModel.java
index 2835f96414f..ef19e96f369 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/multipart/MultiPartBakedModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/multipart/MultiPartBakedModel.java
@@ -2,6 +2,7 @@
import com.gregtechceu.gtceu.api.machine.MachineDefinition;
import com.gregtechceu.gtceu.api.machine.MetaMachine;
+import com.gregtechceu.gtceu.client.model.GTModelProperties;
import com.gregtechceu.gtceu.client.model.machine.MachineRenderState;
import net.minecraft.Util;
@@ -33,8 +34,6 @@
import java.util.*;
import java.util.function.Predicate;
-import static com.gregtechceu.gtceu.api.machine.IMachineBlockEntity.*;
-
public class MultiPartBakedModel implements IDynamicBakedModel {
private final List, BakedModel>> selectors;
@@ -115,8 +114,8 @@ public List getMachineQuads(MachineDefinition definition, MachineRend
@Override
public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, ModelData modelData) {
- BlockAndTintGetter level = modelData.get(MODEL_DATA_LEVEL);
- BlockPos pos = modelData.get(MODEL_DATA_POS);
+ BlockAndTintGetter level = modelData.get(GTModelProperties.LEVEL);
+ BlockPos pos = modelData.get(GTModelProperties.POS);
var machine = (level == null || pos == null) ? null : MetaMachine.getMachine(level, pos);
if (machine == null) return IDynamicBakedModel.super.getRenderTypes(state, rand, modelData);
@@ -137,8 +136,8 @@ public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, Mo
@Override
public ModelData getModelData(BlockAndTintGetter level, BlockPos pos, BlockState state, ModelData modelData) {
ModelData.Builder builder = modelData.derive()
- .with(MODEL_DATA_LEVEL, level)
- .with(MODEL_DATA_POS, pos);
+ .with(GTModelProperties.LEVEL, level)
+ .with(GTModelProperties.POS, pos);
var machine = MetaMachine.getMachine(level, pos);
if (machine == null) return builder.build();
@@ -183,8 +182,8 @@ public boolean isCustomRenderer() {
@Override
public TextureAtlasSprite getParticleIcon(ModelData modelData) {
- BlockAndTintGetter level = modelData.get(MODEL_DATA_LEVEL);
- BlockPos pos = modelData.get(MODEL_DATA_POS);
+ BlockAndTintGetter level = modelData.get(GTModelProperties.LEVEL);
+ BlockPos pos = modelData.get(GTModelProperties.POS);
var machine = (level == null || pos == null) ? null : MetaMachine.getMachine(level, pos);
if (machine != null) return getParticleIcon(machine.getRenderState(), modelData);
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/variant/MultiVariantModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/variant/MultiVariantModel.java
index dcf7da73340..57e7defb97a 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/variant/MultiVariantModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/variant/MultiVariantModel.java
@@ -70,8 +70,8 @@ public void resolveParents(@NotNull Function res
@OnlyIn(Dist.CLIENT)
public static class Deserializer implements JsonDeserializer {
- public MultiVariantModel deserialize(JsonElement json, Type type, JsonDeserializationContext context)
- throws JsonParseException {
+ public MultiVariantModel deserialize(JsonElement json, Type type,
+ JsonDeserializationContext context) throws JsonParseException {
List variants = new ArrayList<>();
if (json.isJsonArray()) {
JsonArray array = json.getAsJsonArray();
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
new file mode 100644
index 00000000000..dc257bd4770
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
@@ -0,0 +1,169 @@
+package com.gregtechceu.gtceu.client.model.pipe;
+
+import com.gregtechceu.gtceu.api.block.PipeBlock;
+import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.data.model.builder.PipeModelBuilder;
+
+import net.minecraft.resources.ResourceLocation;
+import net.minecraftforge.client.model.generators.BlockModelBuilder;
+import net.minecraftforge.client.model.generators.IGeneratedBlockState;
+
+import lombok.Setter;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+
+public class ActivablePipeModel extends PipeModel {
+
+ @Setter
+ public @Nullable ResourceLocation sideActive, endActive;
+ @Setter
+ public @Nullable ResourceLocation sideSecondaryActive, endSecondaryActive;
+ @Setter
+ public @Nullable ResourceLocation sideOverlayActive, endOverlayActive;
+
+ /// Use {@link #getOrCreateActiveBlockModel()} instead of referencing this field directly.
+ private BlockModelBuilder activeBlockModel;
+ /// Use {@link #getOrCreateActiveCenterElement()} instead of referencing this field directly.
+ private BlockModelBuilder activeCenterElement;
+ /// Use {@link #getOrCreateActiveConnectionElement()} instead of referencing this field directly.
+ private BlockModelBuilder activeConnectionElement;
+
+ public ActivablePipeModel(PipeBlock, ?, ?> block, float thickness, ResourceLocation side, ResourceLocation end,
+ GTBlockstateProvider provider) {
+ super(block, provider, thickness, side, end);
+ }
+
+ /**
+ * @see #getOrCreateActiveBlockModel()
+ * @see #getOrCreateConnectionElement()
+ * @see #getOrCreateActiveCenterElement()
+ * @see #getOrCreateActiveConnectionElement()
+ */
+ @Override
+ public void initModels() {
+ getOrCreateActiveCenterElement();
+ getOrCreateActiveConnectionElement();
+ getOrCreateActiveBlockModel();
+
+ super.initModels();
+ }
+
+ /**
+ * Override this to change the actual model {@link #block this.block} will use.
+ *
+ * @return A model builder for the block's actual model.
+ * @see #getOrCreateBlockModel()
+ * @see #getOrCreateActiveCenterElement()
+ * @see #getOrCreateActiveConnectionElement()
+ */
+ @ApiStatus.OverrideOnly
+ protected BlockModelBuilder getOrCreateActiveBlockModel() {
+ if (this.activeBlockModel != null) {
+ return this.activeBlockModel;
+ }
+ // spotless:off
+ return this.activeBlockModel = this.provider.models().getBuilder(this.blockId.withSuffix("_active").toString())
+ .parent(this.getOrCreateActiveCenterElement())
+ .customLoader(PipeModelBuilder::begin)
+ .thickness(this.thickness).provider(this.provider)
+ .centerModels(this.getOrCreateActiveCenterElement().getLocation())
+ .connectionModels(this.getOrCreateActiveConnectionElement().getLocation())
+ .end();
+ // spotless:on
+ }
+
+ /**
+ * Override this to change the center element's model for when the pipe is active.
+ *
+ * @return A model builder for the center element's model.
+ * @see #getOrCreateCenterElement()
+ * @see #getOrCreateActiveConnectionElement()
+ */
+ @ApiStatus.OverrideOnly
+ protected BlockModelBuilder getOrCreateActiveCenterElement() {
+ if (this.activeCenterElement != null) {
+ return this.activeCenterElement;
+ }
+ return this.activeCenterElement = makeActiveVariant(this.getOrCreateCenterElement());
+ }
+
+ /**
+ * Override this to change the 'connection' element's model for when the pipe is active.
+ * By default, this is rotated & used for all connected sides of the pipe.
+ * Note that that is not a hard requirement, and that you may set a model per side in
+ * {@link #getOrCreateBlockModel()}.
+ *
+ * @return A model builder for the connection element's model.
+ * @see #getOrCreateConnectionElement()
+ * @see #getOrCreateActiveCenterElement()
+ */
+ @ApiStatus.OverrideOnly
+ protected BlockModelBuilder getOrCreateActiveConnectionElement() {
+ if (this.activeConnectionElement != null) {
+ return this.activeConnectionElement;
+ }
+ return this.activeConnectionElement = makeActiveVariant(this.getOrCreateConnectionElement());
+ }
+
+ protected BlockModelBuilder makeActiveVariant(BlockModelBuilder parentModel) {
+ BlockModelBuilder model = this.provider.models()
+ .getBuilder(parentModel.getLocation().withSuffix("_active").toString())
+ .parent(parentModel);
+ // override non-null textures, leave unset ones as is
+ if (this.sideActive != null) model.texture("side", this.sideActive);
+ if (this.endActive != null) model.texture("end", this.endActive);
+ if (this.sideSecondaryActive != null) model.texture("side_secondary", this.sideSecondaryActive);
+ if (this.endSecondaryActive != null) model.texture("end_secondary", this.endSecondaryActive);
+ if (this.sideOverlayActive != null) model.texture("side_overlay", this.sideOverlayActive);
+ if (this.endOverlayActive != null) model.texture("end_overlay", this.endOverlayActive);
+
+ return model;
+ }
+
+ @Override
+ public IGeneratedBlockState createBlockState() {
+ if (!this.getBlock().defaultBlockState().hasProperty(GTBlockStateProperties.ACTIVE)) {
+ return super.createBlockState();
+ }
+ // spotless:off
+ return this.provider.getVariantBuilder(this.getBlock())
+ .partialState()
+ .with(GTBlockStateProperties.ACTIVE, false)
+ .modelForState()
+ .modelFile(this.provider.models().getExistingFile(this.blockId))
+ .addModel()
+ .partialState()
+ .with(GTBlockStateProperties.ACTIVE, true)
+ .modelForState()
+ .modelFile(this.provider.models().getExistingFile(this.blockId.withSuffix("_active")))
+ .addModel();
+ // spotless:on
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof ActivablePipeModel pipeModel)) return false;
+ return super.equals(o) &&
+ Objects.equals(sideActive, pipeModel.sideActive) &&
+ Objects.equals(endActive, pipeModel.endActive) &&
+ Objects.equals(sideSecondaryActive, pipeModel.sideSecondaryActive) &&
+ Objects.equals(endSecondaryActive, pipeModel.endSecondaryActive) &&
+ Objects.equals(sideOverlayActive, pipeModel.sideOverlayActive) &&
+ Objects.equals(endOverlayActive, pipeModel.endOverlayActive);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + Objects.hashCode(sideActive);
+ result = 31 * result + Objects.hashCode(endActive);
+ result = 31 * result + Objects.hashCode(sideSecondaryActive);
+ result = 31 * result + Objects.hashCode(endSecondaryActive);
+ result = 31 * result + Objects.hashCode(sideOverlayActive);
+ result = 31 * result + Objects.hashCode(endOverlayActive);
+ return result;
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java
new file mode 100644
index 00000000000..cba98fe97b3
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java
@@ -0,0 +1,152 @@
+package com.gregtechceu.gtceu.client.model.pipe;
+
+import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
+import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
+import com.gregtechceu.gtceu.api.pipenet.IPipeNode;
+import com.gregtechceu.gtceu.api.pipenet.Node;
+import com.gregtechceu.gtceu.client.model.BaseBakedModel;
+import com.gregtechceu.gtceu.client.model.GTModelProperties;
+import com.gregtechceu.gtceu.client.model.IBlockEntityRendererBakedModel;
+import com.gregtechceu.gtceu.client.renderer.cover.ICoverableRenderer;
+import com.gregtechceu.gtceu.client.util.GTQuadTransformers;
+import com.gregtechceu.gtceu.common.data.GTMaterialBlocks;
+import com.gregtechceu.gtceu.utils.GTUtil;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.color.block.BlockColors;
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.client.renderer.RenderType;
+import net.minecraft.client.renderer.block.model.BakedQuad;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.resources.model.BakedModel;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.util.RandomSource;
+import net.minecraft.world.level.BlockAndTintGetter;
+import net.minecraft.world.level.block.entity.BlockEntityType;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraftforge.client.model.data.ModelData;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class BakedPipeModel extends BaseBakedModel implements ICoverableRenderer,
+ IBlockEntityRendererBakedModel> {
+
+ public final static int ITEM_CONNECTIONS = 0b001100;
+
+ private final Map parts;
+ private final Map restrictors;
+
+ public BakedPipeModel(Map parts, Map restrictors) {
+ this.parts = parts;
+ this.restrictors = restrictors;
+ }
+
+ @Override
+ public List getQuads(@Nullable BlockState state, @Nullable Direction side,
+ RandomSource rand, ModelData modelData, @Nullable RenderType renderType) {
+ List quads = new ArrayList<>();
+
+ BlockAndTintGetter level = modelData.get(GTModelProperties.LEVEL);
+ BlockPos pos = modelData.get(GTModelProperties.POS);
+ Integer connectionMask = modelData.get(GTModelProperties.PIPE_CONNECTION_MASK);
+ Integer blockedMask = modelData.get(GTModelProperties.PIPE_BLOCKED_MASK);
+
+ if (level == null || pos == null || state == null) {
+ connectionMask = ITEM_CONNECTIONS;
+ blockedMask = Node.ALL_CLOSED;
+ }
+ if (connectionMask == null || connectionMask != Node.ALL_OPENED) {
+ quads.addAll(parts.get(null).getQuads(state, side, rand, modelData, renderType));
+ if (connectionMask == null) {
+ // return unconnected base model if the model property isn't set
+ return quads;
+ }
+ }
+ for (Direction dir : GTUtil.DIRECTIONS) {
+ if (PipeBlockEntity.isConnected(connectionMask, dir)) {
+ quads.addAll(parts.get(dir).getQuads(state, side, rand, modelData, renderType));
+ if (blockedMask != null && PipeBlockEntity.isFaceBlocked(blockedMask, dir)) {
+ quads.addAll(restrictors.get(dir).getQuads(state, side, rand, modelData, renderType));
+ }
+ }
+ }
+ if (level == null || pos == null || !(level.getBlockEntity(pos) instanceof IPipeNode, ?> pipeNode)) {
+ return quads;
+ }
+ ICoverableRenderer.super.renderCovers(quads, pipeNode.getCoverContainer(), pos, level, side, rand,
+ modelData, renderType);
+
+ if (pipeNode.getFrameMaterial().isNull() || (renderType != null && renderType != RenderType.translucent())) {
+ return quads;
+ }
+ var frameBlockEntry = GTMaterialBlocks.MATERIAL_BLOCKS.get(TagPrefix.frameGt, pipeNode.getFrameMaterial());
+ if (frameBlockEntry == null) {
+ return quads;
+ }
+ BlockState frameState = frameBlockEntry.getDefaultState();
+ BakedModel frameModel = Minecraft.getInstance().getBlockRenderer().getBlockModel(frameState);
+
+ modelData = frameModel.getModelData(level, pos, frameState, modelData);
+
+ List frameQuads = new LinkedList<>();
+ if (side == null || pipeNode.getCoverContainer().getCoverAtSide(side) == null) {
+ frameQuads.addAll(frameModel.getQuads(state, side, rand, modelData, renderType));
+ }
+
+ if (side == null) {
+ for (Direction face : GTUtil.DIRECTIONS) {
+ if (pipeNode.getCoverContainer().getCoverAtSide(face) != null) {
+ continue;
+ }
+ frameQuads.addAll(frameModel.getQuads(state, face, rand, modelData, renderType));
+ }
+ }
+
+ // bake all the quads' tint colors into the vertices
+ BlockColors blockColors = Minecraft.getInstance().getBlockColors();
+ for (BakedQuad frameQuad : frameQuads) {
+ if (frameQuad.isTinted()) {
+ int color = blockColors.getColor(frameState, level, pos, frameQuad.getTintIndex());
+ frameQuad = GTQuadTransformers.setColor(frameQuad, color, true);
+ }
+ quads.add(frameQuad);
+ }
+ return quads;
+ }
+
+ @Override
+ public ModelData getModelData(BlockAndTintGetter level, BlockPos pos, BlockState state, ModelData modelData) {
+ ModelData.Builder builder = modelData.derive()
+ .with(GTModelProperties.LEVEL, level)
+ .with(GTModelProperties.POS, pos);
+
+ if (!(level.getBlockEntity(pos) instanceof PipeBlockEntity, ?> blockEntity)) {
+ return builder.build();
+ }
+ return builder.with(GTModelProperties.PIPE_CONNECTION_MASK, blockEntity.getVisualConnections())
+ .with(GTModelProperties.PIPE_BLOCKED_MASK, blockEntity.getBlockedConnections())
+ .build();
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public TextureAtlasSprite getParticleIcon() {
+ return parts.get(null).getParticleIcon();
+ }
+
+ @Override
+ public @Nullable BlockEntityType extends PipeBlockEntity, ?>> getBlockEntityType() {
+ return null;
+ }
+
+ @Override
+ public void render(PipeBlockEntity, ?> blockEntity, float partialTick, PoseStack poseStack,
+ MultiBufferSource buffer, int packedLight, int packedOverlay) {}
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
new file mode 100644
index 00000000000..83f0ceeb9ca
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
@@ -0,0 +1,377 @@
+package com.gregtechceu.gtceu.client.model.pipe;
+
+import com.gregtechceu.gtceu.api.block.PipeBlock;
+import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties;
+import com.gregtechceu.gtceu.api.registry.registrate.GTBlockBuilder;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.data.model.builder.PipeModelBuilder;
+import com.gregtechceu.gtceu.data.pack.event.RegisterDynamicResourcesEvent;
+import com.gregtechceu.gtceu.utils.GTMath;
+import com.gregtechceu.gtceu.utils.GTUtil;
+
+import net.minecraft.core.Direction;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.data.models.blockstates.MultiVariantGenerator;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraftforge.client.model.generators.*;
+
+import com.tterrag.registrate.util.nullness.NonNullBiConsumer;
+import it.unimi.dsi.fastutil.objects.Reference2FloatMap;
+import it.unimi.dsi.fastutil.objects.Reference2FloatOpenHashMap;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * This is an automatic pipe model generator.
+ *
+ * For material pipes
+ * If the pipe this model belongs to is generated from a material property (or equivalent),
+ * you should call {@link #dynamicModel()}, which adds the model to {@link #DYNAMIC_MODELS}
+ * and automatically processes it as a part of runtime asset generation.
+ *
+ * NOTE:
+ * You must also initialize the models in an {@link RegisterDynamicResourcesEvent} listener as such:
+ *
+ *
+ * {@code
+ *
+ * // in a @EventBusSubscriber-annotated class
+ * @SubscribeEvent
+ * public static void registerDynamicAssets(RegisterDynamicResourcesEvent event) {
+ * for (var block : YourBlocks.YOUR_PIPE_BLOCKS.values()) {
+ * if (block == null) continue;
+ * block.get().createPipeModel(RuntimeExistingFileHelper.INSTANCE).dynamicModel();
+ * }
+ * }
+ * }
+ *
+ *
+ * Remember to replace {@code YourBlocks.YOUR_PIPE_BLOCKS.values()} with a reference to your pipe block collection!
+ *
+ *
+ * For non-material pipes
+ * Conversely, if the pipe is not generated, but has a constant set of variants (such as optical fiber
+ * cables),
+ * you should NOT use {@link #dynamicModel()} and instead set the model with
+ * {@link GTBlockBuilder#gtBlockstate(NonNullBiConsumer)} as such:
+ *
+ *
+ * {@code
+ * // on your pipe block builder
+ * ... = REGISTRATE.block(...)
+ * .properties(...)
+ * .gtBlockstate(GTModels::createPipeBlockModel)
+ * ...more builder things...
+ * .item(...)
+ * .model(NonNullBiConsumer.noop())
+ * ...more builder things...
+ * }
+ *
+ *
+ * This makes the pipe model(s) be generated for you without having to process them at runtime.
+ *
+ */
+public class PipeModel {
+
+ public static final Set DYNAMIC_MODELS = new HashSet<>();
+
+ public static void initDynamicModels() {
+ for (PipeModel generator : DYNAMIC_MODELS) {
+ generator.initModels();
+ }
+ }
+
+ @Getter
+ private final PipeBlock, ?, ?> block;
+ public final @NotNull ResourceLocation blockId;
+ protected final GTBlockstateProvider provider;
+
+ /**
+ * The pipe's "thickness" in the (0,16] voxel range, where 1 is 1 voxel and 16 is a full block thick
+ */
+ protected final float thickness;
+ /**
+ * The pipe model's 'minimum' coordinate in the (0,16] voxel range.
+ * This is ex. the height of the center part's bottom edge.
+ */
+ protected final float minCoord;
+ /**
+ * The pipe model's 'maximum' coordinate in the (0,16] voxel range.
+ * This is ex. the height of the center part's top edge.
+ */
+ protected final float maxCoord;
+ @Setter
+ public ResourceLocation side, end;
+ @Setter
+ public @Nullable ResourceLocation sideSecondary, endSecondary;
+ @Setter
+ public @Nullable ResourceLocation sideOverlay, endOverlay;
+
+ /// Use {@link #getOrCreateBlockModel()} instead of referencing this field directly.
+ private BlockModelBuilder blockModel;
+ /// Use {@link #getOrCreateItemModel()} instead of referencing this field directly.
+ private ItemModelBuilder itemModel;
+
+ /// Use {@link #getOrCreateCenterElement()} instead of referencing this field directly.
+ private BlockModelBuilder centerElement;
+ /// Use {@link #getOrCreateConnectionElement()} instead of referencing this field directly.
+ private BlockModelBuilder connectionElement;
+
+ public PipeModel(PipeBlock, ?, ?> block, GTBlockstateProvider provider,
+ float thickness, ResourceLocation side, ResourceLocation end) {
+ this.block = block;
+ this.blockId = BuiltInRegistries.BLOCK.getKey(this.block);
+ this.provider = provider;
+
+ // assume thickness is in the 0-1 range
+ this.thickness = thickness * 16.0f;
+ this.side = side;
+ this.end = end;
+
+ this.minCoord = (16.0f - this.thickness) / 2.0f;
+ this.maxCoord = this.minCoord + this.thickness;
+ }
+
+ public final void dynamicModel() {
+ DYNAMIC_MODELS.add(this);
+ }
+
+ /**
+ * Initialize all models that are required for this block model to exist.
+ * Order is important! Dependent models must be initialized after their dependencies.
+ *
+ * @see #getOrCreateBlockModel()
+ * @see #getOrCreateCenterElement()
+ * @see #getOrCreateConnectionElement()
+ */
+ public void initModels() {
+ getOrCreateCenterElement();
+ getOrCreateConnectionElement();
+ getOrCreateBlockModel();
+ createBlockState();
+
+ getOrCreateItemModel();
+ }
+
+ /**
+ * Override this to change the actual model {@link #block this.block} will use.
+ *
+ * @return A model builder for the block's actual model.
+ * @see #getOrCreateCenterElement()
+ * @see #getOrCreateConnectionElement()
+ */
+ @ApiStatus.OverrideOnly
+ protected BlockModelBuilder getOrCreateBlockModel() {
+ if (this.blockModel != null) {
+ return this.blockModel;
+ }
+ // spotless:off
+ return this.blockModel = this.provider.models().getBuilder(this.blockId.toString())
+ // make the "default" model be based on the center part's model
+ .parent(this.getOrCreateCenterElement())
+ .customLoader(PipeModelBuilder::begin)
+ .thickness(this.thickness).provider(this.provider)
+ .centerModels(this.getOrCreateCenterElement().getLocation())
+ .connectionModels(this.getOrCreateConnectionElement().getLocation())
+ .end();
+ // spotless:on
+ }
+
+ /**
+ * Override this to change the center element's model.
+ *
+ * @return A model builder for the center element's model.
+ * @see #getOrCreateBlockModel()
+ * @see #getOrCreateConnectionElement()
+ */
+ @ApiStatus.OverrideOnly
+ protected BlockModelBuilder getOrCreateCenterElement() {
+ if (this.centerElement != null) {
+ return this.centerElement;
+ }
+ return this.centerElement = makeElementModel(this.blockId.withPath(path -> "block/pipe/" + path + "/center"),
+ null, minCoord, minCoord, minCoord, maxCoord, maxCoord, maxCoord);
+ }
+
+ /**
+ * Override this to change the 'connection' element's model.
+ * By default, this is rotated & used for all connected sides of the pipe.
+ * Note that that is not a hard requirement, and that you may set a model per side in
+ * {@link #getOrCreateBlockModel()}.
+ *
+ * @return A model builder for the connection element's model.
+ * @see #getOrCreateBlockModel()
+ * @see #getOrCreateCenterElement()
+ */
+ @ApiStatus.OverrideOnly
+ protected BlockModelBuilder getOrCreateConnectionElement() {
+ if (this.connectionElement != null) {
+ return this.connectionElement;
+ }
+ return this.connectionElement = makeElementModel(
+ this.blockId.withPath(path -> "block/pipe/" + path + "/connection"),
+ Direction.DOWN, minCoord, 0, minCoord, maxCoord, minCoord, maxCoord);
+ }
+
+ /**
+ * Override this to change the item model.
+ * By default, this creates a version of the pipe block model with the north & south sides 'connected'.
+ *
+ * @return The item model builder.
+ * @see #getOrCreateBlockModel()
+ */
+ @ApiStatus.OverrideOnly
+ protected ItemModelBuilder getOrCreateItemModel() {
+ return createItemModel(this.blockId, this.minCoord, this.maxCoord);
+ }
+
+ /**
+ * Override this to change the block state set {@link #block this.block} will use.
+ * By default, this creates a simple block state with no properties.
+ * The activable pipes (laser & optical) use this to add a model for the
+ * {@link GTBlockStateProperties#ACTIVE "active"} state of the blocks.
+ *
+ * @return The block state generator, usually a {@link MultiVariantGenerator}.
+ * @see #getOrCreateBlockModel()
+ * @see ActivablePipeModel#createBlockState()
+ */
+ @ApiStatus.OverrideOnly
+ public IGeneratedBlockState createBlockState() {
+ // spotless:off
+ return this.provider.getVariantBuilder(this.getBlock())
+ .partialState()
+ .modelForState()
+ .modelFile(this.provider.models().getExistingFile(this.blockId))
+ .addModel();
+ // spotless:on
+ }
+
+ /**
+ * Creates an item model based on the block model that extends to the north/south end of the block space.
+ *
+ * @param name The resulting model's path.
+ * @param min The minimum X/Y coordinate.
+ * @param max The maximum X/Y coordinate.
+ * @return An item model builder.
+ */
+ protected ItemModelBuilder createItemModel(ResourceLocation name, float min, float max) {
+ Reference2FloatMap faceEndpoints = new Reference2FloatOpenHashMap<>();
+ faceEndpoints.put(Direction.DOWN, min);
+ faceEndpoints.put(Direction.UP, max);
+ faceEndpoints.put(Direction.NORTH, 0);
+ faceEndpoints.put(Direction.SOUTH, 16);
+ faceEndpoints.put(Direction.WEST, min);
+ faceEndpoints.put(Direction.EAST, max);
+
+ ItemModelBuilder model = this.provider.itemModels().getBuilder(name.toString())
+ .parent(this.getOrCreateCenterElement());
+ makePartModelElement(model, Direction.NORTH, false, faceEndpoints, 0.0f, 0, 1,
+ min, min, 0, max, max, 16, this.side, this.end, "side", "end");
+ makePartModelElement(model, Direction.NORTH, true, faceEndpoints, 0.001f, 0, 1,
+ min, min, 0, max, max, 16, this.sideSecondary, this.endSecondary, "side_secondary", "end_secondary");
+ makePartModelElement(model, Direction.NORTH, true, faceEndpoints, 0.002f, 2, 2,
+ min, min, 0, max, max, 16, this.sideOverlay, this.endOverlay, "side_overlay", "end_overlay");
+ return model;
+ }
+
+ /**
+ * Fills out a model builder with applicable pipe model elements and returns it for further use
+ *
+ * @param name the resulting model's path
+ * @param endFace the model face that's being created
+ * @param x1 min X coordinate in the range [-16,32]
+ * @param y1 min Y coordinate in the range [-16,32]
+ * @param z1 min Z coordinate in the range [-16,32]
+ * @param x2 max X coordinate in the range [-16,32]
+ * @param y2 max Y coordinate in the range [-16,32]
+ * @param z2 max Z coordinate in the range [-16,32]
+ * @implNote The coordinates must be in the correct order or the resulting model's cubes will be inside out!
+ */
+ protected BlockModelBuilder makeElementModel(ResourceLocation name, @Nullable Direction endFace,
+ final float x1, final float y1, final float z1,
+ final float x2, final float y2, final float z2) {
+ Reference2FloatMap faceEndpoints = new Reference2FloatOpenHashMap<>();
+ faceEndpoints.defaultReturnValue(GTMath.max(x1, y1, z1, x2, y2, z2));
+ for (Direction dir : GTUtil.DIRECTIONS) {
+ faceEndpoints.put(dir, switch (dir) {
+ case DOWN -> Math.min(y1, y2);
+ case UP -> Math.max(y1, y2);
+ case NORTH -> Math.min(z1, z2);
+ case SOUTH -> Math.max(z1, z2);
+ case WEST -> Math.min(x1, x2);
+ case EAST -> Math.max(x1, x2);
+ });
+ }
+
+ BlockModelBuilder model = this.provider.models().getBuilder(name.toString())
+ .parent(new ModelFile.UncheckedModelFile("block/block"));
+ makePartModelElement(model, endFace, false, faceEndpoints, 0.0f, 0, 1,
+ x1, y1, z1, x2, y2, z2, this.side, this.end, "side", "end");
+ makePartModelElement(model, endFace, true, faceEndpoints, 0.001f, 0, 1,
+ x1, y1, z1, x2, y2, z2, this.sideSecondary, this.endSecondary, "side_secondary", "end_secondary");
+ makePartModelElement(model, endFace, true, faceEndpoints, 0.002f, 2, 2,
+ x1, y1, z1, x2, y2, z2, this.sideOverlay, this.endOverlay, "side_overlay", "end_overlay");
+ return model;
+ }
+
+ protected > void makePartModelElement(T model, @Nullable Direction endFace,
+ boolean useEndWithFullCube,
+ Reference2FloatMap faceEndpoints,
+ float offset, int sideTintIndex, int endTintIndex,
+ final float x1, final float y1, final float z1,
+ final float x2, final float y2, final float z2,
+ @Nullable ResourceLocation sideTexture,
+ @Nullable ResourceLocation endTexture,
+ String sideKey, String endKey) {
+ if (sideTexture == null && endTexture == null) {
+ return;
+ }
+ if (sideTexture != null) model.texture(sideKey, sideTexture);
+ if (endTexture != null) model.texture(endKey, endTexture);
+
+ boolean fullCube = !useEndWithFullCube &&
+ (x1 == y1 && x1 == z1 && x1 <= 0.0f) &&
+ (x2 == y2 && x2 == z2 && x2 >= 16.0f);
+
+ ModelBuilder.ElementBuilder element = model.element()
+ .from(x1 - offset, y1 - offset, z1 - offset)
+ .to(x2 + offset, y2 + offset, z2 + offset);
+
+ for (Direction dir : GTUtil.DIRECTIONS) {
+ ModelBuilder.ElementBuilder.FaceBuilder face = null;
+ boolean isEnd = (endFace == dir || endFace == dir.getOpposite()) && !fullCube;
+ if (isEnd && endTexture != null) {
+ face = element.face(dir).texture("#" + endKey).tintindex(endTintIndex);
+ } else if (!isEnd && sideTexture != null) {
+ face = element.face(dir).texture("#" + sideKey).tintindex(sideTintIndex);
+ }
+
+ float faceEnd = faceEndpoints.getFloat(dir);
+ if (face != null && (faceEnd >= 16.0f || faceEnd <= 0.0f)) {
+ face.cullface(dir);
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof PipeModel pipeModel)) return false;
+ return block == pipeModel.block &&
+ Objects.equals(side, pipeModel.side) &&
+ Objects.equals(end, pipeModel.end) &&
+ Objects.equals(sideSecondary, pipeModel.sideSecondary) &&
+ Objects.equals(endSecondary, pipeModel.endSecondary) &&
+ Objects.equals(sideOverlay, pipeModel.sideOverlay) &&
+ Objects.equals(endOverlay, pipeModel.endOverlay);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(block, side, end, sideSecondary, endSecondary, sideOverlay, endOverlay);
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModelLoader.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModelLoader.java
new file mode 100644
index 00000000000..9465b8f8471
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModelLoader.java
@@ -0,0 +1,62 @@
+package com.gregtechceu.gtceu.client.model.pipe;
+
+import com.gregtechceu.gtceu.GTCEu;
+import com.gregtechceu.gtceu.client.model.machine.MachineModelLoader;
+import com.gregtechceu.gtceu.client.model.machine.variant.MultiVariantModel;
+
+import net.minecraft.client.resources.model.UnbakedModel;
+import net.minecraft.core.Direction;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.util.GsonHelper;
+import net.minecraftforge.client.model.geometry.IGeometryLoader;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+public class PipeModelLoader implements IGeometryLoader {
+
+ public static final PipeModelLoader INSTANCE = new PipeModelLoader();
+ public static final ResourceLocation ID = GTCEu.id("pipe");
+ public static final String PRIMARY_CENTER_KEY = "center";
+ public static final Set CENTER_KEYS = Set.of(PRIMARY_CENTER_KEY, "core", "null", "none");
+
+ @Override
+ public @Nullable UnbakedPipeModel read(JsonObject json,
+ JsonDeserializationContext context) throws JsonParseException {
+ // load the inner models
+ final Map parts = new HashMap<>();
+ if (json.has("parts")) {
+ JsonObject variantsJson = GsonHelper.getAsJsonObject(json, "parts");
+ for (Map.Entry entry : variantsJson.entrySet()) {
+ Direction direction = Direction.byName(entry.getKey());
+ if (direction == null && !CENTER_KEYS.contains(entry.getKey().toLowerCase(Locale.ROOT))) {
+ throw new JsonParseException("Invalid pipe model part specifier " + entry.getKey());
+ }
+ if (direction == null && parts.get(null) != null) {
+ throw new JsonParseException("Cannot specify more than one 'center' model for a pipe model");
+ }
+
+ parts.put(direction, MachineModelLoader.GSON.fromJson(entry.getValue(), MultiVariantModel.class));
+ }
+ }
+ // and the restrictors
+ final Map restrictors = new HashMap<>();
+ if (json.has("restrictors")) {
+ JsonObject variantsJson = GsonHelper.getAsJsonObject(json, "restrictors");
+ for (Map.Entry entry : variantsJson.entrySet()) {
+ Direction direction = Direction.byName(entry.getKey());
+ if (direction == null) {
+ throw new JsonParseException("Invalid pipe model part specifier " + entry.getKey());
+ }
+ restrictors.put(direction, MachineModelLoader.GSON.fromJson(entry.getValue(), MultiVariantModel.class));
+ }
+ }
+
+ return new UnbakedPipeModel(parts, restrictors);
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/UnbakedPipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/UnbakedPipeModel.java
new file mode 100644
index 00000000000..5ea5e68ac76
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/UnbakedPipeModel.java
@@ -0,0 +1,71 @@
+package com.gregtechceu.gtceu.client.model.pipe;
+
+import net.minecraft.client.renderer.block.model.ItemOverrides;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.resources.model.*;
+import net.minecraft.core.Direction;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraftforge.client.model.geometry.IGeometryBakingContext;
+import net.minecraftforge.client.model.geometry.IUnbakedGeometry;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import static com.gregtechceu.gtceu.client.model.machine.MachineModelLoader.MISSING_MARKER;
+
+public class UnbakedPipeModel implements IUnbakedGeometry {
+
+ private final Map<@Nullable Direction, UnbakedModel> parts;
+ private final Map<@NotNull Direction, UnbakedModel> restrictors;
+
+ public UnbakedPipeModel(Map<@Nullable Direction, UnbakedModel> parts,
+ Map<@NotNull Direction, UnbakedModel> restrictors) {
+ this.parts = parts;
+ this.restrictors = restrictors;
+ }
+
+ @Override
+ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker,
+ Function spriteGetter, ModelState modelState,
+ ItemOverrides overrides, ResourceLocation modelLocation) {
+ Map bakedParts = new IdentityHashMap<>();
+ this.parts.forEach((direction, unbaked) -> {
+ bakedParts.put(direction, unbaked.bake(baker, spriteGetter, modelState, modelLocation));
+ });
+ Map bakedRestrictors = new IdentityHashMap<>();
+ this.restrictors.forEach((direction, unbaked) -> {
+ bakedRestrictors.put(direction, unbaked.bake(baker, spriteGetter, modelState, modelLocation));
+ });
+ return new BakedPipeModel(bakedParts, bakedRestrictors);
+ }
+
+ @Override
+ public void resolveParents(Function resolver, IGeometryBakingContext context) {
+ UnbakedModel missingModel = resolver.apply(ModelBakery.MISSING_MODEL_LOCATION);
+
+ Map copy = new IdentityHashMap<>(this.parts);
+ copy.forEach((side, variant) -> {
+ if (variant == null || variant == MISSING_MARKER) {
+ // replace null & markers with the actual missing model
+ this.parts.put(side, missingModel);
+ } else {
+ variant.resolveParents(resolver);
+ this.parts.put(side, variant);
+ }
+ });
+ copy = new IdentityHashMap<>(this.restrictors);
+ copy.forEach((side, variant) -> {
+ if (variant == null || variant == MISSING_MARKER) {
+ // replace null & markers with the actual missing model
+ this.restrictors.put(side, missingModel);
+ } else {
+ variant.resolveParents(resolver);
+ this.restrictors.put(side, variant);
+ }
+ });
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/package-info.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/package-info.java
new file mode 100644
index 00000000000..481c46780dc
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/package-info.java
@@ -0,0 +1,7 @@
+@ParametersAreNonnullByDefault
+@MethodsReturnNonnullByDefault
+package com.gregtechceu.gtceu.client.model.pipe;
+
+import net.minecraft.MethodsReturnNonnullByDefault;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockEntityWithBERModelRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockEntityWithBERModelRenderer.java
index 3508a6e860e..511730ca9aa 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockEntityWithBERModelRenderer.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockEntityWithBERModelRenderer.java
@@ -45,7 +45,7 @@ public void render(T blockEntity, float partialTick,
BakedModel model = blockRenderDispatcher.getBlockModel(blockState);
if (model instanceof IBlockEntityRendererBakedModel> berModel) {
- if (berModel.getBlockEntityType() != blockEntity.getType()) return;
+ if (berModel.getBlockEntityType() != null && berModel.getBlockEntityType() != blockEntity.getType()) return;
((IBlockEntityRendererBakedModel) berModel).render(blockEntity, partialTick,
poseStack, buffer, packedLight, packedOverlay);
@@ -79,7 +79,7 @@ public boolean shouldRenderOffScreen(T blockEntity) {
BakedModel model = blockRenderDispatcher.getBlockModel(blockState);
if (model instanceof IBlockEntityRendererBakedModel> berModel) {
- if (berModel.getBlockEntityType() == blockEntity.getType()) {
+ if (berModel.getBlockEntityType() != null && berModel.getBlockEntityType() == blockEntity.getType()) {
return ((IBlockEntityRendererBakedModel) berModel).shouldRenderOffScreen(blockEntity);
}
}
@@ -92,7 +92,7 @@ public boolean shouldRender(T blockEntity, Vec3 cameraPos) {
BakedModel model = blockRenderDispatcher.getBlockModel(blockState);
if (model instanceof IBlockEntityRendererBakedModel> berModel) {
- if (berModel.getBlockEntityType() == blockEntity.getType()) {
+ if (berModel.getBlockEntityType() != null && berModel.getBlockEntityType() == blockEntity.getType()) {
return ((IBlockEntityRendererBakedModel) berModel).shouldRender(blockEntity, cameraPos);
}
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/LampItemRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/LampItemRenderer.java
new file mode 100644
index 00000000000..aed2072c637
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/LampItemRenderer.java
@@ -0,0 +1,54 @@
+package com.gregtechceu.gtceu.client.renderer.block;
+
+import com.gregtechceu.gtceu.api.item.LampBlockItem;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.client.renderer.block.BlockRenderDispatcher;
+import net.minecraft.client.renderer.entity.ItemRenderer;
+import net.minecraft.client.resources.model.BakedModel;
+import net.minecraft.world.item.ItemDisplayContext;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.state.BlockState;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * All this renderer does is refer rendering to the correct block model based on the lamp item's NBT.
+ * Without it, all item variants would look like the default 'lit, with bloom' one.
+ */
+public class LampItemRenderer extends BlockEntityWithoutLevelRenderer {
+
+ public static final LampItemRenderer INSTANCE = new LampItemRenderer();
+
+ protected final ItemRenderer itemRenderer;
+ protected final BlockRenderDispatcher blockRenderer;
+
+ protected LampItemRenderer() {
+ super(Minecraft.getInstance().getBlockEntityRenderDispatcher(),
+ Minecraft.getInstance().getEntityModels());
+ this.itemRenderer = Minecraft.getInstance().getItemRenderer();
+ this.blockRenderer = Minecraft.getInstance().getBlockRenderer();
+ }
+
+ @Override
+ public void renderByItem(@NotNull ItemStack stack, @NotNull ItemDisplayContext displayContext,
+ @NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer,
+ int packedLight, int packedOverlay) {
+ if (!(stack.getItem() instanceof LampBlockItem item)) {
+ return;
+ }
+ BlockState state = item.getStateFromStack(stack, null);
+ BakedModel p_model = blockRenderer.getBlockModel(state);
+
+ for (var model : p_model.getRenderPasses(stack, true)) {
+ for (var rendertype : model.getRenderTypes(stack, true)) {
+ VertexConsumer foilBuffer = ItemRenderer.getFoilBufferDirect(buffer, rendertype, true, stack.hasFoil());
+ itemRenderer.renderModelLists(model, stack, packedLight, packedOverlay, poseStack, foilBuffer);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/LampRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/LampRenderer.java
deleted file mode 100644
index a9552b7ea83..00000000000
--- a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/LampRenderer.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.gregtechceu.gtceu.client.renderer.block;
-
-import com.gregtechceu.gtceu.GTCEu;
-import com.gregtechceu.gtceu.common.block.LampBlock;
-
-import com.lowdragmc.lowdraglib.client.model.custommodel.ICTMPredicate;
-import com.lowdragmc.lowdraglib.client.renderer.impl.IModelRenderer;
-
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.world.level.BlockAndTintGetter;
-import net.minecraft.world.level.block.state.BlockState;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
-
-public class LampRenderer extends IModelRenderer implements ICTMPredicate {
-
- public LampRenderer(LampBlock lamp, BlockState state) {
- super(GTCEu.id("block/%s%s_lamp%s%s".formatted(
- lamp.color,
- lamp.bordered ? "" : "_borderless",
- state.getValue(LampBlock.LIGHT) ? "" : "_off",
- state.getValue(LampBlock.LIGHT) && state.getValue(LampBlock.BLOOM) ? "_bloom" : "")));
- }
-
- @Override
- public boolean isConnected(BlockAndTintGetter level, BlockState state, BlockPos pos,
- BlockState sourceState, BlockPos sourcePos, Direction side) {
- var stateAppearance = state.getAppearance(level, pos, side, sourceState, sourcePos);
- var sourceStateAppearance = sourceState.getAppearance(level, sourcePos, side, state, pos);
- return stateAppearance.getBlock() == sourceStateAppearance.getBlock();
- }
-
- @Override
- @OnlyIn(Dist.CLIENT)
- public boolean useAO() {
- return true;
- }
-
- @Override
- public boolean reBakeCustomQuads() {
- return true;
- }
-
- @Override
- public float reBakeCustomQuadsOffset() {
- return 0.0f;
- }
-}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/OreBlockRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/OreBlockRenderer.java
index 563f1bc6682..fbd6bff6240 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/OreBlockRenderer.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/OreBlockRenderer.java
@@ -75,12 +75,14 @@ public static void cloneBlockModel(ResourceLocation modelId, TagPrefix prefix, M
JsonObject newJson = original.deepCopy();
JsonObject children = newJson.getAsJsonObject("children");
// add the base stone texture.
- children.getAsJsonObject("base_stone").addProperty("parent",
- TagPrefix.ORES.get(prefix).baseModelLocation().toString());
+ children.getAsJsonObject("base_stone")
+ .addProperty("parent", TagPrefix.ORES.get(prefix).baseModelLocation().toString());
+
+ ResourceLocation layer0 = prefix.materialIconType()
+ .getBlockTexturePath(material.getMaterialIconSet(), true);
+ ResourceLocation layer1 = prefix.materialIconType()
+ .getBlockTexturePath(material.getMaterialIconSet(), "layer2", true);
- ResourceLocation layer0 = prefix.materialIconType().getBlockTexturePath(material.getMaterialIconSet(), true);
- ResourceLocation layer1 = prefix.materialIconType().getBlockTexturePath(material.getMaterialIconSet(), "layer2",
- true);
JsonObject oresTextures = children.getAsJsonObject("ore_texture").getAsJsonObject("textures");
oresTextures.addProperty("layer0", layer0.toString());
oresTextures.addProperty("layer1", layer1.toString());
diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/PipeBlockRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/PipeBlockRenderer.java
deleted file mode 100644
index b06ac84c7ce..00000000000
--- a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/PipeBlockRenderer.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package com.gregtechceu.gtceu.client.renderer.block;
-
-import com.gregtechceu.gtceu.GTCEu;
-import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
-import com.gregtechceu.gtceu.api.pipenet.IPipeNode;
-import com.gregtechceu.gtceu.client.model.PipeModel;
-import com.gregtechceu.gtceu.client.renderer.cover.ICoverableRenderer;
-import com.gregtechceu.gtceu.client.util.GTQuadTransformers;
-import com.gregtechceu.gtceu.common.data.GTMaterialBlocks;
-import com.gregtechceu.gtceu.utils.GTUtil;
-
-import com.lowdragmc.lowdraglib.client.renderer.IRenderer;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.color.block.BlockColors;
-import net.minecraft.client.renderer.MultiBufferSource;
-import net.minecraft.client.renderer.RenderType;
-import net.minecraft.client.renderer.block.model.BakedQuad;
-import net.minecraft.client.renderer.texture.TextureAtlas;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.util.RandomSource;
-import net.minecraft.world.item.ItemDisplayContext;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.level.BlockAndTintGetter;
-import net.minecraft.world.level.block.state.BlockState;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
-import net.minecraftforge.client.model.data.ModelData;
-
-import com.mojang.blaze3d.vertex.PoseStack;
-import lombok.Getter;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.function.Consumer;
-
-import static com.lowdragmc.lowdraglib.client.model.forge.LDLRendererModel.RendererBakedModel.*;
-
-public class PipeBlockRenderer implements IRenderer, ICoverableRenderer {
-
- @Getter
- PipeModel pipeModel;
-
- public PipeBlockRenderer(PipeModel pipeModel) {
- this.pipeModel = pipeModel;
- if (GTCEu.isClientSide()) {
- registerEvent();
- }
- }
-
- @Override
- @OnlyIn(Dist.CLIENT)
- public void renderItem(ItemStack stack,
- ItemDisplayContext transformType,
- boolean leftHand, PoseStack matrixStack,
- MultiBufferSource buffer, int combinedLight,
- int combinedOverlay, BakedModel model) {
- pipeModel.renderItem(stack, transformType, leftHand, matrixStack, buffer, combinedLight, combinedOverlay,
- model);
- }
-
- @Override
- public boolean useAO() {
- return true;
- }
-
- @Override
- @OnlyIn(Dist.CLIENT)
- public boolean useBlockLight(ItemStack stack) {
- return true;
- }
-
- @Override
- @OnlyIn(Dist.CLIENT)
- public List renderModel(BlockAndTintGetter level, BlockPos pos, BlockState state, Direction side,
- RandomSource rand) {
- if (level == null) {
- return pipeModel.bakeQuads(side, PipeModel.ITEM_CONNECTIONS, 0);
- }
- if (!(level.getBlockEntity(pos) instanceof IPipeNode, ?> pipeNode)) {
- return pipeModel.bakeQuads(side, 0, 0);
- }
- RenderType renderType = CURRENT_RENDER_TYPE.get();
- ModelData modelData = CURRENT_MODEL_DATA.get().get(MODEL_DATA);
- if (modelData == null) modelData = ModelData.EMPTY;
-
- List quads = new LinkedList<>();
-
- if (renderType == null || renderType == RenderType.cutoutMipped()) {
- quads.addAll(pipeModel.bakeQuads(side, pipeNode.getVisualConnections(), pipeNode.getBlockedConnections()));
- }
- ICoverableRenderer.super.renderCovers(quads, pipeNode.getCoverContainer(), pos, level, side, rand,
- modelData, renderType);
-
- if (pipeNode.getFrameMaterial().isNull() || (renderType != null && renderType != RenderType.translucent())) {
- return quads;
- }
-
- BlockState frameState = GTMaterialBlocks.MATERIAL_BLOCKS.get(TagPrefix.frameGt, pipeNode.getFrameMaterial())
- .getDefaultState();
- BakedModel frameModel = Minecraft.getInstance().getBlockRenderer().getBlockModel(frameState);
-
- modelData = frameModel.getModelData(level, pos, frameState, modelData);
-
- List frameQuads = new LinkedList<>();
- if (side == null || pipeNode.getCoverContainer().getCoverAtSide(side) == null) {
- frameQuads.addAll(frameModel.getQuads(state, side, rand, modelData, renderType));
- }
- if (side == null) {
- for (Direction face : GTUtil.DIRECTIONS) {
- if (pipeNode.getCoverContainer().getCoverAtSide(face) != null) {
- continue;
- }
- frameQuads.addAll(frameModel.getQuads(state, face, rand, modelData, renderType));
- }
- }
-
- // bake all the quads' tint colors into the vertices
- BlockColors blockColors = Minecraft.getInstance().getBlockColors();
- for (BakedQuad frameQuad : frameQuads) {
- if (frameQuad.isTinted()) {
- int color = blockColors.getColor(frameState, level, pos, frameQuad.getTintIndex());
- frameQuad = GTQuadTransformers.setColor(frameQuad, color, true);
- }
- quads.add(frameQuad);
- }
- return quads;
- }
-
- @NotNull
- @Override
- @OnlyIn(Dist.CLIENT)
- public TextureAtlasSprite getParticleTexture() {
- return pipeModel.getParticleTexture();
- }
-
- @Override
- @OnlyIn(Dist.CLIENT)
- public void onPrepareTextureAtlas(ResourceLocation atlasName, Consumer register) {
- if (atlasName.equals(TextureAtlas.LOCATION_BLOCKS)) {
- pipeModel.registerTextureAtlas(register);
- }
- }
-}
diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java
index e1542d349f3..1abacd672cb 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java
@@ -11,7 +11,8 @@
import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
import com.gregtechceu.gtceu.api.item.tool.GTToolType;
import com.gregtechceu.gtceu.api.pipenet.IPipeNode;
-import com.gregtechceu.gtceu.client.model.PipeModel;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
import com.gregtechceu.gtceu.common.blockentity.CableBlockEntity;
import com.gregtechceu.gtceu.common.data.GTBlockEntities;
import com.gregtechceu.gtceu.common.data.GTDamageTypes;
@@ -54,7 +55,7 @@ public CableBlock(Properties properties, Insulation insulation, Material materia
@Override
public int tinted(BlockState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos, int index) {
- if (pipeType.isCable && index == 0) {
+ if (pipeType.isCable && (index == 0 || index == 2)) {
return 0x404040;
}
return super.tinted(state, level, pos, index);
@@ -94,8 +95,8 @@ public boolean canPipeConnectToBlock(IPipeNode selfT
}
@Override
- protected PipeModel createPipeModel() {
- return pipeType.createPipeModel(material);
+ public PipeModel createPipeModel(GTBlockstateProvider provider) {
+ return pipeType.createPipeModel(this, material, provider);
}
@Override
diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/DuctPipeBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/DuctPipeBlock.java
index f08d13c97f9..69306723f59 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/block/DuctPipeBlock.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/block/DuctPipeBlock.java
@@ -1,5 +1,6 @@
package com.gregtechceu.gtceu.common.block;
+import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.block.PipeBlock;
import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity;
import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
@@ -7,8 +8,8 @@
import com.gregtechceu.gtceu.api.machine.feature.IEnvironmentalHazardCleaner;
import com.gregtechceu.gtceu.api.machine.feature.IEnvironmentalHazardEmitter;
import com.gregtechceu.gtceu.api.pipenet.IPipeNode;
-import com.gregtechceu.gtceu.client.model.PipeModel;
-import com.gregtechceu.gtceu.client.renderer.block.PipeBlockRenderer;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
import com.gregtechceu.gtceu.common.blockentity.DuctPipeBlockEntity;
import com.gregtechceu.gtceu.common.data.GTBlockEntities;
import com.gregtechceu.gtceu.common.pipelike.duct.DuctPipeProperties;
@@ -36,15 +37,11 @@
@MethodsReturnNonnullByDefault
public class DuctPipeBlock extends PipeBlock {
- public final PipeBlockRenderer renderer;
- public final PipeModel model;
private final DuctPipeProperties properties;
public DuctPipeBlock(Properties properties, DuctPipeType type) {
super(properties, type);
this.properties = new DuctPipeProperties(type.getRateMultiplier());
- this.model = type.createPipeModel();
- this.renderer = new PipeBlockRenderer(this.model);
}
@Override
@@ -75,13 +72,9 @@ public DuctPipeProperties getFallbackType() {
}
@Override
- public @Nullable PipeBlockRenderer getRenderer(BlockState state) {
- return renderer;
- }
-
- @Override
- protected PipeModel getPipeModel() {
- return model;
+ public PipeModel createPipeModel(GTBlockstateProvider provider) {
+ return new PipeModel(this, provider, this.pipeType.getThickness(),
+ GTCEu.id("block/pipe/pipe_duct_side"), GTCEu.id("block/pipe/pipe_duct_in"));
}
@Override
diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java
index 3b0173a574b..1af49f770c2 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java
@@ -8,7 +8,8 @@
import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey;
import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
import com.gregtechceu.gtceu.api.pipenet.IPipeNode;
-import com.gregtechceu.gtceu.client.model.PipeModel;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity;
import com.gregtechceu.gtceu.common.data.GTBlockEntities;
import com.gregtechceu.gtceu.common.data.GTMaterialBlocks;
@@ -82,8 +83,8 @@ public boolean canPipeConnectToBlock(IPipeNode renderers = new IdentityHashMap<>();
public LampBlock(Properties properties, DyeColor color, boolean bordered) {
super(properties);
@@ -65,9 +60,6 @@ public LampBlock(Properties properties, DyeColor color, boolean bordered) {
.setValue(LIGHT, true)
.setValue(INVERTED, false)
.setValue(POWERED, false));
- for (BlockState state : getStateDefinition().getPossibleStates()) {
- renderers.put(state, new LampRenderer(this, state));
- }
}
public static boolean isLightActive(BlockState state) {
@@ -126,6 +118,12 @@ public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) {
return state.getValue(LIGHT) && isLightActive(state) ? 15 : 0;
}
+ @Override
+ public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side,
+ @Nullable BlockState queryState, @Nullable BlockPos queryPos) {
+ return state.getBlock().defaultBlockState();
+ }
+
@Override
@SuppressWarnings("deprecation")
public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
@@ -192,10 +190,4 @@ public List getDrops(BlockState state, LootParams.Builder params) {
}
return returnValue;
}
-
- @Nullable
- @Override
- public IRenderer getRenderer(BlockState state) {
- return renderers.get(state);
- }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/LaserPipeBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/LaserPipeBlock.java
index 4b99ed7cdeb..311338b6a1f 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/block/LaserPipeBlock.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/block/LaserPipeBlock.java
@@ -2,12 +2,14 @@
import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.block.PipeBlock;
+import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties;
import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
import com.gregtechceu.gtceu.api.capability.forge.GTCapability;
import com.gregtechceu.gtceu.api.item.tool.GTToolType;
import com.gregtechceu.gtceu.api.pipenet.IPipeNode;
-import com.gregtechceu.gtceu.client.model.PipeModel;
-import com.gregtechceu.gtceu.client.renderer.block.PipeBlockRenderer;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.ActivablePipeModel;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
import com.gregtechceu.gtceu.common.blockentity.LaserPipeBlockEntity;
import com.gregtechceu.gtceu.common.data.GTBlockEntities;
import com.gregtechceu.gtceu.common.pipelike.laser.LaserPipeProperties;
@@ -19,9 +21,11 @@
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -33,23 +37,20 @@
@MethodsReturnNonnullByDefault
public class LaserPipeBlock extends PipeBlock {
- public final PipeBlockRenderer renderer;
- public final PipeModel model;
private final LaserPipeProperties properties;
public LaserPipeBlock(Properties properties, LaserPipeType type) {
super(properties, type);
this.properties = LaserPipeProperties.INSTANCE;
- this.model = new PipeModel(LaserPipeType.NORMAL.getThickness(), () -> GTCEu.id("block/pipe/pipe_laser_side"),
- () -> GTCEu.id("block/pipe/pipe_laser_in"), null, null);
- this.renderer = new PipeBlockRenderer(this.model);
+
+ registerDefaultState(defaultBlockState().setValue(GTBlockStateProperties.ACTIVE, false));
}
@OnlyIn(Dist.CLIENT)
public static BlockColor tintedColor() {
- return (blockState, level, blockPos, index) -> {
- if (blockPos != null && level != null &&
- level.getBlockEntity(blockPos) instanceof PipeBlockEntity, ?> pipe) {
+ return (state, level, pos, index) -> {
+ if (pos != null && level != null &&
+ level.getBlockEntity(pos) instanceof PipeBlockEntity, ?> pipe) {
if (!pipe.getFrameMaterial().isNull()) {
if (index == 3) {
return pipe.getFrameMaterial().getMaterialRGB();
@@ -65,6 +66,12 @@ public static BlockColor tintedColor() {
};
}
+ @Override
+ protected void createBlockStateDefinition(StateDefinition.Builder builder) {
+ super.createBlockStateDefinition(builder);
+ builder.add(GTBlockStateProperties.ACTIVE);
+ }
+
@Override
public LevelLaserPipeNet getWorldPipeNet(ServerLevel world) {
return LevelLaserPipeNet.getOrCreate(world);
@@ -93,12 +100,12 @@ public LaserPipeProperties getFallbackType() {
}
@Override
- public @Nullable PipeBlockRenderer getRenderer(BlockState state) {
- return renderer;
- }
-
- @Override
- protected PipeModel getPipeModel() {
+ public PipeModel createPipeModel(GTBlockstateProvider provider) {
+ ActivablePipeModel model = new ActivablePipeModel(this, LaserPipeType.NORMAL.getThickness(),
+ GTCEu.id("block/pipe/pipe_laser_side"), GTCEu.id("block/pipe/pipe_laser_in"),
+ provider);
+ model.setSideOverlay(GTCEu.id("block/pipe/pipe_laser_side_overlay"));
+ model.setSideOverlayActive(GTCEu.id("block/pipe/pipe_laser_side_overlay_emissive"));
return model;
}
diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/OpticalPipeBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/OpticalPipeBlock.java
index 07d7e22be23..c710e296547 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/block/OpticalPipeBlock.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/block/OpticalPipeBlock.java
@@ -2,12 +2,14 @@
import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.block.PipeBlock;
+import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties;
import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
import com.gregtechceu.gtceu.api.capability.forge.GTCapability;
import com.gregtechceu.gtceu.api.item.tool.GTToolType;
import com.gregtechceu.gtceu.api.pipenet.IPipeNode;
-import com.gregtechceu.gtceu.client.model.PipeModel;
-import com.gregtechceu.gtceu.client.renderer.block.PipeBlockRenderer;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.ActivablePipeModel;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
import com.gregtechceu.gtceu.common.blockentity.OpticalPipeBlockEntity;
import com.gregtechceu.gtceu.common.data.GTBlockEntities;
import com.gregtechceu.gtceu.common.pipelike.optical.LevelOpticalPipeNet;
@@ -18,14 +20,15 @@
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
-import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,20 +37,29 @@
@ParametersAreNonnullByDefault
public class OpticalPipeBlock extends PipeBlock {
- public final PipeBlockRenderer renderer;
- @Getter
- public final PipeModel pipeModel;
-
- private final OpticalPipeType pipeType;
private final OpticalPipeProperties properties;
- public OpticalPipeBlock(BlockBehaviour.Properties properties, @NotNull OpticalPipeType pipeType) {
+ public OpticalPipeBlock(BlockBehaviour.Properties properties, OpticalPipeType pipeType) {
super(properties, pipeType);
- this.pipeType = pipeType;
this.properties = OpticalPipeProperties.INSTANCE;
- this.pipeModel = new PipeModel(pipeType.getThickness(), () -> GTCEu.id("block/pipe/pipe_optical_side"),
- () -> GTCEu.id("block/pipe/pipe_optical_in"), null, null);
- this.renderer = new PipeBlockRenderer(this.pipeModel);
+
+ registerDefaultState(defaultBlockState().setValue(GTBlockStateProperties.ACTIVE, false));
+ }
+
+ @Override
+ protected void createBlockStateDefinition(StateDefinition.Builder builder) {
+ super.createBlockStateDefinition(builder);
+ builder.add(GTBlockStateProperties.ACTIVE);
+ }
+
+ @Override
+ public @NotNull PipeModel createPipeModel(GTBlockstateProvider provider) {
+ ActivablePipeModel pipeModel = new ActivablePipeModel(this, pipeType.getThickness(),
+ GTCEu.id("block/pipe/pipe_optical_side"), GTCEu.id("block/pipe/pipe_optical_in"),
+ provider);
+ pipeModel.setSideOverlay(GTCEu.id("block/pipe/pipe_optical_side_overlay"));
+ pipeModel.setSideOverlayActive(GTCEu.id("block/pipe/pipe_optical_side_overlay_active"));
+ return pipeModel;
}
@Override
@@ -77,11 +89,6 @@ public OpticalPipeProperties getFallbackType() {
return OpticalPipeProperties.INSTANCE;
}
- @Override
- public @Nullable PipeBlockRenderer getRenderer(BlockState state) {
- return renderer;
- }
-
@OnlyIn(Dist.CLIENT)
public static BlockColor tintedColor() {
return (blockState, level, blockPos, index) -> {
diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/CableBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/CableBlockEntity.java
index bdad968b985..9845dd66447 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/CableBlockEntity.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/CableBlockEntity.java
@@ -74,10 +74,6 @@ public CableBlockEntity(BlockEntityType> type, BlockPos pos, BlockState blockS
super(type, pos, blockState);
}
- public static CableBlockEntity create(BlockEntityType> type, BlockPos pos, BlockState blockState) {
- return new CableBlockEntity(type, pos, blockState);
- }
-
@Override
public @NotNull LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) {
if (cap == GTCapability.CAPABILITY_ENERGY_CONTAINER) {
diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/DuctPipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/DuctPipeBlockEntity.java
index d2e27a69840..075cc58e284 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/DuctPipeBlockEntity.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/DuctPipeBlockEntity.java
@@ -36,14 +36,10 @@ public class DuctPipeBlockEntity extends PipeBlockEntity type, BlockPos pos, BlockState blockState) {
+ public DuctPipeBlockEntity(BlockEntityType> type, BlockPos pos, BlockState blockState) {
super(type, pos, blockState);
}
- public static DuctPipeBlockEntity create(BlockEntityType> type, BlockPos pos, BlockState blockState) {
- return new DuctPipeBlockEntity(type, pos, blockState);
- }
-
public static void onBlockEntityRegister(BlockEntityType ductBlockEntityBlockEntityType) {}
@Override
diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/ItemPipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/ItemPipeBlockEntity.java
index 5fa341fd83e..f222c06da11 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/ItemPipeBlockEntity.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/ItemPipeBlockEntity.java
@@ -50,10 +50,6 @@ public ItemPipeBlockEntity(BlockEntityType> type, BlockPos pos, BlockState blo
super(type, pos, blockState);
}
- public static ItemPipeBlockEntity create(BlockEntityType> type, BlockPos pos, BlockState blockState) {
- return new ItemPipeBlockEntity(type, pos, blockState);
- }
-
public long getLevelTime() {
return hasLevel() ? Objects.requireNonNull(getLevel()).getGameTime() : 0L;
}
diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/LaserPipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/LaserPipeBlockEntity.java
index e16ffb9b549..3d8784ca767 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/LaserPipeBlockEntity.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/LaserPipeBlockEntity.java
@@ -1,5 +1,6 @@
package com.gregtechceu.gtceu.common.blockentity;
+import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties;
import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper;
import com.gregtechceu.gtceu.api.capability.ILaserContainer;
@@ -10,13 +11,11 @@
import com.gregtechceu.gtceu.utils.GTUtil;
import com.gregtechceu.gtceu.utils.TaskHandler;
-import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced;
-import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted;
-import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder;
-
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
@@ -32,9 +31,6 @@
public class LaserPipeBlockEntity extends PipeBlockEntity {
- public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(LaserPipeBlockEntity.class,
- PipeBlockEntity.MANAGED_FIELD_HOLDER);
-
@Getter
protected final EnumMap handlers = new EnumMap<>(Direction.class);
// the LaserNetHandler can only be created on the server, so we have an empty placeholder for the client
@@ -43,21 +39,10 @@ public class LaserPipeBlockEntity extends PipeBlockEntity type, BlockPos pos, BlockState blockState) {
+ public LaserPipeBlockEntity(BlockEntityType> type, BlockPos pos, BlockState blockState) {
super(type, pos, blockState);
}
- public static LaserPipeBlockEntity create(BlockEntityType> type, BlockPos pos, BlockState blockState) {
- return new LaserPipeBlockEntity(type, pos, blockState);
- }
-
public static void onBlockEntityRegister(BlockEntityType cableBlockEntityBlockEntityType) {}
@Override
@@ -127,28 +112,11 @@ public LaserPipeNet getLaserPipeNet() {
* @param duration how long the pipe should be active for
*/
public void setActive(boolean active, int duration) {
- if (this.active != active) {
- this.active = active;
- notifyBlockUpdate();
- setChanged();
- if (active && duration != this.activeDuration) {
- TaskHandler.enqueueServerTask((ServerLevel) getLevel(), this::queueDisconnect, 0);
- }
- }
-
- this.activeDuration = duration;
- if (duration > 0 && active) {
- this.ticksActive = 0;
- }
+ setPipeActive(this, this.getBlockState(), active, duration);
}
- public boolean queueDisconnect() {
- if (++this.ticksActive % activeDuration == 0) {
- this.ticksActive = 0;
- setActive(false, -1);
- return false;
- }
- return true;
+ public boolean isActive() {
+ return this.getBlockState().getValue(GTBlockStateProperties.ACTIVE);
}
@Override
@@ -189,9 +157,26 @@ public GTToolType getPipeTuneTool() {
return GTToolType.WIRE_CUTTER;
}
- @Override
- public ManagedFieldHolder getFieldHolder() {
- return MANAGED_FIELD_HOLDER;
+ public static BlockState setPipeActive(PipeBlockEntity, ?> blockEntity,
+ BlockState state, boolean newActive, int duration) {
+ if (!state.hasProperty(GTBlockStateProperties.ACTIVE) ||
+ state.getValue(GTBlockStateProperties.ACTIVE) == newActive) {
+ return state;
+ }
+ BlockState newState = state.setValue(GTBlockStateProperties.ACTIVE, newActive);
+ if (blockEntity == null || blockEntity.getLevel() == null || blockEntity.isRemoved()) {
+ return newState;
+ }
+ Level level = blockEntity.getLevel();
+
+ level.setBlock(blockEntity.getBlockPos(), newState, Block.UPDATE_CLIENTS | Block.UPDATE_KNOWN_SHAPE);
+ blockEntity.notifyBlockUpdate();
+ blockEntity.setChanged();
+
+ if (newActive && level instanceof ServerLevel serverLevel) {
+ TaskHandler.enqueueServerTask(serverLevel, () -> setPipeActive(blockEntity, newState, false, -1), duration);
+ }
+ return newState;
}
private static class DefaultLaserContainer implements ILaserContainer {
diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/OpticalPipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/OpticalPipeBlockEntity.java
index 684ed5d3c93..edd25dcc1fa 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/OpticalPipeBlockEntity.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/OpticalPipeBlockEntity.java
@@ -1,5 +1,6 @@
package com.gregtechceu.gtceu.common.blockentity;
+import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties;
import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
import com.gregtechceu.gtceu.api.capability.IDataAccessHatch;
import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider;
@@ -9,12 +10,6 @@
import com.gregtechceu.gtceu.api.recipe.GTRecipe;
import com.gregtechceu.gtceu.common.pipelike.optical.*;
import com.gregtechceu.gtceu.utils.GTUtil;
-import com.gregtechceu.gtceu.utils.TaskHandler;
-
-import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced;
-import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted;
-import com.lowdragmc.lowdraglib.syncdata.annotation.RequireRerender;
-import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -25,7 +20,6 @@
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
-import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,9 +29,6 @@
public class OpticalPipeBlockEntity extends PipeBlockEntity {
- public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(OpticalPipeBlockEntity.class,
- PipeBlockEntity.MANAGED_FIELD_HOLDER);
-
private final EnumMap handlers = new EnumMap<>(Direction.class);
// the OpticalNetHandler can only be created on the server, so we have an empty placeholder for the client
private final IDataAccessHatch clientDataHandler = new DefaultDataHandler();
@@ -45,12 +36,6 @@ public class OpticalPipeBlockEntity extends PipeBlockEntity currentPipeNet = new WeakReference<>(null);
private OpticalNetHandler defaultHandler;
- @Getter
- @Persisted
- @DescSynced
- @RequireRerender
- private boolean isActive;
-
public OpticalPipeBlockEntity(BlockEntityType> type, BlockPos pos, BlockState blockState) {
super(type, pos, blockState);
}
@@ -157,20 +142,11 @@ public void setConnection(Direction side, boolean connected, boolean fromNeighbo
* @param duration how long the pipe should be active for
*/
public void setActive(boolean active, int duration) {
- boolean stateChanged = false;
- if (this.isActive && !active) {
- this.isActive = false;
- stateChanged = true;
- } else if (!this.isActive && active) {
- this.isActive = true;
- stateChanged = true;
- TaskHandler.enqueueServerTask((ServerLevel) getLevel(), () -> setActive(false, -1), duration);
- }
+ LaserPipeBlockEntity.setPipeActive(this, this.getBlockState(), active, duration);
+ }
- if (stateChanged) {
- notifyBlockUpdate();
- setChanged();
- }
+ public boolean isActive() {
+ return this.getBlockState().getValue(GTBlockStateProperties.ACTIVE);
}
@Override
@@ -184,11 +160,6 @@ public GTToolType getPipeTuneTool() {
return GTToolType.WIRE_CUTTER;
}
- @Override
- public ManagedFieldHolder getFieldHolder() {
- return MANAGED_FIELD_HOLDER;
- }
-
private static class DefaultDataHandler implements IDataAccessHatch {
@Override
diff --git a/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java b/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java
index 14e31f25adb..3b9463eb764 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java
@@ -293,7 +293,7 @@ private static int setActiveCape(CommandSourceStack source, ServerPlayer player,
private static int dumpDataRegistry(CommandContext context,
GTRegistry registry, Codec codec, String folder) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/data");
+ Path parent = GTCEu.GTCEU_FOLDER.resolve("dumped/data");
var ops = RegistryOps.create(JsonOps.INSTANCE, context.getSource().registryAccess());
int dumpedCount = 0;
for (ResourceLocation id : registry.keys()) {
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTBlockEntities.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTBlockEntities.java
index 4355206d72f..c4330ecb17b 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/GTBlockEntities.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTBlockEntities.java
@@ -13,7 +13,7 @@ public class GTBlockEntities {
@SuppressWarnings("unchecked")
public static final BlockEntityEntry CABLE = REGISTRATE
- .blockEntity("cable", CableBlockEntity::create)
+ .blockEntity("cable", CableBlockEntity::new)
.onRegister(CableBlockEntity::onBlockEntityRegister)
.validBlocks(GTMaterialBlocks.CABLE_BLOCKS.values().toArray(BlockEntry[]::new))
.register();
@@ -27,13 +27,13 @@ public class GTBlockEntities {
@SuppressWarnings("unchecked")
public static final BlockEntityEntry ITEM_PIPE = REGISTRATE
- .blockEntity("item_pipe", ItemPipeBlockEntity::create)
+ .blockEntity("item_pipe", ItemPipeBlockEntity::new)
.onRegister(ItemPipeBlockEntity::onBlockEntityRegister)
.validBlocks(GTMaterialBlocks.ITEM_PIPE_BLOCKS.values().toArray(BlockEntry[]::new))
.register();
public static final BlockEntityEntry LASER_PIPE = REGISTRATE
- .blockEntity("laser_pipe", LaserPipeBlockEntity::create)
+ .blockEntity("laser_pipe", LaserPipeBlockEntity::new)
.onRegister(LaserPipeBlockEntity::onBlockEntityRegister)
.validBlocks(GTBlocks.LASER_PIPES)
.register();
@@ -44,7 +44,7 @@ public class GTBlockEntities {
.register();
public static final BlockEntityEntry DUCT_PIPE = REGISTRATE
- .blockEntity("duct_pipe", DuctPipeBlockEntity::create)
+ .blockEntity("duct_pipe", DuctPipeBlockEntity::new)
.onRegister(DuctPipeBlockEntity::onBlockEntityRegister)
.validBlocks(GTBlocks.DUCT_PIPES)
.register();
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java
index a91932797f8..241aa9101ff 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java
@@ -115,7 +115,7 @@ private static void registerLaserPipeBlock(int index) {
.block("%s_laser_pipe".formatted(type.getSerializedName()), (p) -> new LaserPipeBlock(p, type))
.initialProperties(() -> Blocks.IRON_BLOCK)
.properties(p -> p.dynamicShape().noOcclusion().forceSolidOn())
- .blockstate(NonNullBiConsumer.noop())
+ .gtBlockstate(GTModels::createPipeBlockModel)
.defaultLoot()
.tag(CustomTags.MINEABLE_WITH_CONFIG_VALID_PICKAXE_WIRE_CUTTER)
.addLayer(() -> RenderType::cutoutMipped)
@@ -145,13 +145,13 @@ private static void registerOpticalPipeBlock(int index) {
.lang("Optical Fiber Cable")
.initialProperties(() -> Blocks.IRON_BLOCK)
.properties(p -> p.dynamicShape().noOcclusion().forceSolidOn())
- .blockstate(NonNullBiConsumer.noop())
+ .gtBlockstate(GTModels::createPipeBlockModel)
.defaultLoot()
.tag(CustomTags.MINEABLE_WITH_CONFIG_VALID_PICKAXE_WIRE_CUTTER)
.addLayer(() -> RenderType::cutoutMipped)
.addLayer(() -> RenderType::translucent)
.color(() -> OpticalPipeBlock::tintedColor)
- .item(OpticalPipeBlockItem::new)
+ .item(PipeBlockItem::new)
.model(NonNullBiConsumer.noop())
.build()
.register();
@@ -173,12 +173,12 @@ private static void registerDuctPipeBlock(int index) {
.block("%s_duct_pipe".formatted(type.getSerializedName()), (p) -> new DuctPipeBlock(p, type))
.initialProperties(() -> Blocks.IRON_BLOCK)
.properties(p -> p.dynamicShape().noOcclusion().forceSolidOn())
- .blockstate(NonNullBiConsumer.noop())
+ .gtBlockstate(GTModels::createPipeBlockModel)
.defaultLoot()
.tag(CustomTags.MINEABLE_WITH_CONFIG_VALID_PICKAXE_WRENCH)
.addLayer(() -> RenderType::cutoutMipped)
.addLayer(() -> RenderType::translucent)
- .item(DuctPipeBlockItem::new)
+ .item(PipeBlockItem::new)
.model(NonNullBiConsumer.noop())
.build()
.register();
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/models/GTModels.java b/src/main/java/com/gregtechceu/gtceu/common/data/models/GTModels.java
index c33890e76d7..6065874b12c 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/models/GTModels.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/models/GTModels.java
@@ -39,6 +39,8 @@ public class GTModels {
public static final ResourceLocation BLANK_TEXTURE = GTCEu.id("block/void");
+ public static final String ACTIVE_SUFFIX = "_active";
+
// region BLOCK MODELS
public static NonNullBiConsumer, GTBlockstateProvider> createModelBlockState(ResourceLocation modelLocation) {
@@ -273,6 +275,12 @@ public static NonNullBiConsumer, RegistrateBl
};
}
+ public static void createPipeBlockModel(DataGenContext> ctx,
+ GTBlockstateProvider prov) {
+ // the pipe model generator handles adding its models to the provider by itself
+ ctx.getEntry().createPipeModel(prov).initModels();
+ }
+
// endregion
// region RUNTIME GEN
diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/cable/Insulation.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/cable/Insulation.java
index b149d5df98c..fc543f04ff4 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/cable/Insulation.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/cable/Insulation.java
@@ -1,19 +1,19 @@
package com.gregtechceu.gtceu.common.pipelike.cable;
import com.gregtechceu.gtceu.GTCEu;
+import com.gregtechceu.gtceu.api.block.PipeBlock;
import com.gregtechceu.gtceu.api.data.chemical.material.Material;
import com.gregtechceu.gtceu.api.data.chemical.material.info.MaterialIconType;
import com.gregtechceu.gtceu.api.data.chemical.material.properties.WireProperties;
import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
import com.gregtechceu.gtceu.api.pipenet.IMaterialPipeType;
-import com.gregtechceu.gtceu.client.model.PipeModel;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
+import com.gregtechceu.gtceu.common.data.models.GTModels;
import net.minecraft.resources.ResourceLocation;
import lombok.Getter;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.function.Supplier;
import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.*;
@@ -83,20 +83,28 @@ public ResourceLocation type() {
return TYPE_ID;
}
- public PipeModel createPipeModel(Material material) {
- Supplier wireSideTexturePath = () -> MaterialIconType.wire
+ public PipeModel createPipeModel(PipeBlock, ?, ?> block, Material material, GTBlockstateProvider provider) {
+ ResourceLocation side = MaterialIconType.wire
.getBlockTexturePath(material.getMaterialIconSet(), "side", true);
- Supplier wireEndTexturePath = () -> MaterialIconType.wire
+ ResourceLocation end = MaterialIconType.wire
.getBlockTexturePath(material.getMaterialIconSet(), "end", true);
- Supplier<@Nullable ResourceLocation> wireSideOverlayTexturePath = () -> MaterialIconType.wire
+
+ PipeModel model = new PipeModel(block, provider, thickness,
+ isCable ? GTCEu.id("block/cable/insulation_5") : side, end);
+
+ ResourceLocation sideSecondary = MaterialIconType.wire
.getBlockTexturePath(material.getMaterialIconSet(), "side_overlay", true);
- Supplier<@Nullable ResourceLocation> wireEndOverlayTexturePath = () -> MaterialIconType.wire
+ ResourceLocation endSecondary = MaterialIconType.wire
.getBlockTexturePath(material.getMaterialIconSet(), "end_overlay", true);
- PipeModel model = new PipeModel(thickness,
- isCable ? () -> GTCEu.id("block/cable/insulation_5") : wireSideTexturePath, wireEndTexturePath,
- wireSideOverlayTexturePath, wireEndOverlayTexturePath);
+
+ if (sideSecondary != null && !sideSecondary.equals(GTModels.BLANK_TEXTURE)) {
+ model.setSideSecondary(sideSecondary);
+ }
+ if (endSecondary != null && !endSecondary.equals(GTModels.BLANK_TEXTURE)) {
+ model.setEndSecondary(endSecondary);
+ }
if (isCable) {
- model.setEndOverlayTexture(GTCEu.id("block/cable/insulation_%s".formatted(insulationLevel)));
+ model.setEndOverlay(GTCEu.id("block/cable/insulation_%s".formatted(insulationLevel)));
}
return model;
}
diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/duct/DuctPipeType.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/duct/DuctPipeType.java
index 1323fa297f1..feebae0b7ca 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/duct/DuctPipeType.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/duct/DuctPipeType.java
@@ -2,7 +2,6 @@
import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.pipenet.IPipeType;
-import com.gregtechceu.gtceu.client.model.PipeModel;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.StringRepresentable;
@@ -54,10 +53,4 @@ public ResourceLocation type() {
public String getSerializedName() {
return name().toLowerCase(Locale.ROOT);
}
-
- public PipeModel createPipeModel() {
- return new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_duct_side"),
- () -> GTCEu.id("block/pipe/pipe_duct_in"),
- null, null);
- }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeType.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeType.java
index 8ad5940e500..f068dd69236 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeType.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeType.java
@@ -1,12 +1,14 @@
package com.gregtechceu.gtceu.common.pipelike.fluidpipe;
import com.gregtechceu.gtceu.GTCEu;
+import com.gregtechceu.gtceu.api.block.PipeBlock;
import com.gregtechceu.gtceu.api.data.chemical.material.Material;
import com.gregtechceu.gtceu.api.data.chemical.material.properties.FluidPipeProperties;
import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey;
import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
import com.gregtechceu.gtceu.api.pipenet.IMaterialPipeType;
-import com.gregtechceu.gtceu.client.model.PipeModel;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
import net.minecraft.resources.ResourceLocation;
@@ -72,26 +74,20 @@ public ResourceLocation type() {
return TYPE_ID;
}
- public PipeModel createPipeModel(Material material) {
+ public PipeModel createPipeModel(PipeBlock, ?, ?> block, Material material, GTBlockstateProvider provider) {
+ String side = "block/pipe/pipe%s_side";
+ String end = "block/pipe/pipe_%s_in".formatted(name);
if (material.hasProperty(PropertyKey.WOOD)) {
- return new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_side_wood"),
- () -> GTCEu.id("block/pipe/pipe_%s_in_wood".formatted(name)), null, null);
+ side += "_wood";
+ end += "_wood";
}
if (channels == 9) {
- return new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_non_side"),
- () -> GTCEu.id("block/pipe/pipe_%s_in".formatted(name)),
- null, null);
+ side = side.formatted("_non");
} else if (channels == 4) {
- return new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_quad_side"),
- () -> GTCEu.id("block/pipe/pipe_%s_in".formatted(name)),
- null, null);
+ side = side.formatted("_quad");
+ } else {
+ side = side.formatted("");
}
- return new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_side"),
- () -> GTCEu.id("block/pipe/pipe_%s_in".formatted(name)),
- null, null/*
- * () -> GTCEu.id("block/pipe/pipe_side_secondary"), () ->
- * GTCEu.id("block/pipe/pipe_%s_in_secondary".formatted(name)) TODO enable once the textures
- * are added
- */);
+ return new PipeModel(block, provider, thickness, GTCEu.id(side), GTCEu.id(end));
}
}
diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeType.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeType.java
index 68e5c37d016..8c6a4f78083 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeType.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeType.java
@@ -1,12 +1,14 @@
package com.gregtechceu.gtceu.common.pipelike.item;
import com.gregtechceu.gtceu.GTCEu;
+import com.gregtechceu.gtceu.api.block.PipeBlock;
import com.gregtechceu.gtceu.api.data.chemical.material.Material;
import com.gregtechceu.gtceu.api.data.chemical.material.properties.ItemPipeProperties;
import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey;
import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
import com.gregtechceu.gtceu.api.pipenet.IMaterialPipeType;
-import com.gregtechceu.gtceu.client.model.PipeModel;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModel;
import net.minecraft.resources.ResourceLocation;
@@ -72,25 +74,18 @@ public ResourceLocation type() {
return TYPE_ID;
}
- public PipeModel createPipeModel(Material material) {
- PipeModel model;
+ public PipeModel createPipeModel(PipeBlock, ?, ?> block, Material material, GTBlockstateProvider provider) {
+ ResourceLocation sideTexture = GTCEu.id("block/pipe/pipe_side");
+ ResourceLocation endTexture = GTCEu.id("block/pipe/pipe_%s_in"
+ .formatted(this.isRestrictive() ? values()[this.ordinal() - 4].name : name));
if (material.hasProperty(PropertyKey.WOOD)) {
- model = new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_side_wood"),
- () -> GTCEu.id("block/pipe/pipe_%s_in_wood"
- .formatted(this.isRestrictive() ? values()[this.ordinal() - 4].name : name)),
- null, null);
- } else {
- model = new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_side"),
- () -> GTCEu.id("block/pipe/pipe_%s_in"
- .formatted(this.isRestrictive() ? values()[this.ordinal() - 4].name : name)),
- null, null/*
- * () -> GTCEu.id("block/pipe/pipe_side_secondary"), () ->
- * GTCEu.id("block/pipe/pipe_%s_in_secondary".formatted(this.isRestrictive() ?
- * values()[this.ordinal() - 4].name : name)) TODO enable once the textures are added
- */);
+ sideTexture = sideTexture.withSuffix("_wood");
+ endTexture = endTexture.withSuffix("_wood");
}
+
+ PipeModel model = new PipeModel(block, provider, thickness, sideTexture, endTexture);
if (isRestrictive()) {
- model.setSideOverlayTexture(GTCEu.id("block/pipe/pipe_restrictive"));
+ model.setSideOverlay(GTCEu.id("block/pipe/pipe_restrictive"));
}
return model;
}
diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/client/ModelManagerMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/client/ModelManagerMixin.java
index 24605160b28..9c8a8ec19f1 100644
--- a/src/main/java/com/gregtechceu/gtceu/core/mixins/client/ModelManagerMixin.java
+++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/client/ModelManagerMixin.java
@@ -1,14 +1,7 @@
package com.gregtechceu.gtceu.core.mixins.client;
import com.gregtechceu.gtceu.GTCEu;
-import com.gregtechceu.gtceu.client.renderer.block.MaterialBlockRenderer;
-import com.gregtechceu.gtceu.client.renderer.block.OreBlockRenderer;
-import com.gregtechceu.gtceu.client.renderer.block.SurfaceRockRenderer;
-import com.gregtechceu.gtceu.client.renderer.item.ArmorItemRenderer;
-import com.gregtechceu.gtceu.client.renderer.item.TagPrefixItemRenderer;
-import com.gregtechceu.gtceu.client.renderer.item.ToolItemRenderer;
-import com.gregtechceu.gtceu.common.data.models.GTModels;
-import com.gregtechceu.gtceu.integration.kjs.GregTechKubeJSPlugin;
+import com.gregtechceu.gtceu.data.pack.event.RegisterDynamicResourcesEvent;
import com.gregtechceu.gtceu.integration.modernfix.GTModernFixIntegration;
import net.minecraft.client.resources.model.ModelManager;
@@ -37,17 +30,8 @@ public abstract class ModelManagerMixin {
long startTime = System.currentTimeMillis();
// turns out these do have to be init in here after all, as they check for asset existence. whoops.
- MaterialBlockRenderer.reinitModels();
- TagPrefixItemRenderer.reinitModels();
- OreBlockRenderer.reinitModels();
- ToolItemRenderer.reinitModels();
- ArmorItemRenderer.reinitModels();
- SurfaceRockRenderer.reinitModels();
- GTModels.registerMaterialFluidModels();
-
- if (GTCEu.Mods.isKubeJSLoaded()) {
- GregTechKubeJSPlugin.generateMachineBlockModels();
- }
+ ModLoader.get().postEventWrapContainerInModOrder(new RegisterDynamicResourcesEvent());
+
if (GTCEu.Mods.isModernFixLoaded()) {
GTModernFixIntegration.setAsLast();
}
diff --git a/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java b/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java
new file mode 100644
index 00000000000..917e3996be2
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java
@@ -0,0 +1,477 @@
+package com.gregtechceu.gtceu.data.model.builder;
+
+import com.gregtechceu.gtceu.GTCEu;
+import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
+import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.client.model.pipe.PipeModelLoader;
+import com.gregtechceu.gtceu.core.mixins.forge.ConfiguredModelBuilderAccessor;
+import com.gregtechceu.gtceu.utils.GTMath;
+import com.gregtechceu.gtceu.utils.GTUtil;
+import com.gregtechceu.gtceu.utils.memoization.GTMemoizer;
+import com.gregtechceu.gtceu.utils.memoization.function.MemoizedBiFunction;
+
+import net.minecraft.Util;
+import net.minecraft.core.Direction;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraftforge.client.model.generators.*;
+import net.minecraftforge.client.model.generators.BlockStateProvider.ConfiguredModelList;
+import net.minecraftforge.common.data.ExistingFileHelper;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.gson.JsonObject;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.Range;
+import org.joml.Vector3f;
+
+import java.util.*;
+
+import static com.gregtechceu.gtceu.data.model.builder.MachineModelBuilder.configuredModelListToJSON;
+import static com.gregtechceu.gtceu.data.model.builder.MachineModelBuilder.configuredModelToJSON;
+
+@Accessors(fluent = true, chain = true)
+@SuppressWarnings("UnusedReturnValue")
+public class PipeModelBuilder> extends CustomLoaderBuilder {
+
+ public static > PipeModelBuilder begin(T parent,
+ ExistingFileHelper existingFileHelper) {
+ return new PipeModelBuilder<>(parent, existingFileHelper);
+ }
+
+ @Accessors(fluent = false)
+ @Getter
+ private final Map parts = new IdentityHashMap<>();
+ @Setter
+ @Range(from = 0, to = 16)
+ private float thickness = Float.MIN_VALUE;
+ @Setter
+ private @NotNull GTBlockstateProvider provider;
+ private BlockModelBuilder[] restrictors = null;
+
+ protected PipeModelBuilder(T parent, ExistingFileHelper existingFileHelper) {
+ super(PipeModelLoader.ID, parent, existingFileHelper);
+ }
+
+ /**
+ * Set the models for all pipe elements at the same time
+ *
+ * @param centerModel The model to use for the center part of the pipe
+ * @param connectionModels The models to use for all the connection elements
+ * @return {@code this}
+ * @see #allModels(ModelFile, ModelFile...)
+ * @see #allModels(ResourceLocation, ResourceLocation...)
+ */
+ public PipeModelBuilder allModels(ConfiguredModel centerModel, ConfiguredModel... connectionModels) {
+ centerModels(centerModel);
+ connectionModels(connectionModels);
+ return this;
+ }
+
+ /**
+ * Set the models for all pipe elements at the same time
+ *
+ * @param centerModel The model to use for the center part of the pipe
+ * @param connectionModels The models to use for all the connection elements
+ * @return {@code this}
+ * @see #allModels(ModelFile, ModelFile...)
+ * @see #allModels(ResourceLocation, ResourceLocation...)
+ */
+ public PipeModelBuilder allModels(ModelFile centerModel, ModelFile... connectionModels) {
+ centerModels(centerModel);
+ connectionModels(connectionModels);
+ return this;
+ }
+
+ /**
+ * Set the models for all pipe elements at the same time
+ *
+ * @param centerModel The model to use for the center part of the pipe
+ * @param connectionModels The models to use for all the connection elements
+ * @return {@code this}
+ * @see #allModels(ConfiguredModel, ConfiguredModel...)
+ * @see #allModels(ModelFile, ModelFile...)
+ */
+ public PipeModelBuilder allModels(ResourceLocation centerModel, ResourceLocation... connectionModels) {
+ centerModels(centerModel);
+ connectionModels(connectionModels);
+ return this;
+ }
+
+ /**
+ * Set the models for all connection elements
+ *
+ * @param connectionModels The models to use for all the connection elements
+ * @return {@code this}
+ * @see #connectionModels(ModelFile...)
+ * @see #connectionModels(ResourceLocation...)
+ */
+ public PipeModelBuilder connectionModels(ConfiguredModel... connectionModels) {
+ for (Direction dir : GTUtil.DIRECTIONS) {
+ ConfiguredModel[] rotatedModels = Arrays.stream(connectionModels)
+ .map(model -> ConfiguredModel.builder()
+ .modelFile(model.model).uvLock(model.uvLock).weight(model.weight)
+ .rotationX(dir == Direction.DOWN ? 90 : dir == Direction.UP ? 270 : 0)
+ .rotationY(dir.getAxis().isVertical() ? 0 : ((int) dir.toYRot() + 180) % 360)
+ .buildLast())
+ .toArray(ConfiguredModel[]::new);
+ modelsForDirection(dir, rotatedModels);
+ }
+ return this;
+ }
+
+ /**
+ * Set the models for all connection elements
+ *
+ * @param connectionModels The models to use for all the connection elements
+ * @return {@code this}
+ * @see #connectionModels(ConfiguredModel...)
+ * @see #connectionModels(ResourceLocation...)
+ */
+ public PipeModelBuilder connectionModels(ModelFile... connectionModels) {
+ for (Direction dir : GTUtil.DIRECTIONS) {
+ ConfiguredModel[] rotatedModels = Arrays.stream(connectionModels)
+ .map(model -> ConfiguredModel.builder()
+ .modelFile(model)
+ .rotationX(dir == Direction.DOWN ? 0 : dir == Direction.UP ? 180 : 90)
+ .rotationY(dir.getAxis().isVertical() ? 0 : (int) dir.toYRot())
+ .buildLast())
+ .toArray(ConfiguredModel[]::new);
+ modelsForDirection(dir, rotatedModels);
+ }
+ return this;
+ }
+
+ /**
+ * Set the models for all connection elements
+ *
+ * @param connectionModels The models to use for all the connection elements
+ * @return {@code this}
+ * @see #connectionModels(ConfiguredModel...)
+ * @see #connectionModels(ModelFile...)
+ */
+ public PipeModelBuilder connectionModels(ResourceLocation... connectionModels) {
+ return connectionModels(Arrays.stream(connectionModels)
+ .map(loc -> new ModelFile.ExistingModelFile(loc, this.existingFileHelper))
+ .toArray(ModelFile[]::new));
+ }
+
+ /**
+ * Set the models for all connection elements with a builder
+ *
+ * @return A model builder
+ * @see #connectionModels(ConfiguredModel...)
+ * @see #connectionModels(ModelFile...)
+ * @see #connectionModels(ResourceLocation...)
+ */
+ public ConfiguredModel.Builder> connectionModels() {
+ return ConfiguredModelBuilderAccessor.builder(this::connectionModels, ImmutableList.of());
+ }
+
+ /**
+ * Set the models for the center element
+ *
+ * @param centerModels The model to use for the center part of the pipe
+ * @return {@code this}
+ * @see #centerModels(ModelFile...)
+ * @see #centerModels(ResourceLocation...)
+ */
+ public PipeModelBuilder centerModels(ConfiguredModel... centerModels) {
+ return modelsForDirection(null, centerModels);
+ }
+
+ /**
+ * Set the models for the center element
+ *
+ * @param centerModels The model to use for the center part of the pipe
+ * @return {@code this}
+ * @see #centerModels(ConfiguredModel...)
+ * @see #centerModels(ResourceLocation...)
+ */
+ public PipeModelBuilder centerModels(ModelFile... centerModels) {
+ return modelsForDirection(null, centerModels);
+ }
+
+ /**
+ * Set the models for the center element
+ *
+ * @param centerModels The model to use for the center part of the pipe
+ * @return {@code this}
+ * @see #centerModels(ConfiguredModel...)
+ * @see #centerModels(ModelFile...)
+ */
+ public PipeModelBuilder centerModels(ResourceLocation... centerModels) {
+ return modelsForDirection(null, centerModels);
+ }
+
+ /**
+ * Set the models for the center element with a builder
+ *
+ * @return A model builder
+ * @see #centerModels(ConfiguredModel...)
+ * @see #centerModels(ModelFile...)
+ * @see #centerModels(ResourceLocation...)
+ */
+ public ConfiguredModel.Builder> centerModel() {
+ return ConfiguredModelBuilderAccessor.builder(this::centerModels, ImmutableList.of());
+ }
+
+ /**
+ * Set the models for the given direction
+ *
+ * @param direction The direction that'll use the model(s)
+ * @param models The models to set for the direction.
+ * @return {@code this}
+ * @see #modelsForDirection(Direction, ModelFile...)
+ * @see #modelsForDirection(Direction, ResourceLocation...)
+ */
+ public PipeModelBuilder modelsForDirection(@Nullable Direction direction, ConfiguredModel... models) {
+ parts.put(direction, new ConfiguredModelList(models));
+ return this;
+ }
+
+ /**
+ * Set the models for the given direction
+ *
+ * @param direction The direction that'll use the model(s)
+ * @param models The models to set for the direction.
+ * @return {@code this}
+ * @see #modelsForDirection(Direction, ConfiguredModel...)
+ * @see #modelsForDirection(Direction, ResourceLocation...)
+ */
+ public PipeModelBuilder modelsForDirection(@Nullable Direction direction, ModelFile... models) {
+ return modelsForDirection(direction, Arrays.stream(models)
+ .map(model -> ConfiguredModel.builder().modelFile(model).buildLast())
+ .toArray(ConfiguredModel[]::new));
+ }
+
+ /**
+ * Set the models for the given direction
+ *
+ * @param direction The direction that'll use the model(s)
+ * @param models The models to set for the direction.
+ * @return {@code this}
+ * @see #modelsForDirection(Direction, ConfiguredModel...)
+ * @see #modelsForDirection(Direction, ModelFile...)
+ */
+ public PipeModelBuilder modelsForDirection(@Nullable Direction direction, ResourceLocation... models) {
+ return modelsForDirection(direction, Arrays.stream(models)
+ .map(model -> ConfiguredModel.builder()
+ .modelFile(new ModelFile.ExistingModelFile(model, this.existingFileHelper))
+ .buildLast())
+ .toArray(ConfiguredModel[]::new));
+ }
+
+ /**
+ * Set the models for the given direction with a builder
+ *
+ * @return A model builder
+ * @see #modelsForDirection(Direction, ConfiguredModel...)
+ * @see #modelsForDirection(Direction, ModelFile...)
+ * @see #modelsForDirection(Direction, ResourceLocation...)
+ */
+ public ConfiguredModel.Builder> modelsForDirection(@Nullable Direction direction) {
+ return ConfiguredModelBuilderAccessor.builder(models -> this.modelsForDirection(direction, models),
+ ImmutableList.of());
+ }
+
+ @Override
+ public T end() {
+ this.restrictors = getOrCreateRestrictorModels(this.provider.models(), this.thickness);
+ return super.end();
+ }
+
+ @Override
+ public JsonObject toJson(JsonObject json) {
+ Preconditions.checkState(thickness != Float.MIN_VALUE, "A thickness value must be set!");
+ Preconditions.checkState(thickness > 0.0f || thickness <= 16.0f,
+ "Thickness must be between 0 (exclusive) and 16 (inclusive). is %s", thickness);
+ // noinspection ConstantValue
+ Preconditions.checkState(provider != null, "You must pass in a GTBlockStateProvider!");
+
+ json = super.toJson(json);
+
+ if (!getParts().isEmpty()) {
+ final JsonObject parts = new JsonObject();
+ getParts().entrySet().stream()
+ .sorted(Map.Entry.comparingByKey(Comparator.nullsFirst(Direction::compareTo)))
+ .forEach(entry -> {
+ String key = entry.getKey() != null ? entry.getKey().getName() :
+ PipeModelLoader.PRIMARY_CENTER_KEY;
+ parts.add(key, configuredModelListToJSON(entry.getValue()));
+ });
+
+ json.add("parts", parts);
+ }
+
+ if (this.restrictors != null) {
+ final JsonObject restrictors = new JsonObject();
+ for (int i = 0; i < GTUtil.DIRECTIONS.length; i++) {
+ Direction dir = GTUtil.DIRECTIONS[i];
+ restrictors.add(dir.getName(),
+ configuredModelToJSON(ConfiguredModel.builder()
+ .modelFile(new ModelFile.UncheckedModelFile(this.restrictors[i].getLocation()))
+ .buildLast(), false));
+ }
+ json.add("restrictors", restrictors);
+ }
+
+ return json;
+ }
+
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY = GTCEu.id("block/pipe/blocked/pipe_blocked");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_UP = GTCEu.id("block/pipe/blocked/pipe_blocked_up");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_DOWN = GTCEu.id("block/pipe/blocked/pipe_blocked_down");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_LEFT = GTCEu.id("block/pipe/blocked/pipe_blocked_left");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_RIGHT = GTCEu
+ .id("block/pipe/blocked/pipe_blocked_right");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_NU = GTCEu.id("block/pipe/blocked/pipe_blocked_nu");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_ND = GTCEu.id("block/pipe/blocked/pipe_blocked_nd");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_NL = GTCEu.id("block/pipe/blocked/pipe_blocked_nl");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_NR = GTCEu.id("block/pipe/blocked/pipe_blocked_nr");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_UD = GTCEu.id("block/pipe/blocked/pipe_blocked_ud");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_UL = GTCEu.id("block/pipe/blocked/pipe_blocked_ul");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_UR = GTCEu.id("block/pipe/blocked/pipe_blocked_ur");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_DL = GTCEu.id("block/pipe/blocked/pipe_blocked_dl");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_DR = GTCEu.id("block/pipe/blocked/pipe_blocked_dr");
+ private static final ResourceLocation PIPE_BLOCKED_OVERLAY_LR = GTCEu.id("block/pipe/blocked/pipe_blocked_lr");
+
+ private static final Int2ObjectMap RESTRICTOR_MAP = Util.make(() -> {
+ Int2ObjectMap map = new Int2ObjectOpenHashMap<>();
+
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_UP, Border.TOP);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_DOWN, Border.BOTTOM);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_UD, Border.TOP, Border.BOTTOM);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_LEFT, Border.LEFT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_UL, Border.TOP, Border.LEFT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_DL, Border.BOTTOM, Border.LEFT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_NR, Border.TOP, Border.BOTTOM, Border.LEFT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_RIGHT, Border.RIGHT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_UR, Border.TOP, Border.RIGHT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_DR, Border.BOTTOM, Border.RIGHT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_NL, Border.TOP, Border.BOTTOM, Border.RIGHT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_LR, Border.LEFT, Border.RIGHT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_ND, Border.TOP, Border.LEFT, Border.RIGHT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY_NU, Border.BOTTOM, Border.LEFT, Border.RIGHT);
+ addRestrictor(map, PIPE_BLOCKED_OVERLAY, Border.TOP, Border.BOTTOM, Border.LEFT, Border.RIGHT);
+
+ return map;
+ });
+
+ private static BlockModelBuilder[] getOrCreateRestrictorModels(BlockModelProvider provider, float thickness) {
+ return RESTRICTOR_MODEL_CACHE.apply(provider, thickness);
+ }
+
+ private static final MemoizedBiFunction RESTRICTOR_MODEL_CACHE = GTMemoizer
+ .memoizeFunctionWeakIdent(PipeModelBuilder::makeRestrictorModels);
+
+ private static BlockModelBuilder[] makeRestrictorModels(BlockModelProvider provider, float thickness) {
+ BlockModelBuilder[] models = new BlockModelBuilder[GTUtil.DIRECTIONS.length];
+
+ float min = (16.0f - thickness) / 2.0f - 0.003f;
+ float max = min + thickness + 0.006f; // offset by 0.003 * 2
+ for (Direction dir : GTUtil.DIRECTIONS) {
+ String modelPath = "block/pipe/restrictor/" + dir.getName() + "/thickness_" + thickness;
+ ResourceLocation modelName = GTCEu.id(modelPath);
+ if (provider.generatedModels.containsKey(modelName)) {
+ models[dir.ordinal()] = provider.generatedModels.get(modelName);
+ continue;
+ }
+
+ var coords = GTMath.getCoordinates(dir, min, max);
+ Vector3f minPos = coords.getLeft();
+ Vector3f maxPos = coords.getRight();
+ BlockModelBuilder model = provider.getBuilder(modelPath);
+ model.texture("restrictor", PIPE_BLOCKED_OVERLAY)
+ .element()
+ .from(minPos.x, minPos.y, minPos.z)
+ .to(maxPos.x, maxPos.y, maxPos.z)
+ .face(getSideAtBorder(dir, Border.BOTTOM)).end()
+ .face(getSideAtBorder(dir, Border.TOP)).end()
+ .face(getSideAtBorder(dir, Border.LEFT)).end()
+ .face(getSideAtBorder(dir, Border.RIGHT)).end()
+ .faces((face, builder) -> builder.texture("#restrictor"))
+ .end();
+ models[dir.ordinal()] = model;
+ }
+ return models;
+ }
+
+ @ApiStatus.Internal
+ public static void clearRestrictorModelCache() {
+ RESTRICTOR_MODEL_CACHE.getCache().clear();
+ }
+
+ private static final EnumMap> FACE_BORDER_MAP = Util.make(() -> {
+ EnumMap> map = new EnumMap<>(Direction.class);
+
+ map.put(Direction.DOWN, borderMap(Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST));
+ map.put(Direction.UP, borderMap(Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST));
+ map.put(Direction.NORTH, borderMap(Direction.DOWN, Direction.UP, Direction.WEST, Direction.EAST));
+ map.put(Direction.SOUTH, borderMap(Direction.DOWN, Direction.UP, Direction.WEST, Direction.EAST));
+ map.put(Direction.WEST, borderMap(Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH));
+ map.put(Direction.EAST, borderMap(Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH));
+
+ return map;
+ });
+
+ private static EnumMap borderMap(Direction topSide, Direction bottomSide,
+ Direction leftSide, Direction rightSide) {
+ EnumMap sideMap = new EnumMap<>(Border.class);
+ sideMap.put(Border.TOP, topSide);
+ sideMap.put(Border.BOTTOM, bottomSide);
+ sideMap.put(Border.LEFT, leftSide);
+ sideMap.put(Border.RIGHT, rightSide);
+ return sideMap;
+ }
+
+ private static void addRestrictor(Int2ObjectMap map, ResourceLocation texture,
+ Border... borders) {
+ int mask = 0;
+ for (Border border : borders) {
+ mask |= border.mask;
+ }
+ map.put(mask, texture);
+ }
+
+ private static Direction getSideAtBorder(Direction side, Border border) {
+ return FACE_BORDER_MAP.get(side).get(border);
+ }
+
+ private static int computeBorderMask(int blockedConnections, int connections, Direction side) {
+ int borderMask = 0;
+ if (blockedConnections != 0) {
+ for (Border border : Border.VALUES) {
+ Direction borderSide = getSideAtBorder(side, border);
+ if (PipeBlockEntity.isFaceBlocked(blockedConnections, borderSide) &&
+ PipeBlockEntity.isConnected(connections, borderSide)) {
+ // only render when the side is blocked *and* connected
+ borderMask |= border.mask;
+ }
+ }
+ }
+ return borderMask;
+ }
+
+ private enum Border {
+
+ TOP,
+ BOTTOM,
+ LEFT,
+ RIGHT;
+
+ public static final Border[] VALUES = values();
+
+ public final int mask;
+
+ Border() {
+ mask = 1 << this.ordinal();
+ }
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicDataPack.java b/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicDataPack.java
index cbf7560b4f3..103ffba6b4d 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicDataPack.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicDataPack.java
@@ -68,7 +68,7 @@ private static void addToData(ResourceLocation location, byte[] bytes) {
public static void addRecipe(FinishedRecipe recipe) {
JsonObject recipeJson = recipe.serializeRecipe();
byte[] recipeBytes = recipeJson.toString().getBytes(StandardCharsets.UTF_8);
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/data");
+ Path parent = GTCEu.GTCEU_FOLDER.resolve("dumped/data");
ResourceLocation recipeId = recipe.getId();
if (ConfigHolder.INSTANCE.dev.dumpRecipes) {
writeJson(recipeId, "recipes", parent, recipeBytes);
diff --git a/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicResourcePack.java b/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicResourcePack.java
index bb5522a00f3..a33acec7fff 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicResourcePack.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicResourcePack.java
@@ -9,6 +9,8 @@
import net.minecraft.SharedConstants;
import net.minecraft.client.renderer.texture.atlas.SpriteSource;
import net.minecraft.client.renderer.texture.atlas.SpriteSources;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.data.models.blockstates.BlockStateGenerator;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.FileToIdConverter;
import net.minecraft.resources.ResourceLocation;
@@ -17,6 +19,9 @@
import net.minecraft.server.packs.metadata.MetadataSectionSerializer;
import net.minecraft.server.packs.metadata.pack.PackMetadataSection;
import net.minecraft.server.packs.resources.IoSupplier;
+import net.minecraftforge.client.model.generators.BlockModelBuilder;
+import net.minecraftforge.client.model.generators.ItemModelBuilder;
+import net.minecraftforge.client.model.generators.ModelBuilder;
import com.google.common.collect.Sets;
import com.google.gson.JsonElement;
@@ -52,9 +57,8 @@ public class GTDynamicResourcePack implements PackResources {
private static final FileToIdConverter ATLAS_ID_CONVERTER = FileToIdConverter.json("atlases");
private static final FileToIdConverter TEXTURE_ID_CONVERTER = SpriteSource.TEXTURE_ID_CONVERTER;
- private static final FileToIdConverter BLOCKSTATE_ID_CONVERTER = FileToIdConverter.json("blockstates");
- private static final FileToIdConverter BLOCK_MODEL_ID_CONVERTER = FileToIdConverter.json("models/block");
- private static final FileToIdConverter ITEM_MODEL_ID_CONVERTER = FileToIdConverter.json("models/item");
+ public static final FileToIdConverter BLOCKSTATE_ID_CONVERTER = FileToIdConverter.json("blockstates");
+ private static final FileToIdConverter MODEL_ID_CONVERTER = FileToIdConverter.json("models");
private final String name;
@@ -81,89 +85,83 @@ public static void addResource(ResourceLocation location, JsonElement obj) {
public static void addResource(ResourceLocation location, byte[] data) {
if (ConfigHolder.INSTANCE.dev.dumpAssets) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/assets");
+ Path parent = GTCEu.GTCEU_FOLDER.resolve("dumped/assets");
writeJson(location, null, parent, data);
}
CONTENTS.addToData(location, data);
}
public static void addBlockModel(ResourceLocation loc, JsonElement obj) {
- ResourceLocation l = getBlockModelLocation(loc);
- byte[] modelBytes = obj.toString().getBytes(StandardCharsets.UTF_8);
-
- if (ConfigHolder.INSTANCE.dev.dumpAssets) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/assets");
- writeJson(l, null, parent, modelBytes);
+ if (!loc.getPath().startsWith("block/")) {
+ loc = loc.withPrefix("block/");
}
- CONTENTS.addToData(l, modelBytes);
+ addModel(loc, obj);
}
public static void addBlockModel(ResourceLocation loc, Supplier obj) {
addBlockModel(loc, obj.get());
}
- public static void addItemModel(ResourceLocation loc, JsonElement obj) {
- ResourceLocation l = getItemModelLocation(loc);
- byte[] modelBytes = obj.toString().getBytes(StandardCharsets.UTF_8);
+ public static void addBlockModel(BlockModelBuilder builder) {
+ addBlockModel(builder.getLocation(), builder.toJson());
+ }
- if (ConfigHolder.INSTANCE.dev.dumpAssets) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/assets");
- writeJson(l, null, parent, modelBytes);
+ public static void addItemModel(ResourceLocation loc, JsonElement obj) {
+ if (!loc.getPath().startsWith("item/")) {
+ loc = loc.withPrefix("item/");
}
- CONTENTS.addToData(l, modelBytes);
+ addModel(loc, obj);
+ }
+
+ public static void addItemModel(ItemModelBuilder builder) {
+ addItemModel(builder.getLocation(), builder.toJson());
}
public static void addItemModel(ResourceLocation loc, Supplier obj) {
addItemModel(loc, obj.get());
}
- public static void addBlockState(ResourceLocation loc, JsonElement stateJson) {
- ResourceLocation l = getBlockStateLocation(loc);
- byte[] stateBytes = stateJson.toString().getBytes(StandardCharsets.UTF_8);
+ public static void addModel(ResourceLocation loc, JsonElement obj) {
+ loc = MODEL_ID_CONVERTER.idToFile(loc);
+ addResource(loc, obj);
+ }
- if (ConfigHolder.INSTANCE.dev.dumpAssets) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/assets");
- writeJson(l, null, parent, stateBytes);
- }
- CONTENTS.addToData(l, stateBytes);
+ public static void addModel(ResourceLocation loc, Supplier obj) {
+ addModel(loc, obj.get());
+ }
+
+ public static > void addModel(T builder) {
+ addModel(builder.getLocation(), builder.toJson());
+ }
+
+ public static void addBlockState(ResourceLocation loc, JsonElement stateJson) {
+ loc = BLOCKSTATE_ID_CONVERTER.idToFile(loc);
+ addResource(loc, stateJson);
}
public static void addBlockState(ResourceLocation loc, Supplier generator) {
addBlockState(loc, generator.get());
}
- public static void addAtlasSpriteSource(ResourceLocation atlasLoc, SpriteSource source) {
- ResourceLocation l = getAtlasLocation(atlasLoc);
- JsonElement sourceJson = SpriteSources.FILE_CODEC
- .encodeStart(JsonOps.INSTANCE, Collections.singletonList(source))
- .getOrThrow(false,
- error -> GTCEu.LOGGER.error("Failed to encode atlas sprite source. {}", error));
- byte[] sourceBytes = sourceJson.toString().getBytes(StandardCharsets.UTF_8);
-
- if (ConfigHolder.INSTANCE.dev.dumpAssets) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/assets");
- writeJson(l, null, parent, sourceBytes);
- }
- CONTENTS.addToData(l, sourceBytes);
+ public static void addBlockState(BlockStateGenerator generator) {
+ addBlockState(BuiltInRegistries.BLOCK.getKey(generator.getBlock()), generator.get());
}
- public static void addAtlasSpriteSourceList(ResourceLocation atlasLoc, List sources) {
- ResourceLocation l = getAtlasLocation(atlasLoc);
- JsonElement sourceJson = SpriteSources.FILE_CODEC.encodeStart(JsonOps.INSTANCE, sources).getOrThrow(false,
- error -> GTCEu.LOGGER.error("Failed to encode atlas sprite source. {}", error));
- byte[] sourceBytes = sourceJson.toString().getBytes(StandardCharsets.UTF_8);
+ public static void addAtlasSpriteSource(ResourceLocation atlasLoc, SpriteSource source) {
+ addAtlasSpriteSourceList(atlasLoc, Collections.singletonList(source));
+ }
- if (ConfigHolder.INSTANCE.dev.dumpAssets) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/assets");
- writeJson(l, null, parent, sourceBytes);
- }
- CONTENTS.addToData(l, sourceBytes);
+ public static void addAtlasSpriteSourceList(ResourceLocation loc, List sources) {
+ loc = ATLAS_ID_CONVERTER.idToFile(loc);
+ JsonElement sourceJson = SpriteSources.FILE_CODEC.encodeStart(JsonOps.INSTANCE, sources)
+ .getOrThrow(false, error -> GTCEu.LOGGER.error("Failed to encode atlas sprite source. {}", error));
+ addResource(loc, sourceJson);
}
public static void addBlockTexture(ResourceLocation loc, byte[] data) {
ResourceLocation l = getTextureLocation("block", loc);
if (ConfigHolder.INSTANCE.dev.dumpAssets) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/assets");
+ Path parent = GTCEu.GTCEU_FOLDER.resolve("dumped/assets");
writeByteArray(l, null, parent, data);
}
CONTENTS.addToData(l, data);
@@ -172,7 +170,7 @@ public static void addBlockTexture(ResourceLocation loc, byte[] data) {
public static void addItemTexture(ResourceLocation loc, byte[] data) {
ResourceLocation l = getTextureLocation("item", loc);
if (ConfigHolder.INSTANCE.dev.dumpAssets) {
- Path parent = GTCEu.getGameDir().resolve("gtceu/dumped/assets");
+ Path parent = GTCEu.GTCEU_FOLDER.resolve("dumped/assets");
writeByteArray(l, null, parent, data);
}
CONTENTS.addToData(l, data);
@@ -252,26 +250,10 @@ public void close() {
// NOOP
}
- public static ResourceLocation getBlockStateLocation(ResourceLocation blockId) {
- return BLOCKSTATE_ID_CONVERTER.idToFile(blockId);
- }
-
- public static ResourceLocation getBlockModelLocation(ResourceLocation blockId) {
- return BLOCK_MODEL_ID_CONVERTER.idToFile(blockId);
- }
-
- public static ResourceLocation getItemModelLocation(ResourceLocation itemId) {
- return ITEM_MODEL_ID_CONVERTER.idToFile(itemId);
- }
-
public static ResourceLocation getTextureLocation(@Nullable String path, ResourceLocation textureId) {
if (path == null) {
return TEXTURE_ID_CONVERTER.idToFile(textureId);
}
return TEXTURE_ID_CONVERTER.idToFile(textureId.withPrefix(path + "/"));
}
-
- public static ResourceLocation getAtlasLocation(ResourceLocation atlasId) {
- return ATLAS_ID_CONVERTER.idToFile(atlasId);
- }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/data/pack/event/RegisterDynamicResourcesEvent.java b/src/main/java/com/gregtechceu/gtceu/data/pack/event/RegisterDynamicResourcesEvent.java
new file mode 100644
index 00000000000..92f9eaa1d9a
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/data/pack/event/RegisterDynamicResourcesEvent.java
@@ -0,0 +1,12 @@
+package com.gregtechceu.gtceu.data.pack.event;
+
+import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.fml.event.IModBusEvent;
+
+import org.jetbrains.annotations.ApiStatus;
+
+public class RegisterDynamicResourcesEvent extends Event implements IModBusEvent {
+
+ @ApiStatus.Internal
+ public RegisterDynamicResourcesEvent() {}
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/GregTechKubeJSPlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/GregTechKubeJSPlugin.java
index 6300ac47d81..282112a3928 100644
--- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/GregTechKubeJSPlugin.java
+++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/GregTechKubeJSPlugin.java
@@ -70,10 +70,8 @@
import com.gregtechceu.gtceu.common.data.models.GTModels;
import com.gregtechceu.gtceu.common.item.armor.PowerlessJetpack;
import com.gregtechceu.gtceu.common.machine.multiblock.primitive.PrimitiveFancyUIWorkableMachine;
-import com.gregtechceu.gtceu.common.registry.GTRegistration;
import com.gregtechceu.gtceu.common.unification.material.MaterialRegistryManager;
import com.gregtechceu.gtceu.core.mixins.IngredientAccessor;
-import com.gregtechceu.gtceu.data.pack.GTDynamicResourcePack;
import com.gregtechceu.gtceu.data.recipe.CraftingComponent;
import com.gregtechceu.gtceu.data.recipe.GTCraftingComponents;
import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder;
@@ -93,9 +91,7 @@
import com.gregtechceu.gtceu.integration.kjs.recipe.WrappingRecipeSchemaType;
import com.gregtechceu.gtceu.integration.kjs.recipe.components.ExtendedOutputItem;
import com.gregtechceu.gtceu.integration.kjs.recipe.components.GTRecipeComponents;
-import com.gregtechceu.gtceu.utils.data.RuntimeBlockStateProvider;
-import net.minecraft.data.PackOutput;
import net.minecraft.nbt.NbtOps;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.CraftingContainer;
@@ -109,7 +105,6 @@
import net.minecraftforge.registries.ForgeRegistries;
import com.mojang.serialization.DataResult;
-import dev.latvian.mods.kubejs.KubeJSPaths;
import dev.latvian.mods.kubejs.KubeJSPlugin;
import dev.latvian.mods.kubejs.block.state.BlockStatePredicate;
import dev.latvian.mods.kubejs.client.LangEventJS;
@@ -212,23 +207,12 @@ public void generateDataJsons(DataJsonGenerator generator) {
GTRegistryInfo.ALL_BUILDERS.forEach(builderBase -> builderBase.generateDataJsons(generator));
}
- // Fake a data provider for the GT model builders so we don't need to handle this ourselves in any way :3
- public static RuntimeBlockStateProvider RUNTIME_BLOCKSTATE_PROVIDER = new RuntimeBlockStateProvider(
- GTRegistration.REGISTRATE, new PackOutput(KubeJSPaths.DIRECTORY),
- (loc, json) -> {
- if (!loc.getPath().endsWith(".json")) {
- loc = loc.withSuffix(".json");
- }
- GTDynamicResourcePack.addResource(loc, json);
- });
-
public static void generateMachineBlockModels() {
GTRegistryInfo.ALL_BUILDERS.forEach(builderBase -> {
try {
builderBase.generateAssetJsons(null);
} catch (IllegalStateException ignored) {}
});
- GregTechKubeJSPlugin.RUNTIME_BLOCKSTATE_PROVIDER.run();
}
@Override
diff --git a/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java b/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java
index 2877a711f97..ce8ec066a59 100644
--- a/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java
+++ b/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java
@@ -1,12 +1,18 @@
package com.gregtechceu.gtceu.utils;
import net.minecraft.MethodsReturnNonnullByDefault;
+import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.joml.Vector3f;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -93,4 +99,65 @@ public static int ceilDiv(int x, int y) {
}
return q;
}
+
+ public static float min(float @NotNull... values) {
+ // noinspection ConstantValue
+ if (values == null || values.length == 0) throw new IllegalArgumentException();
+ if (values.length == 1) return values[0];
+ if (values.length == 2) return Math.min(values[0], values[1]);
+ float min = Float.MAX_VALUE;
+ for (float i : values) {
+ if (i < min) {
+ min = i;
+ }
+ }
+ return min;
+ }
+
+ public static float max(float @NotNull... values) {
+ // noinspection ConstantValue
+ if (values == null || values.length == 0) throw new IllegalArgumentException();
+ if (values.length == 1) return values[0];
+ if (values.length == 2) return Math.max(values[0], values[1]);
+ float max = Float.MIN_VALUE;
+ for (float i : values) {
+ if (i > max) {
+ max = i;
+ }
+ }
+ return max;
+ }
+
+ public static Pair getCoordinates(@Nullable Direction dir, float min, float max) {
+ float x1 = min, y1 = min, z1 = min, x2 = max, y2 = max, z2 = max;
+ if (dir != null) {
+ switch (dir) {
+ case DOWN -> {
+ y1 = 0;
+ y2 = min;
+ }
+ case UP -> {
+ y1 = max;
+ y2 = 16;
+ }
+ case NORTH -> {
+ z1 = 0;
+ z2 = min;
+ }
+ case SOUTH -> {
+ z1 = max;
+ z2 = 16;
+ }
+ case WEST -> {
+ x1 = 0;
+ x2 = min;
+ }
+ case EAST -> {
+ x1 = max;
+ x2 = 16;
+ }
+ }
+ }
+ return ImmutablePair.of(new Vector3f(x1, y1, z1), new Vector3f(x2, y2, z2));
+ }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/utils/GTUtil.java b/src/main/java/com/gregtechceu/gtceu/utils/GTUtil.java
index 3b42d4f2b80..d699f5223e0 100644
--- a/src/main/java/com/gregtechceu/gtceu/utils/GTUtil.java
+++ b/src/main/java/com/gregtechceu/gtceu/utils/GTUtil.java
@@ -52,6 +52,7 @@
import com.mojang.datafixers.util.Pair;
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import org.apache.commons.lang3.ArrayUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
@@ -67,6 +68,7 @@
public class GTUtil {
public static final Direction[] DIRECTIONS = Direction.values();
+ public static final @Nullable Direction @NotNull [] DIRECTIONS_WITH_NULL = ArrayUtils.add(DIRECTIONS, null);
@SuppressWarnings("UnstableApiUsage")
public static final ImmutableList NON_CORNER_NEIGHBOURS = Util.make(() -> {
diff --git a/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeBlockStateProvider.java b/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeBlockstateProvider.java
similarity index 64%
rename from src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeBlockStateProvider.java
rename to src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeBlockstateProvider.java
index b18f2bcd41d..8d69125eeb2 100644
--- a/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeBlockStateProvider.java
+++ b/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeBlockstateProvider.java
@@ -1,6 +1,9 @@
package com.gregtechceu.gtceu.utils.data;
+import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
+import com.gregtechceu.gtceu.common.registry.GTRegistration;
+import com.gregtechceu.gtceu.data.pack.GTDynamicResourcePack;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.PackOutput;
@@ -14,11 +17,21 @@
import java.util.Map;
import java.util.function.BiConsumer;
-public class RuntimeBlockStateProvider extends GTBlockstateProvider {
+public class RuntimeBlockstateProvider extends GTBlockstateProvider {
+
+ // Fake a data provider for the GT model builders so we don't need to handle this ourselves in any way :3
+ public static final RuntimeBlockstateProvider INSTANCE = new RuntimeBlockstateProvider(
+ GTRegistration.REGISTRATE, new PackOutput(GTCEu.GTCEU_FOLDER),
+ (loc, json) -> {
+ if (!loc.getPath().endsWith(".json")) {
+ loc = loc.withSuffix(".json");
+ }
+ GTDynamicResourcePack.addResource(loc, json);
+ });
protected final BiConsumer consumer;
- public RuntimeBlockStateProvider(AbstractRegistrate> parent, PackOutput packOutput,
+ public RuntimeBlockstateProvider(AbstractRegistrate> parent, PackOutput packOutput,
BiConsumer consumer) {
super(parent, packOutput, RuntimeExistingFileHelper.INSTANCE);
this.consumer = consumer;
@@ -33,7 +46,8 @@ public void run() {
processModelProvider(itemModels());
for (Map.Entry entry : registeredBlocks.entrySet()) {
- ResourceLocation loc = BuiltInRegistries.BLOCK.getKey(entry.getKey()).withPrefix("blockstates/");
+ ResourceLocation loc = GTDynamicResourcePack.BLOCKSTATE_ID_CONVERTER
+ .idToFile(BuiltInRegistries.BLOCK.getKey(entry.getKey()));
this.consumer.accept(loc, entry.getValue().toJson());
}
// only clear the data *after* saving so we can keep track of it during the KJS event
diff --git a/src/main/java/com/gregtechceu/gtceu/utils/memoization/GTMemoizer.java b/src/main/java/com/gregtechceu/gtceu/utils/memoization/GTMemoizer.java
index be27b6cb231..36728327d77 100644
--- a/src/main/java/com/gregtechceu/gtceu/utils/memoization/GTMemoizer.java
+++ b/src/main/java/com/gregtechceu/gtceu/utils/memoization/GTMemoizer.java
@@ -1,12 +1,19 @@
package com.gregtechceu.gtceu.utils.memoization;
+import com.gregtechceu.gtceu.utils.memoization.function.MemoizedBiFunction;
+import com.gregtechceu.gtceu.utils.memoization.function.MemoizedFunction;
+import com.gregtechceu.gtceu.utils.memoization.function.MemoizedTriFunction;
+
import net.minecraft.world.level.block.Block;
+import lombok.Getter;
import org.apache.commons.lang3.function.TriFunction;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -27,32 +34,59 @@ public static MemoizedBlockSupplier memoizeBlockSupplier(Su
return new MemoizedBlockSupplier<>(delegate);
}
- public static Function memoizeFunctionWeakIdent(final Function memoFunction) {
- return new Function<>() {
+ public static MemoizedFunction memoizeFunctionWeakIdent(final Function memoFunction) {
+ return new MemoizedFunction<>() {
+ @Getter
private final Map cache = new ConcurrentWeakIdentityHashMap<>();
+ @Override
public R apply(T key) {
return this.cache.computeIfAbsent(key, memoFunction);
}
+ @Override
public String toString() {
return "memoizeFunctionWeakIdent/1[function=" + memoFunction + ", size=" + this.cache.size() + "]";
}
};
}
- public static TriFunction memoize(final TriFunction memoTriFunction) {
- return new TriFunction<>() {
+ public static MemoizedBiFunction memoizeFunctionWeakIdent(final BiFunction memoBiFunction) {
+ return new MemoizedBiFunction<>() {
+
+ @Getter
+ private final Map, R> cache = new ConcurrentWeakIdentityHashMap<>();
+
+ @Override
+ public R apply(T key1, U key2) {
+ return this.cache.computeIfAbsent(Pair.of(key1, key2), (key) -> {
+ return memoBiFunction.apply(key.getLeft(), key.getRight());
+ });
+ }
+
+ @Override
+ public String toString() {
+ return "memoizeFunctionWeakIdent/2[function=" + memoBiFunction + ", size=" + this.cache.size() + "]";
+ }
+ };
+ }
+
+ public static MemoizedTriFunction memoize(final TriFunction memoTriFunction) {
+ return new MemoizedTriFunction<>() {
+ @Getter
private final Map, R> cache = new ConcurrentHashMap<>();
+ @Override
public R apply(T key1, U key2, V key3) {
return this.cache.computeIfAbsent(Triple.of(key1, key2, key3), (cacheKey) -> {
return memoTriFunction.apply(cacheKey.getLeft(), cacheKey.getMiddle(), cacheKey.getRight());
});
}
+ @Override
public String toString() {
return "memoize/3[function=" + memoTriFunction + ", size=" + this.cache.size() + "]";
}
diff --git a/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedBiFunction.java b/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedBiFunction.java
new file mode 100644
index 00000000000..4934e7033d5
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedBiFunction.java
@@ -0,0 +1,11 @@
+package com.gregtechceu.gtceu.utils.memoization.function;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import java.util.Map;
+import java.util.function.BiFunction;
+
+public interface MemoizedBiFunction extends BiFunction {
+
+ Map, R> getCache();
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedFunction.java b/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedFunction.java
new file mode 100644
index 00000000000..61b79bb6b9d
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedFunction.java
@@ -0,0 +1,9 @@
+package com.gregtechceu.gtceu.utils.memoization.function;
+
+import java.util.Map;
+import java.util.function.Function;
+
+public interface MemoizedFunction extends Function {
+
+ Map getCache();
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedTriFunction.java b/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedTriFunction.java
new file mode 100644
index 00000000000..f5608e2f489
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/utils/memoization/function/MemoizedTriFunction.java
@@ -0,0 +1,11 @@
+package com.gregtechceu.gtceu.utils.memoization.function;
+
+import org.apache.commons.lang3.function.TriFunction;
+import org.apache.commons.lang3.tuple.Triple;
+
+import java.util.Map;
+
+public interface MemoizedTriFunction extends TriFunction {
+
+ Map, R> getCache();
+}
diff --git a/src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side.png b/src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side.png
index fa5c3c037c0e19e0421ad3b07cf173908a31016c..695048d32a3cf9f304c62896a01d9a34fccd7d7d 100644
GIT binary patch
delta 282
zcmV+#0pLO5;`BjzY!JFAdm8Leu$=SjqybIL_
zguB}?f}pHJVSG{^on-+C{SxHI&j}b?7ED2BbB{)q^+dp~vVWijgxj0YDaegZ-vxwQ
zYxe}%;Y;AUHeoH`V8GaPCL9ZlYwMkL=ca$NX!v)FNMK&u3`>CwLuPP{1+Gt`!}*~-
zHV{q(@;Jc0x)WhphjjmofMc1v%6cMjJ<;C+#{Nq{h;V&%i;gAhkm?;`f&L)!lbF{A
gI%)`~dwcZ&!4pYq0kCbKWrbfa7wY84RAT
KelF{r5}E)Z79VK<
literal 0
HcmV?d00001
diff --git a/src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side_overlay_active.png b/src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side_overlay_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0d5cdc54a591822b7d7ade664e72b143c97649d
GIT binary patch
literal 197
zcmeAS@N?(olHy`uVBq!ia0vp^0zj<5!3HFyJAa%3Qfx`y?k)`fL2$v|<&%LToCO|{
z#S9GG!XV7ZFl&wkP>{XE)7O>#IhzQRn6?U^4mVIJ$kW9!#N&8!!U6$LtER*R2IXxG%2CG3%8v^;n=iJQ`!{c((M
m*zVD6IdQ_D3@51!28IRgI?{)f4jTeZXYh3Ob6Mw<&;$TuYCbps
literal 0
HcmV?d00001
diff --git a/src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side_overlay_active.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side_overlay_active.png.mcmeta
new file mode 100644
index 00000000000..21972735d33
--- /dev/null
+++ b/src/main/resources/assets/gtceu/textures/block/pipe/pipe_optical_side_overlay_active.png.mcmeta
@@ -0,0 +1,5 @@
+{
+ "animation": {
+ "frametime": 25
+ }
+}
From e62003c82fbe1b969bf0308d7799aeb937cf3e4f Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Sun, 1 Feb 2026 22:07:11 +0200
Subject: [PATCH 14/78] Fix missing/invalid pipe model issues (#4530)
---
.../resources/assets/gtceu/lang/en_ud.json | 17 ++-
.../resources/assets/gtceu/lang/en_us.json | 28 ++---
.../block/pipe/huge_duct_pipe/center.json | 1 -
.../block/pipe/large_duct_pipe/center.json | 1 -
.../block/pipe/normal_duct_pipe/center.json | 1 -
.../block/pipe/normal_laser_pipe/center.json | 1 -
.../pipe/normal_laser_pipe/center_active.json | 111 +++++++++++++++++-
.../normal_laser_pipe/connection_active.json | 95 ++++++++++++++-
.../pipe/normal_optical_pipe/center.json | 1 -
.../normal_optical_pipe/center_active.json | 111 +++++++++++++++++-
.../connection_active.json | 95 ++++++++++++++-
.../block/pipe/small_duct_pipe/center.json | 1 -
.../model/machine/overlays/HPCAOverlay.java | 63 ++++++----
.../machine/overlays/WorkableOverlays.java | 16 +++
.../client/model/pipe/ActivablePipeModel.java | 95 ++++++++++++---
.../gtceu/client/model/pipe/PipeModel.java | 100 ++++++++++++----
.../data/model/builder/PipeModelBuilder.java | 40 +++----
.../data/model/builder/package-info.java | 4 +
.../utils/data/RuntimeExistingFileHelper.java | 72 ++++++++++--
19 files changed, 736 insertions(+), 117 deletions(-)
create mode 100644 src/main/java/com/gregtechceu/gtceu/data/model/builder/package-info.java
diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json
index a0a937ed0cb..f51d500f0c5 100644
--- a/src/generated/resources/assets/gtceu/lang/en_ud.json
+++ b/src/generated/resources/assets/gtceu/lang/en_ud.json
@@ -66,6 +66,7 @@
"behaviour.lighter.uses": "%d :sǝsn buıuıɐɯǝᴚ",
"behaviour.memory_card.client_msg.cleared": "pǝɹɐǝןɔ uoıʇɐɹnbıɟuoɔ pǝɹoʇS",
"behaviour.memory_card.client_msg.copied": "uoıʇɐɹnbıɟuoɔ ǝuıɥɔɐɯ pǝıdoƆ",
+ "behaviour.memory_card.client_msg.missing_items": "uoıʇɐɹnbıɟuoɔ ǝʇsɐd oʇ pǝɹınbǝɹ sɯǝʇı buıssıW",
"behaviour.memory_card.client_msg.pasted": "uoıʇɐɹnbıɟuoɔ ǝuıɥɔɐɯ pǝıןddⱯ",
"behaviour.memory_card.copy_target": "%s :buıʎdoƆ",
"behaviour.memory_card.disabled": "ɹ§pǝןqɐsıᗡɔ§",
@@ -1745,6 +1746,7 @@
"config.gtceu.option.addLoot": "ʇooꞀppɐ",
"config.gtceu.option.ae2": "ᄅǝɐ",
"config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "ǝpıSʇndʇnOɯoɹℲspınןℲʇnduIsɯnɹᗡʍoןןɐ",
+ "config.gtceu.option.allowedImageDomains": "suıɐɯoᗡǝbɐɯIpǝʍoןןɐ",
"config.gtceu.option.animationTime": "ǝɯı⟘uoıʇɐɯıuɐ",
"config.gtceu.option.arcRecyclingYield": "pןǝıʎbuıןɔʎɔǝᴚɔɹɐ",
"config.gtceu.option.armorHud": "pnHɹoɯɹɐ",
@@ -1892,7 +1894,7 @@
"config.gtceu.option.steelSteamMultiblocks": "sʞɔoןqıʇןnWɯɐǝʇSןǝǝʇs",
"config.gtceu.option.surfaceRockProspectRange": "ǝbuɐᴚʇɔǝdsoɹԀʞɔoᴚǝɔɐɟɹns",
"config.gtceu.option.tankItemFluidPreview": "ʍǝıʌǝɹԀpınןℲɯǝʇIʞuɐʇ",
- "config.gtceu.option.temperaturesInKelvin": "uıʌןǝʞuIsǝɹnʇɐɹǝdɯǝʇ",
+ "config.gtceu.option.temperaturesInCelsius": "snısןǝƆuIsǝɹnʇɐɹǝdɯǝʇ",
"config.gtceu.option.titaniumBoilerHeatSpeed": "pǝǝdSʇɐǝHɹǝןıoᗺɯnıuɐʇıʇ",
"config.gtceu.option.titaniumBoilerMaxTemperature": "ǝɹnʇɐɹǝdɯǝ⟘xɐWɹǝןıoᗺɯnıuɐʇıʇ",
"config.gtceu.option.toggle": "ǝןbboʇ",
@@ -2616,6 +2618,7 @@
"gtceu.key.armor_mode_switch": "ɥɔʇıʍS ǝpoW ɹoɯɹⱯ",
"gtceu.key.enable_boots": "dɯnſ pǝʇsooᗺ ǝןqɐuƎ",
"gtceu.key.enable_jetpack": "ʞɔɐdʇǝſ ǝןqɐuƎ",
+ "gtceu.key.enable_step_assist": "ʇsıssⱯdǝʇS ǝןqɐuƎ",
"gtceu.key.tool_aoe_change": "ɥɔʇıʍS ǝpoW ƎoⱯ ןoo⟘",
"gtceu.large_boiler": "ɹǝןıoᗺ ǝbɹɐꞀ",
"gtceu.large_chemical_reactor": "ɹoʇɔɐǝᴚ ןɐɔıɯǝɥƆ ǝbɹɐꞀ",
@@ -4733,7 +4736,7 @@
"item.gtceu.talc_dust": "ɔןɐ⟘",
"item.gtceu.tantalum_capacitor": "ɹoʇıɔɐdɐƆ ɯnןɐʇuɐ⟘",
"item.gtceu.terminal": "ןɐuıɯɹǝ⟘",
- "item.gtceu.terminal.tooltip": "ʞɔoןq-ıʇןnɯ ǝɥʇ pןınq ʎןןɐɔıʇɐɯoʇnɐ oʇ ɹǝןןoɹʇuoɔ ɐ uo ʞɔıןƆ-ᴚ + ʇɟıɥS",
+ "item.gtceu.terminal.tooltip": "ʎɹoʇuǝʌuı ɹnoʎ ɯoɹɟ sɯǝʇı ɥʇıʍ ʞɔoןqıʇןnɯ ɐ pןınq ʎןןɐɔıʇɐɯoʇnɐ oʇ ɹǝןןoɹʇuoɔ ɐ uo ʞɔıןƆ-ᴚ + ʇɟıɥS",
"item.gtceu.text_module": "ǝןnpoW ʇxǝ⟘",
"item.gtceu.tiny_ash_dust": "sǝɥsⱯ ɟo ǝןıԀ ʎuı⟘",
"item.gtceu.tiny_basaltic_mineral_sand_dust": "puɐS ןɐɹǝuıW ɔıʇןɐsɐᗺ ɟo ǝןıԀ ʎuı⟘",
@@ -4836,7 +4839,7 @@
"item.gtceu.tool.lv_screwdriver.tooltip": "sǝuıɥɔɐW puɐ sɹǝʌoƆ sʇsnظpⱯ8§",
"item.gtceu.tool.lv_wirecutter": ")ΛꞀ( ɹǝʇʇnƆ ǝɹıM %s",
"item.gtceu.tool.lv_wrench": ")ΛꞀ( ɥɔuǝɹM %s",
- "item.gtceu.tool.lv_wrench.tooltip": "sǝuıɥɔɐW ǝןʇuɐɯsıp oʇs ʞɔıןɔ ʇɟǝן pןoH8§",
+ "item.gtceu.tool.lv_wrench.tooltip": "sǝuıɥɔɐW ǝןʇuɐɯsıp oʇ ʞɔıןɔ ʇɟǝן pןoH8§",
"item.gtceu.tool.mallet": "ʇǝןןɐW ʇɟoS %s",
"item.gtceu.tool.mallet.tooltip.0": "˙ǝdıɔǝᴚ ʇuǝɹɹnƆ ɹǝʇɟⱯ ǝuıɥɔɐW ǝsnɐԀ oʇ ʞɐǝuS8§",
"item.gtceu.tool.mallet.tooltip.1": "sǝuıɥɔɐW sʇɹɐʇS/sdoʇS8§",
@@ -5698,20 +5701,24 @@
"metaarmor.message.nightvision.disabled": "ɟɟOɔ§ :uoısıΛʇɥbıNq§",
"metaarmor.message.nightvision.enabled": "uOɐ§ :uoısıΛʇɥbıNq§",
"metaarmor.message.nightvision.error": "¡ɹǝʍod ɥbnouǝ ʇoNɔ§",
- "metaarmor.nms.boosted_jump.disabled": "pǝןqɐsıᗡ ʇsooᗺ dɯnſ :ǝʇınS ™ǝןɔsnWouɐN",
- "metaarmor.nms.boosted_jump.enabled": "pǝןqɐuƎ ʇsooᗺ dɯnſ :ǝʇınS ™ǝןɔsnWouɐN",
"metaarmor.nms.nightvision.disabled": "pǝןqɐsıᗡ uoısıΛʇɥbıN :ǝʇınS ™ǝןɔsnWouɐN",
"metaarmor.nms.nightvision.enabled": "pǝןqɐuƎ uoısıΛʇɥbıN :ǝʇınS ™ǝןɔsnWouɐN",
"metaarmor.nms.nightvision.error": "¡ɹǝʍod ɥbnouǝ ʇoNɔ§ :ǝʇınS ™ǝןɔsnWouɐN",
"metaarmor.nms.share.disable": "pǝןqɐsıᗡ buıbɹɐɥƆ :ǝʇınS ™ǝןɔsnWouɐN",
"metaarmor.nms.share.enable": "pǝןqɐuƎ buıbɹɐɥƆ :ǝʇınS ™ǝןɔsnWouɐN",
"metaarmor.nms.share.error": "¡buıbɹɐɥɔ ɹoɟ ɹǝʍod ɥbnouǝ ʇoNɔ§ :ǝʇınS ™ǝןɔsnWouɐN",
+ "metaarmor.nms.step_assist.disabled": "pǝןqɐsıᗡ ʇsıssⱯdǝʇS :ǝʇınS ™ǝןɔsnWouɐN",
+ "metaarmor.nms.step_assist.enabled": "pǝןqɐuƎ ʇsıssⱯdǝʇS :ǝʇınS ™ǝןɔsnWouɐN",
+ "metaarmor.qts.boosted_jump.disabled": "pǝןqɐsıᗡ ʇsooᗺ dɯnſ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
+ "metaarmor.qts.boosted_jump.enabled": "pǝןqɐuƎ ʇsooᗺ dɯnſ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
"metaarmor.qts.nightvision.disabled": "pǝןqɐsıᗡ uoısıΛʇɥbıN :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
"metaarmor.qts.nightvision.enabled": "pǝןqɐuƎ uoısıΛʇɥbıN :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
"metaarmor.qts.nightvision.error": "¡ɹǝʍod ɥbnouǝ ʇoNɔ§ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
"metaarmor.qts.share.disable": "pǝןqɐsıᗡ buıbɹɐɥƆ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
"metaarmor.qts.share.enable": "pǝןqɐuƎ buıbɹɐɥƆ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
"metaarmor.qts.share.error": "¡buıbɹɐɥɔ ɹoɟ ɹǝʍod ɥbnouǝ ʇoNɔ§ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
+ "metaarmor.qts.step_assist.disabled": "pǝןqɐsıᗡ ʇsıssⱯdǝʇS :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
+ "metaarmor.qts.step_assist.enabled": "pǝןqɐuƎ ʇsıssⱯdǝʇS :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ",
"metaarmor.tooltip.autoeat": "ʎɹoʇuǝʌuI ɯoɹɟ pooℲ buıs∩ ʎq ɹɐᗺ pooℲ sǝɥsıuǝןdǝᴚ",
"metaarmor.tooltip.breath": "ɹɐᗺ ɥʇɐǝɹᗺ ɹǝʇɐʍɹǝpu∩ sǝɥsıuǝןdǝᴚ",
"metaarmor.tooltip.burning": "buıuɹnᗺ sǝıɟıןןnN",
diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json
index b738160a97f..3ceb805dee1 100644
--- a/src/generated/resources/assets/gtceu/lang/en_us.json
+++ b/src/generated/resources/assets/gtceu/lang/en_us.json
@@ -66,6 +66,7 @@
"behaviour.lighter.uses": "Remaining uses: %d",
"behaviour.memory_card.client_msg.cleared": "Stored configuration cleared",
"behaviour.memory_card.client_msg.copied": "Copied machine configuration",
+ "behaviour.memory_card.client_msg.missing_items": "Missing items required to paste configuration",
"behaviour.memory_card.client_msg.pasted": "Applied machine configuration",
"behaviour.memory_card.copy_target": "Copying: %s",
"behaviour.memory_card.disabled": "§cDisabled§r",
@@ -1745,6 +1746,7 @@
"config.gtceu.option.addLoot": "addLoot",
"config.gtceu.option.ae2": "ae2",
"config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "allowDrumsInputFluidsFromOutputSide",
+ "config.gtceu.option.allowedImageDomains": "allowedImageDomains",
"config.gtceu.option.animationTime": "animationTime",
"config.gtceu.option.arcRecyclingYield": "arcRecyclingYield",
"config.gtceu.option.armorHud": "armorHud",
@@ -1892,7 +1894,7 @@
"config.gtceu.option.steelSteamMultiblocks": "steelSteamMultiblocks",
"config.gtceu.option.surfaceRockProspectRange": "surfaceRockProspectRange",
"config.gtceu.option.tankItemFluidPreview": "tankItemFluidPreview",
- "config.gtceu.option.temperaturesInKelvin": "temperaturesInKelvin",
+ "config.gtceu.option.temperaturesInCelsius": "temperaturesInCelsius",
"config.gtceu.option.titaniumBoilerHeatSpeed": "titaniumBoilerHeatSpeed",
"config.gtceu.option.titaniumBoilerMaxTemperature": "titaniumBoilerMaxTemperature",
"config.gtceu.option.toggle": "toggle",
@@ -2616,8 +2618,8 @@
"gtceu.key.armor_mode_switch": "Armor Mode Switch",
"gtceu.key.enable_boots": "Enable Boosted Jump",
"gtceu.key.enable_jetpack": "Enable Jetpack",
- "gtceu.key.tool_aoe_change": "Tool AoE Mode Switch",
"gtceu.key.enable_step_assist": "Enable StepAssist",
+ "gtceu.key.tool_aoe_change": "Tool AoE Mode Switch",
"gtceu.large_boiler": "Large Boiler",
"gtceu.large_chemical_reactor": "Large Chemical Reactor",
"gtceu.laser_engraver": "Laser Engraver",
@@ -4734,7 +4736,7 @@
"item.gtceu.talc_dust": "Talc",
"item.gtceu.tantalum_capacitor": "Tantalum Capacitor",
"item.gtceu.terminal": "Terminal",
- "item.gtceu.terminal.tooltip": "Shift + R-Click on a controller to automatically build the multi-block",
+ "item.gtceu.terminal.tooltip": "Shift + R-Click on a controller to automatically build a multiblock with items from your inventory",
"item.gtceu.text_module": "Text Module",
"item.gtceu.tiny_ash_dust": "Tiny Pile of Ashes",
"item.gtceu.tiny_basaltic_mineral_sand_dust": "Tiny Pile of Basaltic Mineral Sand",
@@ -5699,26 +5701,24 @@
"metaarmor.message.nightvision.disabled": "§bNightVision: §cOff",
"metaarmor.message.nightvision.enabled": "§bNightVision: §aOn",
"metaarmor.message.nightvision.error": "§cNot enough power!",
- "metaarmor.message.step_assist.disabled": "StepAssist: §cOff",
- "metaarmor.message.step_assist.enabled": "StepAssist: §aOn",
"metaarmor.nms.nightvision.disabled": "NanoMuscle™ Suite: NightVision Disabled",
"metaarmor.nms.nightvision.enabled": "NanoMuscle™ Suite: NightVision Enabled",
"metaarmor.nms.nightvision.error": "NanoMuscle™ Suite: §cNot enough power!",
- "metaarmor.qts.nightvision.disabled": "QuarkTech™ Suite: NightVision Disabled",
- "metaarmor.qts.nightvision.enabled": "QuarkTech™ Suite: NightVision Enabled",
- "metaarmor.qts.nightvision.error": "QuarkTech™ Suite: §cNot enough power!",
- "metaarmor.nms.step_assist.disabled": "NanoMuscle™ Suite: StepAssist Disabled",
- "metaarmor.nms.step_assist.enabled": "NanoMuscle™ Suite: StepAssist Enabled",
- "metaarmor.qts.step_assist.disabled": "QuarkTech™ Suite: StepAssist Disabled",
- "metaarmor.qts.step_assist.enabled": "QuarkTech™ Suite: StepAssist Enabled",
"metaarmor.nms.share.disable": "NanoMuscle™ Suite: Charging Disabled",
"metaarmor.nms.share.enable": "NanoMuscle™ Suite: Charging Enabled",
"metaarmor.nms.share.error": "NanoMuscle™ Suite: §cNot enough power for charging!",
+ "metaarmor.nms.step_assist.disabled": "NanoMuscle™ Suite: StepAssist Disabled",
+ "metaarmor.nms.step_assist.enabled": "NanoMuscle™ Suite: StepAssist Enabled",
+ "metaarmor.qts.boosted_jump.disabled": "QuarkTech™ Suite: Jump Boost Disabled",
+ "metaarmor.qts.boosted_jump.enabled": "QuarkTech™ Suite: Jump Boost Enabled",
+ "metaarmor.qts.nightvision.disabled": "QuarkTech™ Suite: NightVision Disabled",
+ "metaarmor.qts.nightvision.enabled": "QuarkTech™ Suite: NightVision Enabled",
+ "metaarmor.qts.nightvision.error": "QuarkTech™ Suite: §cNot enough power!",
"metaarmor.qts.share.disable": "QuarkTech™ Suite: Charging Disabled",
"metaarmor.qts.share.enable": "QuarkTech™ Suite: Charging Enabled",
"metaarmor.qts.share.error": "QuarkTech™ Suite: §cNot enough power for charging!",
- "metaarmor.qts.boosted_jump.disabled": "QuarkTech™ Suite: Jump Boost Disabled",
- "metaarmor.qts.boosted_jump.enabled": "QuarkTech™ Suite: Jump Boost Enabled",
+ "metaarmor.qts.step_assist.disabled": "QuarkTech™ Suite: StepAssist Disabled",
+ "metaarmor.qts.step_assist.enabled": "QuarkTech™ Suite: StepAssist Enabled",
"metaarmor.tooltip.autoeat": "Replenishes Food Bar by Using Food from Inventory",
"metaarmor.tooltip.breath": "Replenishes Underwater Breath Bar",
"metaarmor.tooltip.burning": "Nullifies Burning",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
index 6318ac6c5b3..1916aa7d966 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
@@ -41,7 +41,6 @@
}
],
"textures": {
- "end": "gtceu:block/pipe/pipe_duct_in",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
index 26aeac6acf3..39b3a894eac 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
@@ -41,7 +41,6 @@
}
],
"textures": {
- "end": "gtceu:block/pipe/pipe_duct_in",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
index 55bac017a34..1c7b6fe9ce9 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
@@ -41,7 +41,6 @@
}
],
"textures": {
- "end": "gtceu:block/pipe/pipe_duct_in",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
index 0cc3032c0e5..9de7a83201f 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
@@ -79,7 +79,6 @@
}
],
"textures": {
- "end": "gtceu:block/pipe/pipe_laser_in",
"side": "gtceu:block/pipe/pipe_laser_side",
"side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
index 18781c339d2..088aa774a9f 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
@@ -1,6 +1,115 @@
{
- "parent": "gtceu:block/pipe/normal_laser_pipe/center",
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 5,
+ 5
+ ],
+ "to": [
+ 11,
+ 11,
+ 11
+ ]
+ },
+ {
+ "faces": {
+ "down": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "east": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "north": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "south": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "up": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ 4.998,
+ 4.998
+ ],
+ "to": [
+ 11.002,
+ 11.002,
+ 11.002
+ ]
+ }
+ ],
"textures": {
+ "side": "gtceu:block/pipe/pipe_laser_side",
"side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay_emissive"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
index a9170249dab..83cb7127326 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
@@ -1,6 +1,99 @@
{
- "parent": "gtceu:block/pipe/normal_laser_pipe/connection",
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "cullface": "down",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 0,
+ 5
+ ],
+ "to": [
+ 11,
+ 5,
+ 11
+ ]
+ },
+ {
+ "faces": {
+ "east": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "north": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "south": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ -0.002,
+ 4.998
+ ],
+ "to": [
+ 11.002,
+ 5.002,
+ 11.002
+ ]
+ }
+ ],
"textures": {
+ "end": "gtceu:block/pipe/pipe_laser_in",
+ "side": "gtceu:block/pipe/pipe_laser_side",
"side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay_emissive"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
index c5356268055..1c46b15f85c 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
@@ -79,7 +79,6 @@
}
],
"textures": {
- "end": "gtceu:block/pipe/pipe_optical_in",
"side": "gtceu:block/pipe/pipe_optical_side",
"side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
index ac513d036e5..3a643f6dcc4 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
@@ -1,6 +1,115 @@
{
- "parent": "gtceu:block/pipe/normal_optical_pipe/center",
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 5,
+ 5
+ ],
+ "to": [
+ 11,
+ 11,
+ 11
+ ]
+ },
+ {
+ "faces": {
+ "down": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "east": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "north": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "south": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "up": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ 4.998,
+ 4.998
+ ],
+ "to": [
+ 11.002,
+ 11.002,
+ 11.002
+ ]
+ }
+ ],
"textures": {
+ "side": "gtceu:block/pipe/pipe_optical_side",
"side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay_active"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
index 224c446f985..962efa95cf6 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
@@ -1,6 +1,99 @@
{
- "parent": "gtceu:block/pipe/normal_optical_pipe/connection",
+ "parent": "minecraft:block/block",
+ "elements": [
+ {
+ "faces": {
+ "down": {
+ "cullface": "down",
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "east": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "north": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "south": {
+ "texture": "#side",
+ "tintindex": 0
+ },
+ "up": {
+ "texture": "#end",
+ "tintindex": 1
+ },
+ "west": {
+ "texture": "#side",
+ "tintindex": 0
+ }
+ },
+ "from": [
+ 5,
+ 0,
+ 5
+ ],
+ "to": [
+ 11,
+ 5,
+ 11
+ ]
+ },
+ {
+ "faces": {
+ "east": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "north": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "south": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ },
+ "west": {
+ "forge_data": {
+ "ambient_occlusion": false,
+ "block_light": 15,
+ "sky_light": 15
+ },
+ "texture": "#side_overlay",
+ "tintindex": 2
+ }
+ },
+ "from": [
+ 4.998,
+ -0.002,
+ 4.998
+ ],
+ "to": [
+ 11.002,
+ 5.002,
+ 11.002
+ ]
+ }
+ ],
"textures": {
+ "end": "gtceu:block/pipe/pipe_optical_in",
+ "side": "gtceu:block/pipe/pipe_optical_side",
"side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay_active"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
index 98a31bc47ef..cf2698d2453 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
@@ -41,7 +41,6 @@
}
],
"textures": {
- "end": "gtceu:block/pipe/pipe_duct_in",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/HPCAOverlay.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/HPCAOverlay.java
index 3ea09f9003c..ed8de15bb92 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/HPCAOverlay.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/HPCAOverlay.java
@@ -3,6 +3,7 @@
import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic.Status;
import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
import com.gregtechceu.gtceu.common.data.models.GTModels;
+import com.gregtechceu.gtceu.utils.data.RuntimeExistingFileHelper;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.resources.ResourceLocation;
@@ -23,31 +24,47 @@ public class HPCAOverlay {
// spotless:off
public static HPCAOverlay get(ResourceLocation normalSprite, ResourceLocation damagedSprite,
ExistingFileHelper fileHelper) {
- // normal
- if (!fileHelper.exists(normalSprite, GTBlockstateProvider.TEXTURE)) {
- return HPCAOverlay.EMPTY;
+ if (fileHelper instanceof RuntimeExistingFileHelper runtimeFileHelper) {
+ // if fileHelper is an instance of RuntimeExistingFileHelper, we have to enable its existence checking.
+ // the AutoCloseable warning is suppressed here because there's no clean way to
+ // use a try-with-resources statement in this.
+ //noinspection resource
+ fileHelper = runtimeFileHelper.activeHelper();
}
- ResourceLocation activeSprite = normalSprite.withSuffix("_active");
- if (!fileHelper.exists(activeSprite, GTBlockstateProvider.TEXTURE)) activeSprite = normalSprite;
- ResourceLocation damagedActiveSprite = damagedSprite.withSuffix("_active");
- if (!fileHelper.exists(damagedActiveSprite, GTBlockstateProvider.TEXTURE)) damagedActiveSprite = damagedSprite;
-
- // emissive
- ResourceLocation normalSpriteEmissive = normalSprite.withSuffix("_emissive");
- if (!fileHelper.exists(normalSpriteEmissive, GTBlockstateProvider.TEXTURE)) normalSpriteEmissive = null;
-
- ResourceLocation activeSpriteEmissive = activeSprite.withSuffix("_emissive");
- if (!fileHelper.exists(activeSpriteEmissive, GTBlockstateProvider.TEXTURE)) activeSpriteEmissive = null;
-
- ResourceLocation damagedSpriteEmissive = damagedSprite.withSuffix("_emissive");
- if (!fileHelper.exists(damagedSpriteEmissive, GTBlockstateProvider.TEXTURE)) damagedSpriteEmissive = null;
-
- ResourceLocation damagedActiveSpriteEmissive = damagedActiveSprite.withSuffix("_emissive");
- if (!fileHelper.exists(damagedActiveSpriteEmissive, GTBlockstateProvider.TEXTURE)) damagedActiveSpriteEmissive = null;
-
- return new HPCAOverlay(normalSprite, activeSprite, damagedSprite, damagedActiveSprite,
- normalSpriteEmissive, activeSpriteEmissive, damagedSpriteEmissive, damagedActiveSpriteEmissive);
+ try {
+ // normal
+ if (!fileHelper.exists(normalSprite, GTBlockstateProvider.TEXTURE)) {
+ return HPCAOverlay.EMPTY;
+ }
+ ResourceLocation activeSprite = normalSprite.withSuffix("_active");
+ if (!fileHelper.exists(activeSprite, GTBlockstateProvider.TEXTURE)) activeSprite = normalSprite;
+
+ ResourceLocation damagedActiveSprite = damagedSprite.withSuffix("_active");
+ if (!fileHelper.exists(damagedActiveSprite, GTBlockstateProvider.TEXTURE)) damagedActiveSprite = damagedSprite;
+
+ // emissive
+ ResourceLocation normalSpriteEmissive = normalSprite.withSuffix("_emissive");
+ if (!fileHelper.exists(normalSpriteEmissive, GTBlockstateProvider.TEXTURE)) normalSpriteEmissive = null;
+
+ ResourceLocation activeSpriteEmissive = activeSprite.withSuffix("_emissive");
+ if (!fileHelper.exists(activeSpriteEmissive, GTBlockstateProvider.TEXTURE)) activeSpriteEmissive = null;
+
+ ResourceLocation damagedSpriteEmissive = damagedSprite.withSuffix("_emissive");
+ if (!fileHelper.exists(damagedSpriteEmissive, GTBlockstateProvider.TEXTURE)) damagedSpriteEmissive = null;
+
+ ResourceLocation damagedActiveSpriteEmissive = damagedActiveSprite.withSuffix("_emissive");
+ if (!fileHelper.exists(damagedActiveSpriteEmissive, GTBlockstateProvider.TEXTURE)) damagedActiveSpriteEmissive = null;
+
+ return new HPCAOverlay(normalSprite, activeSprite, damagedSprite, damagedActiveSprite,
+ normalSpriteEmissive, activeSpriteEmissive, damagedSpriteEmissive, damagedActiveSpriteEmissive);
+ } finally {
+ if (fileHelper instanceof RuntimeExistingFileHelper.Active activeHelper) {
+ // close the active helper, just for good measure.
+ // Also in case we ever make it do anything, this won't be forgotten.
+ activeHelper.close();
+ }
+ }
}
// spotless:on
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/WorkableOverlays.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/WorkableOverlays.java
index bf09a89f026..373ab7b33c6 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/WorkableOverlays.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/WorkableOverlays.java
@@ -4,6 +4,7 @@
import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
import com.gregtechceu.gtceu.common.data.models.GTMachineModels;
import com.gregtechceu.gtceu.common.data.models.GTModels;
+import com.gregtechceu.gtceu.utils.data.RuntimeExistingFileHelper;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.Direction;
@@ -25,6 +26,14 @@
public class WorkableOverlays {
public static WorkableOverlays get(ResourceLocation textureDir, ExistingFileHelper fileHelper) {
+ if (fileHelper instanceof RuntimeExistingFileHelper runtimeFileHelper) {
+ // if fileHelper is an instance of RuntimeExistingFileHelper, we have to enable its existence checking.
+ // the AutoCloseable warning is suppressed here because there's no clean way to
+ // use a try-with-resources statement in this.
+ // noinspection resource
+ fileHelper = runtimeFileHelper.activeHelper();
+ }
+
WorkableOverlays model = new WorkableOverlays(textureDir);
for (OverlayFace overlayFace : OverlayFace.VALUES) {
@@ -55,6 +64,13 @@ public static WorkableOverlays get(ResourceLocation textureDir, ExistingFileHelp
model.textures.put(overlayFace, new StatusTextures(normalSprite, activeSprite, pausedSprite,
normalSpriteEmissive, activeSpriteEmissive, pausedSpriteEmissive));
}
+
+ if (fileHelper instanceof RuntimeExistingFileHelper.Active activeHelper) {
+ // close the active helper, just for good measure.
+ // Also in case we ever make it do anything, this won't be forgotten.
+ activeHelper.close();
+ }
+
return model;
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
index dc257bd4770..4213be34926 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
@@ -5,10 +5,14 @@
import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider;
import com.gregtechceu.gtceu.data.model.builder.PipeModelBuilder;
+import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.client.model.generators.BlockModelBuilder;
import net.minecraftforge.client.model.generators.IGeneratedBlockState;
+import net.minecraftforge.client.model.generators.ModelBuilder;
+import net.minecraftforge.client.model.generators.ModelFile;
+import it.unimi.dsi.fastutil.objects.Reference2FloatMap;
import lombok.Setter;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@@ -23,6 +27,8 @@ public class ActivablePipeModel extends PipeModel {
public @Nullable ResourceLocation sideSecondaryActive, endSecondaryActive;
@Setter
public @Nullable ResourceLocation sideOverlayActive, endOverlayActive;
+ @Setter
+ public int activeEmissivity = 15;
/// Use {@link #getOrCreateActiveBlockModel()} instead of referencing this field directly.
private BlockModelBuilder activeBlockModel;
@@ -67,8 +73,7 @@ protected BlockModelBuilder getOrCreateActiveBlockModel() {
// spotless:off
return this.activeBlockModel = this.provider.models().getBuilder(this.blockId.withSuffix("_active").toString())
.parent(this.getOrCreateActiveCenterElement())
- .customLoader(PipeModelBuilder::begin)
- .thickness(this.thickness).provider(this.provider)
+ .customLoader(PipeModelBuilder.begin(this.thickness, this.provider))
.centerModels(this.getOrCreateActiveCenterElement().getLocation())
.connectionModels(this.getOrCreateActiveConnectionElement().getLocation())
.end();
@@ -87,7 +92,9 @@ protected BlockModelBuilder getOrCreateActiveCenterElement() {
if (this.activeCenterElement != null) {
return this.activeCenterElement;
}
- return this.activeCenterElement = makeActiveVariant(this.getOrCreateCenterElement());
+ return this.activeCenterElement = makeActiveElementModel(
+ this.blockId.withPath(path -> "block/pipe/" + path + "/center_active"),
+ null, minCoord, minCoord, minCoord, maxCoord, maxCoord, maxCoord);
}
/**
@@ -105,24 +112,82 @@ protected BlockModelBuilder getOrCreateActiveConnectionElement() {
if (this.activeConnectionElement != null) {
return this.activeConnectionElement;
}
- return this.activeConnectionElement = makeActiveVariant(this.getOrCreateConnectionElement());
+ return this.activeConnectionElement = makeActiveElementModel(
+ this.blockId.withPath(path -> "block/pipe/" + path + "/connection_active"),
+ Direction.DOWN, minCoord, 0, minCoord, maxCoord, minCoord, maxCoord);
}
- protected BlockModelBuilder makeActiveVariant(BlockModelBuilder parentModel) {
- BlockModelBuilder model = this.provider.models()
- .getBuilder(parentModel.getLocation().withSuffix("_active").toString())
- .parent(parentModel);
- // override non-null textures, leave unset ones as is
- if (this.sideActive != null) model.texture("side", this.sideActive);
- if (this.endActive != null) model.texture("end", this.endActive);
- if (this.sideSecondaryActive != null) model.texture("side_secondary", this.sideSecondaryActive);
- if (this.endSecondaryActive != null) model.texture("end_secondary", this.endSecondaryActive);
- if (this.sideOverlayActive != null) model.texture("side_overlay", this.sideOverlayActive);
- if (this.endOverlayActive != null) model.texture("end_overlay", this.endOverlayActive);
+ /**
+ * Fills out a model builder with applicable pipe model elements and returns it for further use
+ *
+ * This method is a copy of {@linkplain #makeElementModel} with the texture references changed for active variants.
+ *
+ * @param name the resulting model's path
+ * @param endFace the model face that's being created
+ * @param x1 min X coordinate in the range [-16,32]
+ * @param y1 min Y coordinate in the range [-16,32]
+ * @param z1 min Z coordinate in the range [-16,32]
+ * @param x2 max X coordinate in the range [-16,32]
+ * @param y2 max Y coordinate in the range [-16,32]
+ * @param z2 max Z coordinate in the range [-16,32]
+ * @implNote The coordinates must be in the correct order or the resulting model's cubes will be inside out!
+ * @see #makeElementModel
+ */
+ protected BlockModelBuilder makeActiveElementModel(ResourceLocation name, @Nullable Direction endFace,
+ final float x1, final float y1, final float z1,
+ final float x2, final float y2, final float z2) {
+ Reference2FloatMap faceEndpoints = makeFaceEndpointMap(x1, y1, z1, x2, y2, z2);
+
+ BlockModelBuilder model = this.provider.models().getBuilder(name.toString())
+ .parent(new ModelFile.UncheckedModelFile("block/block"));
+
+ ResourceLocation side = this.sideActive != null ? this.sideActive : this.side;
+ ResourceLocation end = this.endActive != null ? this.endActive : this.end;
+ ResourceLocation sideSecondary = this.sideSecondaryActive != null ? this.sideSecondaryActive :
+ this.sideSecondary;
+ ResourceLocation endSecondary = this.endSecondaryActive != null ? this.endSecondaryActive : this.endSecondary;
+ ResourceLocation sideOverlay = this.sideOverlayActive != null ? this.sideOverlayActive : this.sideOverlay;
+ ResourceLocation endOverlay = this.endOverlayActive != null ? this.endOverlayActive : this.endOverlay;
+
+ makePartModelElement(model, endFace, false, faceEndpoints, 0.0f, 0, 1,
+ x1, y1, z1, x2, y2, z2, side, end, SIDE_KEY, END_KEY,
+ this.sideActive != null, this.endActive != null);
+
+ makePartModelElement(model, endFace, true, faceEndpoints, 0.001f, 0, 1,
+ x1, y1, z1, x2, y2, z2, sideSecondary, endSecondary, SIDE_SECONDARY_KEY, END_SECONDARY_KEY,
+ this.sideSecondaryActive != null, this.endSecondaryActive != null);
+
+ makePartModelElement(model, endFace, true, faceEndpoints, 0.002f, 2, 2,
+ x1, y1, z1, x2, y2, z2, sideOverlay, endOverlay, SIDE_OVERLAY_KEY, END_OVERLAY_KEY,
+ this.sideOverlayActive != null, this.endOverlayActive != null);
return model;
}
+ protected > void makePartModelElement(T model, @Nullable Direction endFace,
+ boolean useEndWithFullCube,
+ Reference2FloatMap faceEndpoints,
+ float offset, int sideTintIndex, int endTintIndex,
+ final float x1, final float y1, final float z1,
+ final float x2, final float y2, final float z2,
+ @Nullable ResourceLocation sideTexture,
+ @Nullable ResourceLocation endTexture,
+ String sideKey, String endKey,
+ boolean sideEmissive, boolean endEmissive) {
+ this.makePartModelElement(model, endFace, useEndWithFullCube, faceEndpoints, offset,
+ sideTintIndex, endTintIndex, x1, y1, z1, x2, y2, z2, sideTexture, endTexture, sideKey, endKey,
+ (face, textureKey, builder) -> {
+ if (activeEmissivity == 0) {
+ return;
+ }
+ if (sideEmissive && textureKey.equals(sideKey)) {
+ builder.emissivity(activeEmissivity, activeEmissivity).ao(false);
+ } else if (endEmissive && textureKey.equals(endKey)) {
+ builder.emissivity(activeEmissivity, activeEmissivity).ao(false);
+ }
+ });
+ }
+
@Override
public IGeneratedBlockState createBlockState() {
if (!this.getBlock().defaultBlockState().hasProperty(GTBlockStateProperties.ACTIVE)) {
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
index 83f0ceeb9ca..3fa772c5756 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
@@ -21,6 +21,7 @@
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.MustBeInvokedByOverriders;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -78,6 +79,16 @@
*/
public class PipeModel {
+ // spotless:off
+ public static final String
+ SIDE_KEY = "side",
+ END_KEY = "end",
+ SIDE_SECONDARY_KEY = "side_secondary",
+ END_SECONDARY_KEY = "end_secondary",
+ SIDE_OVERLAY_KEY = "side_overlay",
+ END_OVERLAY_KEY = "end_overlay";
+ // spotless:on
+
public static final Set DYNAMIC_MODELS = new HashSet<>();
public static void initDynamicModels() {
@@ -149,6 +160,7 @@ public final void dynamicModel() {
* @see #getOrCreateCenterElement()
* @see #getOrCreateConnectionElement()
*/
+ @MustBeInvokedByOverriders
public void initModels() {
getOrCreateCenterElement();
getOrCreateConnectionElement();
@@ -174,8 +186,7 @@ protected BlockModelBuilder getOrCreateBlockModel() {
return this.blockModel = this.provider.models().getBuilder(this.blockId.toString())
// make the "default" model be based on the center part's model
.parent(this.getOrCreateCenterElement())
- .customLoader(PipeModelBuilder::begin)
- .thickness(this.thickness).provider(this.provider)
+ .customLoader(PipeModelBuilder.begin(this.thickness, this.provider))
.centerModels(this.getOrCreateCenterElement().getLocation())
.connectionModels(this.getOrCreateConnectionElement().getLocation())
.end();
@@ -227,7 +238,10 @@ protected BlockModelBuilder getOrCreateConnectionElement() {
*/
@ApiStatus.OverrideOnly
protected ItemModelBuilder getOrCreateItemModel() {
- return createItemModel(this.blockId, this.minCoord, this.maxCoord);
+ if (this.itemModel != null) {
+ return this.itemModel;
+ }
+ return this.itemModel = createItemModel(this.blockId, this.minCoord, this.maxCoord);
}
/**
@@ -271,11 +285,12 @@ protected ItemModelBuilder createItemModel(ResourceLocation name, float min, flo
ItemModelBuilder model = this.provider.itemModels().getBuilder(name.toString())
.parent(this.getOrCreateCenterElement());
makePartModelElement(model, Direction.NORTH, false, faceEndpoints, 0.0f, 0, 1,
- min, min, 0, max, max, 16, this.side, this.end, "side", "end");
+ min, min, 0, max, max, 16, this.side, this.end, SIDE_KEY, END_KEY);
makePartModelElement(model, Direction.NORTH, true, faceEndpoints, 0.001f, 0, 1,
- min, min, 0, max, max, 16, this.sideSecondary, this.endSecondary, "side_secondary", "end_secondary");
+ min, min, 0, max, max, 16, this.sideSecondary, this.endSecondary, SIDE_SECONDARY_KEY,
+ END_SECONDARY_KEY);
makePartModelElement(model, Direction.NORTH, true, faceEndpoints, 0.002f, 2, 2,
- min, min, 0, max, max, 16, this.sideOverlay, this.endOverlay, "side_overlay", "end_overlay");
+ min, min, 0, max, max, 16, this.sideOverlay, this.endOverlay, SIDE_OVERLAY_KEY, END_OVERLAY_KEY);
return model;
}
@@ -295,23 +310,12 @@ protected ItemModelBuilder createItemModel(ResourceLocation name, float min, flo
protected BlockModelBuilder makeElementModel(ResourceLocation name, @Nullable Direction endFace,
final float x1, final float y1, final float z1,
final float x2, final float y2, final float z2) {
- Reference2FloatMap faceEndpoints = new Reference2FloatOpenHashMap<>();
- faceEndpoints.defaultReturnValue(GTMath.max(x1, y1, z1, x2, y2, z2));
- for (Direction dir : GTUtil.DIRECTIONS) {
- faceEndpoints.put(dir, switch (dir) {
- case DOWN -> Math.min(y1, y2);
- case UP -> Math.max(y1, y2);
- case NORTH -> Math.min(z1, z2);
- case SOUTH -> Math.max(z1, z2);
- case WEST -> Math.min(x1, x2);
- case EAST -> Math.max(x1, x2);
- });
- }
+ Reference2FloatMap faceEndpoints = makeFaceEndpointMap(x1, y1, z1, x2, y2, z2);
BlockModelBuilder model = this.provider.models().getBuilder(name.toString())
.parent(new ModelFile.UncheckedModelFile("block/block"));
makePartModelElement(model, endFace, false, faceEndpoints, 0.0f, 0, 1,
- x1, y1, z1, x2, y2, z2, this.side, this.end, "side", "end");
+ x1, y1, z1, x2, y2, z2, this.side, this.end, SIDE_KEY, END_KEY);
makePartModelElement(model, endFace, true, faceEndpoints, 0.001f, 0, 1,
x1, y1, z1, x2, y2, z2, this.sideSecondary, this.endSecondary, "side_secondary", "end_secondary");
makePartModelElement(model, endFace, true, faceEndpoints, 0.002f, 2, 2,
@@ -328,11 +332,26 @@ protected > void makePartModelElement(T model, @Nullab
@Nullable ResourceLocation sideTexture,
@Nullable ResourceLocation endTexture,
String sideKey, String endKey) {
- if (sideTexture == null && endTexture == null) {
+ makePartModelElement(model, endFace, useEndWithFullCube, faceEndpoints,
+ offset, sideTintIndex, endTintIndex, x1, y1, z1, x2, y2, z2,
+ sideTexture, endTexture, sideKey, endKey, (face, texture, builder) -> {});
+ }
+
+ protected > void makePartModelElement(T model, @Nullable Direction endFace,
+ boolean useEndWithFullCube,
+ Reference2FloatMap faceEndpoints,
+ float offset, int sideTintIndex, int endTintIndex,
+ final float x1, final float y1, final float z1,
+ final float x2, final float y2, final float z2,
+ @Nullable ResourceLocation sideTexture,
+ @Nullable ResourceLocation endTexture,
+ String sideKey, String endKey,
+ FaceConfigurator faceConfigurator) {
+ if (sideTexture == null && (endFace == null || endTexture == null)) {
return;
}
if (sideTexture != null) model.texture(sideKey, sideTexture);
- if (endTexture != null) model.texture(endKey, endTexture);
+ if (endFace != null && endTexture != null) model.texture(endKey, endTexture);
boolean fullCube = !useEndWithFullCube &&
(x1 == y1 && x1 == z1 && x1 <= 0.0f) &&
@@ -344,11 +363,13 @@ protected > void makePartModelElement(T model, @Nullab
for (Direction dir : GTUtil.DIRECTIONS) {
ModelBuilder.ElementBuilder.FaceBuilder face = null;
- boolean isEnd = (endFace == dir || endFace == dir.getOpposite()) && !fullCube;
+ boolean isEnd = !fullCube && endFace != null && (endFace == dir || endFace == dir.getOpposite());
if (isEnd && endTexture != null) {
face = element.face(dir).texture("#" + endKey).tintindex(endTintIndex);
+ faceConfigurator.accept(dir, endKey, face);
} else if (!isEnd && sideTexture != null) {
face = element.face(dir).texture("#" + sideKey).tintindex(sideTintIndex);
+ faceConfigurator.accept(dir, sideKey, face);
}
float faceEnd = faceEndpoints.getFloat(dir);
@@ -358,6 +379,23 @@ protected > void makePartModelElement(T model, @Nullab
}
}
+ protected final Reference2FloatMap makeFaceEndpointMap(final float x1, final float y1, final float z1,
+ final float x2, final float y2, final float z2) {
+ Reference2FloatMap faceEndpoints = new Reference2FloatOpenHashMap<>();
+ faceEndpoints.defaultReturnValue(GTMath.max(x1, y1, z1, x2, y2, z2));
+ for (Direction dir : GTUtil.DIRECTIONS) {
+ faceEndpoints.put(dir, switch (dir) {
+ case DOWN -> Math.min(y1, y2);
+ case UP -> Math.max(y1, y2);
+ case NORTH -> Math.min(z1, z2);
+ case SOUTH -> Math.max(z1, z2);
+ case WEST -> Math.min(x1, x2);
+ case EAST -> Math.max(x1, x2);
+ });
+ }
+ return faceEndpoints;
+ }
+
@Override
public boolean equals(Object o) {
if (!(o instanceof PipeModel pipeModel)) return false;
@@ -374,4 +412,22 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(block, side, end, sideSecondary, endSecondary, sideOverlay, endOverlay);
}
+
+ @FunctionalInterface
+ public interface FaceConfigurator> {
+
+ /**
+ * This is a callback for modifying a block element face builder in ways not supported by "basic" API.
+ * For example, you can make faces emissive, like {@link ActivablePipeModel#makePartModelElement}.
+ *
+ * @param face The normal direction of this face.
+ * @param texture The texture of the face, usually in {@code #reference} format.
+ * Note that the String does NOT begin with {@code #}.
+ * @param builder The face builder.
+ * @see ActivablePipeModel#makePartModelElement(ModelBuilder, Direction, boolean, Reference2FloatMap, float,
+ * int, int, float, float, float, float, float, float, ResourceLocation, ResourceLocation, String, String,
+ * boolean, boolean) ActivablePipeModel.makePartModelElement
+ */
+ void accept(Direction face, String texture, ModelBuilder.ElementBuilder.FaceBuilder builder);
+ }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java b/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java
index 917e3996be2..57ffd1f470c 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java
@@ -23,15 +23,14 @@
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
-import lombok.Setter;
import lombok.experimental.Accessors;
import org.jetbrains.annotations.ApiStatus;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Range;
import org.joml.Vector3f;
import java.util.*;
+import java.util.function.BiFunction;
import static com.gregtechceu.gtceu.data.model.builder.MachineModelBuilder.configuredModelListToJSON;
import static com.gregtechceu.gtceu.data.model.builder.MachineModelBuilder.configuredModelToJSON;
@@ -40,23 +39,28 @@
@SuppressWarnings("UnusedReturnValue")
public class PipeModelBuilder> extends CustomLoaderBuilder {
- public static > PipeModelBuilder begin(T parent,
- ExistingFileHelper existingFileHelper) {
- return new PipeModelBuilder<>(parent, existingFileHelper);
+ // spotless:off
+ public static > BiFunction> begin(@Range(from = 0, to = 16) float thickness,
+ GTBlockstateProvider provider) {
+ return (parent, existingFileHelper) -> new PipeModelBuilder<>(parent, existingFileHelper, thickness, provider);
}
+ // spotless:on
@Accessors(fluent = false)
@Getter
- private final Map parts = new IdentityHashMap<>();
- @Setter
- @Range(from = 0, to = 16)
- private float thickness = Float.MIN_VALUE;
- @Setter
- private @NotNull GTBlockstateProvider provider;
- private BlockModelBuilder[] restrictors = null;
-
- protected PipeModelBuilder(T parent, ExistingFileHelper existingFileHelper) {
+ private final Map<@Nullable Direction, ConfiguredModelList> parts = new IdentityHashMap<>();
+ private final float thickness;
+ private final GTBlockstateProvider provider;
+ private BlockModelBuilder @Nullable [] restrictors = null;
+
+ protected PipeModelBuilder(T parent, ExistingFileHelper existingFileHelper,
+ float thickness, GTBlockstateProvider provider) {
super(PipeModelLoader.ID, parent, existingFileHelper);
+
+ Preconditions.checkArgument(thickness > 0.0f && thickness <= 16.0f,
+ "Thickness must be between 0 (exclusive) and 16 (inclusive). It is %s", thickness);
+ this.thickness = thickness;
+ this.provider = provider;
}
/**
@@ -289,12 +293,6 @@ public T end() {
@Override
public JsonObject toJson(JsonObject json) {
- Preconditions.checkState(thickness != Float.MIN_VALUE, "A thickness value must be set!");
- Preconditions.checkState(thickness > 0.0f || thickness <= 16.0f,
- "Thickness must be between 0 (exclusive) and 16 (inclusive). is %s", thickness);
- // noinspection ConstantValue
- Preconditions.checkState(provider != null, "You must pass in a GTBlockStateProvider!");
-
json = super.toJson(json);
if (!getParts().isEmpty()) {
@@ -368,7 +366,7 @@ private static BlockModelBuilder[] getOrCreateRestrictorModels(BlockModelProvide
return RESTRICTOR_MODEL_CACHE.apply(provider, thickness);
}
- private static final MemoizedBiFunction RESTRICTOR_MODEL_CACHE = GTMemoizer
+ private static final MemoizedBiFunction RESTRICTOR_MODEL_CACHE = GTMemoizer
.memoizeFunctionWeakIdent(PipeModelBuilder::makeRestrictorModels);
private static BlockModelBuilder[] makeRestrictorModels(BlockModelProvider provider, float thickness) {
diff --git a/src/main/java/com/gregtechceu/gtceu/data/model/builder/package-info.java b/src/main/java/com/gregtechceu/gtceu/data/model/builder/package-info.java
new file mode 100644
index 00000000000..2f6102b3cd1
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/data/model/builder/package-info.java
@@ -0,0 +1,4 @@
+@NotNullByDefault
+package com.gregtechceu.gtceu.data.model.builder;
+
+import org.jetbrains.annotations.NotNullByDefault;
diff --git a/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeExistingFileHelper.java b/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeExistingFileHelper.java
index e6e7c50d4c4..f2d04d3629d 100644
--- a/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeExistingFileHelper.java
+++ b/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeExistingFileHelper.java
@@ -12,7 +12,7 @@
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
-import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.FileNotFoundException;
import java.util.Collections;
@@ -23,25 +23,41 @@
/**
* Existing file helper that wraps the client/server resource manager instead of creating its own.
* Useful for using data generators outside datagen.
+ *
+ * By default, this class assumes all resources exist and does not check any references' validity.
+ * To enable actual checking, you may use a try-with-resources statement like this:
+ *
+ *
{@code
+ * try (var helper = RuntimeExistingFileHelper.INSTANCE.activeHelper()) {
+ * // If you don't use a try-with-resources or try-finally block to
+ * // enable checking, calling `exists` will always return true.
+ * if (helper.exists(texture, GTBlockstateProvider.TEXTURE)) {
+ * // do stuff
+ * }
+ * }
+ * }
+ *
*/
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class RuntimeExistingFileHelper extends ExistingFileHelper {
- public static final RuntimeExistingFileHelper INSTANCE = new RuntimeExistingFileHelper();
+ public static final RuntimeExistingFileHelper INSTANCE = new RuntimeExistingFileHelper(HashMultimap.create());
- protected final Multimap generated = HashMultimap.create();
+ protected final Multimap generated;
+ protected @Nullable Active activeHelper;
- protected RuntimeExistingFileHelper() {
+ protected RuntimeExistingFileHelper(Multimap generated) {
super(Collections.emptySet(), Collections.emptySet(), false, null, null);
+ this.generated = generated;
}
- public static @NotNull ResourceManager getManager(PackType packType) {
+ public static ResourceManager getManager(PackType packType) {
if (packType == PackType.CLIENT_RESOURCES) {
return Minecraft.getInstance().getResourceManager();
} else if (packType == PackType.SERVER_DATA) {
if (GTCEu.getMinecraftServer() == null) {
- throw new IllegalStateException("Cannot get server resources without a server or on a remote client.");
+ throw new IllegalStateException("Cannot get server resources without a server / on a remote client.");
}
return GTCEu.getMinecraftServer().getResourceManager();
} else {
@@ -53,11 +69,26 @@ protected ResourceLocation getLocation(ResourceLocation base, String prefix, Str
return base.withPath(path -> prefix + "/" + path + suffix);
}
+ public RuntimeExistingFileHelper.Active activeHelper() {
+ if (this.activeHelper == null) {
+ // pass the same generated resources map into the subclass
+ // so any resources added/checked by it are automatically updated here
+ this.activeHelper = new Active(this.generated);
+ }
+ return this.activeHelper;
+ }
+
+ /**
+ * Bypass the normal {@code exists} function so missing/invalid references etc. don't cause runtime errors.
+ * A toggle for enabling proper functionality is implemented in the form of {@link #activeHelper()}-
+ */
@Override
public boolean exists(ResourceLocation loc, PackType packType) {
- return generated.get(packType).contains(loc) || getManager(packType).getResource(loc).isPresent();
+ return true;
}
+ /// Implement a copy of the normal {@code exists} function that we can use for checking
+
@Override
public void trackGenerated(ResourceLocation loc, IResourceType type) {
trackGenerated(loc, type.getPackType(), type.getSuffix(), type.getPrefix());
@@ -83,4 +114,31 @@ public Resource getResource(ResourceLocation loc, PackType packType) throws File
public List getResourceStack(ResourceLocation loc, PackType packType) {
return getManager(packType).getResourceStack(loc);
}
+
+ /**
+ * This class implements {@link AutoCloseable} for ease of enabling actual checking when it is required.
+ *
+ * Note that it's safe to ignore "unclosed AutoCloseable"/{@code resource} warnings on this class, as is done in
+ * {@linkplain com.gregtechceu.gtceu.client.model.machine.overlays.WorkableOverlays#get WorkableOverlays#get}.
+ *
+ */
+ public static class Active extends RuntimeExistingFileHelper implements AutoCloseable {
+
+ protected Active(Multimap parentGenerated) {
+ super(parentGenerated);
+ }
+
+ @Override
+ public Active activeHelper() {
+ return this;
+ }
+
+ @Override
+ public boolean exists(ResourceLocation loc, PackType packType) {
+ return this.generated.get(packType).contains(loc) || getManager(packType).getResource(loc).isPresent();
+ }
+
+ @Override
+ public void close() {}
+ }
}
From 7075fc094090facb5488bcefeba1b4718312e197 Mon Sep 17 00:00:00 2001
From: Mqrius
Date: Tue, 3 Feb 2026 07:44:47 +0100
Subject: [PATCH 15/78] Fix bug in NBTPredicateIngredient serializer (#4536)
---
.../gtceu/api/recipe/ingredient/NBTPredicateIngredient.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateIngredient.java
index 2fde075f7b6..b0cd45576d8 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateIngredient.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateIngredient.java
@@ -96,7 +96,7 @@ public static class Serializer implements IIngredientSerializer
Date: Tue, 3 Feb 2026 15:08:17 +0800
Subject: [PATCH 16/78] Fix dust disassembly recipes (#4456)
---
.../gtceu/api/recipe/StrictShapedRecipe.java | 17 +++++-
.../data/recipe/VanillaRecipeHelper.java | 61 +++++++++++++++----
.../recipe/builder/ShapedRecipeBuilder.java | 9 +++
.../generated/MaterialRecipeHandler.java | 10 ++-
4 files changed, 80 insertions(+), 17 deletions(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/StrictShapedRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/StrictShapedRecipe.java
index 529e54e4fce..e8501709ab2 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/recipe/StrictShapedRecipe.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/StrictShapedRecipe.java
@@ -16,6 +16,7 @@
import net.minecraft.world.level.Level;
import com.google.gson.JsonObject;
+import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -28,13 +29,18 @@ public class StrictShapedRecipe extends ShapedRecipe {
public static final RecipeSerializer SERIALIZER = new Serializer();
+ @Getter
+ private final boolean matchSize;
+
public StrictShapedRecipe(ResourceLocation id, String group, CraftingBookCategory category, int width, int height,
- NonNullList recipeItems, ItemStack result) {
+ NonNullList recipeItems, ItemStack result, boolean matchSize) {
super(id, group, category, width, height, recipeItems, result);
+ this.matchSize = matchSize;
}
@Override
public boolean matches(CraftingContainer inv, Level level) {
+ if (matchSize && (inv.getWidth() != this.getWidth() || inv.getHeight() != this.getHeight())) return false;
for (int i = 0; i <= inv.getWidth() - this.getWidth(); ++i) {
for (int j = 0; j <= inv.getHeight() - this.getHeight(); ++j) {
if (this.matches(inv, i, j)) {
@@ -82,7 +88,9 @@ public StrictShapedRecipe fromJson(ResourceLocation recipeId, JsonObject json) {
int j = strings.length;
NonNullList nonNullList = ShapedRecipeAccessor.callDissolvePattern(strings, map, i, j);
ItemStack itemStack = StrictShapedRecipe.itemStackFromJson(GsonHelper.getAsJsonObject(json, "result"));
- return new StrictShapedRecipe(recipeId, string, craftingBookCategory, i, j, nonNullList, itemStack);
+ boolean matchSize = json.get("matchSize").getAsBoolean();
+ return new StrictShapedRecipe(recipeId, string, craftingBookCategory, i, j, nonNullList, itemStack,
+ matchSize);
}
@Override
@@ -94,7 +102,9 @@ public StrictShapedRecipe fromNetwork(ResourceLocation recipeId, FriendlyByteBuf
NonNullList nonNullList = NonNullList.withSize(i * j, Ingredient.EMPTY);
nonNullList.replaceAll(ignored -> Ingredient.fromNetwork(buffer));
ItemStack itemStack = buffer.readItem();
- return new StrictShapedRecipe(recipeId, string, craftingBookCategory, i, j, nonNullList, itemStack);
+ boolean matchSize = buffer.readBoolean();
+ return new StrictShapedRecipe(recipeId, string, craftingBookCategory, i, j, nonNullList, itemStack,
+ matchSize);
}
@Override
@@ -107,6 +117,7 @@ public void toNetwork(FriendlyByteBuf buffer, StrictShapedRecipe recipe) {
ingredient.toNetwork(buffer);
}
buffer.writeItem(((ShapedRecipeAccessor) recipe).getResult());
+ buffer.writeBoolean(recipe.matchSize);
}
}
}
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java
index ee3b7ff2257..1cfd3ddac9f 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java
@@ -224,7 +224,7 @@ public static void addShapedNBTClearingRecipe(Consumer provider,
}
/**
- * @see #addShapedRecipe(Consumer, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
*/
public static void addShapedRecipe(Consumer provider, @NotNull String regName,
@NotNull ItemStack result, @NotNull Object... recipe) {
@@ -232,7 +232,7 @@ public static void addShapedRecipe(Consumer provider, @NotNull S
}
/**
- * @see #addShapedRecipe(Consumer, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
*/
public static void addShapedRecipe(Consumer provider, @NotNull ResourceLocation regName,
@NotNull ItemStack result, @NotNull Object... recipe) {
@@ -240,7 +240,7 @@ public static void addShapedRecipe(Consumer provider, @NotNull R
}
/**
- * @see #addShapedRecipe(Consumer, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
*/
public static void addStrictShapedRecipe(Consumer provider, @NotNull String regName,
@NotNull ItemStack result, @NotNull Object... recipe) {
@@ -248,7 +248,7 @@ public static void addStrictShapedRecipe(Consumer provider, @Not
}
/**
- * @see #addShapedRecipe(Consumer, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
*/
public static void addStrictShapedRecipe(Consumer provider, boolean setMaterialInfoData,
@NotNull String regName,
@@ -257,13 +257,38 @@ public static void addStrictShapedRecipe(Consumer provider, bool
}
/**
- * @see #addShapedRecipe(Consumer, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
*/
public static void addStrictShapedRecipe(Consumer provider, @NotNull ResourceLocation regName,
@NotNull ItemStack result, @NotNull Object... recipe) {
addStrictShapedRecipe(provider, false, regName, result, recipe);
}
+ /**
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ */
+ public static void addStrictSizeShapedRecipe(Consumer provider, @NotNull String regName,
+ @NotNull ItemStack result, @NotNull Object... recipe) {
+ addStrictSizeShapedRecipe(provider, GTCEu.id(regName), result, recipe);
+ }
+
+ /**
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ */
+ public static void addStrictSizeShapedRecipe(Consumer provider, boolean setMaterialInfoData,
+ @NotNull String regName,
+ @NotNull ItemStack result, @NotNull Object... recipe) {
+ addStrictSizeShapedRecipe(provider, setMaterialInfoData, GTCEu.id(regName), result, recipe);
+ }
+
+ /**
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ */
+ public static void addStrictSizeShapedRecipe(Consumer provider, @NotNull ResourceLocation regName,
+ @NotNull ItemStack result, @NotNull Object... recipe) {
+ addStrictSizeShapedRecipe(provider, false, regName, result, recipe);
+ }
+
/**
* Adds Shaped Crafting Recipes.
*
@@ -284,17 +309,20 @@ public static void addStrictShapedRecipe(Consumer provider, @Not
* {@code 'w'} - {@code craftingToolWrench}
* {@code 'x'} - {@code craftingToolWireCutter}
*
- *
+ *
* @param setMaterialInfoData whether to add material decomposition information to the recipe output
+ *
+ * @param matchSize
* @param regName the registry name for the recipe
* @param result the output for the recipe
* @param recipe the contents of the recipe
*/
public static void addShapedRecipe(Consumer provider, boolean setMaterialInfoData, boolean isStrict,
- @NotNull ResourceLocation regName, @NotNull ItemStack result,
+ boolean matchSize, @NotNull ResourceLocation regName, @NotNull ItemStack result,
@NotNull Object... recipe) {
var builder = new ShapedRecipeBuilder(regName).output(result);
builder.isStrict(isStrict);
+ builder.matchSize(matchSize);
final CharSet tools = ToolHelper.getToolSymbols();
CharSet foundTools = new CharArraySet(9);
for (int i = 0; i < recipe.length; i++) {
@@ -354,7 +382,7 @@ public static void addShapedRecipe(Consumer provider, boolean se
}
/**
- * @see #addShapedRecipe(Consumer, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
*/
public static void addShapedRecipe(Consumer provider, boolean setMaterialInfoData,
@NotNull String regName, @NotNull ItemStack result, @NotNull Object... recipe) {
@@ -362,21 +390,30 @@ public static void addShapedRecipe(Consumer provider, boolean se
}
/**
- * @see #addShapedRecipe(Consumer, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
*/
public static void addShapedRecipe(Consumer provider, boolean setMaterialInfoData,
@NotNull ResourceLocation regName, @NotNull ItemStack result,
@NotNull Object... recipe) {
- addShapedRecipe(provider, setMaterialInfoData, false, regName, result, recipe);
+ addShapedRecipe(provider, setMaterialInfoData, false, false, regName, result, recipe);
}
/**
- * @see #addShapedRecipe(Consumer, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
*/
public static void addStrictShapedRecipe(Consumer provider, boolean setMaterialInfoData,
@NotNull ResourceLocation regName, @NotNull ItemStack result,
@NotNull Object... recipe) {
- addShapedRecipe(provider, setMaterialInfoData, true, regName, result, recipe);
+ addShapedRecipe(provider, setMaterialInfoData, true, false, regName, result, recipe);
+ }
+
+ /**
+ * @see #addShapedRecipe(Consumer, boolean, boolean, boolean, ResourceLocation, ItemStack, Object...)
+ */
+ public static void addStrictSizeShapedRecipe(Consumer provider, boolean setMaterialInfoData,
+ @NotNull ResourceLocation regName, @NotNull ItemStack result,
+ @NotNull Object... recipe) {
+ addShapedRecipe(provider, setMaterialInfoData, true, true, regName, result, recipe);
}
public static void addShapelessRecipe(Consumer provider, @NotNull String regName,
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/ShapedRecipeBuilder.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/ShapedRecipeBuilder.java
index 26d6f675325..b871319e325 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/ShapedRecipeBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/ShapedRecipeBuilder.java
@@ -30,6 +30,7 @@ public class ShapedRecipeBuilder extends Builder provider,
ItemStack smallDustStack = ChemicalHelper.get(dustSmall, material);
ItemStack dustStack = ChemicalHelper.get(dust, material);
- VanillaRecipeHelper.addStrictShapedRecipe(provider,
+ VanillaRecipeHelper.addStrictSizeShapedRecipe(provider,
String.format("small_dust_disassembling_%s", material.getName()),
smallDustStack.copyWithCount(4), " X", " ", 'X', new MaterialEntry(dust, material));
+ VanillaRecipeHelper.addStrictSizeShapedRecipe(provider,
+ String.format("small_dust_disassembling_3x3_%s", material.getName()),
+ smallDustStack.copyWithCount(4), " X ", " ", " ", 'X', new MaterialEntry(dust, material));
VanillaRecipeHelper.addShapedRecipe(provider, String.format("small_dust_assembling_%s", material.getName()),
dustStack, "XX", "XX", 'X', new MaterialEntry(dustSmall, material));
@@ -282,9 +285,12 @@ private static void processTinyDust(@NotNull Consumer provider,
ItemStack tinyDustStack = ChemicalHelper.get(dustTiny, material);
ItemStack dustStack = ChemicalHelper.get(dust, material);
- VanillaRecipeHelper.addStrictShapedRecipe(provider,
+ VanillaRecipeHelper.addStrictSizeShapedRecipe(provider,
String.format("tiny_dust_disassembling_%s", material.getName()),
tinyDustStack.copyWithCount(9), "X ", " ", 'X', new MaterialEntry(dust, material));
+ VanillaRecipeHelper.addStrictSizeShapedRecipe(provider,
+ String.format("tiny_dust_disassembling_3x3_%s", material.getName()),
+ tinyDustStack.copyWithCount(9), "X ", " ", " ", 'X', new MaterialEntry(dust, material));
VanillaRecipeHelper.addShapedRecipe(provider, String.format("tiny_dust_assembling_%s", material.getName()),
dustStack, "XXX", "XXX", "XXX", 'X', new MaterialEntry(dustTiny, material));
From 33a95021ee4996c5b14f14eeb5d48f4c4c1b328f Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk
Date: Tue, 3 Feb 2026 10:37:41 +0100
Subject: [PATCH 17/78] Re-run ranged input tests multiple times (#4538)
---
.../IntProviderFluidIngredientTest.java | 24 ++++++++++++++-----
.../ingredient/IntProviderIngredientTest.java | 24 ++++++++++++++-----
2 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java
index 36a06165618..8e40cfbf616 100644
--- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java
+++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java
@@ -596,7 +596,9 @@ public static void multiblockLCRRangedFluidOutput(GameTestHelper helper) {
// test for multiblock machine with 16x Parallels with ranged fluid input
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedFluidIngredients",
- timeoutTicks = 200)
+ timeoutTicks = 200,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedFluidInput16Parallel(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -668,7 +670,9 @@ public static void multiblockLCentRangedFluidInput16Parallel(GameTestHelper help
// test for multiblock machine with 16x Parallels with ranged fluid output
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedFluidIngredients",
- timeoutTicks = 200)
+ timeoutTicks = 200,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedFluidOutput16Parallel(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -742,7 +746,9 @@ public static void multiblockLCentRangedFluidOutput16Parallel(GameTestHelper hel
// test for multiblock machine with 16x Parallels with ranged fluid input
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedFluidIngredients",
- timeoutTicks = 200)
+ timeoutTicks = 200,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedFluidInputBatched(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -814,7 +820,9 @@ public static void multiblockLCentRangedFluidInputBatched(GameTestHelper helper)
// test for multiblock machine with 16x Parallels with ranged fluid output
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedFluidIngredients",
- timeoutTicks = 200)
+ timeoutTicks = 200,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedFluidOutputBatched(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -888,7 +896,9 @@ public static void multiblockLCentRangedFluidOutputBatched(GameTestHelper helper
// test for multiblock machine with 16x Parallels with ranged fluid input
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedFluidIngredients",
- timeoutTicks = 500)
+ timeoutTicks = 500,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedFluidInput16ParallelBatched(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -965,7 +975,9 @@ public static void multiblockLCentRangedFluidInput16ParallelBatched(GameTestHelp
// test for multiblock machine with 16x Parallels with ranged fluid output
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedFluidIngredients",
- timeoutTicks = 500)
+ timeoutTicks = 500,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedFluidOutput16ParallelBatched(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java
index 51120392ffb..520ff1bbb76 100644
--- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java
+++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java
@@ -585,7 +585,9 @@ public static void multiblockLCRRangedItemOutput(GameTestHelper helper) {
// test for multiblock machine with 16x Parallels with ranged item input
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedIngredients",
- timeoutTicks = 200)
+ timeoutTicks = 200,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedItemInput16Parallel(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -655,7 +657,9 @@ public static void multiblockLCentRangedItemInput16Parallel(GameTestHelper helpe
// test for multiblock machine with 16x Parallels with ranged item output
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedIngredients",
- timeoutTicks = 200)
+ timeoutTicks = 200,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedItemOutput16Parallel(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -729,7 +733,9 @@ public static void multiblockLCentRangedItemOutput16Parallel(GameTestHelper help
// test for multiblock machine with 16x Parallels with ranged item input
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedIngredients",
- timeoutTicks = 200)
+ timeoutTicks = 200,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedItemInputBatched(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -799,7 +805,9 @@ public static void multiblockLCentRangedItemInputBatched(GameTestHelper helper)
// test for multiblock machine with 16x Parallels with ranged item output
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedIngredients",
- timeoutTicks = 200)
+ timeoutTicks = 200,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedItemOutputBatched(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -873,7 +881,9 @@ public static void multiblockLCentRangedItemOutputBatched(GameTestHelper helper)
// test for multiblock machine with 16x Parallels with ranged item input
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedIngredients",
- timeoutTicks = 500)
+ timeoutTicks = 500,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedItemInput16ParallelBatched(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
@@ -955,7 +965,9 @@ public static void multiblockLCentRangedItemInput16ParallelBatched(GameTestHelpe
// test for multiblock machine with 16x Parallels with ranged item output
@GameTest(template = "large_centrifuge_zpm_batch_parallel16",
batch = "RangedIngredients",
- timeoutTicks = 500)
+ timeoutTicks = 500,
+ requiredSuccesses = 1,
+ attempts = 10)
public static void multiblockLCentRangedItemOutput16ParallelBatched(GameTestHelper helper) {
BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper);
From b02c901ae92347249f634e6d6c6d1eeba0f2fb83 Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Tue, 3 Feb 2026 11:42:35 +0200
Subject: [PATCH 18/78] Fix pipes missing break particle textures (#4533)
---
.../assets/gtceu/models/block/pipe/huge_duct_pipe/center.json | 1 +
.../gtceu/models/block/pipe/huge_duct_pipe/connection.json | 1 +
.../assets/gtceu/models/block/pipe/large_duct_pipe/center.json | 1 +
.../gtceu/models/block/pipe/large_duct_pipe/connection.json | 1 +
.../gtceu/models/block/pipe/normal_duct_pipe/center.json | 1 +
.../gtceu/models/block/pipe/normal_duct_pipe/connection.json | 1 +
.../gtceu/models/block/pipe/normal_laser_pipe/center.json | 1 +
.../models/block/pipe/normal_laser_pipe/center_active.json | 1 +
.../gtceu/models/block/pipe/normal_laser_pipe/connection.json | 1 +
.../models/block/pipe/normal_laser_pipe/connection_active.json | 1 +
.../gtceu/models/block/pipe/normal_optical_pipe/center.json | 1 +
.../models/block/pipe/normal_optical_pipe/center_active.json | 1 +
.../models/block/pipe/normal_optical_pipe/connection.json | 1 +
.../block/pipe/normal_optical_pipe/connection_active.json | 1 +
.../assets/gtceu/models/block/pipe/small_duct_pipe/center.json | 1 +
.../gtceu/models/block/pipe/small_duct_pipe/connection.json | 1 +
.../gtceu/client/model/pipe/ActivablePipeModel.java | 3 ++-
.../com/gregtechceu/gtceu/client/model/pipe/PipeModel.java | 3 ++-
18 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
index 1916aa7d966..02a16c80e83 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
@@ -41,6 +41,7 @@
}
],
"textures": {
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
index b5f34317735..2226641a443 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
@@ -43,6 +43,7 @@
],
"textures": {
"end": "gtceu:block/pipe/pipe_duct_in",
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
index 39b3a894eac..a55cb442878 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
@@ -41,6 +41,7 @@
}
],
"textures": {
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
index e5504c54c2b..99be7317456 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
@@ -43,6 +43,7 @@
],
"textures": {
"end": "gtceu:block/pipe/pipe_duct_in",
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
index 1c7b6fe9ce9..2d0b6ace2aa 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
@@ -41,6 +41,7 @@
}
],
"textures": {
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
index c004f0de717..0204502f18f 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
@@ -43,6 +43,7 @@
],
"textures": {
"end": "gtceu:block/pipe/pipe_duct_in",
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
index 9de7a83201f..d42a077b7d3 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
@@ -79,6 +79,7 @@
}
],
"textures": {
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_laser_side",
"side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
index 088aa774a9f..4415d9932a9 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
@@ -109,6 +109,7 @@
}
],
"textures": {
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_laser_side",
"side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay_emissive"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
index 7dc25d11fdd..ca2bd68f7d2 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
@@ -73,6 +73,7 @@
],
"textures": {
"end": "gtceu:block/pipe/pipe_laser_in",
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_laser_side",
"side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
index 83cb7127326..a589a8af80f 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
@@ -93,6 +93,7 @@
],
"textures": {
"end": "gtceu:block/pipe/pipe_laser_in",
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_laser_side",
"side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay_emissive"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
index 1c46b15f85c..7ce8bf8c21a 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
@@ -79,6 +79,7 @@
}
],
"textures": {
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_optical_side",
"side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
index 3a643f6dcc4..552b717cf3e 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
@@ -109,6 +109,7 @@
}
],
"textures": {
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_optical_side",
"side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay_active"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
index b7ee34bd7f4..4c0b091c60a 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
@@ -73,6 +73,7 @@
],
"textures": {
"end": "gtceu:block/pipe/pipe_optical_in",
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_optical_side",
"side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
index 962efa95cf6..ec0d096c1a0 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
@@ -93,6 +93,7 @@
],
"textures": {
"end": "gtceu:block/pipe/pipe_optical_in",
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_optical_side",
"side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay_active"
}
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
index cf2698d2453..73b8cd699db 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
@@ -41,6 +41,7 @@
}
],
"textures": {
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
index 569180a1fba..c6d3c85d4b0 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
@@ -43,6 +43,7 @@
],
"textures": {
"end": "gtceu:block/pipe/pipe_duct_in",
+ "particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
}
}
\ No newline at end of file
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
index 4213be34926..74da42c293b 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
@@ -139,7 +139,8 @@ protected BlockModelBuilder makeActiveElementModel(ResourceLocation name, @Nulla
Reference2FloatMap faceEndpoints = makeFaceEndpointMap(x1, y1, z1, x2, y2, z2);
BlockModelBuilder model = this.provider.models().getBuilder(name.toString())
- .parent(new ModelFile.UncheckedModelFile("block/block"));
+ .parent(new ModelFile.UncheckedModelFile("block/block"))
+ .texture("particle", "#" + (this.side != null ? SIDE_KEY : END_KEY));
ResourceLocation side = this.sideActive != null ? this.sideActive : this.side;
ResourceLocation end = this.endActive != null ? this.endActive : this.end;
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
index 3fa772c5756..68cbe9f0e22 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
@@ -313,7 +313,8 @@ protected BlockModelBuilder makeElementModel(ResourceLocation name, @Nullable Di
Reference2FloatMap faceEndpoints = makeFaceEndpointMap(x1, y1, z1, x2, y2, z2);
BlockModelBuilder model = this.provider.models().getBuilder(name.toString())
- .parent(new ModelFile.UncheckedModelFile("block/block"));
+ .parent(new ModelFile.UncheckedModelFile("block/block"))
+ .texture("particle", "#" + (this.side != null ? SIDE_KEY : END_KEY));
makePartModelElement(model, endFace, false, faceEndpoints, 0.0f, 0, 1,
x1, y1, z1, x2, y2, z2, this.side, this.end, SIDE_KEY, END_KEY);
makePartModelElement(model, endFace, true, faceEndpoints, 0.001f, 0, 1,
From 2fbef83df2b2444ce317ae4bbaa96dc2333cc5cf Mon Sep 17 00:00:00 2001
From: "Nikola J." <72603953+GirixK@users.noreply.github.com>
Date: Tue, 3 Feb 2026 11:33:58 +0100
Subject: [PATCH 19/78] Remove muffler hatch requirement from Large Distillery
(#4195)
Co-authored-by: GirixK
Co-authored-by: Jurre Groenendijk
---
docs/content/Modpacks/Changes/v7.5.0.md | 5 ++++-
.../gregtechceu/gtceu/common/data/machines/GCYMMachines.java | 3 +--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/docs/content/Modpacks/Changes/v7.5.0.md b/docs/content/Modpacks/Changes/v7.5.0.md
index efe36c8eadb..f7adb890ff2 100644
--- a/docs/content/Modpacks/Changes/v7.5.0.md
+++ b/docs/content/Modpacks/Changes/v7.5.0.md
@@ -10,6 +10,9 @@ We have added a second Generic argument to our (Multiblock)MachineBuilder. This
## Machine & Cover Copy/Paste System
A new system for copying machines using the Machine Memory Card has been added, see [this page](../Other-Topics/Cover-Machine-Copy-Paste-Support.md) if you want to add extra copy/paste behaviour to your own machines and covers.
+## Multiblock Structure Change
+The Large Fractionating Still no longer requires a muffler hatch, allowing it to be used in cleanrooms.
+
## RecipeCondition Generics
We have added a Generic argument to `RecipeCondition` describing the condition.
This means that your custom recipe conditions now need to extend `RecipeCondition` (whereas before they just extended `RecipeCondition`).
@@ -71,4 +74,4 @@ you should **NOT** use `PipeModel#dynamicModel()` and instead set the model with
## Lamp Predicates
Previously, lamps were not useable with the terminal in multiblocks. There are new lamp predicates that will help solve this problem.
The predicate to use all lamps is: `Predicates.anyLamp()`
-The predicate to use a specific color is: `Predicates.lampsByColor(DyeColor.DYE_COLOR)`. Where DYE_COLOR is the name of the color you want.
+The predicate to use a specific color is: `Predicates.lampsByColor(DyeColor.DYE_COLOR)`. Where DYE_COLOR is the name of the color you want.
\ No newline at end of file
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
index e793954c8f5..4fffdc064a9 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
@@ -636,7 +636,7 @@ public static void init() {}
.aisle("#YYY#", "YYYYY", "YYYYY", "YYYYY", "#YYY#")
.aisle("#YSY#", "YAAAY", "YAAAY", "YAAAY", "#YYY#")
.aisle("##X##", "#XAX#", "XAPAX", "#XAX#", "##X##").setRepeatable(1, 12)
- .aisle("#####", "#ZZZ#", "#ZCZ#", "#ZZZ#", "#####")
+ .aisle("#####", "#ZZZ#", "#ZZZ#", "#ZZZ#", "#####")
.where('S', controller(blocks(definition.get())))
.where('Y', casingPredicate.or(abilities(IMPORT_ITEMS))
.or(abilities(INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(2))
@@ -646,7 +646,6 @@ public static void init() {}
.where('X', casingPredicate.or(exportPredicate))
.where('Z', casingPredicate)
.where('P', blocks(CASING_STEEL_PIPE.get()))
- .where('C', abilities(MUFFLER))
.where('A', air())
.where('#', any())
.build();
From aaea1cc630e6bb27665d0514351b2dc31ba1d94d Mon Sep 17 00:00:00 2001
From: zetrock1 <144679746+zetrock1@users.noreply.github.com>
Date: Wed, 4 Feb 2026 09:32:09 +0000
Subject: [PATCH 20/78] Trinium spring (#4470)
---
.../gtceu/common/data/materials/ElementMaterials.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/materials/ElementMaterials.java b/src/main/java/com/gregtechceu/gtceu/common/data/materials/ElementMaterials.java
index d006d0cd977..62409787155 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/materials/ElementMaterials.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/materials/ElementMaterials.java
@@ -1026,7 +1026,7 @@ public static void register() {
Trinium = new Material.Builder(GTCEu.id("trinium"))
.ingot(7).fluid()
.color(0x81808a).secondaryColor(0x351d4b).iconSet(SHINY)
- .flags(GENERATE_FOIL, GENERATE_BOLT_SCREW, GENERATE_GEAR)
+ .flags(GENERATE_FOIL, GENERATE_BOLT_SCREW, GENERATE_GEAR, GENERATE_SPRING)
.element(GTElements.Ke)
.cableProperties(V[ZPM], 6, 4)
.blast(b -> b.temp(7200, GasTier.HIGH)
From 1cbd9d60da3cc2a6f50e0f35a7aa9c59aee8f0a9 Mon Sep 17 00:00:00 2001
From: Pyritie
Date: Wed, 4 Feb 2026 09:33:16 +0000
Subject: [PATCH 21/78] Remove apatite bolt and screw, remove rubber bolt,
screw, and gears (#4495)
---
.../gtceu/common/data/materials/OrganicChemistryMaterials.java | 2 +-
.../gtceu/common/data/materials/SecondDegreeMaterials.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/materials/OrganicChemistryMaterials.java b/src/main/java/com/gregtechceu/gtceu/common/data/materials/OrganicChemistryMaterials.java
index 545e3030f6e..b581ac7cf73 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/materials/OrganicChemistryMaterials.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/materials/OrganicChemistryMaterials.java
@@ -509,7 +509,7 @@ public static void register() {
.color(0x353529).secondaryColor(0x080808)
.toolStats(
ToolProperty.Builder.of(1.0F, 1.0F, 256, 1, GTToolType.SOFT_MALLET, GTToolType.PLUNGER).build())
- .flags(GENERATE_GEAR, GENERATE_RING, GENERATE_FOIL, GENERATE_BOLT_SCREW)
+ .flags(GENERATE_RING, GENERATE_FOIL)
.components(Carbon, 5, Hydrogen, 8)
.buildAndRegister();
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/materials/SecondDegreeMaterials.java b/src/main/java/com/gregtechceu/gtceu/common/data/materials/SecondDegreeMaterials.java
index 0bd7ea7c667..4ece776f76b 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/materials/SecondDegreeMaterials.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/materials/SecondDegreeMaterials.java
@@ -107,7 +107,7 @@ public static void register() {
Apatite = new Material.Builder(GTCEu.id("apatite"))
.gem(1).ore(4, 2)
.color(0x06cdf1).secondaryColor(0x701c07).iconSet(DIAMOND)
- .flags(NO_SMASHING, NO_SMELTING, CRYSTALLIZABLE, GENERATE_BOLT_SCREW, DISABLE_DECOMPOSITION)
+ .flags(NO_SMASHING, NO_SMELTING, CRYSTALLIZABLE, DISABLE_DECOMPOSITION)
.components(Calcium, 5, Phosphate, 3, Chlorine, 1)
.buildAndRegister();
From 2f3a6a1bcb2ab9bc0094999a1cd20009582086b6 Mon Sep 17 00:00:00 2001
From: Pyritie
Date: Wed, 4 Feb 2026 09:40:08 +0000
Subject: [PATCH 22/78] Give three alloy smelter glass recipes the right
category (#4497)
---
.../com/gregtechceu/gtceu/data/recipe/misc/CircuitRecipes.java | 2 ++
.../gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java | 1 +
.../gtceu/data/recipe/misc/VanillaStandardRecipes.java | 2 ++
3 files changed, 5 insertions(+)
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CircuitRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CircuitRecipes.java
index ea1ca537eff..36f3b7e7a2e 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CircuitRecipes.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CircuitRecipes.java
@@ -3,6 +3,7 @@
import com.gregtechceu.gtceu.api.data.chemical.material.MarkerMaterials.Color;
import com.gregtechceu.gtceu.api.data.chemical.material.stack.MaterialEntry;
import com.gregtechceu.gtceu.api.machine.multiblock.CleanroomType;
+import com.gregtechceu.gtceu.common.data.GTRecipeCategories;
import com.gregtechceu.gtceu.config.ConfigHolder;
import com.gregtechceu.gtceu.data.recipe.CustomTags;
import com.gregtechceu.gtceu.data.recipe.VanillaRecipeHelper;
@@ -338,6 +339,7 @@ private static void componentRecipes(Consumer provider) {
.inputItems(dust, Glass)
.notConsumable(SHAPE_MOLD_BALL)
.outputItems(GLASS_TUBE)
+ .category(GTRecipeCategories.INGOT_MOLDING)
.duration(160).EUt(16).save(provider);
FLUID_SOLIDFICATION_RECIPES.recipeBuilder("solidify_glass_tube")
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java
index df745a5e92b..38914de3715 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java
@@ -401,6 +401,7 @@ public static void init(Consumer provider) {
.inputItems(dust, Glass, 2)
.notConsumable(SHAPE_MOLD_PLATE)
.outputItems(plate, Glass)
+ .category(GTRecipeCategories.INGOT_MOLDING)
.duration(40).EUt(6).save(provider);
// Dyed Lens Recipes
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/VanillaStandardRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/VanillaStandardRecipes.java
index 7543739d90e..7d996a54f0b 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/VanillaStandardRecipes.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/VanillaStandardRecipes.java
@@ -225,6 +225,7 @@ private static void glassRecipes(Consumer provider) {
.inputItems(dust, Glass)
.notConsumable(SHAPE_MOLD_BOTTLE)
.outputItems(new ItemStack(Items.GLASS_BOTTLE))
+ .category(GTRecipeCategories.INGOT_MOLDING)
.addMaterialInfo(true)
.save(provider);
@@ -250,6 +251,7 @@ private static void glassRecipes(Consumer provider) {
.inputItems(dust, Glass)
.notConsumable(SHAPE_MOLD_BLOCK)
.outputItems(new ItemStack(Blocks.GLASS, 1))
+ .category(GTRecipeCategories.INGOT_MOLDING)
.save(provider);
CUTTER_RECIPES.recipeBuilder("cut_glass_block_to_plate").duration(50).EUt(VA[ULV])
From 2c5fe8ab5d7f14467ecc58419e86d6666125cd26 Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Wed, 4 Feb 2026 23:58:24 +0200
Subject: [PATCH 23/78] Simplify material block models and fix issues they had
with shaders (#4532)
Co-authored-by: Ghostipedia / Caitlynn <46772882+Ghostipedia@users.noreply.github.com>
---
.../material/info/MaterialIconType.java | 1 +
.../gtceu/api/data/tag/TagPrefix.java | 12 ++
.../renderer/block/MaterialBlockRenderer.java | 8 +-
.../renderer/block/OreBlockRenderer.java | 115 ++++++++++++------
.../gtceu/config/ConfigHolder.java | 7 +-
.../mixins/client/LevelRendererMixin.java | 55 ++-------
.../data/pack/GTDynamicResourcePack.java | 4 +-
.../block/material_sets/diamond/ore.json | 51 ++++++++
.../material_sets/diamond/ore_emissive.json | 53 ++++++++
.../block/material_sets/dull/block.json | 28 ++++-
.../block/material_sets/dull/frame_gt.json | 28 ++++-
.../models/block/material_sets/dull/ore.json | 51 ++++++++
.../material_sets/dull/ore_emissive.json | 53 ++++++++
.../block/material_sets/emerald/block.json | 28 ++++-
.../block/material_sets/fine/block.json | 28 ++++-
.../models/block/material_sets/fine/ore.json | 51 ++++++++
.../material_sets/fine/ore_emissive.json | 53 ++++++++
.../models/block/material_sets/flint/ore.json | 51 ++++++++
.../material_sets/flint/ore_emissive.json | 53 ++++++++
.../block/material_sets/lapis/block.json | 28 ++++-
.../models/block/material_sets/lapis/ore.json | 51 ++++++++
.../material_sets/lapis/ore_emissive.json | 53 ++++++++
.../block/material_sets/lignite/block.json | 28 ++++-
.../block/material_sets/lignite/ore.json | 51 ++++++++
.../material_sets/lignite/ore_emissive.json | 53 ++++++++
.../block/material_sets/netherstar/block.json | 28 ++++-
.../block/material_sets/opal/block.json | 28 ++++-
.../models/block/material_sets/paper/ore.json | 51 ++++++++
.../material_sets/paper/ore_emissive.json | 53 ++++++++
.../block/material_sets/powder/ore.json | 51 ++++++++
.../material_sets/powder/ore_emissive.json | 53 ++++++++
.../block/material_sets/quartz/block.json | 28 ++++-
.../block/material_sets/quartz/ore.json | 51 ++++++++
.../material_sets/quartz/ore_emissive.json | 53 ++++++++
.../material_sets/radioactive/block.json | 24 +++-
.../material_sets/radioactive/frame_gt.json | 24 +++-
.../block/material_sets/rough/block.json | 28 ++++-
.../models/block/material_sets/rough/ore.json | 51 ++++++++
.../material_sets/rough/ore_emissive.json | 53 ++++++++
.../block/material_sets/sand/block.json | 28 ++++-
.../block/material_sets/shiny/block.json | 28 ++++-
.../block/material_sets/wood/block.json | 28 ++++-
.../block/material_sets/paper/foil.png | Bin 588 -> 0 bytes
.../paper/{wire.png => wire_side.png} | Bin
44 files changed, 1505 insertions(+), 149 deletions(-)
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/diamond/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/diamond/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/dull/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/dull/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/fine/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/fine/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/flint/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/flint/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/lapis/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/lapis/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/lignite/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/lignite/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/paper/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/paper/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/powder/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/powder/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/quartz/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/quartz/ore_emissive.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/rough/ore.json
create mode 100644 src/main/resources/assets/gtceu/models/block/material_sets/rough/ore_emissive.json
delete mode 100644 src/main/resources/assets/gtceu/textures/block/material_sets/paper/foil.png
rename src/main/resources/assets/gtceu/textures/block/material_sets/paper/{wire.png => wire_side.png} (100%)
diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/info/MaterialIconType.java b/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/info/MaterialIconType.java
index c96add6eaf3..52d57bac337 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/info/MaterialIconType.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/info/MaterialIconType.java
@@ -97,6 +97,7 @@ public record MaterialIconType(String name) {
public static final MaterialIconType molten = new MaterialIconType("molten");
public static final MaterialIconType block = new MaterialIconType("block");
public static final MaterialIconType ore = new MaterialIconType("ore");
+ public static final MaterialIconType oreEmissive = new MaterialIconType("oreEmissive");
public static final MaterialIconType oreSmall = new MaterialIconType("oreSmall");
public static final MaterialIconType frameGt = new MaterialIconType("frameGt");
public static final MaterialIconType wire = new MaterialIconType("wire");
diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/tag/TagPrefix.java b/src/main/java/com/gregtechceu/gtceu/api/data/tag/TagPrefix.java
index 777131be6e6..a518f4a4493 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/data/tag/TagPrefix.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/data/tag/TagPrefix.java
@@ -10,6 +10,7 @@
import com.gregtechceu.gtceu.api.data.chemical.material.Material;
import com.gregtechceu.gtceu.api.data.chemical.material.info.MaterialFlags;
import com.gregtechceu.gtceu.api.data.chemical.material.info.MaterialIconType;
+import com.gregtechceu.gtceu.api.data.chemical.material.properties.OreProperty;
import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey;
import com.gregtechceu.gtceu.api.data.chemical.material.stack.MaterialStack;
import com.gregtechceu.gtceu.api.item.MaterialBlockItem;
@@ -1232,6 +1233,17 @@ public boolean doGenerateBlock(Material material) {
hasItemTable() && this.itemTable.get() != null && getItemFromTable(material) != null;
}
+ public MaterialIconType getMaterialIconType(Material material) {
+ // special case emissive ores
+ if (materialIconType == MaterialIconType.ore && material.hasProperty(PropertyKey.ORE)) {
+ OreProperty oreProp = material.getProperty(PropertyKey.ORE);
+ if (oreProp.isEmissive()) {
+ return MaterialIconType.oreEmissive;
+ }
+ }
+ return materialIconType;
+ }
+
public String getLowerCaseName() {
return FormattingUtil.toLowerCaseUnderscore(this.name);
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/MaterialBlockRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/MaterialBlockRenderer.java
index 193c889179f..f6559abfce2 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/MaterialBlockRenderer.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/MaterialBlockRenderer.java
@@ -15,7 +15,6 @@
public class MaterialBlockRenderer {
- public static final String LAYER_2_SUFFIX = "_layer2";
private static final Set MODELS = new HashSet<>();
public static void create(Block block, MaterialIconType type, MaterialIconSet iconSet) {
@@ -25,12 +24,11 @@ public static void create(Block block, MaterialIconType type, MaterialIconSet ic
public static void reinitModels() {
for (MaterialBlockRenderer model : MODELS) {
ResourceLocation blockId = BuiltInRegistries.BLOCK.getKey(model.block);
- ResourceLocation modelId = blockId.withPrefix("block/");
- GTDynamicResourcePack.addBlockModel(blockId,
- new DelegatedModel(model.type.getBlockModelPath(model.iconSet, true)));
+ ResourceLocation modelId = model.type.getBlockModelPath(model.iconSet, true);
+
GTDynamicResourcePack.addBlockState(blockId, BlockModelGenerators.createSimpleBlock(model.block, modelId));
GTDynamicResourcePack.addItemModel(BuiltInRegistries.ITEM.getKey(model.block.asItem()),
- new DelegatedModel(ModelLocationUtils.getModelLocation(model.block)));
+ new DelegatedModel(modelId));
}
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/OreBlockRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/OreBlockRenderer.java
index fbd6bff6240..8453f93fbce 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/renderer/block/OreBlockRenderer.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/block/OreBlockRenderer.java
@@ -3,10 +3,12 @@
import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.block.MaterialBlock;
import com.gregtechceu.gtceu.api.data.chemical.material.Material;
-import com.gregtechceu.gtceu.api.data.chemical.material.properties.OreProperty;
-import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey;
+import com.gregtechceu.gtceu.api.data.chemical.material.info.MaterialIconSet;
+import com.gregtechceu.gtceu.api.data.chemical.material.info.MaterialIconType;
import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
import com.gregtechceu.gtceu.data.pack.GTDynamicResourcePack;
+import com.gregtechceu.gtceu.utils.memoization.GTMemoizer;
+import com.gregtechceu.gtceu.utils.memoization.function.MemoizedBiFunction;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft;
@@ -14,22 +16,32 @@
import net.minecraft.data.models.BlockModelGenerators;
import net.minecraft.data.models.model.*;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.packs.resources.Resource;
+import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.GsonHelper;
-import com.google.common.base.Preconditions;
import com.google.gson.JsonObject;
+import org.jetbrains.annotations.ApiStatus;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashSet;
+import java.util.Optional;
import java.util.Set;
@MethodsReturnNonnullByDefault
public class OreBlockRenderer {
- private static final Set MODELS = new HashSet<>();
+ protected static final Set MODELS = new HashSet<>();
- private final MaterialBlock block;
+ protected static final JsonObject NULL_ELEMENT_MARKER = new JsonObject();
+ protected static final MemoizedBiFunction TEMPLATE_MODEL_CACHE = GTMemoizer
+ .memoizeFunctionWeakIdent(OreBlockRenderer::loadTemplateOreModel);
+
+ // First format key is material set name, 2nd is stone type prefix's name, 3rd is icon type's name
+ public static final String ORE_MODEL_NAME_FORMAT = "block/material_sets/%s/ores/%s/%s";
+
+ protected final MaterialBlock block;
public static void create(MaterialBlock block) {
MODELS.add(new OreBlockRenderer(block));
@@ -39,56 +51,81 @@ public OreBlockRenderer(MaterialBlock block) {
this.block = block;
}
+ @ApiStatus.Internal
public static void reinitModels() {
+ // first set up all the stone types for all tag prefixes
+ for (MaterialIconSet iconSet : MaterialIconSet.ICON_SETS.values()) {
+ for (var entry : TagPrefix.ORES.entrySet()) {
+ copyOreModelWithBaseStone(entry.getKey(), entry.getValue(), MaterialIconType.ore, iconSet);
+ copyOreModelWithBaseStone(entry.getKey(), entry.getValue(), MaterialIconType.oreEmissive, iconSet);
+ // TODO uncomment if/when small ores are added
+ // copyOreModelWithBaseStone(entry.getKey(), entry.getValue(), MaterialIconType.oreSmall, iconSet);
+ }
+ }
+
+ // then create block state JSONs for all ore blocks with those models
for (OreBlockRenderer model : MODELS) {
+ Material material = model.block.material;
+ TagPrefix tagPrefix = model.block.tagPrefix;
+ MaterialIconSet iconSet = material.getMaterialIconSet();
+ MaterialIconType iconType = tagPrefix.getMaterialIconType(material);
+
ResourceLocation blockId = BuiltInRegistries.BLOCK.getKey(model.block);
- ResourceLocation modelId = blockId.withPrefix("block/");
- OreBlockRenderer.cloneBlockModel(blockId, model.block.tagPrefix, model.block.material);
+ ResourceLocation modelId = GTCEu.id(ORE_MODEL_NAME_FORMAT
+ .formatted(iconSet.name, tagPrefix.name, iconType.name()));
+
GTDynamicResourcePack.addBlockState(blockId, BlockModelGenerators.createSimpleBlock(model.block, modelId));
GTDynamicResourcePack.addItemModel(BuiltInRegistries.ITEM.getKey(model.block.asItem()),
- new DelegatedModel(ModelLocationUtils.getModelLocation(model.block)));
+ new DelegatedModel(modelId));
}
- }
- /**
- * Clones & modifies the base JSON for a single ore block.
- *
- * @param modelId the model id (usually {@code gtceu:block/})
- * @param prefix the TagPrefix of the block being added.
- * @param material the material of the block being added. must have an ore property.
- */
- public static void cloneBlockModel(ResourceLocation modelId, TagPrefix prefix, Material material) {
- OreProperty prop = material.getProperty(PropertyKey.ORE);
- Preconditions.checkNotNull(prop,
- "material %s has no ore property, but needs one for an ore model!".formatted(material.getName()));
+ TEMPLATE_MODEL_CACHE.getCache().clear();
+ }
+ /// This is called for every combination of tag prefix + icon type + icon set
+ protected static void copyOreModelWithBaseStone(TagPrefix tagPrefix, TagPrefix.OreType oreType,
+ MaterialIconType iconType, MaterialIconSet iconSet) {
// read the base ore model JSON
JsonObject original;
- try (BufferedReader reader = Minecraft.getInstance().getResourceManager()
- .openAsReader(GTCEu.id("models/block/ore%s.json".formatted(prop.isEmissive() ? "_emissive" : "")))) {
- original = GsonHelper.parse(reader, true);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ try {
+ original = TEMPLATE_MODEL_CACHE.apply(iconType, iconSet);
+ } catch (RuntimeException e) {
+ GTCEu.LOGGER.error("Could not load template block model for ore type {}, icon type '{}', icon set '{}'",
+ tagPrefix.name, iconType.name(), iconSet.name, e);
+ return;
+ }
+ if (original == NULL_ELEMENT_MARKER) {
+ // if the icon set doesn't have an ore model (somehow...), skip it
+ return;
}
- // clone it
+ // copy it
JsonObject newJson = original.deepCopy();
- JsonObject children = newJson.getAsJsonObject("children");
- // add the base stone texture.
- children.getAsJsonObject("base_stone")
- .addProperty("parent", TagPrefix.ORES.get(prefix).baseModelLocation().toString());
+ // add the base stone model.
+ newJson.getAsJsonObject("children")
+ .getAsJsonObject("base_stone")
+ .addProperty("parent", oreType.baseModelLocation().toString());
- ResourceLocation layer0 = prefix.materialIconType()
- .getBlockTexturePath(material.getMaterialIconSet(), true);
- ResourceLocation layer1 = prefix.materialIconType()
- .getBlockTexturePath(material.getMaterialIconSet(), "layer2", true);
+ GTDynamicResourcePack.addBlockModel(
+ GTCEu.id(ORE_MODEL_NAME_FORMAT.formatted(iconSet.name, tagPrefix.name, iconType.name())), newJson);
+ }
- JsonObject oresTextures = children.getAsJsonObject("ore_texture").getAsJsonObject("textures");
- oresTextures.addProperty("layer0", layer0.toString());
- oresTextures.addProperty("layer1", layer1.toString());
+ private static JsonObject loadTemplateOreModel(MaterialIconType iconType, MaterialIconSet iconSet) {
+ ResourceLocation baseModelPath = iconType.getBlockModelPath(iconSet, true);
+ baseModelPath = GTDynamicResourcePack.MODEL_ID_CONVERTER.idToFile(baseModelPath);
- newJson.getAsJsonObject("textures").addProperty("particle", layer0.toString());
+ ResourceManager resourceManager = Minecraft.getInstance().getResourceManager();
+ Optional modelResource = resourceManager.getResource(baseModelPath);
- GTDynamicResourcePack.addBlockModel(modelId, newJson);
+ if (modelResource.isEmpty()) {
+ // if the icon set doesn't have an ore model (somehow...), skip it gracefully
+ return NULL_ELEMENT_MARKER;
+ }
+ // read & cache the base ore model JSON
+ try (BufferedReader reader = modelResource.get().openAsReader()) {
+ return GsonHelper.parse(reader, true);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java b/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java
index 0956ffa83be..34384172da0 100644
--- a/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java
+++ b/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java
@@ -862,13 +862,18 @@ public static class RendererConfigs {
@Configurable.Comment({ "Render growing plants in multiblocks that support them?", "Default: true" })
public boolean renderGrowingPlants = true;
+ @Configurable
+ @Configurable.Comment({ "Whether or not to color material/ore block highlights in the material color",
+ "Default: true" })
+ public boolean coloredMaterialBlockOutline = true;
+
@Configurable
@Configurable.Comment({ "Whether or not to color tiered machine highlights in the tier color",
"Default: true" })
public boolean coloredTieredMachineOutline = true;
@Configurable
- @Configurable.Comment({ "Whether or not to color wire/cable highlights based on voltage tier",
+ @Configurable.Comment({ "Whether or not to color wire/cable highlights based on voltage tier or material color",
"Default: true" })
public boolean coloredWireOutline = true;
}
diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/client/LevelRendererMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/client/LevelRendererMixin.java
index 06f24b56d02..6176d65c52e 100644
--- a/src/main/java/com/gregtechceu/gtceu/core/mixins/client/LevelRendererMixin.java
+++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/client/LevelRendererMixin.java
@@ -19,7 +19,6 @@
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.*;
-import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.BlockDestructionProgress;
@@ -44,7 +43,6 @@
import com.mojang.blaze3d.vertex.SheetedDecalTextureGenerator;
import com.mojang.blaze3d.vertex.VertexConsumer;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final;
@@ -177,26 +175,25 @@ private static void renderShape(PoseStack poseStack, VertexConsumer consumer, Vo
assert level != null;
var rendererCfg = ConfigHolder.INSTANCE.client.renderer;
int rgb = 0;
- boolean doRenderColoredOutline = false;
+ boolean renderColoredOutline = false;
// spotless:off
- // if it's translucent and a material block, always do the colored outline
- MaterialEntry materialEntry = gtceu$getTranslucentBlockMaterial(state, pos);
- if (!materialEntry.isEmpty()) {
- doRenderColoredOutline = true;
+ MaterialEntry materialEntry = ChemicalHelper.getMaterialEntry(state.getBlock());
+ if (rendererCfg.coloredMaterialBlockOutline && !materialEntry.isEmpty()) {
+ renderColoredOutline = true;
rgb = materialEntry.material().getMaterialRGB();
} else if (level.getBlockEntity(pos) instanceof IMachineBlockEntity mbe) {
if (rendererCfg.coloredTieredMachineOutline) {
if (mbe.getMetaMachine() instanceof SteamMachine steam) {
- doRenderColoredOutline = true;
+ renderColoredOutline = true;
rgb = steam.isHighPressure() ? GTValues.VC_HP_STEAM : GTValues.VC_LP_STEAM;
} else if (mbe.getMetaMachine() instanceof ITieredMachine tiered) {
- doRenderColoredOutline = true;
+ renderColoredOutline = true;
rgb = GTValues.VCM[tiered.getTier()];
}
}
} else if (rendererCfg.coloredWireOutline && level.getBlockEntity(pos) instanceof IPipeNode, ?> pipe) {
- doRenderColoredOutline = true;
+ renderColoredOutline = true;
if (!pipe.getFrameMaterial().isNull()) {
rgb = pipe.getFrameMaterial().getMaterialRGB();
} else if (pipe instanceof CableBlockEntity cable) {
@@ -205,48 +202,18 @@ private static void renderShape(PoseStack poseStack, VertexConsumer consumer, Vo
rgb = materialPipe.material.getMaterialRGB();
}
}
-
- VoxelShape blockShape = state.getShape(level, pos, CollisionContext.of(entity));
// spotless:on
- if (doRenderColoredOutline) {
+ VoxelShape blockShape = state.getShape(level, pos, CollisionContext.of(entity));
+
+ if (renderColoredOutline) {
float red = FastColor.ARGB32.red(rgb) / 255f;
float green = FastColor.ARGB32.green(rgb) / 255f;
float blue = FastColor.ARGB32.blue(rgb) / 255f;
renderShape(poseStack, consumer, blockShape,
pos.getX() - camX, pos.getY() - camY, pos.getZ() - camZ,
- red, green, blue, 1f);
+ red, green, blue, 0.4f);
return;
}
- BlockPos.MutableBlockPos mutable = pos.mutable();
- for (BlockPos o : GTUtil.NON_CORNER_NEIGHBOURS) {
- BlockPos offset = mutable.setWithOffset(pos, o);
- if (!gtceu$getTranslucentBlockMaterial(level.getBlockState(offset), offset).isEmpty()) {
- renderShape(poseStack, consumer, blockShape,
- pos.getX() - camX, pos.getY() - camY, pos.getZ() - camZ,
- 0, 0, 0, 1f);
- return;
- }
- }
original.call(instance, poseStack, consumer, entity, camX, camY, camZ, pos, state);
}
-
- @Unique
- private @NotNull MaterialEntry gtceu$getTranslucentBlockMaterial(BlockState state, BlockPos pos) {
- assert level != null;
- // skip non-solid blocks from other mods (like vanilla ice blocks)
- if (!state.isSolidRender(level, pos) && !(state.getBlock() instanceof MaterialBlock)) {
- return MaterialEntry.NULL_ENTRY;
- }
-
- BakedModel blockModel = minecraft.getBlockRenderer().getBlockModel(state);
- ModelData modelData = level.getModelDataManager().getAt(pos);
- if (modelData == null) modelData = ModelData.EMPTY;
- modelData = blockModel.getModelData(level, pos, state, modelData);
-
- gtceu$modelRandom.setSeed(state.getSeed(pos));
- if (blockModel.getRenderTypes(state, gtceu$modelRandom, modelData).contains(RenderType.translucent())) {
- return ChemicalHelper.getMaterialEntry(state.getBlock());
- }
- return MaterialEntry.NULL_ENTRY;
- }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicResourcePack.java b/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicResourcePack.java
index a33acec7fff..986d7be8744 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicResourcePack.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/pack/GTDynamicResourcePack.java
@@ -56,9 +56,9 @@ public class GTDynamicResourcePack implements PackResources {
protected static final GTDynamicPackContents CONTENTS = new GTDynamicPackContents();
private static final FileToIdConverter ATLAS_ID_CONVERTER = FileToIdConverter.json("atlases");
- private static final FileToIdConverter TEXTURE_ID_CONVERTER = SpriteSource.TEXTURE_ID_CONVERTER;
+ public static final FileToIdConverter TEXTURE_ID_CONVERTER = SpriteSource.TEXTURE_ID_CONVERTER;
public static final FileToIdConverter BLOCKSTATE_ID_CONVERTER = FileToIdConverter.json("blockstates");
- private static final FileToIdConverter MODEL_ID_CONVERTER = FileToIdConverter.json("models");
+ public static final FileToIdConverter MODEL_ID_CONVERTER = FileToIdConverter.json("models");
private final String name;
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/diamond/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/diamond/ore.json
new file mode 100644
index 00000000000..239cf811df9
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/diamond/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/diamond/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/diamond/ore",
+ "layer1": "gtceu:block/material_sets/diamond/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/diamond/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/diamond/ore_emissive.json
new file mode 100644
index 00000000000..530e76750b5
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/diamond/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/diamond/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/diamond/ore_emissive",
+ "layer1": "gtceu:block/material_sets/diamond/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/dull/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/dull/block.json
index f3e2aec258c..9220a964136 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/dull/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/dull/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/dull/block",
- "top_all": "gtceu:block/material_sets/dull/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/dull/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/dull/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/dull/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/dull/frame_gt.json b/src/main/resources/assets/gtceu/models/block/material_sets/dull/frame_gt.json
index 4145d0ceb64..b74dc0fe62f 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/dull/frame_gt.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/dull/frame_gt.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/dull/frame_gt",
- "top_all": "gtceu:block/material_sets/dull/frame_gt_secondary"
- }
+ "particle": "gtceu:block/material_sets/dull/frame_gt"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "cutout",
+ "textures": {
+ "all": "gtceu:block/material_sets/dull/frame_gt"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/dull/frame_gt_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/dull/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/dull/ore.json
new file mode 100644
index 00000000000..87059560e15
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/dull/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/dull/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/dull/ore",
+ "layer1": "gtceu:block/material_sets/dull/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/dull/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/dull/ore_emissive.json
new file mode 100644
index 00000000000..41b0e9971cd
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/dull/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/dull/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/dull/ore_emissive",
+ "layer1": "gtceu:block/material_sets/dull/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/emerald/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/emerald/block.json
index 4c82d064ae1..561f7ff3061 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/emerald/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/emerald/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/emerald/block",
- "top_all": "gtceu:block/material_sets/emerald/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/emerald/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/emerald/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/emerald/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/fine/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/fine/block.json
index f0ea3273608..e67185edb1a 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/fine/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/fine/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/fine/block",
- "top_all": "gtceu:block/material_sets/fine/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/fine/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/fine/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/fine/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/fine/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/fine/ore.json
new file mode 100644
index 00000000000..d1a151c2ed9
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/fine/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/fine/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/fine/ore",
+ "layer1": "gtceu:block/material_sets/fine/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/fine/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/fine/ore_emissive.json
new file mode 100644
index 00000000000..1f3a55ddf91
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/fine/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/fine/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/fine/ore_emissive",
+ "layer1": "gtceu:block/material_sets/fine/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/flint/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/flint/ore.json
new file mode 100644
index 00000000000..db813a630ac
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/flint/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/flint/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/flint/ore",
+ "layer1": "gtceu:block/material_sets/flint/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/flint/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/flint/ore_emissive.json
new file mode 100644
index 00000000000..d1dac37287d
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/flint/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/flint/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/flint/ore_emissive",
+ "layer1": "gtceu:block/material_sets/flint/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/lapis/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/lapis/block.json
index 5470aee534b..c9d66e5f5a7 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/lapis/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/lapis/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/lapis/block",
- "top_all": "gtceu:block/material_sets/lapis/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/lapis/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/lapis/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/lapis/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/lapis/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/lapis/ore.json
new file mode 100644
index 00000000000..df02a9b8199
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/lapis/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/lapis/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/lapis/ore",
+ "layer1": "gtceu:block/material_sets/lapis/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/lapis/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/lapis/ore_emissive.json
new file mode 100644
index 00000000000..bb285c1e3b6
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/lapis/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/lapis/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/lapis/ore_emissive",
+ "layer1": "gtceu:block/material_sets/lapis/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/lignite/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/lignite/block.json
index 4509d7f85d4..e29ae1c608f 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/lignite/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/lignite/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/lignite/block",
- "top_all": "gtceu:block/material_sets/lignite/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/lignite/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/lignite/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/lignite/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/lignite/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/lignite/ore.json
new file mode 100644
index 00000000000..7bff65a2d15
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/lignite/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/lignite/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/lignite/ore",
+ "layer1": "gtceu:block/material_sets/lignite/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/lignite/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/lignite/ore_emissive.json
new file mode 100644
index 00000000000..c37c4c6f90f
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/lignite/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/lignite/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/lignite/ore_emissive",
+ "layer1": "gtceu:block/material_sets/lignite/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/netherstar/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/netherstar/block.json
index 3ec8294e7d3..78c44413ca4 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/netherstar/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/netherstar/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/netherstar/block",
- "top_all": "gtceu:block/material_sets/netherstar/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/netherstar/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/netherstar/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/netherstar/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/opal/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/opal/block.json
index 03c9569efef..c50e7409747 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/opal/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/opal/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/opal/block",
- "top_all": "gtceu:block/material_sets/opal/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/opal/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/opal/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/opal/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/paper/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/paper/ore.json
new file mode 100644
index 00000000000..b49f3ceee85
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/paper/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/paper/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/paper/ore",
+ "layer1": "gtceu:block/material_sets/paper/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/paper/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/paper/ore_emissive.json
new file mode 100644
index 00000000000..d5a86695f64
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/paper/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/paper/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/paper/ore_emissive",
+ "layer1": "gtceu:block/material_sets/paper/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/powder/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/powder/ore.json
new file mode 100644
index 00000000000..f8cbb176f81
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/powder/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/powder/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/powder/ore",
+ "layer1": "gtceu:block/material_sets/powder/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/powder/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/powder/ore_emissive.json
new file mode 100644
index 00000000000..001449aa154
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/powder/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/powder/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/powder/ore_emissive",
+ "layer1": "gtceu:block/material_sets/powder/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/quartz/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/quartz/block.json
index 8c4b0140993..5241a54615e 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/quartz/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/quartz/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/quartz/block",
- "top_all": "gtceu:block/material_sets/quartz/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/quartz/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/quartz/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/quartz/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/quartz/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/quartz/ore.json
new file mode 100644
index 00000000000..228158d1450
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/quartz/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/quartz/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/quartz/ore",
+ "layer1": "gtceu:block/material_sets/quartz/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/quartz/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/quartz/ore_emissive.json
new file mode 100644
index 00000000000..646132f17cd
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/quartz/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/quartz/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/quartz/ore_emissive",
+ "layer1": "gtceu:block/material_sets/quartz/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/radioactive/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/radioactive/block.json
index 5158d10858e..5194e406e48 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/radioactive/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/radioactive/block.json
@@ -1,6 +1,24 @@
{
"parent": "gtceu:block/material_sets/dull/block",
- "textures": {
- "top_all": "gtceu:block/material_sets/radioactive/block_secondary"
- }
+ "loader": "forge:composite",
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/dull/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/radioactive/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/radioactive/frame_gt.json b/src/main/resources/assets/gtceu/models/block/material_sets/radioactive/frame_gt.json
index 03b56173f7f..b3050276fa1 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/radioactive/frame_gt.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/radioactive/frame_gt.json
@@ -1,6 +1,24 @@
{
"parent": "gtceu:block/material_sets/dull/frame_gt",
- "textures": {
- "top_all": "gtceu:block/material_sets/radioactive/frame_gt_secondary"
- }
+ "loader": "forge:composite",
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "cutout",
+ "textures": {
+ "all": "gtceu:block/material_sets/dull/frame_gt"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/radioactive/frame_gt_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/rough/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/rough/block.json
index 52fa4e18cb6..0564fbf8739 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/rough/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/rough/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/rough/block",
- "top_all": "gtceu:block/material_sets/rough/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/rough/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/rough/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/rough/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/rough/ore.json b/src/main/resources/assets/gtceu/models/block/material_sets/rough/ore.json
new file mode 100644
index 00000000000..5f76ff8831f
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/rough/ore.json
@@ -0,0 +1,51 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/rough/ore"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/rough/ore",
+ "layer1": "gtceu:block/material_sets/rough/ore_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": 0 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": 0 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": 0 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": 0 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": 0 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": 0 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": 1 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": 1 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": 1 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": 1 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": 1 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": 1 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/rough/ore_emissive.json b/src/main/resources/assets/gtceu/models/block/material_sets/rough/ore_emissive.json
new file mode 100644
index 00000000000..cfb1d0996a4
--- /dev/null
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/rough/ore_emissive.json
@@ -0,0 +1,53 @@
+{
+ "parent": "block/block",
+ "loader": "forge:composite",
+ "textures": {
+ "particle": "gtceu:block/material_sets/rough/ore_emissive"
+ },
+ "children": {
+ "base_stone": {
+ "render_type": "solid"
+ },
+ "ore_texture": {
+ "parent": "block/block",
+ "textures": {
+ "layer0": "gtceu:block/material_sets/rough/ore_emissive",
+ "layer1": "gtceu:block/material_sets/rough/ore_emissive_layer2",
+ "particle": "#layer0"
+ },
+ "render_type": "translucent",
+ "elements": [
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer0", "cullface": "down", "tintindex": -101 },
+ "up": { "texture": "#layer0", "cullface": "up", "tintindex": -101 },
+ "north": { "texture": "#layer0", "cullface": "north", "tintindex": -101 },
+ "south": { "texture": "#layer0", "cullface": "south", "tintindex": -101 },
+ "west": { "texture": "#layer0", "cullface": "west", "tintindex": -101 },
+ "east": { "texture": "#layer0", "cullface": "east", "tintindex": -101 }
+ }
+ },
+ {
+ "from": [0, 0, 0 ],
+ "to": [16, 16, 16],
+ "forge_data": { "block_light": 15, "sky_light": 15 },
+ "faces": {
+ "down": { "texture": "#layer1", "cullface": "down", "tintindex": -102 },
+ "up": { "texture": "#layer1", "cullface": "up", "tintindex": -102 },
+ "north": { "texture": "#layer1", "cullface": "north", "tintindex": -102 },
+ "south": { "texture": "#layer1", "cullface": "south", "tintindex": -102 },
+ "west": { "texture": "#layer1", "cullface": "west", "tintindex": -102 },
+ "east": { "texture": "#layer1", "cullface": "east", "tintindex": -102 }
+ }
+ }
+ ]
+ }
+ },
+ "item_render_order": [
+ "base_stone",
+ "ore_texture"
+ ]
+}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/sand/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/sand/block.json
index 5c23ce2fa58..99feb35f9bd 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/sand/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/sand/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/sand/block",
- "top_all": "gtceu:block/material_sets/sand/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/sand/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/sand/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/sand/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/shiny/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/shiny/block.json
index c260da6326c..2c9c91c7368 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/shiny/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/shiny/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/shiny/block",
- "top_all": "gtceu:block/material_sets/shiny/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/shiny/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/shiny/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/shiny/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/models/block/material_sets/wood/block.json b/src/main/resources/assets/gtceu/models/block/material_sets/wood/block.json
index 847ff131455..375e29e2abf 100644
--- a/src/main/resources/assets/gtceu/models/block/material_sets/wood/block.json
+++ b/src/main/resources/assets/gtceu/models/block/material_sets/wood/block.json
@@ -1,7 +1,27 @@
{
- "parent": "gtceu:block/cube_2_layer/tinted_both/all_translucent",
+ "parent": "block/block",
+ "loader": "forge:composite",
"textures": {
- "bot_all": "gtceu:block/material_sets/wood/block",
- "top_all": "gtceu:block/material_sets/wood/block_secondary"
- }
+ "particle": "gtceu:block/material_sets/wood/block"
+ },
+ "children": {
+ "base": {
+ "parent": "gtceu:block/cube/tinted/all_0",
+ "render_type": "solid",
+ "textures": {
+ "all": "gtceu:block/material_sets/wood/block"
+ }
+ },
+ "secondary": {
+ "parent": "gtceu:block/cube/tinted/all",
+ "render_type": "translucent",
+ "textures": {
+ "all": "gtceu:block/material_sets/wood/block_secondary"
+ }
+ }
+ },
+ "item_render_order": [
+ "base",
+ "secondary"
+ ]
}
diff --git a/src/main/resources/assets/gtceu/textures/block/material_sets/paper/foil.png b/src/main/resources/assets/gtceu/textures/block/material_sets/paper/foil.png
deleted file mode 100644
index 2f1b92d5cdc310b7575a1028e66b8240e9015def..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 588
zcmV-S0<-;zP)Tt>m0Jj)UVkXst2EKx(b1D!uphsVXr>
zdhdAeQB`uze0_cK`}@n!&(Fe0jFIQ(XH=Dx(z5Tp$2o_YalKvvNGYvO%nT7hy!W)$
zXsw~Ds|)WvW`?SA90xgPRFzq{_x>z?UYKBjecurg#uyyOK`Djn^-8T3GsDanW1K5o
zE*D;2Ue-jDOjW715<(!Q#NFK;tu=b@nAw?M1Q8MTeP65-SZk%VwiE$E2#hfZA+T-R
zxk4$0Qp#fQy;DkAxu;^zc}186&N<}f=7y)IC(LXS&CTar0IIrTdhZD#oCE-$pP#F+
z8DaJ?9jNM>&^bp4;p}1G_eC(Lnit0y%h|r~^xg>}5JEsiD5ab$JU%|sdnf0-8lK>}
z#I|jO5CHzU5HsWZ`+NN;wblimPDF&;+gn8B-(xZ}q_xKT`}>-3o-xK!3n5@;IOkR`
aQ{)c-#ng`#f;WW#0000
Date: Wed, 4 Feb 2026 23:59:22 +0200
Subject: [PATCH 24/78] Fix pipes' block break animation being the wrong shape
(#4543)
---
.../block/pipe/huge_duct_pipe/center.json | 1 +
.../block/pipe/huge_duct_pipe/connection.json | 1 +
.../block/pipe/large_duct_pipe/center.json | 1 +
.../pipe/large_duct_pipe/connection.json | 1 +
.../block/pipe/normal_duct_pipe/center.json | 1 +
.../pipe/normal_duct_pipe/connection.json | 1 +
.../block/pipe/normal_laser_pipe/center.json | 1 +
.../pipe/normal_laser_pipe/center_active.json | 1 +
.../pipe/normal_laser_pipe/connection.json | 1 +
.../normal_laser_pipe/connection_active.json | 1 +
.../pipe/normal_optical_pipe/center.json | 1 +
.../normal_optical_pipe/center_active.json | 1 +
.../pipe/normal_optical_pipe/connection.json | 1 +
.../connection_active.json | 1 +
.../block/pipe/small_duct_pipe/center.json | 1 +
.../pipe/small_duct_pipe/connection.json | 1 +
.../api/blockentity/PipeBlockEntity.java | 4 +-
.../gtceu/api/pipenet/IPipeNode.java | 25 ++++++++++++-
.../gtceu/client/model/GTModelProperties.java | 2 -
.../client/model/pipe/ActivablePipeModel.java | 5 ++-
.../client/model/pipe/BakedPipeModel.java | 37 ++++++++++++-------
.../gtceu/client/model/pipe/PipeModel.java | 6 ++-
22 files changed, 72 insertions(+), 23 deletions(-)
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
index 02a16c80e83..94e63584b2c 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json
@@ -40,6 +40,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
index 2226641a443..e76d23f3a85 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/connection.json
@@ -41,6 +41,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"end": "gtceu:block/pipe/pipe_duct_in",
"particle": "#side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
index a55cb442878..a2321bea230 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json
@@ -40,6 +40,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
index 99be7317456..3cbd0c515e5 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/connection.json
@@ -41,6 +41,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"end": "gtceu:block/pipe/pipe_duct_in",
"particle": "#side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
index 2d0b6ace2aa..1c26580e3bf 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json
@@ -40,6 +40,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
index 0204502f18f..8dd3319f1de 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/connection.json
@@ -41,6 +41,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"end": "gtceu:block/pipe/pipe_duct_in",
"particle": "#side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
index d42a077b7d3..465a616919f 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json
@@ -78,6 +78,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"particle": "#side",
"side": "gtceu:block/pipe/pipe_laser_side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
index 4415d9932a9..d7ad0f481b2 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json
@@ -108,6 +108,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"particle": "#side",
"side": "gtceu:block/pipe/pipe_laser_side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
index ca2bd68f7d2..9e2730a1c5b 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection.json
@@ -71,6 +71,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"end": "gtceu:block/pipe/pipe_laser_in",
"particle": "#side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
index a589a8af80f..f45e0d010d3 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json
@@ -91,6 +91,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"end": "gtceu:block/pipe/pipe_laser_in",
"particle": "#side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
index 7ce8bf8c21a..ff938952e9e 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json
@@ -78,6 +78,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"particle": "#side",
"side": "gtceu:block/pipe/pipe_optical_side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
index 552b717cf3e..ca30b085f41 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json
@@ -108,6 +108,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"particle": "#side",
"side": "gtceu:block/pipe/pipe_optical_side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
index 4c0b091c60a..d01e5420817 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection.json
@@ -71,6 +71,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"end": "gtceu:block/pipe/pipe_optical_in",
"particle": "#side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
index ec0d096c1a0..1f89bf4bc9c 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json
@@ -91,6 +91,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"end": "gtceu:block/pipe/pipe_optical_in",
"particle": "#side",
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
index 73b8cd699db..1033b2f0f73 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json
@@ -40,6 +40,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"particle": "#side",
"side": "gtceu:block/pipe/pipe_duct_side"
diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
index c6d3c85d4b0..c7eb5ea67dc 100644
--- a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
+++ b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/connection.json
@@ -41,6 +41,7 @@
]
}
],
+ "render_type": "minecraft:cutout_mipped",
"textures": {
"end": "gtceu:block/pipe/pipe_duct_in",
"particle": "#side",
diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java
index bc5757ac7b8..471e8ca1f77 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java
@@ -250,8 +250,8 @@ public int getVisualConnections() {
@Override
public void setConnection(Direction side, boolean connected, boolean fromNeighbor) {
- // fix desync between two connections. Can happen if a pipe side is blocked, and a new pipe is placed next to
- // it.
+ // fix desync between two connections.
+ // Can happen if a pipe side is blocked, and a new pipe is placed next to it.
if (!getLevel().isClientSide) {
if (isConnected(side) == connected) {
return;
diff --git a/src/main/java/com/gregtechceu/gtceu/api/pipenet/IPipeNode.java b/src/main/java/com/gregtechceu/gtceu/api/pipenet/IPipeNode.java
index f002edec6e8..83284557af6 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/pipenet/IPipeNode.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/pipenet/IPipeNode.java
@@ -7,6 +7,7 @@
import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity;
import com.gregtechceu.gtceu.api.capability.ICoverable;
import com.gregtechceu.gtceu.api.data.chemical.material.Material;
+import com.gregtechceu.gtceu.client.model.GTModelProperties;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -14,12 +15,16 @@
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraftforge.client.model.data.ModelData;
+import net.minecraftforge.client.model.data.ModelDataManager;
+import net.minecraftforge.common.extensions.IForgeBlockEntity;
+import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface IPipeNode & IPipeType, NodeDataType>
- extends ITickSubscription, IPaintable {
+ extends ITickSubscription, IPaintable, IForgeBlockEntity {
long getOffsetTimer();
@@ -140,12 +145,19 @@ default NodeDataType getNodeData() {
void notifyBlockUpdate();
+ @SuppressWarnings("UnstableApiUsage")
default void scheduleRenderUpdate() {
var pos = getPipePos();
var level = getPipeLevel();
if (level != null) {
var state = level.getBlockState(pos);
if (level.isClientSide) {
+ // simplified from requestModelDataUpdate
+ ModelDataManager manager = level.getModelDataManager();
+ if (manager != null) {
+ manager.requestRefresh(self());
+ }
+
level.sendBlockUpdated(pos, state, state, Block.UPDATE_IMMEDIATE);
} else {
level.blockEvent(pos, state.getBlock(), 1, 0);
@@ -176,4 +188,15 @@ default int getDefaultPaintingColor() {
@NotNull
Material getFrameMaterial();
+
+ @ApiStatus.Internal
+ @Override
+ default @NotNull ModelData getModelData() {
+ return ModelData.builder()
+ .with(GTModelProperties.LEVEL, self().getLevel())
+ .with(GTModelProperties.POS, self().getBlockPos())
+ .with(GTModelProperties.PIPE_CONNECTION_MASK, this.getVisualConnections())
+ .with(GTModelProperties.PIPE_BLOCKED_MASK, this.getBlockedConnections())
+ .build();
+ }
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java b/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java
index 2f58894072b..547af6d647e 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java
@@ -11,6 +11,4 @@ public class GTModelProperties {
public static final ModelProperty PIPE_CONNECTION_MASK = new ModelProperty<>();
public static final ModelProperty PIPE_BLOCKED_MASK = new ModelProperty<>();
-
- public static final ModelProperty PIPE_ACTIVE = new ModelProperty<>();
}
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
index 74da42c293b..46331b3fb90 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java
@@ -58,7 +58,7 @@ public void initModels() {
}
/**
- * Override this to change the actual model {@link #block this.block} will use.
+ * Override this to change the active model {@link #block this.block} will use.
*
* @return A model builder for the block's actual model.
* @see #getOrCreateBlockModel()
@@ -140,7 +140,8 @@ protected BlockModelBuilder makeActiveElementModel(ResourceLocation name, @Nulla
BlockModelBuilder model = this.provider.models().getBuilder(name.toString())
.parent(new ModelFile.UncheckedModelFile("block/block"))
- .texture("particle", "#" + (this.side != null ? SIDE_KEY : END_KEY));
+ .texture("particle", "#" + (this.side != null ? SIDE_KEY : END_KEY))
+ .renderType(RENDERTYPE_CUTOUT_MIPPED);
ResourceLocation side = this.sideActive != null ? this.sideActive : this.side;
ResourceLocation end = this.endActive != null ? this.endActive : this.end;
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java
index cba98fe97b3..3553bd37510 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java
@@ -58,12 +58,16 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction
Integer connectionMask = modelData.get(GTModelProperties.PIPE_CONNECTION_MASK);
Integer blockedMask = modelData.get(GTModelProperties.PIPE_BLOCKED_MASK);
- if (level == null || pos == null || state == null) {
+ if (state == null) {
connectionMask = ITEM_CONNECTIONS;
blockedMask = Node.ALL_CLOSED;
}
if (connectionMask == null || connectionMask != Node.ALL_OPENED) {
- quads.addAll(parts.get(null).getQuads(state, side, rand, modelData, renderType));
+ BakedModel centerModel = parts.get(null);
+ if (renderType == null ||
+ state != null && centerModel.getRenderTypes(state, rand, modelData).contains(renderType)) {
+ quads.addAll(centerModel.getQuads(state, side, rand, modelData, renderType));
+ }
if (connectionMask == null) {
// return unconnected base model if the model property isn't set
return quads;
@@ -71,9 +75,17 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction
}
for (Direction dir : GTUtil.DIRECTIONS) {
if (PipeBlockEntity.isConnected(connectionMask, dir)) {
- quads.addAll(parts.get(dir).getQuads(state, side, rand, modelData, renderType));
+ BakedModel model = parts.get(dir);
+ if (renderType == null ||
+ (state != null && model.getRenderTypes(state, rand, modelData).contains(renderType))) {
+ quads.addAll(model.getQuads(state, side, rand, modelData, renderType));
+ }
if (blockedMask != null && PipeBlockEntity.isFaceBlocked(blockedMask, dir)) {
- quads.addAll(restrictors.get(dir).getQuads(state, side, rand, modelData, renderType));
+ model = restrictors.get(dir);
+ if (renderType == null ||
+ (state != null && model.getRenderTypes(state, rand, modelData).contains(renderType))) {
+ quads.addAll(model.getQuads(state, side, rand, modelData, renderType));
+ }
}
}
}
@@ -83,7 +95,7 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction
ICoverableRenderer.super.renderCovers(quads, pipeNode.getCoverContainer(), pos, level, side, rand,
modelData, renderType);
- if (pipeNode.getFrameMaterial().isNull() || (renderType != null && renderType != RenderType.translucent())) {
+ if (pipeNode.getFrameMaterial().isNull()) {
return quads;
}
var frameBlockEntry = GTMaterialBlocks.MATERIAL_BLOCKS.get(TagPrefix.frameGt, pipeNode.getFrameMaterial());
@@ -123,16 +135,13 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction
@Override
public ModelData getModelData(BlockAndTintGetter level, BlockPos pos, BlockState state, ModelData modelData) {
- ModelData.Builder builder = modelData.derive()
- .with(GTModelProperties.LEVEL, level)
- .with(GTModelProperties.POS, pos);
-
- if (!(level.getBlockEntity(pos) instanceof PipeBlockEntity, ?> blockEntity)) {
- return builder.build();
+ for (BakedModel part : this.parts.values()) {
+ modelData = part.getModelData(level, pos, state, modelData);
+ }
+ for (BakedModel restrictor : this.restrictors.values()) {
+ modelData = restrictor.getModelData(level, pos, state, modelData);
}
- return builder.with(GTModelProperties.PIPE_CONNECTION_MASK, blockEntity.getVisualConnections())
- .with(GTModelProperties.PIPE_BLOCKED_MASK, blockEntity.getBlockedConnections())
- .build();
+ return modelData;
}
@SuppressWarnings("deprecation")
diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
index 68cbe9f0e22..5f440b0214f 100644
--- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
+++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java
@@ -88,6 +88,7 @@ public class PipeModel {
SIDE_OVERLAY_KEY = "side_overlay",
END_OVERLAY_KEY = "end_overlay";
// spotless:on
+ protected static final ResourceLocation RENDERTYPE_CUTOUT_MIPPED = new ResourceLocation("cutout_mipped");
public static final Set DYNAMIC_MODELS = new HashSet<>();
@@ -98,7 +99,7 @@ public static void initDynamicModels() {
}
@Getter
- private final PipeBlock, ?, ?> block;
+ protected final PipeBlock, ?, ?> block;
public final @NotNull ResourceLocation blockId;
protected final GTBlockstateProvider provider;
@@ -314,7 +315,8 @@ protected BlockModelBuilder makeElementModel(ResourceLocation name, @Nullable Di
BlockModelBuilder model = this.provider.models().getBuilder(name.toString())
.parent(new ModelFile.UncheckedModelFile("block/block"))
- .texture("particle", "#" + (this.side != null ? SIDE_KEY : END_KEY));
+ .texture("particle", "#" + (this.side != null ? SIDE_KEY : END_KEY))
+ .renderType(RENDERTYPE_CUTOUT_MIPPED);
makePartModelElement(model, endFace, false, faceEndpoints, 0.0f, 0, 1,
x1, y1, z1, x2, y2, z2, this.side, this.end, SIDE_KEY, END_KEY);
makePartModelElement(model, endFace, true, faceEndpoints, 0.001f, 0, 1,
From 04a829909bea23239f07c8305349a82446db2c77 Mon Sep 17 00:00:00 2001
From: Haze
Date: Wed, 4 Feb 2026 17:00:38 -0500
Subject: [PATCH 25/78] Fixed tooltip order for Large Assembler (#4552)
---
.../gregtechceu/gtceu/common/data/machines/GCYMMachines.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
index 4fffdc064a9..8682cc2e563 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
@@ -283,9 +283,9 @@ public static void init() {}
.multiblock("large_assembler", WorkableElectricMultiblockMachine::new)
.langValue("Large Assembling Factory")
.tooltips(Component.translatable("gtceu.multiblock.parallelizable.tooltip"))
- .tooltips(Component.translatable("gtceu.multiblock.exact_hatch_1.tooltip"))
.tooltips(Component.translatable("gtceu.machine.available_recipe_map_1.tooltip",
Component.translatable("gtceu.assembler")))
+ .tooltips(Component.translatable("gtceu.multiblock.exact_hatch_1.tooltip"))
.conditionalTooltip(GTMachineUtils.defaultEnvironmentRequirement(),
ConfigHolder.INSTANCE.gameplay.environmentalHazards)
.rotationState(RotationState.ALL)
From 83ecd01a8d1d3bd07dea2f95fd25cf1b79993119 Mon Sep 17 00:00:00 2001
From: iouter <62897714+iouter@users.noreply.github.com>
Date: Sat, 7 Feb 2026 06:40:50 +0800
Subject: [PATCH 26/78] Update zh_cn.json (#4516)
---
.../resources/assets/gtceu/lang/zh_cn.json | 81 +++++++++++++++----
1 file changed, 64 insertions(+), 17 deletions(-)
diff --git a/src/main/resources/assets/gtceu/lang/zh_cn.json b/src/main/resources/assets/gtceu/lang/zh_cn.json
index ca9c93f6ff7..057f5ffa80c 100644
--- a/src/main/resources/assets/gtceu/lang/zh_cn.json
+++ b/src/main/resources/assets/gtceu/lang/zh_cn.json
@@ -64,8 +64,16 @@
"behaviour.lighter.tooltip.description": "可以点火",
"behaviour.lighter.tooltip.usage": "潜行右击以开/关",
"behaviour.lighter.uses": "剩余次数:%d",
- "behaviour.meta.machine.config.copy.tooltip": "§7潜行右键单击以复制机器配置",
- "behaviour.meta.machine.config.paste.tooltip": "§7右键单击以粘贴机器配置",
+ "behaviour.memory_card.client_msg.cleared": "已清除存储的配置",
+ "behaviour.memory_card.client_msg.copied": "已复制机器配置",
+ "behaviour.memory_card.client_msg.pasted": "已应用机器配置",
+ "behaviour.memory_card.copy_target": "复制源:%s",
+ "behaviour.memory_card.disabled": "§c已禁用§r",
+ "behaviour.memory_card.enabled": "§a已启用§r",
+ "behaviour.memory_card.tooltip.copy": "§7潜行+右键单击机器或管道复制配置,单击其他方块则会清除数据",
+ "behaviour.memory_card.tooltip.items_to_paste": "应用此配置需要以下物品:",
+ "behaviour.memory_card.tooltip.paste": "§7右键单击以粘贴机器配置",
+ "behaviour.memory_card.tooltip.view_stored": "§8<潜行以查看存储的配置>",
"behaviour.paintspray.black.tooltip": "可以将物品染成黑色",
"behaviour.paintspray.blue.tooltip": "可以将物品染成蓝色",
"behaviour.paintspray.brown.tooltip": "可以将物品染成棕色",
@@ -85,10 +93,15 @@
"behaviour.paintspray.white.tooltip": "可以将物品染成白色",
"behaviour.paintspray.yellow.tooltip": "可以将物品染成黄色",
"behaviour.prospecting": "适用于探矿",
- "behaviour.setting.allow.input.from.output.tooltip": "%s-允许从输出面输入:%s",
- "behaviour.setting.item_auto_output.tooltip": "%s-自动输出:%s",
- "behaviour.setting.muffled.tooltip": "静音:%s",
- "behaviour.setting.output.direction.tooltip": "%s-输出面方向:%s",
+ "behaviour.setting.tooltip.allow_input": "§2允许输入§r",
+ "behaviour.setting.tooltip.auto_output": "§2自动输出§r",
+ "behaviour.setting.tooltip.auto_output_allow_input": "§2自动输出/允许输入§r",
+ "behaviour.setting.tooltip.circuit_config": "编程电路:",
+ "behaviour.setting.tooltip.fluid_io": "流体输出:%s(%s)",
+ "behaviour.setting.tooltip.item_io": "物品输出:%s(%s)",
+ "behaviour.setting.tooltip.muffled": "静音%s",
+ "behaviour.setting.tooltip.pipe_blocked_connections": "管道禁入:%s",
+ "behaviour.setting.tooltip.pipe_connections": "管道连接:%s",
"behaviour.soft_hammer": "用来开启与关闭机器",
"behaviour.soft_hammer.disabled": "已暂停工作",
"behaviour.soft_hammer.disabled_cycle": "本运行周期后暂停工作",
@@ -1731,7 +1744,6 @@
"command.gtceu.share_prospection_data.notification": "%s向你分享了矿脉数据!",
"config.gtceu.option.addLoot": "添加战利品",
"config.gtceu.option.ae2": "ae2",
- "config.gtceu.option.allUniqueStoneTypes": "所有独特石头类型",
"config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "允许桶从输出面输入流体",
"config.gtceu.option.animationTime": "动画时间",
"config.gtceu.option.arcRecyclingYield": "电弧炉回收率",
@@ -1880,6 +1892,7 @@
"config.gtceu.option.steelSteamMultiblocks": "用钢的蒸汽多方块结构",
"config.gtceu.option.surfaceRockProspectRange": "地表岩石探测半径",
"config.gtceu.option.tankItemFluidPreview": "储罐流体预览",
+ "config.gtceu.option.temperaturesInKelvin": "开尔文温度",
"config.gtceu.option.titaniumBoilerHeatSpeed": "钛锅炉-加热速度",
"config.gtceu.option.titaniumBoilerMaxTemperature": "钛锅炉-最高温度",
"config.gtceu.option.toggle": "切换",
@@ -1906,6 +1919,7 @@
"config.gtceu.option.yOffset": "y偏移",
"config.gtceu.option.zombieSpawnWithSabers": "带纳米剑的僵尸生成",
"config.jade.plugin_gtceu.auto_output_info": "[GTCEu] 自动输出信息",
+ "config.jade.plugin_gtceu.battery_info": "[GTCEu] 电池信息",
"config.jade.plugin_gtceu.cable_info": "[GTCEu] 线缆信息",
"config.jade.plugin_gtceu.controllable_provider": "[GTCEu] 是否停工",
"config.jade.plugin_gtceu.data_bank": "[GTCEu] 数据库信息",
@@ -1913,6 +1927,7 @@
"config.jade.plugin_gtceu.energy_converter_provider": "[GTCEu] 能量转换器模式",
"config.jade.plugin_gtceu.exhaust_vent_info": "[GTCEu] 排气口信息",
"config.jade.plugin_gtceu.hazard_cleaner_provider": "[GTCEu] 污染清理",
+ "config.jade.plugin_gtceu.ldp_endpoint": "[GTCEu] 长距离管道接口信息",
"config.jade.plugin_gtceu.machine_mode": "[GTCEu] 机器模式",
"config.jade.plugin_gtceu.maintenance_info": "[GTCEu] 维护信息",
"config.jade.plugin_gtceu.me_pattern_buffer": "[GTCEu] 样板总成信息",
@@ -1961,7 +1976,7 @@
"cover.advanced_fluid_detector.invert.enabled.1": "",
"cover.advanced_fluid_detector.invert.enabled.2": "切换以反转红石逻辑",
"cover.advanced_fluid_detector.invert.enabled.3": "默认情况下,流体量介于所设定的最小值和最大值之间时覆盖板将发出红石信号,小于最小值时则停止发出红石信号",
- "cover.advanced_fluid_detector.label": "进阶流体探测器",
+ "cover.advanced_fluid_detector.label": "进阶流体探测覆盖板",
"cover.advanced_fluid_detector.max": "最大流体量(mB)",
"cover.advanced_fluid_detector.min": "最小流体量(mB)",
"cover.advanced_item_detector.invert.disabled.0": "输出:普通",
@@ -1972,7 +1987,7 @@
"cover.advanced_item_detector.invert.enabled.1": "",
"cover.advanced_item_detector.invert.enabled.2": "切换以反转红石逻辑",
"cover.advanced_item_detector.invert.enabled.3": "默认情况下,物品数量介于所设定的最小值和最大值之间时覆盖板将发出红石信号,小于最小值时则停止发出红石信号",
- "cover.advanced_item_detector.label": "进阶物品探测器",
+ "cover.advanced_item_detector.label": "进阶物品探测覆盖板",
"cover.advanced_item_detector.max": "最大物品数量",
"cover.advanced_item_detector.min": "最小物品数量",
"cover.bucket.mode.bucket": "B",
@@ -2293,8 +2308,10 @@
"gtceu.electrolyzer": "电解机",
"gtceu.electromagnetic_separator": "电磁选矿机",
"gtceu.ender_item_link_cover.title": "末影物品连接",
+ "gtceu.ender_item_link_cover.tooltip": "作§f覆盖板§7时利用§f无线§7§d末影§f连接§7传输§f物品§7。",
"gtceu.ender_redstone_link_cover.label": "红石信号强度:%d",
"gtceu.ender_redstone_link_cover.title": "末影红石连接",
+ "gtceu.ender_redstone_link_cover.tooltip": "作§f覆盖板§7时利用§f无线§7§d末影§f连接§7传输§f红石信号§7。",
"gtceu.extractor": "提取机",
"gtceu.extruder": "压模器",
"gtceu.fermenter": "发酵槽",
@@ -2312,7 +2329,7 @@
"gtceu.fluid.state_gas": "§a状态:气态",
"gtceu.fluid.state_liquid": "§a状态:液态",
"gtceu.fluid.state_plasma": "§a状态:等离子态",
- "gtceu.fluid.temperature": "§c温度:%d",
+ "gtceu.fluid.temperature": "§c温度:%s",
"gtceu.fluid.temperature.cryogenic": "§b低温流体!轻拿轻放!",
"gtceu.fluid.type_acid.tooltip": "§6酸性流体!轻拿轻放!",
"gtceu.fluid_heater": "流体加热器",
@@ -2394,6 +2411,8 @@
"gtceu.gui.content.units.per_second": "/s",
"gtceu.gui.content.units.per_tick": "/t",
"gtceu.gui.cover_setting.title": "覆盖板设置",
+ "gtceu.gui.directional_setting.tab_tooltip": "更改方向设置",
+ "gtceu.gui.directional_setting.title": "方向设置",
"gtceu.gui.editor.group.recipe_type": "封顶",
"gtceu.gui.editor.tips.citation": "引用次数",
"gtceu.gui.fisher_mode.tooltip.0": "捕捉垃圾物品",
@@ -2486,12 +2505,20 @@
"gtceu.item_pipe.priority": "§9优先级:§f%d",
"gtceu.jade.amperage_use": "%s A",
"gtceu.jade.at": " @ ",
+ "gtceu.jade.changes_eu_sec": "%sEU/s",
"gtceu.jade.cleaned_this_second": "污染清理速率:%s/s",
+ "gtceu.jade.days": "%s天",
"gtceu.jade.energy_stored": "%d / %d EU",
"gtceu.jade.fluid_use": "%s mB/t",
+ "gtceu.jade.hours": "%s小时",
+ "gtceu.jade.minutes": "%s分钟",
"gtceu.jade.progress_computation": "%s / %s CWU",
"gtceu.jade.progress_sec": "%s / %s s",
"gtceu.jade.progress_tick": "%s / %s t",
+ "gtceu.jade.remaining_charge_time": "预计充满时间:%s",
+ "gtceu.jade.remaining_discharge_time": "预计耗空时间:%s",
+ "gtceu.jade.seconds": "%s秒",
+ "gtceu.jade.years": "%s年",
"gtceu.jei.bedrock_fluid.heavy_oil_deposit": "重油矿藏",
"gtceu.jei.bedrock_fluid.lava_deposit": "熔岩矿藏",
"gtceu.jei.bedrock_fluid.light_oil_deposit": "轻油矿藏",
@@ -2589,6 +2616,7 @@
"gtceu.key.armor_mode_switch": "切换盔甲模式",
"gtceu.key.enable_boots": "启用跳跃提升",
"gtceu.key.enable_jetpack": "启用喷气背包",
+ "gtceu.key.enable_step_assist": "启用步行辅助",
"gtceu.key.tool_aoe_change": "切换工具范围模式",
"gtceu.large_boiler": "大型锅炉",
"gtceu.large_chemical_reactor": "大型化学反应釜",
@@ -3541,6 +3569,10 @@
"gtceu.placeholder_info.block.0": "返回方块符号‘█’。",
"gtceu.placeholder_info.block.1": "用法:",
"gtceu.placeholder_info.block.2": " {block} -> '█'",
+ "gtceu.placeholder_info.blockNbt.0": "返回方块实体的NBT",
+ "gtceu.placeholder_info.blockNbt.1": "用法:",
+ "gtceu.placeholder_info.blockNbt.2": " {blockNbt} -> 方块实体的全部NBT",
+ "gtceu.placeholder_info.blockNbt.3": " {blockNbt [键1] [键2] ...} -> 部分NBT",
"gtceu.placeholder_info.bufferText.0": "返回ComputerCraft可访问的缓冲区中的文本",
"gtceu.placeholder_info.bufferText.1": "用法:",
"gtceu.placeholder_info.bufferText.2": " {bufferText <行>} -> 缓冲区中指定行的文本(行号为1-100)",
@@ -3852,6 +3884,10 @@
"gtceu.top.fuel_none": "无燃料",
"gtceu.top.invalid_structure": "结构不完整",
"gtceu.top.item_auto_output": "物品输出:%s",
+ "gtceu.top.ldp_endpoint.io_type": "IO类型:%s",
+ "gtceu.top.ldp_endpoint.is_formed": "§a管路已成型§r",
+ "gtceu.top.ldp_endpoint.not_formed": "§c管路未连接§r",
+ "gtceu.top.ldp_endpoint.output_direction": "输出方向:%s",
"gtceu.top.link_cover.color": "颜色:",
"gtceu.top.machine_mode": "机器模式:",
"gtceu.top.maintenance.crowbar": "这东西不属于这儿",
@@ -3943,12 +3979,12 @@
"item.glass_lens": "玻璃透镜(白色)",
"item.gtceu.activity_detector_cover": "活跃探测覆盖板",
"item.gtceu.activity_detector_cover.tooltip": "§7作§f覆盖板§7时依照§f机器活跃状态§7发出红石信号。",
- "item.gtceu.advanced_activity_detector_cover": "进阶活跃状态探测器",
+ "item.gtceu.advanced_activity_detector_cover": "进阶活跃状态探测覆盖板",
"item.gtceu.advanced_activity_detector_cover.tooltip": "§7作§f覆盖板§7时依照§f机器处理进度§7发出红石信号。",
"item.gtceu.advanced_electric_jetpack": "进阶电力喷气背包",
"item.gtceu.advanced_energy_detector_cover": "进阶能量探测覆盖板",
"item.gtceu.advanced_energy_detector_cover.tooltip": "§7作§f覆盖板§7时依照由§fRS锁存器§7控制的§f能量状态§7发出红石信号。",
- "item.gtceu.advanced_fluid_detector_cover": "进阶流体探测器",
+ "item.gtceu.advanced_fluid_detector_cover": "进阶流体探测覆盖板",
"item.gtceu.advanced_fluid_detector_cover.tooltip": "作§f覆盖板§7时依照由§fRS锁存器§7控制的§f流体存储状态§7发出红石信号。",
"item.gtceu.advanced_fluid_voiding_cover": "进阶流体销毁覆盖板",
"item.gtceu.advanced_fluid_voiding_cover.tooltip.0": "§7作§f覆盖板§7时允许按数量销毁§f流体§7。",
@@ -3956,7 +3992,7 @@
"item.gtceu.advanced_integrated_circuit": "进阶集成电路",
"item.gtceu.advanced_integrated_circuit.tooltip.0": "§7更小也更强",
"item.gtceu.advanced_integrated_circuit.tooltip.1": "§6HV级电路",
- "item.gtceu.advanced_item_detector_cover": "进阶物品探测器",
+ "item.gtceu.advanced_item_detector_cover": "进阶物品探测覆盖板",
"item.gtceu.advanced_item_detector_cover.tooltip": "作§f覆盖板§7时依照由§fRS锁存器§7控制的§f物品存储状态§7发出红石信号。",
"item.gtceu.advanced_item_voiding_cover": "进阶物品销毁覆盖板",
"item.gtceu.advanced_item_voiding_cover.tooltip.0": "§7作§f覆盖板§7时销毁物品。",
@@ -4743,7 +4779,7 @@
"item.gtceu.tool.behavior.block_rotation": "§2精械师傅:§f旋转方块",
"item.gtceu.tool.behavior.crop_harvesting": "§a庄稼收割:§f收获成熟的作物",
"item.gtceu.tool.behavior.damage_boost": "§4伤害增益:§f对%s造成额外伤害",
- "item.gtceu.tool.behavior.dowse_campfire": "§F消防战士:§f扑灭营火",
+ "item.gtceu.tool.behavior.dowse_campfire": "§1消防战士:§f扑灭营火",
"item.gtceu.tool.behavior.grass_path": "§e园林策划:§f制造草径",
"item.gtceu.tool.behavior.ground_tilling": "§e耕地农夫:§f耕耘土地",
"item.gtceu.tool.behavior.plunger": "§9水管工人:§f清除流体",
@@ -4781,10 +4817,15 @@
"item.gtceu.tool.hoe": "%s锄",
"item.gtceu.tool.hv_chainsaw": "%s链锯(§6HV§r)",
"item.gtceu.tool.hv_drill": "%s电钻(§6HV§r)",
+ "item.gtceu.tool.hv_screwdriver": "%s螺丝刀(§6HV§r)",
+ "item.gtceu.tool.hv_screwdriver.tooltip": "§8调整覆盖板和机器",
"item.gtceu.tool.hv_wirecutter": "%s剪线钳(HV)",
"item.gtceu.tool.hv_wrench": "%s扳手(§6HV§r)",
"item.gtceu.tool.hv_wrench.tooltip": "§8按住左键以拆卸机器",
+ "item.gtceu.tool.iv_chainsaw": "%s链锯(§9IV§r)",
"item.gtceu.tool.iv_drill": "%s电钻(§9IV§r)",
+ "item.gtceu.tool.iv_screwdriver": "%s螺丝刀(§9IV§r)",
+ "item.gtceu.tool.iv_screwdriver.tooltip": "§8调整覆盖板和机器",
"item.gtceu.tool.iv_wirecutter": "%s剪线钳(IV)",
"item.gtceu.tool.iv_wrench": "%s扳手(§9IV§r)",
"item.gtceu.tool.iv_wrench.tooltip": "§8按住左键以拆卸机器",
@@ -4965,7 +5006,6 @@
"item.gtceu.zpm_voltage_coil.tooltip": "超级线圈",
"item.invalid.name": "无效物品",
"item.netherrack_nether_quartz": "下界石英矿石",
- "item.toggle.advanced.info.tooltip": "§8<按住Shift查阅已存储配置信息>",
"itemGroup.gtceu.decoration": "格雷科技 | 装饰方块",
"itemGroup.gtceu.item": "格雷科技 | 物品",
"itemGroup.gtceu.machine": "格雷科技 | 机器",
@@ -5592,6 +5632,7 @@
"material.gtceu.tritanium": "三钛",
"material.gtceu.tritium": "氚",
"material.gtceu.trona": "天然碱",
+ "material.gtceu.tuff": "凝灰岩",
"material.gtceu.tungstate": "钨酸锂",
"material.gtceu.tungsten": "钨",
"material.gtceu.tungsten_carbide": "碳化钨",
@@ -5658,20 +5699,26 @@
"metaarmor.message.nightvision.disabled": "§b夜视:§c关闭",
"metaarmor.message.nightvision.enabled": "§b夜视:§a开启",
"metaarmor.message.nightvision.error": "§c能量不足!",
- "metaarmor.nms.boosted_jump.disabled": "纳米肌体™套装:跳跃提升已禁用",
- "metaarmor.nms.boosted_jump.enabled": "纳米肌体™套装:跳跃提升已启用",
+ "metaarmor.message.step_assist.disabled": "步行辅助:§c关",
+ "metaarmor.message.step_assist.enabled": "步行辅助:§a开",
"metaarmor.nms.nightvision.disabled": "纳米肌体™套装:夜视已禁用",
"metaarmor.nms.nightvision.enabled": "纳米肌体™套装:夜视已启用",
"metaarmor.nms.nightvision.error": "纳米肌体™套装:§c能量不足!",
"metaarmor.nms.share.disable": "纳米肌体™套装:供能模式已禁用",
"metaarmor.nms.share.enable": "纳米肌体™套装:供能模式已启用",
"metaarmor.nms.share.error": "纳米肌体™套装:§c能量不足,无法供能!",
+ "metaarmor.nms.step_assist.disabled": "纳米肌体™套装:步行辅助已禁用",
+ "metaarmor.nms.step_assist.enabled": "纳米肌体™套装:步行辅助已启用",
+ "metaarmor.qts.boosted_jump.disabled": "夸克高科™套装:跳跃提升已禁用",
+ "metaarmor.qts.boosted_jump.enabled": "夸克高科™套装:跳跃提升已启用",
"metaarmor.qts.nightvision.disabled": "夸克高科™套装:夜视已禁用",
"metaarmor.qts.nightvision.enabled": "夸克高科™套装:夜视已启用",
"metaarmor.qts.nightvision.error": "夸克高科™套装:§c能量不足!",
"metaarmor.qts.share.disable": "夸克高科™套装:供能模式已禁用",
"metaarmor.qts.share.enable": "夸克高科™套装:供能模式已启用",
"metaarmor.qts.share.error": "夸克高科™套装:§c能量不足,无法供能!",
+ "metaarmor.qts.step_assist.disabled": "夸克高科™套装:步行辅助已禁用",
+ "metaarmor.qts.step_assist.enabled": "夸克高科™套装:步行辅助已启用",
"metaarmor.tooltip.autoeat": "使用物品栏中的食物补充饱食度",
"metaarmor.tooltip.breath": "补充氧气条",
"metaarmor.tooltip.burning": "扑灭身上的火焰",
From a380ea35acad398ab23a50f87473b0396f8bdb95 Mon Sep 17 00:00:00 2001
From: Karthi <75553966+JuiceyBeans@users.noreply.github.com>
Date: Sun, 8 Feb 2026 05:45:55 +0000
Subject: [PATCH 27/78] Add recipes for netherite tools (#4368)
---
.../mixins/SmithingTransformRecipeMixin.java | 63 +++++++++++++++++++
.../data/recipe/VanillaRecipeHelper.java | 41 +++++++++++-
.../recipe/generated/ToolRecipeHandler.java | 7 +++
src/main/resources/gtceu.mixins.json | 1 +
4 files changed, 111 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java
diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java
new file mode 100644
index 00000000000..d349dc17cb2
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java
@@ -0,0 +1,63 @@
+package com.gregtechceu.gtceu.core.mixins;
+
+import com.gregtechceu.gtceu.api.item.IGTTool;
+import com.gregtechceu.gtceu.api.item.tool.ToolHelper;
+
+import net.minecraft.core.RegistryAccess;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.Tag;
+import net.minecraft.world.Container;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.crafting.SmithingTransformRecipe;
+
+import com.llamalad7.mixinextras.sugar.Share;
+import com.llamalad7.mixinextras.sugar.ref.LocalRef;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.Redirect;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Mixin(SmithingTransformRecipe.class)
+public class SmithingTransformRecipeMixin {
+
+ @Shadow
+ @Final
+ ItemStack result;
+
+ @Inject(method = "assemble",
+ at = @At(value = "INVOKE",
+ target = "Lnet/minecraft/world/item/ItemStack;setTag(Lnet/minecraft/nbt/CompoundTag;)V"))
+ private void gtceu$gtToolSmithingTransform1(Container container, RegistryAccess registryAccess,
+ CallbackInfoReturnable cir,
+ @Share("newTag") LocalRef sharedTag) {
+ ItemStack output = this.result.copy();
+
+ if (!(output.getItem() instanceof IGTTool igtTool)) return;
+
+ CompoundTag originalTag = container.getItem(1).getTag();
+ CompoundTag newTag = originalTag != null ? originalTag.copy() : null;
+ if (newTag == null) return;
+
+ // Remove old tool stats
+ newTag.remove("GT.Tool");
+
+ // Copy stats from the upgraded tool
+ ItemStack newStack = ToolHelper.get(igtTool.getToolType(), igtTool.getMaterial());
+ Tag newStats = newStack.getTag() != null ? newStack.getTag().get("GT.Tool") : null;
+ if (newStats != null) {
+ newTag.put("GT.Tool", newStats);
+ sharedTag.set(newTag);
+ }
+ }
+
+ @Redirect(method = "assemble",
+ at = @At(value = "INVOKE",
+ target = "Lnet/minecraft/world/item/ItemStack;setTag(Lnet/minecraft/nbt/CompoundTag;)V"))
+ private void gtceu$gtToolSmithingTransform2(ItemStack itemStack, CompoundTag tag,
+ @Share("newTag") LocalRef sharedTag) {
+ itemStack.setTag(sharedTag.get());
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java
index 1cfd3ddac9f..f2035827169 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java
@@ -10,10 +10,13 @@
import com.gregtechceu.gtceu.api.data.chemical.material.stack.MaterialEntry;
import com.gregtechceu.gtceu.api.data.chemical.material.stack.MaterialStack;
import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
+import com.gregtechceu.gtceu.api.item.tool.GTToolType;
import com.gregtechceu.gtceu.api.item.tool.ToolHelper;
import com.gregtechceu.gtceu.data.recipe.builder.*;
import net.minecraft.data.recipes.FinishedRecipe;
+import net.minecraft.data.recipes.RecipeCategory;
+import net.minecraft.data.recipes.SmithingTransformRecipeBuilder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
@@ -22,12 +25,16 @@
import net.minecraft.world.level.ItemLike;
import com.tterrag.registrate.util.entry.ItemProviderEntry;
-import it.unimi.dsi.fastutil.chars.*;
+import it.unimi.dsi.fastutil.chars.Char2IntOpenHashMap;
+import it.unimi.dsi.fastutil.chars.CharArraySet;
+import it.unimi.dsi.fastutil.chars.CharSet;
import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer;
+import static com.tterrag.registrate.providers.RegistrateRecipeProvider.has;
+
public class VanillaRecipeHelper {
public static void addSmeltingRecipe(Consumer provider, @NotNull String regName, TagKey- input,
@@ -618,6 +625,38 @@ public static void addShapelessRecipe(Consumer provider, @NotNul
builder.save(provider);
}
+ public static void addSmithingTransformRecipe(Consumer provider, @NotNull ResourceLocation regName,
+ @NotNull Item result, @NotNull ItemLike baseInput,
+ @NotNull ItemLike template, @NotNull ItemLike addition,
+ @NotNull RecipeCategory category) {
+ SmithingTransformRecipeBuilder
+ .smithing(Ingredient.of(template), Ingredient.of(baseInput), Ingredient.of(addition), category, result)
+ .unlocks(String.format("has_%s", baseInput), has(baseInput))
+ .save(provider, regName);
+ }
+
+ public static void addSmithingTransformRecipe(Consumer provider, @NotNull String regName,
+ @NotNull Item result, @NotNull ItemLike baseInput,
+ @NotNull ItemLike template, @NotNull ItemLike addition) {
+ addSmithingTransformRecipe(provider, GTCEu.id(regName), result, baseInput, template, addition,
+ RecipeCategory.MISC);
+ }
+
+ public static void addToolUpgradingRecipe(@NotNull Consumer provider, @NotNull GTToolType tool,
+ @NotNull Material upgradeMaterial, @NotNull Material baseMaterial,
+ @NotNull ItemLike template, @NotNull ItemLike addition) {
+ ItemStack upgradeToolStack = ToolHelper.get(tool, upgradeMaterial);
+ ItemStack baseToolStack = ToolHelper.get(tool, baseMaterial);
+
+ if (upgradeToolStack.isEmpty() || baseToolStack.isEmpty()) return;
+
+ VanillaRecipeHelper.addSmithingTransformRecipe(provider,
+ String.format("%s_%s_smithing_transform_from_%s", upgradeMaterial.getName(), tool.name,
+ baseMaterial.getName()),
+ upgradeToolStack.getItem(), baseToolStack.getItem(),
+ template, addition);
+ }
+
/**
* @param material the material to check
* @return if the material is a wood
diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java
index 79f2bf28a5a..1b809ec0bd5 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java
@@ -201,6 +201,8 @@ private static void processTool(@NotNull Consumer provider, @Not
GTCEu.LOGGER.warn("Did not find rod for " + material.getName() +
", skipping wirecutter, butchery knife, screwdriver, crowbar recipes");
}
+
+ GTToolType.getTypes().forEach((s, gtToolType) -> addNetheriteToolRecipe(provider, gtToolType));
}
private static void processElectricTool(@NotNull Consumer provider, @NotNull ToolProperty property,
@@ -356,6 +358,11 @@ public static void addToolRecipe(@NotNull Consumer provider, @No
}
}
+ public static void addNetheriteToolRecipe(@NotNull Consumer provider, @NotNull GTToolType tool) {
+ VanillaRecipeHelper.addToolUpgradingRecipe(provider, tool, GTMaterials.Netherite, GTMaterials.Diamond,
+ Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, ChemicalHelper.get(ingot, GTMaterials.Netherite).getItem());
+ }
+
public static void addArmorRecipe(Consumer provider, @NotNull Material material,
@NotNull ArmorItem.Type armor, Object... recipe) {
ItemStack armorStack = ToolHelper.getArmor(armor, material);
diff --git a/src/main/resources/gtceu.mixins.json b/src/main/resources/gtceu.mixins.json
index 3ade6f7cca3..79b50f5d84e 100644
--- a/src/main/resources/gtceu.mixins.json
+++ b/src/main/resources/gtceu.mixins.json
@@ -57,6 +57,7 @@
"ServerGamePacketListenerImplAccessor",
"ShapedRecipeAccessor",
"SidedRedstoneConnectivityMixin",
+ "SmithingTransformRecipeMixin",
"TagLoaderMixin",
"TagManagerMixin",
"TagValueAccessor",
From 53dc2bf6262e933e7b17cb7cc7db44f06c31d973 Mon Sep 17 00:00:00 2001
From: zetrock1 <144679746+zetrock1@users.noreply.github.com>
Date: Sun, 8 Feb 2026 05:53:48 +0000
Subject: [PATCH 28/78] Output bus filtering (#4337)
Co-authored-by: jurrejelle
---
.../multiblock/part/ItemBusPartMachine.java | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java
index 279dd585e38..0038b49e98e 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java
@@ -2,6 +2,9 @@
import com.gregtechceu.gtceu.api.blockentity.IPaintable;
import com.gregtechceu.gtceu.api.capability.recipe.IO;
+import com.gregtechceu.gtceu.api.cover.filter.FilterHandler;
+import com.gregtechceu.gtceu.api.cover.filter.FilterHandlers;
+import com.gregtechceu.gtceu.api.cover.filter.ItemFilter;
import com.gregtechceu.gtceu.api.gui.GuiTextures;
import com.gregtechceu.gtceu.api.gui.fancy.ConfiguratorPanel;
import com.gregtechceu.gtceu.api.gui.widget.SlotWidget;
@@ -78,12 +81,17 @@ public class ItemBusPartMachine extends TieredIOPartMachine
@Persisted
@DescSynced
private boolean isDistinct = false;
+ @Persisted
+ @DescSynced
+ @Getter
+ protected final FilterHandler filterHandler;
public ItemBusPartMachine(IMachineBlockEntity holder, int tier, IO io, Object... args) {
super(holder, tier, io);
this.inventory = createInventory(args);
this.circuitSlotEnabled = true;
this.circuitInventory = createCircuitItemHandler(io).shouldSearchContent(false);
+ filterHandler = FilterHandlers.item(this);
}
//////////////////////////////////////
@@ -99,8 +107,14 @@ protected int getInventorySize() {
return sizeRoot * sizeRoot;
}
+ protected boolean matchesFilter(ItemStack stack) {
+ if (filterHandler.isFilterPresent())
+ return filterHandler.getFilter().test(stack);
+ return true;
+ }
+
protected NotifiableItemStackHandler createInventory(Object... args) {
- return new NotifiableItemStackHandler(this, getInventorySize(), io);
+ return new NotifiableItemStackHandler(this, getInventorySize(), io).setFilter(this::matchesFilter);
}
protected NotifiableItemStackHandler createCircuitItemHandler(Object... args) {
@@ -318,6 +332,7 @@ public Widget createUIWidget() {
var group = new WidgetGroup(0, 0, 18 * rowSize + 16, 18 * colSize + 16);
var container = new WidgetGroup(4, 4, 18 * rowSize + 8, 18 * colSize + 8);
int index = 0;
+ group.addWidget(filterHandler.createFilterSlotUI(-115 + (18 * rowSize) / 2, 35 + 11 * rowSize));
for (int y = 0; y < colSize; y++) {
for (int x = 0; x < rowSize; x++) {
container.addWidget(
@@ -329,7 +344,6 @@ public Widget createUIWidget() {
container.setBackground(GuiTextures.BACKGROUND_INVERSE);
group.addWidget(container);
-
return group;
}
}
From 5c91489f43ebcb46ca97c3a7997e13018340191d Mon Sep 17 00:00:00 2001
From: Tar Laboratories <159147059+TarLaboratories@users.noreply.github.com>
Date: Sun, 8 Feb 2026 08:54:44 +0300
Subject: [PATCH 29/78] Allow rendering other modules from placeholders (#3900)
---
docs/content/Gameplay/Central-Monitor.md | 72 +++++++
.../Modpacks/Other-Topics/Central-Monitor.md | 107 +++++++++++
.../item/component/IMonitorModuleItem.java | 5 +-
.../api/placeholder/GraphicsComponent.java | 60 ++++++
.../api/placeholder/IPlaceholderRenderer.java | 15 ++
.../api/placeholder/MultiLineComponent.java | 56 +++++-
.../api/placeholder/PlaceholderContext.java | 15 +-
.../api/placeholder/PlaceholderHandler.java | 60 ++++--
.../api/placeholder/PlaceholderUtils.java | 4 +
.../gtceu/client/renderer/GTRenderTypes.java | 11 ++
.../machine/impl/CentralMonitorRender.java | 2 +-
.../renderer/monitor/MonitorTextRenderer.java | 26 ++-
.../ModulePlaceholderRenderer.java | 31 +++
.../placeholder/QuadPlaceholderRenderer.java | 35 ++++
.../placeholder/RectPlaceholderRenderer.java | 34 ++++
.../gtceu/common/data/GTPlaceholders.java | 181 ++++++++++++++++--
.../item/modules/ImageModuleBehaviour.java | 2 +-
.../item/modules/TextModuleBehaviour.java | 36 ++--
.../electric/CentralMonitorMachine.java | 2 +-
.../electric/monitor/MonitorGroup.java | 5 +-
.../gtceu/data/lang/LangHandler.java | 21 ++
.../gtceu/syncdata/MonitorGroupPayload.java | 2 +-
22 files changed, 709 insertions(+), 73 deletions(-)
create mode 100644 docs/content/Gameplay/Central-Monitor.md
create mode 100644 docs/content/Modpacks/Other-Topics/Central-Monitor.md
create mode 100644 src/main/java/com/gregtechceu/gtceu/api/placeholder/GraphicsComponent.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/api/placeholder/IPlaceholderRenderer.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/renderer/placeholder/ModulePlaceholderRenderer.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/renderer/placeholder/QuadPlaceholderRenderer.java
create mode 100644 src/main/java/com/gregtechceu/gtceu/client/renderer/placeholder/RectPlaceholderRenderer.java
diff --git a/docs/content/Gameplay/Central-Monitor.md b/docs/content/Gameplay/Central-Monitor.md
new file mode 100644
index 00000000000..037ab83c6e2
--- /dev/null
+++ b/docs/content/Gameplay/Central-Monitor.md
@@ -0,0 +1,72 @@
+---
+title: The Central Monitor & Placeholder System
+---
+
+### The Central Monitor
+
+The Central Monitor is a multiblock that allows you to insert modules into it to render images and text.
+Images update every 120 seconds, text update rate depends on the voltage provided to the multiblock.
+Guide on how to use the central monitor:
+
+1. Right-click the controller
+2. In the UI, you will see a grid of monitors, the controller, energy hatch and (optionally) a data hatch
+3. Select some of the monitors (in any configuration) by left-clicking on them
+4. Click the "Create group" button
+5. You should see a group appear on the left of the UI, click on it to select all monitors in that group, click again to unselect
+6. Click on the gear icon next to the name of the group you want to edit
+7. A UI with a single slot should open, put a module into that slot (while it is possible to put a stack of modules in, that does literally nothing)
+8. If it's a text/image module a new field should appear, where you can enter some text (for image it'll be a single line for a URL)
+9. Once you've entered your text, click on the green checkmark below the slot, that will save the text you entered
+10. Click on the gear icon next to the group you're editing to go back to the main menu
+11. You should see the text/image on the Central Monitor
+
+To remove a group, select it and click "Remove from group". To remove a single monitor from a group select only it and click "Remove from group".
+You cannot add monitors to a group after it has been created. Image dimensions are determined by the left-up corner of the group and the right-down corner,
+the blocks between them have to be in the same group. The text module will only display text on monitors of its group.
+
+!!! warning "The image module is a bit buggy, so the image may not appear immediately"
+
+### Text Module
+
+You may have noticed that the text module has a number input in its UI. It is the text scale, where 1 represents a line height of 1/16th of a block.
+You may have also noticed that the text module has some additional slots on the left.
+Those are referenced by placeholders, you can put any item in them. Most placeholders also need a target block to work. To select a target for your monitor group,
+in the main UI of the controller select the group, right-click the block you want to target and click "Set target". You may want to target a block that is not in the
+central monitor, to do that you have to use a Wireless Transmitter Cover. Place it on the block you want to target and right-click it with a data stick. Then put that
+data stick into a data hatch in the Central Monitor multiblock. If you select the data hatch as a target, you will see a new number field appear. Enter the number of the
+slot your data stick is in and click "Set target". The target will be set to the block the Wireless Transmitter Cover is on. It can work cross-dimensionally.
+
+!!! note "For the Computer Monitor Cover, the targeted block is always the block it's placed on."
+
+### Placeholders
+Placeholders can be used by players in the monitor text module, or in the computer monitor cover (though a bit more limited).
+For example, a player may write something like this in a text module:
+```
+Hello on day {calc {tick} / 20000}!
+Current energy buffer: {formatInt {energy}}/{formatInt {energyCapacity}} EU\
+{if {cmp {energy} < 5000000} {color red "\nLOW ENERGY!"}}
+Here's some random stuff:
+{repeat 5 {repeat {random 2 10} {block}}
+```
+And something like this would be displayed:
+```
+Hello on day 420!
+Current energy buffer: 4.2M/6.9M EU
+LOW ENERGY!
+Here's some random stuff:
+███████
+██
+█████
+████
+██████████
+```
+This system is turing-complete (i.e. if the player really wanted to play Doom on the Central Monitor, they could).
+All placeholders work on strings (or, more specifically, `Component`s to allow text formatting), so when you write `{calc {calc 2 + 4} * 3}`,
+first `{calc 2 + 4}` will be evaluated into `6`, then it will be converted to a string and back to an int, and then it will be passed into the second placeholder
+to evaluate `{calc 6 * 3}` into `18`, which will be turned into a string again. That also allows for things like `{calc 3 + 1}2`, which will evaluate into `42`,
+since outside of placeholders text is simply concatenated. Placeholder arguments are separated by spaces, which may be a bit annoying, when wanting to pass a string
+with a space into a placeholder, for example `{if 1 string with spaces}`, which will cause an error. In these cases, double quotes can be used: `{if 1 "string with spaces"}`
+will work perfectly fine. There are placeholders that need reference items, to achieve that, there are 8 slots in the text module's UI on the left.
+Items can be inserted/extracted from these slots automatically using the `ender` placeholder by interacting with Ender Item Links.
+
+!!! tip "The full list of placeholders with explanations on what they do and usage examples can be found in-game in the text module or computer monitor UI on the left."
\ No newline at end of file
diff --git a/docs/content/Modpacks/Other-Topics/Central-Monitor.md b/docs/content/Modpacks/Other-Topics/Central-Monitor.md
new file mode 100644
index 00000000000..c199ae1790d
--- /dev/null
+++ b/docs/content/Modpacks/Other-Topics/Central-Monitor.md
@@ -0,0 +1,107 @@
+---
+title: Central Monitor & Placeholder System
+---
+
+### Custom monitor modules
+If you want to add a monitor module, simply attach a component that implements `IMonitorModuleItem` to your `ComponentItem`.
+Modules can have a custom UI, can be ticked (in a placeholder or not) and, most importantly, rendered.
+??? example "Example of a custom module in Java"
+ ```java
+ public class ExampleModuleBehaviour implements IMonitorModuleItem {
+ @Override
+ public String getType() {
+ // can be any string, this is currently only used for CC: Tweaked compat
+ return "example";
+ }
+
+ @Override
+ public void tick(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) {
+ // this is only called on the logical server
+ // put all of your module's logic here instead of in getRenderer(stack)
+ // can also be left completely empty (like in the image module)
+ }
+
+ @Override
+ public void tickInPlaceholder(ItemStack stack, PlaceholderContext context) {
+ // this is also only called on the logical server, but only when a placeholder accesses this module and wants to render it
+ // this *isn't* called on each tick
+ // you can even put the same code here as in the tick() method, like the text module does
+ }
+
+ @Override
+ public IMonitorRenderer getRenderer(ItemStack stack) {
+ // this is only called on the logical client
+ // should return a new instance of the renderer for this module (not null)
+ // for examples of renderer code look in the GTCEu Modern github:
+ // https://github.com/GregTechCEu/GregTech-Modern/tree/1.20.1/src/main/java/com/gregtechceu/gtceu/client/renderer
+ return new MonitorTextRenderer(MultiLineComponent.of("this text is displayed on the monitor"), 1.0);
+ }
+
+ @Override
+ public Widget createUIWidget(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) {
+ // should create the UI for your module and return it
+ // if the module doesn't need a UI just return new WidgetGroup()
+ return new WidgetGroup();
+ }
+ }
+ ```
+
+!!! info "For info on the placeholder system itself, see [the gameplay wiki page](../../Gameplay/Central-Monitor.md)"
+
+### Adding custom placeholders
+
+Placeholders can be added by calling `PlaceholderHandler.addPlaceholder(...)` at any point during runtime (preferably at mod init time).
+They can take any number of arguments in the form of a `List`. They also take an instance of `PlaceholderContext` and
+must return a `MultiLineComponent`. Placeholders can also render literally anything, not only text, using `MultiLineComponent.addRenderer()`,
+`GraphicsComponent` and an `IPlaceholderRenderer` (that has to be registered separately using `PlaceholderHandler.addRenderer(...)`)
+
+??? example "Example of a `sum` placeholder in Java"
+ ```java
+ public class Example {
+ // you should call this function at mod initialization
+ public static void addPlaceholders() {
+ int priority = 1; // by default the priority of all placeholders is 0 (you don't have to specify it)
+ PlaceholderHandler.addPlaceholder(new Placeholder("sum", priority) {
+ @Override
+ public MultiLineComponent apply(PlaceholderContext ctx, List args) throws PlaceholderException {
+ PlaceholderUtils.checkArgs(args, 2); // check that there are exactly 2 arguments
+ double a = PlaceholderUtils.toDouble(args.get(0));
+ double b = PlaceholderUtils.toDouble(args.get(1));
+ return MultiLineComponent.literal(a + b);
+ }
+ });
+ // you can call addPlaceholder as many times as you need
+ // if you want to override an existing placeholder, simply add a new one with the same name and a higher or equal priority
+ }
+ }
+ ```
+
+!!! tip "Placeholder exceptions"
+ Any runtime exception that occurs while processing a placeholder will be caught and even displayed to the player.
+ Instead of relying on runtime exceptions though, you should throw any subclass of `PlaceholderException`, for example
+ `InvalidNumberException` or `MissingItemException`. All the `PlaceholderUtils` methods throw these, so you should use them
+ instead of calling `parseDouble` yourself, for example.
+
+!!! note "Placeholder data"
+ If your placeholder needs to save any data specific to the placeholder caller, you can use `getData(ctx)` at any point in
+ a placeholder. It will return a `CompoundTag` that is automatically saved, and you're free to modify it in whatever way you want.
+
+### Placeholder graphics
+
+You may have noticed, that some placeholders output graphics instead of text, for example `rect` or `quad`.
+To achieve that you have to write your own class that implements `IPlaceholderRenderer`, or use an existing one.
+They work similarly to normal renderers, except you can pass a `CompoundTag` into them from your placeholder.
+To register one, call `PlaceholderHandler.addRenderer("put_id_here", new YourRendererClassHere())`.
+After that, you can reference it from any placeholder by calling `output.addGraphics(new GraphicsComponent(x, y, "put_id_here", renderData)`
+on the object that your placeholder will return. `renderData` is the same `CompoundTag` that will be passed into your renderer as an argument.
+This is done to avoid calling rendering code on the server side, as all placeholders are processed server-side only. A neat side effect of that
+is that all players will (almost always) see the same thing on the monitor.
+
+!!! warning "Graphics do not work on the Computer Monitor Cover"
+
+### Placeholder parsing
+
+You may want to add something that needs to parse a string containing placeholders. To achieve that, you can use
+`PlaceholderHandler.processPlaceholders(string, context)`. You can also use `PlaceholderHandler.placeholderExists(name)`
+to check if a placeholder exists, or `PlaceholderHandler.getAllPlaceholderNames()` to get all placeholders.
+To get a `PlaceholderContext`, you just have to call its constructor (it takes in basic parameters like `Level`, `BlockPos`, etc., most of which can be `null`).
\ No newline at end of file
diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/component/IMonitorModuleItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/component/IMonitorModuleItem.java
index 6bfa55da341..91a12e74343 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/item/component/IMonitorModuleItem.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/item/component/IMonitorModuleItem.java
@@ -1,5 +1,6 @@
package com.gregtechceu.gtceu.api.item.component;
+import com.gregtechceu.gtceu.api.placeholder.PlaceholderContext;
import com.gregtechceu.gtceu.client.renderer.monitor.IMonitorRenderer;
import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine;
import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup;
@@ -12,7 +13,9 @@ public interface IMonitorModuleItem extends IItemComponent {
default void tick(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) {}
- IMonitorRenderer getRenderer(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group);
+ default void tickInPlaceholder(ItemStack stack, PlaceholderContext context) {}
+
+ IMonitorRenderer getRenderer(ItemStack stack);
Widget createUIWidget(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group);
diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/GraphicsComponent.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/GraphicsComponent.java
new file mode 100644
index 00000000000..650f2645202
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/GraphicsComponent.java
@@ -0,0 +1,60 @@
+package com.gregtechceu.gtceu.api.placeholder;
+
+import com.gregtechceu.gtceu.GTCEu;
+import com.gregtechceu.gtceu.client.renderer.monitor.IMonitorRenderer;
+import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine;
+import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup;
+
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.NbtOps;
+import net.minecraft.nbt.Tag;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+
+import java.util.function.Supplier;
+
+public record GraphicsComponent(float x, float y, float x2, float y2, String rendererId, CompoundTag renderData)
+ implements Supplier {
+
+ public GraphicsComponent(double x, double y, double x2, double y2, String rendererId, CompoundTag renderData) {
+ this((float) x, (float) y, (float) x2, (float) y2, rendererId, renderData);
+ }
+
+ public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group(
+ Codec.FLOAT.fieldOf("x").forGetter(GraphicsComponent::x),
+ Codec.FLOAT.fieldOf("y").forGetter(GraphicsComponent::y),
+ Codec.FLOAT.fieldOf("x2").forGetter(GraphicsComponent::x2),
+ Codec.FLOAT.fieldOf("y2").forGetter(GraphicsComponent::y2),
+ Codec.STRING.fieldOf("rendererId").forGetter(GraphicsComponent::rendererId),
+ CompoundTag.CODEC.fieldOf("renderData").forGetter(GraphicsComponent::renderData))
+ .apply(instance, GraphicsComponent::new));
+
+ @Override
+ public IMonitorRenderer get() {
+ return new IMonitorRenderer() {
+
+ private final IMonitorRenderer renderer = PlaceholderHandler.getRenderer(rendererId, renderData);
+
+ @Override
+ public void render(CentralMonitorMachine machine, MonitorGroup group, float partialTick,
+ PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) {
+ poseStack.pushPose();
+ poseStack.translate(x, y, 0);
+ assert this.renderer != null;
+ this.renderer.render(machine, group, partialTick, poseStack, buffer, packedLight, packedOverlay);
+ poseStack.popPose();
+ }
+ };
+ }
+
+ public Tag toTag() {
+ return CODEC.encodeStart(NbtOps.INSTANCE, this).getOrThrow(false, GTCEu.LOGGER::error);
+ }
+
+ public static GraphicsComponent fromTag(Tag tag) {
+ return CODEC.decode(NbtOps.INSTANCE, tag).getOrThrow(false, GTCEu.LOGGER::error).getFirst();
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/IPlaceholderRenderer.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/IPlaceholderRenderer.java
new file mode 100644
index 00000000000..5d55415ee85
--- /dev/null
+++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/IPlaceholderRenderer.java
@@ -0,0 +1,15 @@
+package com.gregtechceu.gtceu.api.placeholder;
+
+import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine;
+import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup;
+
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.nbt.CompoundTag;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+
+public interface IPlaceholderRenderer {
+
+ void render(CentralMonitorMachine machine, MonitorGroup group, float partialTick, PoseStack poseStack,
+ MultiBufferSource buffer, int packedLight, int packedOverlay, CompoundTag tag);
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java
index 0889644579b..ac19946fe1b 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java
@@ -3,23 +3,32 @@
import com.gregtechceu.gtceu.utils.GTUtil;
import net.minecraft.ChatFormatting;
+import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.*;
import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Objects;
+@Accessors(chain = true)
public class MultiLineComponent extends ArrayList {
@Getter
+ @Setter
private boolean ignoreSpaces = false;
+ @Getter
+ private final List graphics = new ArrayList<>();
+
public MultiLineComponent(List components) {
super();
this.addAll(components);
@@ -79,7 +88,10 @@ public double toDouble() {
public int toInt() {
if (this.isEmpty()) return 0;
if (this.size() > 1) throw new NumberFormatException(this.toString());
- return Integer.parseInt(this.get(0).getString());
+ String s = this.get(0).getString();
+ if (s.startsWith("0x")) return Integer.parseInt(s.substring(2), 16);
+ if (s.startsWith("0b")) return Integer.parseInt(s.substring(2), 2);
+ return Integer.parseInt(s);
}
public void append(@Nullable String s) {
@@ -102,6 +114,12 @@ public MultiLineComponent append(@Nullable List extends Component> lines) {
return this;
}
+ public MultiLineComponent append(MultiLineComponent multiLineComponent) {
+ if (multiLineComponent == null) return this;
+ this.graphics.addAll(multiLineComponent.getGraphics());
+ return this.append(multiLineComponent.toImmutable());
+ }
+
public void appendNewline() {
this.add(MutableComponent.create(ComponentContents.EMPTY));
}
@@ -131,18 +149,33 @@ public List toImmutable() {
}
public Tag toTag() {
+ CompoundTag compoundTag = new CompoundTag();
ListTag tag = new ListTag();
for (MutableComponent component : this) {
tag.add(StringTag.valueOf(Component.Serializer.toJson(component)));
}
- return tag;
+ compoundTag.put("text", tag);
+ ListTag graphicsTag = new ListTag();
+ for (GraphicsComponent component : this.getGraphics()) {
+ graphicsTag.add(component.toTag());
+ }
+ compoundTag.put("graphics", graphicsTag);
+ return compoundTag;
}
- public static MultiLineComponent fromTag(ListTag tag) {
+ public static MultiLineComponent fromTag(@Nullable Tag tag) {
MultiLineComponent out = MultiLineComponent.empty();
out.clear();
- for (Tag i : tag) {
- out.add(Component.Serializer.fromJson(i.getAsString()));
+ if (tag == null) return out;
+ if (tag instanceof ListTag listTag) {
+ for (Tag i : listTag) {
+ out.add(Component.Serializer.fromJson(i.getAsString()));
+ }
+ } else if (tag instanceof CompoundTag compoundTag) {
+ ListTag textTag = compoundTag.getList("text", Tag.TAG_STRING);
+ for (Tag i : textTag) out.add(Component.Serializer.fromJson(i.getAsString()));
+ ListTag graphicsTag = compoundTag.getList("graphics", Tag.TAG_COMPOUND);
+ for (Tag i : graphicsTag) out.addGraphics(GraphicsComponent.fromTag(i));
}
return out;
}
@@ -150,11 +183,18 @@ public static MultiLineComponent fromTag(ListTag tag) {
public long toLong() {
if (this.isEmpty()) return 0;
if (this.size() > 1) throw new NumberFormatException(this.toString());
- return Long.parseLong(this.get(0).getString());
+ String s = this.get(0).getString();
+ if (s.startsWith("0b")) return Long.parseLong(s.substring(2), 2);
+ if (s.startsWith("0x")) return Long.parseLong(s.substring(2), 16);
+ return Long.parseLong(s);
+ }
+
+ public MultiLineComponent addGraphics(GraphicsComponent... graphicsComponents) {
+ return this.addGraphics(List.of(graphicsComponents));
}
- public MultiLineComponent setIgnoreSpaces(boolean ignoreSpaces) {
- this.ignoreSpaces = ignoreSpaces;
+ public MultiLineComponent addGraphics(Collection graphicsComponents) {
+ this.graphics.addAll(graphicsComponents);
return this;
}
}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderContext.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderContext.java
index 9e55e356f85..223692a7b6d 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderContext.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderContext.java
@@ -7,6 +7,7 @@
import net.minecraft.world.level.Level;
import net.minecraftforge.items.ItemStackHandler;
+import lombok.With;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
@@ -17,4 +18,16 @@ public record PlaceholderContext(Level level,
@Nullable ItemStackHandler itemStackHandler,
@Nullable CoverBehavior cover,
@Nullable MultiLineComponent previousText,
- UUID uuid) {}
+ UUID uuid,
+ @With int index) {
+
+ public PlaceholderContext(Level level,
+ BlockPos pos,
+ Direction side,
+ @Nullable ItemStackHandler itemStackHandler,
+ @Nullable CoverBehavior cover,
+ @Nullable MultiLineComponent previousText,
+ UUID uuid) {
+ this(level, pos, side, itemStackHandler, cover, previousText, uuid, 0);
+ }
+}
diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java
index 86edbd0bd77..00a80df2825 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java
@@ -5,6 +5,7 @@
import com.gregtechceu.gtceu.api.placeholder.exceptions.UnclosedBracketException;
import com.gregtechceu.gtceu.api.placeholder.exceptions.UnexpectedBracketException;
import com.gregtechceu.gtceu.api.placeholder.exceptions.UnknownPlaceholderException;
+import com.gregtechceu.gtceu.client.renderer.monitor.IMonitorRenderer;
import com.gregtechceu.gtceu.data.lang.LangHandler;
import com.gregtechceu.gtceu.utils.GTStringUtils;
import com.gregtechceu.gtceu.utils.GTUtil;
@@ -14,16 +15,20 @@
import com.lowdragmc.lowdraglib.gui.widget.TextTextureWidget;
import com.lowdragmc.lowdraglib.gui.widget.Widget;
import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup;
-import com.lowdragmc.lowdraglib.gui.widget.codeeditor.language.LanguageDefinition;
-import com.lowdragmc.lowdraglib.gui.widget.codeeditor.language.TokenTypes;
import net.minecraft.ChatFormatting;
import net.minecraft.MethodsReturnNonnullByDefault;
+import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.MutableComponent;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.util.*;
import java.util.function.Consumer;
+import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
@ParametersAreNonnullByDefault
@@ -40,18 +45,11 @@ public class PlaceholderHandler {
private static final Map placeholders = new HashMap<>();
- public static final LanguageDefinition LANG_DEFINITION = new LanguageDefinition(
- "Placeholders",
- List.of(
- TokenTypes.KEYWORD.createTokenType(PlaceholderHandler.getAllPlaceholderNames().stream().toList()),
- TokenTypes.IDENTIFIER,
- TokenTypes.STRING,
- TokenTypes.COMMENT,
- TokenTypes.NUMBER,
- TokenTypes.OPERATOR,
- TokenTypes.WHITESPACE,
- TokenTypes.OTHER),
- Set.of());
+ @OnlyIn(Dist.CLIENT)
+ private static final class RendererHolder {
+
+ public static final Map renderers = new HashMap<>();
+ }
public static void addPlaceholder(Placeholder placeholder) {
if (placeholders.containsKey(placeholder.getName())) {
@@ -65,11 +63,35 @@ public static boolean placeholderExists(MultiLineComponent placeholder) {
return placeholders.containsKey(placeholder.toString());
}
+ @OnlyIn(Dist.CLIENT)
+ public static void addRenderer(String id, IPlaceholderRenderer renderer) {
+ RendererHolder.renderers.put(id, renderer);
+ }
+
+ @OnlyIn(Dist.CLIENT)
+ public static @Nullable IMonitorRenderer getRenderer(String id, CompoundTag renderData) {
+ if (!RendererHolder.renderers.containsKey(id)) {
+ GTCEu.LOGGER.warn("Attempt to access a placeholder renderer that doesn't exist ({})", id);
+ return null;
+ }
+ IPlaceholderRenderer renderer = RendererHolder.renderers.get(id);
+ CompoundTag tag = renderData.copy();
+ return (machine, group,
+ partialTick, poseStack, buffer,
+ packedLight, packedOverlay) -> renderer.render(
+ machine, group,
+ partialTick, poseStack, buffer,
+ packedLight, packedOverlay, tag);
+ }
+
public static MultiLineComponent processPlaceholder(List placeholder,
- PlaceholderContext context) throws PlaceholderException {
+ PlaceholderContext context,
+ Object2IntOpenHashMap