From 3ddaffa70555504912c9845585c5ba6db5686918 Mon Sep 17 00:00:00 2001 From: Bruno Ploumhans <13494793+Technici4n@users.noreply.github.com> Date: Tue, 26 Nov 2024 13:40:16 +0100 Subject: [PATCH 01/27] Use the same userdev config for userdev and neodev (#1698) --- .../neoforged/neodev/CreateUserDevConfig.java | 16 +++----- .../neoforged/neodev/NeoDevExtraPlugin.java | 10 +++-- .../net/neoforged/neodev/NeoDevPlugin.java | 39 +++++++------------ gradle.properties | 2 +- 4 files changed, 27 insertions(+), 40 deletions(-) diff --git a/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java b/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java index ab24c91d4d..aa61592371 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java @@ -29,12 +29,6 @@ abstract class CreateUserDevConfig extends DefaultTask { @Inject public CreateUserDevConfig() {} - /** - * Toggles the launch type written to the userdev configuration between *dev and *userdev. - */ - @Input - abstract Property getForNeoDev(); - @Input abstract Property getFmlVersion(); @@ -85,11 +79,11 @@ public void writeUserDevConfig() throws IOException { for (var runType : RunType.values()) { var launchTarget = switch (runType) { - case CLIENT -> "forgeclient"; - case DATA -> "forgedata"; - case GAME_TEST_SERVER, SERVER -> "forgeserver"; - case JUNIT -> "forgejunit"; - } + (getForNeoDev().get() ? "dev" : "userdev"); + case CLIENT -> "forgeclientdev"; + case DATA -> "forgedatadev"; + case GAME_TEST_SERVER, SERVER -> "forgeserverdev"; + case JUNIT -> "forgejunitdev"; + }; List args = new ArrayList<>(); Collections.addAll(args, diff --git a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevExtraPlugin.java b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevExtraPlugin.java index 912fd4bfe5..fd5c0d391e 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevExtraPlugin.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevExtraPlugin.java @@ -2,7 +2,6 @@ import net.neoforged.minecraftdependencies.MinecraftDependenciesPlugin; import net.neoforged.moddevgradle.internal.NeoDevFacade; -import net.neoforged.nfrtgradle.CreateMinecraftArtifacts; import net.neoforged.nfrtgradle.DownloadAssets; import org.gradle.api.Plugin; import org.gradle.api.Project; @@ -33,7 +32,10 @@ public void apply(Project project) { // TODO: this is temporary var downloadAssets = neoForgeProject.getTasks().named("downloadAssets", DownloadAssets.class); - var writeNeoDevConfig = neoForgeProject.getTasks().named("writeNeoDevConfig", CreateUserDevConfig.class); + + var neoForgeConfigOnly = project.getConfigurations().create("neoForgeConfigOnly", spec -> { + spec.getDependencies().add(projectDep(dependencyFactory, neoForgeProject, "net.neoforged:neoforge-moddev-config")); + }); Consumer configureLegacyClasspath = spec -> { spec.getDependencies().add(projectDep(dependencyFactory, neoForgeProject, "net.neoforged:neoforge-dependencies")); @@ -46,7 +48,7 @@ public void apply(Project project) { project, neoDevBuildDir, extension.getRuns(), - writeNeoDevConfig, + neoForgeConfigOnly, modulePath -> modulePath.getDependencies().add(modulePathDependency), configureLegacyClasspath, downloadAssets.flatMap(DownloadAssets::getAssetPropertiesFile) @@ -60,7 +62,7 @@ public void apply(Project project) { project, neoDevBuildDir, testTask, - writeNeoDevConfig, + neoForgeConfigOnly, testExtension.getLoadedMods(), testExtension.getTestedMod(), modulePath -> modulePath.getDependencies().add(modulePathDependency), diff --git a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java index e7f9f77934..f77fbe9098 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java @@ -94,32 +94,23 @@ public void apply(Project project) { */ // 1. Write configs that contain the runs in a format understood by MDG/NG/etc. Currently one for neodev and one for userdev. - var writeNeoDevConfig = tasks.register("writeNeoDevConfig", CreateUserDevConfig.class, task -> { - task.getForNeoDev().set(true); - task.getUserDevConfig().set(neoDevBuildDir.map(dir -> dir.file("neodev-config.json"))); - }); var writeUserDevConfig = tasks.register("writeUserDevConfig", CreateUserDevConfig.class, task -> { - task.getForNeoDev().set(false); + task.setGroup(INTERNAL_GROUP); task.getUserDevConfig().set(neoDevBuildDir.map(dir -> dir.file("userdev-config.json"))); + task.getFmlVersion().set(fmlVersion); + task.getMinecraftVersion().set(minecraftVersion); + task.getNeoForgeVersion().set(neoForgeVersion); + task.getRawNeoFormVersion().set(rawNeoFormVersion); + task.getLibraries().addAll(DependencyUtils.configurationToGavList(configurations.userdevClasspath)); + task.getModules().addAll(DependencyUtils.configurationToGavList(configurations.modulePath)); + task.getTestLibraries().addAll(DependencyUtils.configurationToGavList(configurations.userdevTestClasspath)); + task.getTestLibraries().add(neoForgeVersion.map(v -> "net.neoforged:testframework:" + v)); + task.getIgnoreList().addAll(configurations.userdevCompileOnlyClasspath.getIncoming().getArtifacts().getResolvedArtifacts().map(results -> { + return results.stream().map(r -> r.getFile().getName()).toList(); + })); + task.getIgnoreList().addAll("client-extra", "neoforge-"); + task.getBinpatcherGav().set(Tools.BINPATCHER.asGav(project)); }); - for (var taskProvider : List.of(writeNeoDevConfig, writeUserDevConfig)) { - taskProvider.configure(task -> { - task.setGroup(INTERNAL_GROUP); - task.getFmlVersion().set(fmlVersion); - task.getMinecraftVersion().set(minecraftVersion); - task.getNeoForgeVersion().set(neoForgeVersion); - task.getRawNeoFormVersion().set(rawNeoFormVersion); - task.getLibraries().addAll(DependencyUtils.configurationToGavList(configurations.userdevClasspath)); - task.getModules().addAll(DependencyUtils.configurationToGavList(configurations.modulePath)); - task.getTestLibraries().addAll(DependencyUtils.configurationToGavList(configurations.userdevTestClasspath)); - task.getTestLibraries().add(neoForgeVersion.map(v -> "net.neoforged:testframework:" + v)); - task.getIgnoreList().addAll(configurations.userdevCompileOnlyClasspath.getIncoming().getArtifacts().getResolvedArtifacts().map(results -> { - return results.stream().map(r -> r.getFile().getName()).toList(); - })); - task.getIgnoreList().addAll("client-extra", "neoforge-"); - task.getBinpatcherGav().set(Tools.BINPATCHER.asGav(project)); - }); - } // 2. Task to download assets. var downloadAssets = tasks.register("downloadAssets", DownloadAssets.class, task -> { @@ -140,7 +131,7 @@ public void apply(Project project) { project, neoDevBuildDir, extension.getRuns(), - writeNeoDevConfig, + writeUserDevConfig, modulePath -> { modulePath.extendsFrom(configurations.moduleLibraries); }, diff --git a/gradle.properties b/gradle.properties index 1c1d602cd3..d6e5d02ae1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -43,7 +43,7 @@ jetbrains_annotations_version=24.0.1 slf4j_api_version=2.0.7 apache_maven_artifact_version=3.8.5 jarjar_version=0.4.1 -fancy_mod_loader_version=5.0.1 +fancy_mod_loader_version=5.0.6 mojang_logging_version=1.1.1 log4j_version=2.22.1 guava_version=31.1.2-jre From 284ce28400090b7f044081a23fec078a2a6ec573 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:51:52 -0500 Subject: [PATCH 02/27] [1.21.3] Add NF's needs_netherite_tool block tag to vanilla's incorrect_for_*_tool block tags (#1572) --- .../block/incorrect_for_diamond_tool.json | 5 +++++ .../tags/block/incorrect_for_gold_tool.json | 5 +++++ .../tags/block/incorrect_for_iron_tool.json | 5 +++++ .../tags/block/incorrect_for_stone_tool.json | 5 +++++ .../tags/block/incorrect_for_wooden_tool.json | 5 +++++ .../tags/block/needs_netherite_tool.json | 3 +++ .../net/neoforged/neoforge/common/Tags.java | 20 +++++++++++++++++++ .../internal/NeoForgeBlockTagsProvider.java | 8 ++++++++ 8 files changed, 56 insertions(+) create mode 100644 src/generated/resources/data/minecraft/tags/block/incorrect_for_diamond_tool.json create mode 100644 src/generated/resources/data/minecraft/tags/block/incorrect_for_gold_tool.json create mode 100644 src/generated/resources/data/minecraft/tags/block/incorrect_for_iron_tool.json create mode 100644 src/generated/resources/data/minecraft/tags/block/incorrect_for_stone_tool.json create mode 100644 src/generated/resources/data/minecraft/tags/block/incorrect_for_wooden_tool.json create mode 100644 src/generated/resources/data/neoforge/tags/block/needs_netherite_tool.json diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_diamond_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_diamond_tool.json new file mode 100644 index 0000000000..1486484827 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_diamond_tool.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#neoforge:needs_netherite_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_gold_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_gold_tool.json new file mode 100644 index 0000000000..1486484827 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_gold_tool.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#neoforge:needs_netherite_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_iron_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_iron_tool.json new file mode 100644 index 0000000000..1486484827 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_iron_tool.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#neoforge:needs_netherite_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_stone_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_stone_tool.json new file mode 100644 index 0000000000..1486484827 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_stone_tool.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#neoforge:needs_netherite_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_wooden_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_wooden_tool.json new file mode 100644 index 0000000000..1486484827 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_wooden_tool.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#neoforge:needs_netherite_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/block/needs_netherite_tool.json b/src/generated/resources/data/neoforge/tags/block/needs_netherite_tool.json new file mode 100644 index 0000000000..f72d209df7 --- /dev/null +++ b/src/generated/resources/data/neoforge/tags/block/needs_netherite_tool.json @@ -0,0 +1,3 @@ +{ + "values": [] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index 8a57785dc8..8e3333d0fd 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -35,8 +35,28 @@ public static class Blocks { * This is patched into the following method: {@link net.minecraft.world.entity.monster.EnderMan.EndermanLeaveBlockGoal#canPlaceBlock(Level, BlockPos, BlockState, BlockState, BlockState, BlockPos)} */ public static final TagKey ENDERMAN_PLACE_ON_BLACKLIST = neoforgeTag("enderman_place_on_blacklist"); + + /** + * For denoting blocks that need tools that are Wood or higher to mine. + * By default, this is not added to any Minecraft tag since Wood is in the lowest "tier". + */ public static final TagKey NEEDS_WOOD_TOOL = neoforgeTag("needs_wood_tool"); + + /** + * For denoting blocks that need tools that are Gold or higher to mine. + * By default, this is not added to any Minecraft tag since Gold is in the lowest "tier". + */ public static final TagKey NEEDS_GOLD_TOOL = neoforgeTag("needs_gold_tool"); + + /** + * For denoting blocks that need tools that are Netherite or higher to mine. + * Blocks in this tag gets added to the following Minecraft tags: + * {@link BlockTags#INCORRECT_FOR_WOODEN_TOOL} + * {@link BlockTags#INCORRECT_FOR_STONE_TOOL} + * {@link BlockTags#INCORRECT_FOR_IRON_TOOL} + * {@link BlockTags#INCORRECT_FOR_GOLD_TOOL} + * {@link BlockTags#INCORRECT_FOR_DIAMOND_TOOL} + */ public static final TagKey NEEDS_NETHERITE_TOOL = neoforgeTag("needs_netherite_tool"); // `c` tags for common conventions diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java index a1959d5aa8..09b564d1b0 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java @@ -160,6 +160,14 @@ public void addTags(HolderLookup.Provider p_256380_) { tag(Tags.Blocks.VILLAGER_FARMLANDS).add(Blocks.FARMLAND); + // Make our Needs Netherite Tool tag be functional. + tag(Tags.Blocks.NEEDS_NETHERITE_TOOL); + tag(BlockTags.INCORRECT_FOR_WOODEN_TOOL).addTag(Tags.Blocks.NEEDS_NETHERITE_TOOL); + tag(BlockTags.INCORRECT_FOR_STONE_TOOL).addTag(Tags.Blocks.NEEDS_NETHERITE_TOOL); + tag(BlockTags.INCORRECT_FOR_IRON_TOOL).addTag(Tags.Blocks.NEEDS_NETHERITE_TOOL); + tag(BlockTags.INCORRECT_FOR_GOLD_TOOL).addTag(Tags.Blocks.NEEDS_NETHERITE_TOOL); + tag(BlockTags.INCORRECT_FOR_DIAMOND_TOOL).addTag(Tags.Blocks.NEEDS_NETHERITE_TOOL); + // Backwards compat with pre-1.21 tags. Done after so optional tag is last for better readability. // TODO: Remove backwards compat tag entries in 1.22 tagWithOptionalLegacy(Tags.Blocks.BARRELS); From cf6cc71a76e71323b803aa9cf96ece7b4a7f2c04 Mon Sep 17 00:00:00 2001 From: Apex <29412632+ApexModder@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:00:18 +0000 Subject: [PATCH 03/27] [1.21.3] Fix recipe manager not using ConditionalOps (#1710) --- .../item/crafting/RecipeManager.java.patch | 23 ++++--- .../recipes/misc/always_disabled_recipe.json | 37 +++++++++++ .../recipe/always_disabled_recipe.json | 16 +++++ .../neoforge/debug/ConditionalRecipeTest.java | 61 +++++++++++++++++++ 4 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 tests/src/generated/resources/data/neotests_test_conditional_recipe/advancement/recipes/misc/always_disabled_recipe.json create mode 100644 tests/src/generated/resources/data/neotests_test_conditional_recipe/recipe/always_disabled_recipe.json create mode 100644 tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java diff --git a/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch b/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch index e1cbdae41d..f33bac52e3 100644 --- a/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch +++ b/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch @@ -1,14 +1,23 @@ --- a/net/minecraft/world/item/crafting/RecipeManager.java +++ b/net/minecraft/world/item/crafting/RecipeManager.java -@@ -260,6 +_,11 @@ +@@ -69,7 +_,7 @@ + protected RecipeMap prepare(ResourceManager p_379845_, ProfilerFiller p_380058_) { + SortedMap> sortedmap = new TreeMap<>(); + SimpleJsonResourceReloadListener.scanDirectory( +- p_379845_, Registries.elementsDirPath(Registries.RECIPE), this.registries.createSerializationContext(JsonOps.INSTANCE), Recipe.CODEC, sortedmap ++ p_379845_, Registries.elementsDirPath(Registries.RECIPE), new net.neoforged.neoforge.common.conditions.ConditionalOps<>(this.registries.createSerializationContext(JsonOps.INSTANCE), getContext()), Recipe.CODEC, sortedmap // Neo: add condition context + ); + List> list = new ArrayList<>(sortedmap.size()); + sortedmap.forEach((p_379232_, p_379233_) -> { +@@ -258,6 +_,11 @@ + return p_380850_ -> p_380850_.getType() == p_381108_ && p_380850_ instanceof SingleItemRecipe singleitemrecipe + ? Optional.of(singleitemrecipe.input()) : Optional.empty(); - } - ++ } ++ + // Neo: expose recipe map + public RecipeMap recipeMap() { + return this.recipes; -+ } -+ - public interface CachedCheck> { - Optional> getRecipeFor(I p_344938_, ServerLevel p_379487_); } + + public interface CachedCheck> { diff --git a/tests/src/generated/resources/data/neotests_test_conditional_recipe/advancement/recipes/misc/always_disabled_recipe.json b/tests/src/generated/resources/data/neotests_test_conditional_recipe/advancement/recipes/misc/always_disabled_recipe.json new file mode 100644 index 0000000000..e13d7504ae --- /dev/null +++ b/tests/src/generated/resources/data/neotests_test_conditional_recipe/advancement/recipes/misc/always_disabled_recipe.json @@ -0,0 +1,37 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:false" + } + ], + "parent": "minecraft:recipes/root", + "criteria": { + "has_stone": { + "conditions": { + "items": [ + { + "items": "minecraft:stone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "neotests_test_conditional_recipe:always_disabled_recipe" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_stone" + ] + ], + "rewards": { + "recipes": [ + "neotests_test_conditional_recipe:always_disabled_recipe" + ] + } +} \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_test_conditional_recipe/recipe/always_disabled_recipe.json b/tests/src/generated/resources/data/neotests_test_conditional_recipe/recipe/always_disabled_recipe.json new file mode 100644 index 0000000000..404842c813 --- /dev/null +++ b/tests/src/generated/resources/data/neotests_test_conditional_recipe/recipe/always_disabled_recipe.json @@ -0,0 +1,16 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:false" + } + ], + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:stone" + ], + "result": { + "count": 1, + "id": "minecraft:bedrock" + } +} \ No newline at end of file diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java new file mode 100644 index 0000000000..e4b71b535f --- /dev/null +++ b/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.debug; + +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.recipes.RecipeCategory; +import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.data.recipes.RecipeProvider; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Items; +import net.neoforged.neoforge.common.conditions.FalseCondition; +import net.neoforged.neoforge.event.server.ServerStartedEvent; +import net.neoforged.testframework.DynamicTest; +import net.neoforged.testframework.annotation.ForEachTest; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.registration.RegistrationHelper; + +@ForEachTest(groups = "conditional_recipes") +public interface ConditionalRecipeTest { + @TestHolder(description = "Validates that recipes support conditionals by generating a new recipe disabled by the FALSE condition", enabledByDefault = true) + static void testConditionalRecipe(DynamicTest test, RegistrationHelper reg) { + // name pointing to recipe which should never be enabled + var recipeName = ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath(reg.modId(), "always_disabled_recipe")); + + reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + @Override + protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + return new RecipeProvider(registries, output) { + @Override + protected void buildRecipes() { + // generic stone -> bedrock recipe + shapeless(RecipeCategory.MISC, Items.BEDROCK) + .requires(Items.STONE) + .unlockedBy("has_stone", has(Items.STONE)) + // false condition to have this recipe always disabled + .save(output.withConditions(FalseCondition.INSTANCE), recipeName); + } + }; + } + + @Override + public String getName() { + return "always_disabled_recipe_provider"; + } + }); + + test.eventListeners().forge().addListener((ServerStartedEvent event) -> { + var recipe = event.getServer().getRecipeManager().recipeMap().byKey(recipeName); + + if (recipe == null) + test.pass(); + else + test.fail("Found recipe: '" + recipeName.location() + "', This should always be disabled due to 'FALSE' condition!"); + }); + } +} From 979d8e58993dd53d116d191b9a5d744c9a7d5675 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Wed, 27 Nov 2024 03:40:56 -0500 Subject: [PATCH 04/27] Throw only when passed clientside level (#1707) --- .../neoforge/network/PacketDistributor.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java b/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java index f09dfae0c9..ea23ac4dcc 100644 --- a/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java +++ b/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java @@ -87,22 +87,24 @@ public static void sendToAllPlayers(CustomPacketPayload payload, CustomPacketPay * Send the given payload(s) to all players tracking the given entity */ public static void sendToPlayersTrackingEntity(Entity entity, CustomPacketPayload payload, CustomPacketPayload... payloads) { - if (entity.level().getChunkSource() instanceof ServerChunkCache chunkCache) { - chunkCache.broadcast(entity, makeClientboundPacket(payload, payloads)); - } else { + if (entity.level().isClientSide()) { throw new IllegalStateException("Cannot send clientbound payloads on the client"); + } else if (entity.level().getChunkSource() instanceof ServerChunkCache chunkCache) { + chunkCache.broadcast(entity, makeClientboundPacket(payload, payloads)); } + // Silently ignore custom Level implementations which may not return ServerChunkCache. } /** * Send the given payload(s) to all players tracking the given entity and the entity itself if it is a player */ public static void sendToPlayersTrackingEntityAndSelf(Entity entity, CustomPacketPayload payload, CustomPacketPayload... payloads) { - if (entity.level().getChunkSource() instanceof ServerChunkCache chunkCache) { - chunkCache.broadcastAndSend(entity, makeClientboundPacket(payload, payloads)); - } else { + if (entity.level().isClientSide()) { throw new IllegalStateException("Cannot send clientbound payloads on the client"); + } else if (entity.level().getChunkSource() instanceof ServerChunkCache chunkCache) { + chunkCache.broadcastAndSend(entity, makeClientboundPacket(payload, payloads)); } + // Silently ignore custom Level implementations which may not return ServerChunkCache. } /** From cb5220bfc236d2ebaaf0f7194253139328250537 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Wed, 27 Nov 2024 03:42:22 -0500 Subject: [PATCH 05/27] Only factor in tabs with items on Creative Menu pages (#1711) Co-authored-by: Marc Hermans --- .../screens/inventory/CreativeModeInventoryScreen.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch index 37ccae8839..e590cf0739 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch @@ -40,7 +40,7 @@ + this.pages.clear(); + int tabIndex = 0; + List currentPage = new java.util.ArrayList<>(); -+ for (CreativeModeTab sortedCreativeModeTab : net.neoforged.neoforge.common.CreativeModeTabRegistry.getSortedCreativeModeTabs()) { ++ for (CreativeModeTab sortedCreativeModeTab : net.neoforged.neoforge.common.CreativeModeTabRegistry.getSortedCreativeModeTabs().stream().filter(CreativeModeTab::hasAnyItems).toList()) { + currentPage.add(sortedCreativeModeTab); + tabIndex++; + if (tabIndex == 10) { From 4a14d55de8c225c899168876bbda93c52e9089d1 Mon Sep 17 00:00:00 2001 From: Apex <29412632+ApexModder@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:43:15 +0000 Subject: [PATCH 06/27] [1.21.3] Append unknown modded flags to `removed_features` level data (#1703) --- .../level/storage/PrimaryLevelData.java.patch | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/patches/net/minecraft/world/level/storage/PrimaryLevelData.java.patch b/patches/net/minecraft/world/level/storage/PrimaryLevelData.java.patch index b9f9edb375..1ff81563a8 100644 --- a/patches/net/minecraft/world/level/storage/PrimaryLevelData.java.patch +++ b/patches/net/minecraft/world/level/storage/PrimaryLevelData.java.patch @@ -17,6 +17,16 @@ p_78531_.get("Player").flatMap(CompoundTag.CODEC::parse).result().orElse(null), p_78531_.get("WasModded").asBoolean(false), new BlockPos(p_78531_.get("SpawnX").asInt(0), p_78531_.get("SpawnY").asInt(0), p_78531_.get("SpawnZ").asInt(0)), +@@ -192,7 +_,8 @@ + .asStream() + .flatMap(p_338118_ -> p_338118_.asString().result().stream()) + .collect(Collectors.toCollection(Sets::newLinkedHashSet)), +- p_78531_.get("removed_features").asStream().flatMap(p_338117_ -> p_338117_.asString().result().stream()).collect(Collectors.toSet()), ++ // Neo: Append removed modded feature flags ++ updateRemovedFeatureFlags(p_78531_.get("removed_features").asStream().flatMap(p_338117_ -> p_338117_.asString().result().stream()), p_78531_.get("enabled_features").asStream().flatMap(features -> features.asString().result().stream())).collect(Collectors.toSet()), + new TimerQueue<>(TimerCallbacks.SERVER_CALLBACKS, p_78531_.get("ScheduledEvents").asStream()), + (CompoundTag)p_78531_.get("CustomBossEvents").orElseEmptyMap().getValue(), + p_78531_.get("DragonFight").read(EndDragonFight.Data.CODEC).resultOrPartial(LOGGER::error).orElse(EndDragonFight.Data.DEFAULT), @@ -200,7 +_,11 @@ p_251864_, p_250651_, @@ -42,7 +52,7 @@ } private static ListTag stringCollectionToTag(Set p_277880_) { -@@ -572,10 +_,44 @@ +@@ -572,10 +_,58 @@ return this.settings.copy(); } @@ -85,5 +95,19 @@ + @Override + public void setDayTimePerTick(float dayTimePerTick) { + this.dayTimePerTick = dayTimePerTick; ++ } ++ ++ private static java.util.stream.Stream updateRemovedFeatureFlags(java.util.stream.Stream removedFeatures, java.util.stream.Stream enabledFeatures) { ++ var unknownFeatureFlags = new HashSet(); ++ // parses the incoming Stream and spits out unknown flag names (ResourceLocation) ++ // we do not care about the returned FeatureFlagSet, only the flags which do not exist ++ net.minecraft.world.flag.FeatureFlags.REGISTRY.fromNames(enabledFeatures.map(net.minecraft.resources.ResourceLocation::parse).collect(Collectors.toSet()), unknownFeatureFlags::add); ++ // concat the received removed flags with our new additions ++ return java.util.stream.Stream.concat(removedFeatures, unknownFeatureFlags.stream() ++ // we only want modded flags, mojang has datafixers for vanilla flags ++ .filter(java.util.function.Predicate.not(name -> name.getNamespace().equals(net.minecraft.resources.ResourceLocation.DEFAULT_NAMESPACE))) ++ .map(net.minecraft.resources.ResourceLocation::toString)) ++ // no duplicates should exist in this stream ++ .distinct(); } } From cc64d631b235ba30b5d1903acd07ebaddfc4b01c Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Wed, 27 Nov 2024 04:07:56 -0500 Subject: [PATCH 07/27] Add attributeAdvancedTooltipDebugInfo config option (#1709) Co-authored-by: Marc Hermans --- .../net/neoforged/neoforge/common/NeoForgeConfig.java | 8 ++++++++ .../neoforge/common/extensions/IAttributeExtension.java | 3 ++- src/main/resources/assets/neoforge/lang/en_us.json | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeConfig.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeConfig.java index 696fa0728d..e7335e0b74 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeConfig.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeConfig.java @@ -65,8 +65,11 @@ public static class Server { */ public static class Common { public final ModConfigSpec.EnumValue logUntranslatedItemTagWarnings; + public final ModConfigSpec.EnumValue logLegacyTagWarnings; + public final BooleanValue attributeAdvancedTooltipDebugInfo; + Common(ModConfigSpec.Builder builder) { logUntranslatedItemTagWarnings = builder .comment("A config option mainly for developers. Logs out modded item tags that do not have translations when running on integrated server. Format desired is tag.item.. for the translation key. Defaults to SILENCED.") @@ -77,6 +80,11 @@ public static class Common { .comment("A config option mainly for developers. Logs out modded tags that are using the 'forge' namespace when running on integrated server. Defaults to DEV_SHORT.") .translation("neoforge.configgui.logLegacyTagWarnings") .defineEnum("logLegacyTagWarnings", TagConventionLogWarning.LogWarningMode.DEV_SHORT); + + attributeAdvancedTooltipDebugInfo = builder + .comment("Set this to true to enable showing debug information about attributes on an item when advanced tooltips is on.") + .translation("neoforge.configgui.attributeAdvancedTooltipDebugInfo") + .define("attributeAdvancedTooltipDebugInfo", true); } } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IAttributeExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IAttributeExtension.java index 6a5c51564d..dd7074d93c 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IAttributeExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IAttributeExtension.java @@ -23,6 +23,7 @@ import net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.item.TooltipFlag; +import net.neoforged.neoforge.common.NeoForgeConfig; import net.neoforged.neoforge.common.NeoForgeMod; import net.neoforged.neoforge.common.util.AttributeUtil; import org.jetbrains.annotations.Nullable; @@ -83,7 +84,7 @@ default MutableComponent toComponent(AttributeModifier modif, TooltipFlag flag) default Component getDebugInfo(AttributeModifier modif, TooltipFlag flag) { Component debugInfo = CommonComponents.EMPTY; - if (flag.isAdvanced()) { + if (flag.isAdvanced() && NeoForgeConfig.COMMON.attributeAdvancedTooltipDebugInfo.get()) { // Advanced Tooltips show the underlying operation and the "true" value. We offset MULTIPLY_TOTAL by 1 due to how the operation is calculated. double advValue = (modif.operation() == Operation.ADD_MULTIPLIED_TOTAL ? 1 : 0) + modif.amount(); String valueStr = FORMAT.format(advValue); diff --git a/src/main/resources/assets/neoforge/lang/en_us.json b/src/main/resources/assets/neoforge/lang/en_us.json index 44647a6d89..7cd26fc40b 100644 --- a/src/main/resources/assets/neoforge/lang/en_us.json +++ b/src/main/resources/assets/neoforge/lang/en_us.json @@ -192,6 +192,8 @@ "neoforge.configuration.section.neoforge.server.toml.title": "Server settings", "neoforge.configgui.advertiseDedicatedServerToLan": "Advertise Dedicated Server To LAN", "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Set this to true to enable advertising the dedicated server to local LAN clients so that it shows up in the Multiplayer screen automatically.", + "neoforge.configgui.attributeAdvancedTooltipDebugInfo": "Additional Attribute Advanced Tooltips", + "neoforge.configgui.attributeAdvancedTooltipDebugInfo.tooltip": "Set this to true to enable additional information about attributes on an item when advanced tooltips is on.", "neoforge.configgui.forgeLightPipelineEnabled": "NeoForge Light Pipeline", "neoforge.configgui.forgeLightPipelineEnabled.tooltip": "Enable the NeoForge block rendering pipeline - fixes the lighting of custom models.", "neoforge.configgui.fullBoundingBoxLadders": "Full Bounding Box Ladders", From c0dbe2161b4fe612507e7055f2cacfd414324e2e Mon Sep 17 00:00:00 2001 From: Apex <29412632+ApexModder@users.noreply.github.com> Date: Wed, 27 Nov 2024 09:12:53 +0000 Subject: [PATCH 08/27] [1.21.3] Add condition to validate feature flags enabled state (#1712) Co-authored-by: Marc Hermans --- .../ReloadableServerResources.java.patch | 2 +- .../neoforge/common/NeoForgeMod.java | 2 + .../common/conditions/ConditionContext.java | 20 ++++- .../common/conditions/FlagCondition.java | 72 ++++++++++++++++++ .../common/conditions/ICondition.java | 13 ++++ .../common/conditions/IConditionBuilder.java | 26 +++++++ .../recipes/misc/diamonds_from_dirt.json | 40 ++++++++++ .../recipes/misc/dirt_from_diamonds.json | 41 ++++++++++ .../recipe/diamonds_from_dirt.json | 19 +++++ .../recipe/dirt_from_diamonds.json | 20 +++++ .../debug/data/CustomFeatureFlagsTests.java | 76 +++++++++++++++++++ 11 files changed, 329 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/common/conditions/FlagCondition.java create mode 100644 tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/diamonds_from_dirt.json create mode 100644 tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/dirt_from_diamonds.json create mode 100644 tests/src/generated/resources/data/neotests_test_flag_condition/recipe/diamonds_from_dirt.json create mode 100644 tests/src/generated/resources/data/neotests_test_flag_condition/recipe/dirt_from_diamonds.json diff --git a/patches/net/minecraft/server/ReloadableServerResources.java.patch b/patches/net/minecraft/server/ReloadableServerResources.java.patch index 4af3bf71c6..fae77e4d24 100644 --- a/patches/net/minecraft/server/ReloadableServerResources.java.patch +++ b/patches/net/minecraft/server/ReloadableServerResources.java.patch @@ -6,7 +6,7 @@ this.functionLibrary = new ServerFunctionLibrary(p_206859_, this.commands.getDispatcher()); + // Neo: Store registries and create context object + this.registryLookup = p_361583_; -+ this.context = new net.neoforged.neoforge.common.conditions.ConditionContext(this.postponedTags); ++ this.context = new net.neoforged.neoforge.common.conditions.ConditionContext(this.postponedTags, p_250695_); } public ServerFunctionLibrary getFunctionLibrary() { diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index 4f7ae5a757..bbdffc2b55 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -87,6 +87,7 @@ import net.neoforged.neoforge.common.advancements.critereon.SnowBootsEntityPredicate; import net.neoforged.neoforge.common.conditions.AndCondition; import net.neoforged.neoforge.common.conditions.FalseCondition; +import net.neoforged.neoforge.common.conditions.FlagCondition; import net.neoforged.neoforge.common.conditions.ICondition; import net.neoforged.neoforge.common.conditions.ItemExistsCondition; import net.neoforged.neoforge.common.conditions.ModLoadedCondition; @@ -385,6 +386,7 @@ public class NeoForgeMod { public static final DeferredHolder, MapCodec> OR_CONDITION = CONDITION_CODECS.register("or", () -> OrCondition.CODEC); public static final DeferredHolder, MapCodec> TAG_EMPTY_CONDITION = CONDITION_CODECS.register("tag_empty", () -> TagEmptyCondition.CODEC); public static final DeferredHolder, MapCodec> TRUE_CONDITION = CONDITION_CODECS.register("true", () -> TrueCondition.CODEC); + public static final DeferredHolder, MapCodec> FEATURE_FLAG_CONDITION = CONDITION_CODECS.register("feature_flags", () -> FlagCondition.CODEC); private static final DeferredRegister> ENTITY_PREDICATE_CODECS = DeferredRegister.create(Registries.ENTITY_SUB_PREDICATE_TYPE, NeoForgeVersion.MOD_ID); public static final DeferredHolder, MapCodec> PIGLIN_NEUTRAL_ARMOR_PREDICATE = ENTITY_PREDICATE_CODECS.register("piglin_neutral_armor", () -> PiglinNeutralArmorEntityPredicate.CODEC); diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/ConditionContext.java b/src/main/java/net/neoforged/neoforge/common/conditions/ConditionContext.java index de5b9b5d36..cffc6d0106 100644 --- a/src/main/java/net/neoforged/neoforge/common/conditions/ConditionContext.java +++ b/src/main/java/net/neoforged/neoforge/common/conditions/ConditionContext.java @@ -12,17 +12,30 @@ import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.flag.FeatureFlags; +import org.jetbrains.annotations.ApiStatus; public class ConditionContext implements ICondition.IContext { private final Map>, HolderLookup.RegistryLookup> pendingTags; + private final FeatureFlagSet enabledFeatures; - public ConditionContext(List> pendingTags) { + public ConditionContext(List> pendingTags, FeatureFlagSet enabledFeatures) { this.pendingTags = new IdentityHashMap<>(); + this.enabledFeatures = enabledFeatures; + for (var tags : pendingTags) { this.pendingTags.put(tags.key(), tags.lookup()); } } + // Use FeatureFlagSet sensitive constructor + @ApiStatus.ScheduledForRemoval(inVersion = "1.21.4") + @Deprecated(forRemoval = true, since = "1.21.3") + public ConditionContext(List> pendingTags) { + this(pendingTags, FeatureFlags.VANILLA_SET); + } + public void clear() { this.pendingTags.clear(); } @@ -33,4 +46,9 @@ public boolean isTagLoaded(TagKey key) { var lookup = pendingTags.get(key.registry()); return lookup != null && lookup.get((TagKey) key).isPresent(); } + + @Override + public FeatureFlagSet enabledFeatures() { + return enabledFeatures; + } } diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/FlagCondition.java b/src/main/java/net/neoforged/neoforge/common/conditions/FlagCondition.java new file mode 100644 index 0000000000..2b59ed1584 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/conditions/FlagCondition.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.conditions; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.flag.FeatureFlag; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.flag.FeatureFlags; + +/** + * Condition checking for the enabled state of a given {@link FeatureFlagSet}. + *

+ * {@code requiredFeatures} - {@link FeatureFlagSet} containing all {@link FeatureFlag feature flags} to be validated. + * {@code expectedResult} - Validates that all given {@link FeatureFlag feature flags} are enabled when {@code true} or disabled when {@code false}. + * + * @apiNote Mainly to be used when flagged content is not contained within the same feature pack which also enables said {@link FeatureFlag feature flags}. + */ +public final class FlagCondition implements ICondition { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + FeatureFlags.CODEC.fieldOf("flags").forGetter(condition -> condition.requiredFeatures), + Codec.BOOL.lenientOptionalFieldOf("expected_result", true).forGetter(condition -> condition.expectedResult)).apply(instance, FlagCondition::new)); + + private final FeatureFlagSet requiredFeatures; + private final boolean expectedResult; + + private FlagCondition(FeatureFlagSet requiredFeatures, boolean expectedResult) { + this.requiredFeatures = requiredFeatures; + this.expectedResult = expectedResult; + } + + @Override + public boolean test(IContext context) { + var flagsEnabled = requiredFeatures.isSubsetOf(context.enabledFeatures()); + // true if: 'expectedResult' is true nd all given flags are enabled + // false if: `enabledEnabled' is false and all given flags are disabled + return flagsEnabled == expectedResult; + } + + @Override + public MapCodec codec() { + return CODEC; + } + + public static ICondition isEnabled(FeatureFlagSet requiredFeatures) { + return new FlagCondition(requiredFeatures, true); + } + + public static ICondition isEnabled(FeatureFlag requiredFlag) { + return isEnabled(FeatureFlagSet.of(requiredFlag)); + } + + public static ICondition isEnabled(FeatureFlag requiredFlag, FeatureFlag... requiredFlags) { + return isEnabled(FeatureFlagSet.of(requiredFlag, requiredFlags)); + } + + public static ICondition isDisabled(FeatureFlagSet requiredFeatures) { + return new FlagCondition(requiredFeatures, false); + } + + public static ICondition isDisabled(FeatureFlag requiredFlag) { + return isDisabled(FeatureFlagSet.of(requiredFlag)); + } + + public static ICondition isDisabled(FeatureFlag requiredFlag, FeatureFlag... requiredFlags) { + return isDisabled(FeatureFlagSet.of(requiredFlag, requiredFlags)); + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/ICondition.java b/src/main/java/net/neoforged/neoforge/common/conditions/ICondition.java index 1be7e0ce94..2c8ca8583d 100644 --- a/src/main/java/net/neoforged/neoforge/common/conditions/ICondition.java +++ b/src/main/java/net/neoforged/neoforge/common/conditions/ICondition.java @@ -19,7 +19,10 @@ import net.minecraft.resources.RegistryOps; import net.minecraft.tags.TagKey; import net.minecraft.util.Unit; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.flag.FeatureFlags; import net.neoforged.neoforge.registries.NeoForgeRegistries; +import net.neoforged.neoforge.server.ServerLifecycleHooks; public interface ICondition { Codec CODEC = NeoForgeRegistries.CONDITION_SERIALIZERS.byNameCodec() @@ -91,5 +94,15 @@ public boolean isTagLoaded(TagKey key) { * Returns {@code true} if the requested tag is available. */ boolean isTagLoaded(TagKey key); + + default FeatureFlagSet enabledFeatures() { + // returning the vanilla set causes reports false positives for flags outside of vanilla + // return FeatureFlags.VANILLA_SET; + + // lookup the active enabledFeatures from the current server + // if no server exists, delegating back to 'VANILLA_SET' should be fine (should rarely ever happen) + var server = ServerLifecycleHooks.getCurrentServer(); + return server == null ? FeatureFlags.VANILLA_SET : server.getWorldData().enabledFeatures(); + } } } diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/IConditionBuilder.java b/src/main/java/net/neoforged/neoforge/common/conditions/IConditionBuilder.java index 06836647a8..f0a532ac16 100644 --- a/src/main/java/net/neoforged/neoforge/common/conditions/IConditionBuilder.java +++ b/src/main/java/net/neoforged/neoforge/common/conditions/IConditionBuilder.java @@ -7,6 +7,8 @@ import java.util.List; import net.minecraft.tags.TagKey; +import net.minecraft.world.flag.FeatureFlag; +import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.item.Item; public interface IConditionBuilder { @@ -41,4 +43,28 @@ default ICondition modLoaded(String modid) { default ICondition tagEmpty(TagKey tag) { return new TagEmptyCondition(tag.location()); } + + default ICondition isFeatureEnabled(FeatureFlagSet requiredFeatures) { + return FlagCondition.isEnabled(requiredFeatures); + } + + default ICondition isFeatureEnabled(FeatureFlag requiredFlag) { + return FlagCondition.isEnabled(requiredFlag); + } + + default ICondition isFeatureEnabled(FeatureFlag requiredFlag, FeatureFlag... requiredFlags) { + return FlagCondition.isEnabled(requiredFlag, requiredFlags); + } + + default ICondition isFeatureDisabled(FeatureFlagSet requiredFeatures) { + return FlagCondition.isDisabled(requiredFeatures); + } + + default ICondition isFeatureDisabled(FeatureFlag requiredFlag) { + return FlagCondition.isDisabled(requiredFlag); + } + + default ICondition isFeatureDisabled(FeatureFlag requiredFlag, FeatureFlag... requiredFlags) { + return FlagCondition.isDisabled(requiredFlag, requiredFlags); + } } diff --git a/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/diamonds_from_dirt.json b/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/diamonds_from_dirt.json new file mode 100644 index 0000000000..2228d43a8b --- /dev/null +++ b/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/diamonds_from_dirt.json @@ -0,0 +1,40 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:feature_flags", + "flags": [ + "custom_feature_flags_pack_test:test_flag" + ] + } + ], + "parent": "minecraft:recipes/root", + "criteria": { + "has_dirt": { + "conditions": { + "items": [ + { + "items": "#minecraft:dirt" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "neotests_test_flag_condition:diamonds_from_dirt" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_dirt" + ] + ], + "rewards": { + "recipes": [ + "neotests_test_flag_condition:diamonds_from_dirt" + ] + } +} \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/dirt_from_diamonds.json b/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/dirt_from_diamonds.json new file mode 100644 index 0000000000..bde8245ef5 --- /dev/null +++ b/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/dirt_from_diamonds.json @@ -0,0 +1,41 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:feature_flags", + "expected_result": false, + "flags": [ + "custom_feature_flags_pack_test:test_flag" + ] + } + ], + "parent": "minecraft:recipes/root", + "criteria": { + "has_diamond": { + "conditions": { + "items": [ + { + "items": "#c:gems/diamond" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "neotests_test_flag_condition:dirt_from_diamonds" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_diamond" + ] + ], + "rewards": { + "recipes": [ + "neotests_test_flag_condition:dirt_from_diamonds" + ] + } +} \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/diamonds_from_dirt.json b/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/diamonds_from_dirt.json new file mode 100644 index 0000000000..51550166a3 --- /dev/null +++ b/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/diamonds_from_dirt.json @@ -0,0 +1,19 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:feature_flags", + "flags": [ + "custom_feature_flags_pack_test:test_flag" + ] + } + ], + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "#minecraft:dirt" + ], + "result": { + "count": 1, + "id": "minecraft:diamond" + } +} \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/dirt_from_diamonds.json b/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/dirt_from_diamonds.json new file mode 100644 index 0000000000..d1984cf97c --- /dev/null +++ b/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/dirt_from_diamonds.json @@ -0,0 +1,20 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:feature_flags", + "expected_result": false, + "flags": [ + "custom_feature_flags_pack_test:test_flag" + ] + } + ], + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "#c:gems/diamond" + ], + "result": { + "count": 1, + "id": "minecraft:dirt" + } +} \ No newline at end of file diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java index 86f539a15e..0e852b9840 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java @@ -5,22 +5,33 @@ package net.neoforged.neoforge.debug.data; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.recipes.RecipeCategory; +import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.data.recipes.RecipeProvider; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackSource; +import net.minecraft.tags.ItemTags; import net.minecraft.world.flag.FeatureFlag; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; +import net.neoforged.neoforge.common.Tags; +import net.neoforged.neoforge.common.conditions.FlagCondition; import net.neoforged.neoforge.event.AddPackFindersEvent; import net.neoforged.neoforge.event.server.ServerStartedEvent; import net.neoforged.neoforge.registries.DeferredItem; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.registration.RegistrationHelper; @ForEachTest(groups = "data.feature_flags") public class CustomFeatureFlagsTests { @@ -89,4 +100,69 @@ static void testFeatureGating(final DynamicTest test) { } }); } + + @TestHolder(description = "Tests that elements can be toggled via conditions using the flag condition", enabledByDefault = true) + static void testFlagCondition(DynamicTest test, RegistrationHelper reg) { + // custom flag are provided by our other flag tests + // and enabled via our `custom featureflag test pack` + var flagName = ResourceLocation.fromNamespaceAndPath("custom_feature_flags_pack_test", "test_flag"); + var flag = FeatureFlags.REGISTRY.getFlag(flagName); + + var modId = reg.modId(); + var enabledRecipeName = ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath(modId, "diamonds_from_dirt")); + var disabledRecipeName = ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath(modId, "dirt_from_diamonds")); + + reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + @Override + protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + return new RecipeProvider(registries, output) { + @Override + protected void buildRecipes() { + // recipe available when above flag is enabled + shapeless(RecipeCategory.MISC, Items.DIAMOND) + .requires(ItemTags.DIRT) + .unlockedBy("has_dirt", has(ItemTags.DIRT)) + .save(output.withConditions(FlagCondition.isEnabled(flag)), enabledRecipeName); + + // recipe available when above flag is disabled + shapeless(RecipeCategory.MISC, Items.DIRT) + .requires(Tags.Items.GEMS_DIAMOND) + .unlockedBy("has_diamond", has(Tags.Items.GEMS_DIAMOND)) + .save(output.withConditions(FlagCondition.isDisabled(flag)), disabledRecipeName); + } + }; + } + + @Override + public String getName() { + return "conditional_flag_recipes"; + } + }); + + test.eventListeners().forge().addListener((ServerStartedEvent event) -> { + var server = event.getServer(); + var isFlagEnabled = server.getWorldData().enabledFeatures().contains(flag); + var recipeMap = server.getRecipeManager().recipeMap(); + var hasEnabledRecipe = recipeMap.byKey(enabledRecipeName) != null; + var hasDisabledRecipe = recipeMap.byKey(disabledRecipeName) != null; + + if (isFlagEnabled) { + if (!hasEnabledRecipe) { + test.fail("Missing recipe '" + enabledRecipeName.location() + "', This should be enabled due to our flag '" + flagName + "' being enabled"); + } + if (hasDisabledRecipe) { + test.fail("Found recipe '" + disabledRecipeName.location() + "', This should be disabled due to our flag '" + flagName + "' being disabled"); + } + } else { + if (hasEnabledRecipe) { + test.fail("Found recipe '" + enabledRecipeName.location() + "', This should be disabled due to our flag '" + flagName + "' being enabled"); + } + if (!hasDisabledRecipe) { + test.fail("Missing recipe '" + disabledRecipeName.location() + "', This should be enabled due to our flag '" + flagName + "' being disabled"); + } + } + + test.pass(); + }); + } } From 7730007ab5aa05f3f3003db76fe983bdac7108cd Mon Sep 17 00:00:00 2001 From: Bruno Ploumhans <13494793+Technici4n@users.noreply.github.com> Date: Thu, 28 Nov 2024 08:28:01 +0100 Subject: [PATCH 09/27] Simplify FlagCondition (#1713) --- .../neoforge/common/NeoForgeMod.java | 4 +- .../FeatureFlagsEnabledCondition.java | 38 ++++++++++ .../common/conditions/FlagCondition.java | 72 ------------------- .../common/conditions/IConditionBuilder.java | 32 ++++----- .../recipes/misc/diamonds_from_dirt.json | 2 +- .../recipes/misc/dirt_from_diamonds.json | 41 ----------- .../recipe/diamonds_from_dirt.json | 2 +- .../recipe/dirt_from_diamonds.json | 20 ------ .../debug/data/CustomFeatureFlagsTests.java | 28 +++----- 9 files changed, 63 insertions(+), 176 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/common/conditions/FeatureFlagsEnabledCondition.java delete mode 100644 src/main/java/net/neoforged/neoforge/common/conditions/FlagCondition.java delete mode 100644 tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/dirt_from_diamonds.json delete mode 100644 tests/src/generated/resources/data/neotests_test_flag_condition/recipe/dirt_from_diamonds.json diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index bbdffc2b55..d9ad69fcf7 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -87,7 +87,7 @@ import net.neoforged.neoforge.common.advancements.critereon.SnowBootsEntityPredicate; import net.neoforged.neoforge.common.conditions.AndCondition; import net.neoforged.neoforge.common.conditions.FalseCondition; -import net.neoforged.neoforge.common.conditions.FlagCondition; +import net.neoforged.neoforge.common.conditions.FeatureFlagsEnabledCondition; import net.neoforged.neoforge.common.conditions.ICondition; import net.neoforged.neoforge.common.conditions.ItemExistsCondition; import net.neoforged.neoforge.common.conditions.ModLoadedCondition; @@ -386,7 +386,7 @@ public class NeoForgeMod { public static final DeferredHolder, MapCodec> OR_CONDITION = CONDITION_CODECS.register("or", () -> OrCondition.CODEC); public static final DeferredHolder, MapCodec> TAG_EMPTY_CONDITION = CONDITION_CODECS.register("tag_empty", () -> TagEmptyCondition.CODEC); public static final DeferredHolder, MapCodec> TRUE_CONDITION = CONDITION_CODECS.register("true", () -> TrueCondition.CODEC); - public static final DeferredHolder, MapCodec> FEATURE_FLAG_CONDITION = CONDITION_CODECS.register("feature_flags", () -> FlagCondition.CODEC); + public static final DeferredHolder, MapCodec> FEATURE_FLAGS_ENABLED_CONDITION = CONDITION_CODECS.register("feature_flags_enabled", () -> FeatureFlagsEnabledCondition.CODEC); private static final DeferredRegister> ENTITY_PREDICATE_CODECS = DeferredRegister.create(Registries.ENTITY_SUB_PREDICATE_TYPE, NeoForgeVersion.MOD_ID); public static final DeferredHolder, MapCodec> PIGLIN_NEUTRAL_ARMOR_PREDICATE = ENTITY_PREDICATE_CODECS.register("piglin_neutral_armor", () -> PiglinNeutralArmorEntityPredicate.CODEC); diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/FeatureFlagsEnabledCondition.java b/src/main/java/net/neoforged/neoforge/common/conditions/FeatureFlagsEnabledCondition.java new file mode 100644 index 0000000000..6eb0aef8ab --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/conditions/FeatureFlagsEnabledCondition.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.conditions; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.flag.FeatureFlag; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.flag.FeatureFlags; + +/** + * Condition checking that a set of {@link FeatureFlag feature flags} are enabled. + * + * @apiNote Mainly to be used when flagged content is not contained within the same feature pack which also enables said {@link FeatureFlag feature flags}. + */ +public record FeatureFlagsEnabledCondition(FeatureFlagSet flags) implements ICondition { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + FeatureFlags.CODEC.fieldOf("flags").forGetter(condition -> condition.flags)).apply(instance, FeatureFlagsEnabledCondition::new)); + + public FeatureFlagsEnabledCondition { + if (flags.isEmpty()) { + throw new IllegalArgumentException("FeatureFlagsEnabledCondition requires a non-empty feature flag set"); + } + } + + @Override + public boolean test(IContext context) { + return flags.isSubsetOf(context.enabledFeatures()); + } + + @Override + public MapCodec codec() { + return CODEC; + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/FlagCondition.java b/src/main/java/net/neoforged/neoforge/common/conditions/FlagCondition.java deleted file mode 100644 index 2b59ed1584..0000000000 --- a/src/main/java/net/neoforged/neoforge/common/conditions/FlagCondition.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common.conditions; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.world.flag.FeatureFlag; -import net.minecraft.world.flag.FeatureFlagSet; -import net.minecraft.world.flag.FeatureFlags; - -/** - * Condition checking for the enabled state of a given {@link FeatureFlagSet}. - *

- * {@code requiredFeatures} - {@link FeatureFlagSet} containing all {@link FeatureFlag feature flags} to be validated. - * {@code expectedResult} - Validates that all given {@link FeatureFlag feature flags} are enabled when {@code true} or disabled when {@code false}. - * - * @apiNote Mainly to be used when flagged content is not contained within the same feature pack which also enables said {@link FeatureFlag feature flags}. - */ -public final class FlagCondition implements ICondition { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - FeatureFlags.CODEC.fieldOf("flags").forGetter(condition -> condition.requiredFeatures), - Codec.BOOL.lenientOptionalFieldOf("expected_result", true).forGetter(condition -> condition.expectedResult)).apply(instance, FlagCondition::new)); - - private final FeatureFlagSet requiredFeatures; - private final boolean expectedResult; - - private FlagCondition(FeatureFlagSet requiredFeatures, boolean expectedResult) { - this.requiredFeatures = requiredFeatures; - this.expectedResult = expectedResult; - } - - @Override - public boolean test(IContext context) { - var flagsEnabled = requiredFeatures.isSubsetOf(context.enabledFeatures()); - // true if: 'expectedResult' is true nd all given flags are enabled - // false if: `enabledEnabled' is false and all given flags are disabled - return flagsEnabled == expectedResult; - } - - @Override - public MapCodec codec() { - return CODEC; - } - - public static ICondition isEnabled(FeatureFlagSet requiredFeatures) { - return new FlagCondition(requiredFeatures, true); - } - - public static ICondition isEnabled(FeatureFlag requiredFlag) { - return isEnabled(FeatureFlagSet.of(requiredFlag)); - } - - public static ICondition isEnabled(FeatureFlag requiredFlag, FeatureFlag... requiredFlags) { - return isEnabled(FeatureFlagSet.of(requiredFlag, requiredFlags)); - } - - public static ICondition isDisabled(FeatureFlagSet requiredFeatures) { - return new FlagCondition(requiredFeatures, false); - } - - public static ICondition isDisabled(FeatureFlag requiredFlag) { - return isDisabled(FeatureFlagSet.of(requiredFlag)); - } - - public static ICondition isDisabled(FeatureFlag requiredFlag, FeatureFlag... requiredFlags) { - return isDisabled(FeatureFlagSet.of(requiredFlag, requiredFlags)); - } -} diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/IConditionBuilder.java b/src/main/java/net/neoforged/neoforge/common/conditions/IConditionBuilder.java index f0a532ac16..ef10000e02 100644 --- a/src/main/java/net/neoforged/neoforge/common/conditions/IConditionBuilder.java +++ b/src/main/java/net/neoforged/neoforge/common/conditions/IConditionBuilder.java @@ -10,6 +10,7 @@ import net.minecraft.world.flag.FeatureFlag; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.item.Item; +import org.apache.commons.lang3.ArrayUtils; public interface IConditionBuilder { default ICondition and(ICondition... values) { @@ -44,27 +45,18 @@ default ICondition tagEmpty(TagKey tag) { return new TagEmptyCondition(tag.location()); } - default ICondition isFeatureEnabled(FeatureFlagSet requiredFeatures) { - return FlagCondition.isEnabled(requiredFeatures); + default ICondition featureFlagsEnabled(FeatureFlagSet requiredFeatures) { + return new FeatureFlagsEnabledCondition(requiredFeatures); } - default ICondition isFeatureEnabled(FeatureFlag requiredFlag) { - return FlagCondition.isEnabled(requiredFlag); - } - - default ICondition isFeatureEnabled(FeatureFlag requiredFlag, FeatureFlag... requiredFlags) { - return FlagCondition.isEnabled(requiredFlag, requiredFlags); - } - - default ICondition isFeatureDisabled(FeatureFlagSet requiredFeatures) { - return FlagCondition.isDisabled(requiredFeatures); - } - - default ICondition isFeatureDisabled(FeatureFlag requiredFlag) { - return FlagCondition.isDisabled(requiredFlag); - } - - default ICondition isFeatureDisabled(FeatureFlag requiredFlag, FeatureFlag... requiredFlags) { - return FlagCondition.isDisabled(requiredFlag, requiredFlags); + default ICondition featureFlagsEnabled(FeatureFlag... requiredFlags) { + if (requiredFlags.length == 0) { + throw new IllegalArgumentException("FeatureFlagsEnabledCondition requires at least one feature flag."); + } + if (requiredFlags.length == 1) { + return new FeatureFlagsEnabledCondition(FeatureFlagSet.of(requiredFlags[0])); + } else { + return new FeatureFlagsEnabledCondition(FeatureFlagSet.of(requiredFlags[0], ArrayUtils.remove(requiredFlags, 0))); + } } } diff --git a/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/diamonds_from_dirt.json b/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/diamonds_from_dirt.json index 2228d43a8b..e0d40e6e34 100644 --- a/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/diamonds_from_dirt.json +++ b/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/diamonds_from_dirt.json @@ -1,7 +1,7 @@ { "neoforge:conditions": [ { - "type": "neoforge:feature_flags", + "type": "neoforge:feature_flags_enabled", "flags": [ "custom_feature_flags_pack_test:test_flag" ] diff --git a/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/dirt_from_diamonds.json b/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/dirt_from_diamonds.json deleted file mode 100644 index bde8245ef5..0000000000 --- a/tests/src/generated/resources/data/neotests_test_flag_condition/advancement/recipes/misc/dirt_from_diamonds.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "neoforge:conditions": [ - { - "type": "neoforge:feature_flags", - "expected_result": false, - "flags": [ - "custom_feature_flags_pack_test:test_flag" - ] - } - ], - "parent": "minecraft:recipes/root", - "criteria": { - "has_diamond": { - "conditions": { - "items": [ - { - "items": "#c:gems/diamond" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "neotests_test_flag_condition:dirt_from_diamonds" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "requirements": [ - [ - "has_the_recipe", - "has_diamond" - ] - ], - "rewards": { - "recipes": [ - "neotests_test_flag_condition:dirt_from_diamonds" - ] - } -} \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/diamonds_from_dirt.json b/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/diamonds_from_dirt.json index 51550166a3..5accc57d95 100644 --- a/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/diamonds_from_dirt.json +++ b/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/diamonds_from_dirt.json @@ -1,7 +1,7 @@ { "neoforge:conditions": [ { - "type": "neoforge:feature_flags", + "type": "neoforge:feature_flags_enabled", "flags": [ "custom_feature_flags_pack_test:test_flag" ] diff --git a/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/dirt_from_diamonds.json b/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/dirt_from_diamonds.json deleted file mode 100644 index d1984cf97c..0000000000 --- a/tests/src/generated/resources/data/neotests_test_flag_condition/recipe/dirt_from_diamonds.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "neoforge:conditions": [ - { - "type": "neoforge:feature_flags", - "expected_result": false, - "flags": [ - "custom_feature_flags_pack_test:test_flag" - ] - } - ], - "type": "minecraft:crafting_shapeless", - "category": "misc", - "ingredients": [ - "#c:gems/diamond" - ], - "result": { - "count": 1, - "id": "minecraft:dirt" - } -} \ No newline at end of file diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java index 0e852b9840..10419da329 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java @@ -23,8 +23,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; -import net.neoforged.neoforge.common.Tags; -import net.neoforged.neoforge.common.conditions.FlagCondition; +import net.neoforged.neoforge.common.conditions.IConditionBuilder; import net.neoforged.neoforge.event.AddPackFindersEvent; import net.neoforged.neoforge.event.server.ServerStartedEvent; import net.neoforged.neoforge.registries.DeferredItem; @@ -110,27 +109,25 @@ static void testFlagCondition(DynamicTest test, RegistrationHelper reg) { var modId = reg.modId(); var enabledRecipeName = ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath(modId, "diamonds_from_dirt")); - var disabledRecipeName = ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath(modId, "dirt_from_diamonds")); reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { - return new RecipeProvider(registries, output) { + class Provider extends RecipeProvider implements IConditionBuilder { + protected Provider(HolderLookup.Provider p_360573_, RecipeOutput p_360872_) { + super(p_360573_, p_360872_); + } + @Override protected void buildRecipes() { // recipe available when above flag is enabled shapeless(RecipeCategory.MISC, Items.DIAMOND) .requires(ItemTags.DIRT) .unlockedBy("has_dirt", has(ItemTags.DIRT)) - .save(output.withConditions(FlagCondition.isEnabled(flag)), enabledRecipeName); - - // recipe available when above flag is disabled - shapeless(RecipeCategory.MISC, Items.DIRT) - .requires(Tags.Items.GEMS_DIAMOND) - .unlockedBy("has_diamond", has(Tags.Items.GEMS_DIAMOND)) - .save(output.withConditions(FlagCondition.isDisabled(flag)), disabledRecipeName); + .save(output.withConditions(featureFlagsEnabled(flag)), enabledRecipeName); } - }; + } + return new Provider(registries, output); } @Override @@ -144,22 +141,15 @@ public String getName() { var isFlagEnabled = server.getWorldData().enabledFeatures().contains(flag); var recipeMap = server.getRecipeManager().recipeMap(); var hasEnabledRecipe = recipeMap.byKey(enabledRecipeName) != null; - var hasDisabledRecipe = recipeMap.byKey(disabledRecipeName) != null; if (isFlagEnabled) { if (!hasEnabledRecipe) { test.fail("Missing recipe '" + enabledRecipeName.location() + "', This should be enabled due to our flag '" + flagName + "' being enabled"); } - if (hasDisabledRecipe) { - test.fail("Found recipe '" + disabledRecipeName.location() + "', This should be disabled due to our flag '" + flagName + "' being disabled"); - } } else { if (hasEnabledRecipe) { test.fail("Found recipe '" + enabledRecipeName.location() + "', This should be disabled due to our flag '" + flagName + "' being enabled"); } - if (!hasDisabledRecipe) { - test.fail("Missing recipe '" + disabledRecipeName.location() + "', This should be enabled due to our flag '" + flagName + "' being disabled"); - } } test.pass(); From 95ff2221d037dc7a62b7f3a2883cd7a8763b58fa Mon Sep 17 00:00:00 2001 From: shartte Date: Thu, 28 Nov 2024 13:54:17 +0100 Subject: [PATCH 10/27] E2E Self-Tests of production server and client (#1700) --- .github/workflows/test-prs.yml | 9 + .../neodev/CreateCleanArtifacts.java | 10 + .../net/neoforged/neodev/NeoDevPlugin.java | 84 ++++ .../neodev/e2e/InstallProductionClient.java | 64 ++++ .../neodev/e2e/InstallProductionServer.java | 63 +++ .../neodev/e2e/RunProductionClient.java | 362 ++++++++++++++++++ .../neodev/e2e/RunProductionServer.java | 47 +++ .../neodev/e2e/TestProductionClient.java | 38 ++ .../neodev/e2e/TestProductionServer.java | 55 +++ .../neodev/installer/IdentifiedFile.java | 8 +- .../neodev/utils/MavenIdentifier.java | 40 ++ .../neoforge/client/ClientNeoForgeMod.java | 3 + .../neoforge/common/NeoForgeMod.java | 3 + .../neoforge/common/util/SelfTest.java | 76 ++++ 14 files changed, 858 insertions(+), 4 deletions(-) create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/e2e/InstallProductionClient.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/e2e/InstallProductionServer.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionServer.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionClient.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionServer.java create mode 100644 src/main/java/net/neoforged/neoforge/common/util/SelfTest.java diff --git a/.github/workflows/test-prs.yml b/.github/workflows/test-prs.yml index 51afdcddad..471304015a 100644 --- a/.github/workflows/test-prs.yml +++ b/.github/workflows/test-prs.yml @@ -47,6 +47,15 @@ jobs: - name: Run JUnit tests with Gradle run: ./gradlew :tests:runUnitTests + - name: Install software OpenGL rendering + run: sudo apt-get install xvfb libgl1-mesa-dri + + - name: Run production client self-test + run: xvfb-run ./gradlew :neoforge:testProductionClient + + - name: Run production server self-test + run: ./gradlew :neoforge:testProductionServer + - name: Store reports if: failure() uses: actions/upload-artifact@v4 diff --git a/buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java b/buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java index 2cb2e89ade..9854d597e4 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java @@ -7,9 +7,18 @@ import javax.inject.Inject; abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts { + /** + * The unmodified downloaded client jar. + */ + @OutputFile + abstract RegularFileProperty getRawClientJar(); + @OutputFile abstract RegularFileProperty getCleanClientJar(); + /** + * The unmodified downloaded server jar. + */ @OutputFile abstract RegularFileProperty getRawServerJar(); @@ -24,6 +33,7 @@ abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts { @Inject public CreateCleanArtifacts() { + getAdditionalResults().put("node.downloadClient.output.output", getRawClientJar().getAsFile()); getAdditionalResults().put("node.stripClient.output.output", getCleanClientJar().getAsFile()); getAdditionalResults().put("node.downloadServer.output.output", getRawServerJar().getAsFile()); getAdditionalResults().put("node.stripServer.output.output", getCleanServerJar().getAsFile()); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java index f77fbe9098..9595efc840 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java @@ -3,9 +3,16 @@ import net.neoforged.minecraftdependencies.MinecraftDependenciesPlugin; import net.neoforged.moddevgradle.internal.NeoDevFacade; import net.neoforged.moddevgradle.tasks.JarJar; +import net.neoforged.neodev.e2e.InstallProductionClient; +import net.neoforged.neodev.e2e.InstallProductionServer; +import net.neoforged.neodev.e2e.RunProductionClient; +import net.neoforged.neodev.e2e.RunProductionServer; +import net.neoforged.neodev.e2e.TestProductionClient; +import net.neoforged.neodev.e2e.TestProductionServer; import net.neoforged.neodev.installer.CreateArgsFile; import net.neoforged.neodev.installer.CreateInstallerProfile; import net.neoforged.neodev.installer.CreateLauncherProfile; +import net.neoforged.neodev.installer.IdentifiedFile; import net.neoforged.neodev.installer.InstallerProcessor; import net.neoforged.neodev.utils.DependencyUtils; import net.neoforged.nfrtgradle.CreateMinecraftArtifacts; @@ -32,6 +39,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.function.Consumer; public class NeoDevPlugin implements Plugin { static final String GROUP = "neoforge development"; @@ -206,7 +214,9 @@ public void apply(Project project) { var createCleanArtifacts = tasks.register("createCleanArtifacts", CreateCleanArtifacts.class, task -> { task.setGroup(INTERNAL_GROUP); + task.setDescription("This task retrieves various files for the Minecraft version without applying NeoForge patches to them"); var cleanArtifactsDir = neoDevBuildDir.map(dir -> dir.dir("artifacts/clean")); + task.getRawClientJar().set(cleanArtifactsDir.map(dir -> dir.file("raw-client.jar"))); task.getCleanClientJar().set(cleanArtifactsDir.map(dir -> dir.file("client.jar"))); task.getRawServerJar().set(cleanArtifactsDir.map(dir -> dir.file("raw-server.jar"))); task.getCleanServerJar().set(cleanArtifactsDir.map(dir -> dir.file("server.jar"))); @@ -404,6 +414,18 @@ public void apply(Project project) { task.dependsOn(userdevJar); task.dependsOn(sourcesJarProvider); }); + + // Set up E2E testing of the produced installer + setupProductionClientTest( + project, + configurations, + downloadAssets, + installerJar, + minecraftVersion, + neoForgeVersion, + createCleanArtifacts.flatMap(CreateCleanArtifacts::getRawClientJar) + ); + setupProductionServerTest(project, installerJar); } private static TaskProvider configureAccessTransformer( @@ -528,4 +550,66 @@ static TaskProvider configureMinecraftDecompilation(Pr task.getNeoFormArtifact().set(mcAndNeoFormVersion.map(version -> "net.neoforged:neoform:" + version + "@zip")); }); } + + private void setupProductionClientTest(Project project, + NeoDevConfigurations configurations, + TaskProvider downloadAssets, + TaskProvider installer, + Provider minecraftVersion, + Provider neoForgeVersion, + Provider originalClientJar + ) { + + var installClient = project.getTasks().register("installProductionClient", InstallProductionClient.class, task -> { + task.setGroup(INTERNAL_GROUP); + task.setDescription("Runs the installer produced by this build and installs a production client."); + task.getInstaller().from(installer.flatMap(AbstractArchiveTask::getArchiveFile)); + + var destinationDir = project.getLayout().getBuildDirectory().dir("production-client"); + task.getInstallationDir().set(destinationDir); + }); + + Consumer configureRunProductionClient = task -> { + task.getLibraryFiles().addAll(IdentifiedFile.listFromConfiguration(project, configurations.neoFormClasspath)); + task.getLibraryFiles().addAll(IdentifiedFile.listFromConfiguration(project, configurations.launcherProfileClasspath)); + task.getAssetPropertiesFile().set(downloadAssets.flatMap(DownloadAssets::getAssetPropertiesFile)); + task.getMinecraftVersion().set(minecraftVersion); + task.getNeoForgeVersion().set(neoForgeVersion); + task.getInstallationDir().set(installClient.flatMap(InstallProductionClient::getInstallationDir)); + task.getOriginalClientJar().set(originalClientJar); + }; + project.getTasks().register("runProductionClient", RunProductionClient.class, task -> { + task.setGroup(INTERNAL_GROUP); + task.setDescription("Runs the production client installed by installProductionClient."); + configureRunProductionClient.accept(task); + }); + project.getTasks().register("testProductionClient", TestProductionClient.class, task -> { + task.setGroup(INTERNAL_GROUP); + task.setDescription("Tests the production client installed by installProductionClient."); + configureRunProductionClient.accept(task); + }); + } + + private void setupProductionServerTest(Project project, TaskProvider installer) { + var installServer = project.getTasks().register("installProductionServer", InstallProductionServer.class, task -> { + task.setGroup(INTERNAL_GROUP); + task.setDescription("Runs the installer produced by this build and installs a production server."); + task.getInstaller().from(installer.flatMap(AbstractArchiveTask::getArchiveFile)); + + var destinationDir = project.getLayout().getBuildDirectory().dir("production-server"); + task.getInstallationDir().set(destinationDir); + }); + + project.getTasks().register("runProductionServer", RunProductionServer.class, task -> { + task.setGroup(INTERNAL_GROUP); + task.setDescription("Runs the production server installed by installProductionServer."); + task.getInstallationDir().set(installServer.flatMap(InstallProductionServer::getInstallationDir)); + }); + + project.getTasks().register("testProductionServer", TestProductionServer.class, task -> { + task.setGroup(INTERNAL_GROUP); + task.setDescription("Tests the production server installed by installProductionServer."); + task.getInstallationDir().set(installServer.flatMap(InstallProductionServer::getInstallationDir)); + }); + } } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/InstallProductionClient.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/InstallProductionClient.java new file mode 100644 index 0000000000..bc16b4b386 --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/InstallProductionClient.java @@ -0,0 +1,64 @@ +package net.neoforged.neodev.e2e; + +import org.gradle.api.GradleException; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.JavaExec; +import org.gradle.api.tasks.OutputDirectory; +import org.gradle.api.tasks.TaskAction; + +import javax.inject.Inject; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; + +/** + * Downloads and installs a production NeoForge client. + * By extending this task from {@link JavaExec}, it's possible to debug the actual legacy installer + * via IntelliJ directly. + */ +public abstract class InstallProductionClient extends JavaExec { + /** + * This file collection should contain exactly one file: + * The NeoForge Installer Jar-File. + */ + @InputFiles + public abstract ConfigurableFileCollection getInstaller(); + + /** + * Where NeoForge should be installed. + */ + @OutputDirectory + public abstract DirectoryProperty getInstallationDir(); + + @Inject + public InstallProductionClient() { + classpath(getInstaller()); + } + + @TaskAction + @Override + public void exec() { + var installDir = getInstallationDir().getAsFile().get().toPath().toAbsolutePath(); + + // Installer looks for this file + var profilesJsonPath = installDir.resolve("launcher_profiles.json"); + try { + Files.writeString(profilesJsonPath, "{}"); + } catch (IOException e) { + throw new GradleException("Failed to write fake launcher profiles file.", e); + } + + setWorkingDir(installDir.toFile()); + args("--install-client", installDir.toString()); + try { + setStandardOutput(new BufferedOutputStream(Files.newOutputStream(installDir.resolve("install.log")))); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + super.exec(); + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/InstallProductionServer.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/InstallProductionServer.java new file mode 100644 index 0000000000..9360a88e88 --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/InstallProductionServer.java @@ -0,0 +1,63 @@ +package net.neoforged.neodev.e2e; + +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.JavaExec; +import org.gradle.api.tasks.OutputDirectory; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.TaskAction; + +import javax.inject.Inject; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; + +/** + * Runs the installer produced by the main build to install a dedicated server in a chosen directory. + */ +public abstract class InstallProductionServer extends JavaExec { + /** + * The NeoForge installer jar is expected to be the only file in this file collection. + */ + @InputFiles + public abstract ConfigurableFileCollection getInstaller(); + + /** + * Where the server should be installed. + */ + @OutputDirectory + public abstract DirectoryProperty getInstallationDir(); + + /** + * Points to the server.jar produced by the installer. + */ + @OutputFile + public abstract RegularFileProperty getServerLauncher(); + + @Inject + public InstallProductionServer() { + classpath(getInstaller()); + getServerLauncher().set(getInstallationDir().map(id -> id.file("server.jar"))); + getServerLauncher().finalizeValueOnRead(); + } + + @TaskAction + @Override + public void exec() { + var installDir = getInstallationDir().getAsFile().get().toPath().toAbsolutePath(); + + setWorkingDir(installDir.toFile()); + args("--install-server", installDir.toString()); + args("--server.jar"); + try { + setStandardOutput(new BufferedOutputStream(Files.newOutputStream(installDir.resolve("install.log")))); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + super.exec(); + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java new file mode 100644 index 0000000000..f279952f78 --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java @@ -0,0 +1,362 @@ +package net.neoforged.neodev.e2e; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import net.neoforged.neodev.installer.IdentifiedFile; +import net.neoforged.neodev.utils.MavenIdentifier; +import org.apache.tools.ant.taskdefs.condition.Os; +import org.gradle.api.GradleException; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputDirectory; +import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.JavaExec; +import org.gradle.api.tasks.Nested; +import org.gradle.api.tasks.TaskAction; +import org.gradle.process.ExecOperations; +import org.gradle.process.JavaExecSpec; + +import javax.inject.Inject; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Runs a production client previously installed by {@link InstallProductionClient}. + *

+ * This task has to extend from {@link JavaExec} instead of using {@link org.gradle.process.ExecOperations} internally + * to allow debugging it via IntelliJ directly. + * (Technically, implementing {@link org.gradle.process.JavaForkOptions} would suffice). + *

+ * The main complication of this task is evaluating the Vanilla version manifest and building a libraries + * directory and classpath as the Vanilla launcher would. + */ +public abstract class RunProductionClient extends JavaExec { + private final ExecOperations execOperations; + + /** + * The folder where the game was installed. + */ + @InputDirectory + public abstract DirectoryProperty getInstallationDir(); + + /** + * The pre-processed libraries as a file collection. + */ + @Nested + public abstract ListProperty getLibraryFiles(); + + /** + * The asset properties file produced by {@link net.neoforged.nfrtgradle.DownloadAssets}. + */ + @InputFile + public abstract RegularFileProperty getAssetPropertiesFile(); + + /** + * The Minecraft version matching the NeoForge version to install. + */ + @Input + public abstract Property getMinecraftVersion(); + + /** + * The NeoForge version, used for placeholders when launching the game. + * It needs to match the installer used. + */ + @Input + public abstract Property getNeoForgeVersion(); + + /** + * The original, unmodified client jar. + * The Vanilla launcher puts this on the classpath when it launches the game. + */ + @InputFile + public abstract RegularFileProperty getOriginalClientJar(); + + @Inject + public RunProductionClient(ExecOperations execOperations) { + this.execOperations = execOperations; + } + + @TaskAction + @Override + public void exec() { + var installDir = getInstallationDir().getAsFile().get().toPath(); + var nativesDir = installDir.resolve("natives"); + try { + Files.createDirectories(nativesDir); + } catch (IOException e) { + throw new GradleException("Failed to pre-create natives directory " + nativesDir, e); + } + var librariesDir = installDir.resolve("libraries"); + + var minecraftVersion = getMinecraftVersion().get(); + var versionId = "neoforge-" + getNeoForgeVersion().get(); + + var assetProperties = new Properties(); + try (var in = new FileInputStream(getAssetPropertiesFile().getAsFile().get())) { + assetProperties.load(in); + } catch (IOException e) { + throw new GradleException("Failed to read asset properties " + getAssetPropertiesFile(), e); + } + + var assetIndex = Objects.requireNonNull(assetProperties.getProperty("asset_index"), "asset_index"); + var assetsRoot = Objects.requireNonNull(assetProperties.getProperty("assets_root"), "assets_root"); + + // Set up the placeholders generally used by Vanilla profiles in their argument definitions. + var placeholders = new HashMap(); + placeholders.put("auth_player_name", "Dev"); + placeholders.put("version_name", minecraftVersion); + placeholders.put("game_directory", installDir.toAbsolutePath().toString()); + placeholders.put("auth_uuid", "00000000-0000-4000-8000-000000000000"); + placeholders.put("auth_access_token", "0"); + placeholders.put("clientid", "0"); + placeholders.put("auth_xuid", "0"); + placeholders.put("user_type", "legacy"); + placeholders.put("version_type", "release"); + placeholders.put("assets_index_name", assetIndex); + placeholders.put("assets_root", assetsRoot); + placeholders.put("launcher_name", "NeoForgeProdInstallation"); + placeholders.put("launcher_version", "1.0"); + placeholders.put("natives_directory", nativesDir.toAbsolutePath().toString()); + // These are used by NF but provided by the launcher + placeholders.put("library_directory", librariesDir.toAbsolutePath().toString()); + placeholders.put("classpath_separator", File.pathSeparator); + + execOperations.javaexec(spec -> { + // The JVM args at this point may include debugging options when started through IntelliJ + spec.jvmArgs(getJvmArguments().get()); + spec.workingDir(installDir); + + spec.environment(getEnvironment()); + applyVersionManifest(installDir, versionId, placeholders, librariesDir, spec); + }); + } + + /** + * Applies a Vanilla Launcher version manifest to the JavaForkOptions. + */ + private void applyVersionManifest(Path installDir, + String versionId, + Map placeholders, + Path librariesDir, + JavaExecSpec spec) { + var manifests = loadVersionManifests(installDir, versionId); + + var mergedProgramArgs = new ArrayList(); + var mergedJvmArgs = new ArrayList(); + + for (var manifest : manifests) { + var mainClass = manifest.getAsJsonPrimitive("mainClass"); + if (mainClass != null) { + spec.getMainClass().set(mainClass.getAsString()); + } + + mergedProgramArgs.addAll(getArguments(manifest, "game")); + mergedJvmArgs.addAll(getArguments(manifest, "jvm")); + } + + // Index all available libraries + var availableLibraries = new HashMap(); + for (var identifiedFile : getLibraryFiles().get()) { + availableLibraries.put( + identifiedFile.getIdentifier().get(), + identifiedFile.getFile().get().getAsFile().toPath() + ); + } + + // The libraries are built in reverse, and libraries already added are not added again from parent manifests + var librariesAdded = new HashSet(); + var classpathItems = new ArrayList(); + for (var i = manifests.size() - 1; i >= 0; i--) { + var manifest = manifests.get(i); + + var libraries = manifest.getAsJsonArray("libraries"); + for (var library : libraries) { + var libraryObj = library.getAsJsonObject(); + + // Skip if disabled by rule + if (isDisabledByRules(libraryObj)) { + getLogger().info("Skipping library {} since it's condition is not met.", libraryObj); + continue; + } + + var id = MavenIdentifier.parse(libraryObj.get("name").getAsString()); + + // We use this to deduplicate the same library in different versions across manifests + var idWithoutVersion = new MavenIdentifier( + id.group(), + id.artifact(), + "", + id.classifier(), + id.extension() + ); + + if (!librariesAdded.add(idWithoutVersion)) { + continue; // The library was overridden by a child profile + } + + // Try finding the library in the classpath we got from Gradle + var availableLibrary = availableLibraries.get(id); + if (availableLibrary == null) { + throw new GradleException("Version manifest asks for " + id + " but this library is not available through Gradle."); + } + + // Copy over the library to the libraries directory, since our loader only deduplicates class-path + // items with module-path items when they are at the same location (and the module-path is defined + // relative to the libraries directory). + Path destination = librariesDir.resolve(id.repositoryPath()); + copyIfNeeded(availableLibrary, destination); + classpathItems.add(destination.toAbsolutePath().toString()); + } + } + + // The Vanilla launcher adds the actual game jar (obfuscated) as the last classpath item + var gameJar = installDir.resolve("versions").resolve(versionId).resolve(versionId + ".jar"); + copyIfNeeded(getOriginalClientJar().get().getAsFile().toPath(), gameJar); + classpathItems.add(gameJar.toAbsolutePath().toString()); + + var classpath = String.join(File.pathSeparator, classpathItems); + placeholders.putIfAbsent("classpath", classpath); + + expandPlaceholders(mergedProgramArgs, placeholders); + spec.args(mergedProgramArgs); + expandPlaceholders(mergedJvmArgs, placeholders); + spec.jvmArgs(mergedJvmArgs); + } + + // Returns the inherited manifests first + private static List loadVersionManifests(Path installDir, String versionId) { + // Read back the version manifest and get the startup arguments + var manifestPath = installDir.resolve("versions").resolve(versionId).resolve(versionId + ".json"); + JsonObject manifest; + try { + manifest = readJson(manifestPath); + } catch (IOException e) { + throw new GradleException("Failed to read launcher profile " + manifestPath, e); + } + + var result = new ArrayList(); + var inheritsFrom = manifest.getAsJsonPrimitive("inheritsFrom"); + if (inheritsFrom != null) { + result.addAll(loadVersionManifests(installDir, inheritsFrom.getAsString())); + } + + result.add(manifest); + + return result; + } + + private static void expandPlaceholders(List args, Map variables) { + var pattern = Pattern.compile("\\$\\{([^}]+)}"); + + args.replaceAll(s -> { + var matcher = pattern.matcher(s); + return matcher.replaceAll(match -> { + var variable = match.group(1); + return Matcher.quoteReplacement(variables.getOrDefault(variable, matcher.group())); + }); + }); + } + + private static List getArguments(JsonObject manifest, String kind) { + var result = new ArrayList(); + + var gameArgs = manifest.getAsJsonObject("arguments").getAsJsonArray(kind); + for (var gameArg : gameArgs) { + if (gameArg.isJsonObject()) { + var conditionalArgument = gameArg.getAsJsonObject(); + if (!isDisabledByRules(conditionalArgument)) { + var value = conditionalArgument.get("value"); + if (value.isJsonPrimitive()) { + result.add(value.getAsString()); + } else { + for (var valueEl : value.getAsJsonArray()) { + result.add(valueEl.getAsString()); + } + } + } + } else { + result.add(gameArg.getAsString()); + } + } + + return result; + } + + private static boolean isDisabledByRules(JsonObject ruleObject) { + var rules = ruleObject.getAsJsonArray("rules"); + if (rules == null) { + return false; + } + + for (var ruleEl : rules) { + var rule = ruleEl.getAsJsonObject(); + boolean allow = "allow".equals(rule.getAsJsonPrimitive("action").getAsString()); + // We only care about "os" rules + if (rule.has("os")) { + var os = rule.getAsJsonObject("os"); + var name = os.getAsJsonPrimitive("name"); + var arch = os.getAsJsonPrimitive("arch"); + boolean ruleMatches = (name == null || isCurrentOsName(name.getAsString())) && (arch == null || isCurrentOsArch(arch.getAsString())); + if (ruleMatches != allow) { + return true; + } + } else { + // We assume unknown rules do not apply + return true; + } + } + return false; + } + + private static boolean isCurrentOsName(String os) { + return switch (os) { + case "windows" -> Os.isFamily(Os.FAMILY_WINDOWS); + case "osx" -> Os.isFamily(Os.FAMILY_MAC); + case "linux" -> Os.isFamily(Os.FAMILY_UNIX); + default -> false; + }; + } + + private static boolean isCurrentOsArch(String arch) { + return switch (arch) { + case "x86" -> System.getProperty("os.arch").equals("x86"); + default -> false; + }; + } + + private static JsonObject readJson(Path path) throws IOException { + try (var reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { + return new Gson().fromJson(reader, JsonObject.class); + } + } + + private static void copyIfNeeded(Path source, Path destination) { + try { + if (!Files.exists(destination) + || !Objects.equals(Files.getLastModifiedTime(destination), Files.getLastModifiedTime(source)) + || Files.size(destination) != Files.size(source)) { + Files.createDirectories(destination.getParent()); + Files.copy(source, destination, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); + } + } catch (IOException e) { + throw new GradleException("Failed to copy " + source + " to " + destination + ": " + e, e); + } + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionServer.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionServer.java new file mode 100644 index 0000000000..e65ed58ecb --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionServer.java @@ -0,0 +1,47 @@ +package net.neoforged.neodev.e2e; + +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.tasks.InputDirectory; +import org.gradle.api.tasks.JavaExec; +import org.gradle.api.tasks.TaskAction; +import org.gradle.process.ExecOperations; + +import javax.inject.Inject; + +/** + * Runs the {@code server.jar} installed by our installer using {@link InstallProductionServer}. + *

+ * This task has to extend from {@link JavaExec} instead of using {@link ExecOperations} internally + * to allow debugging the launched server with IntelliJ. + * (Technically, implementing {@link org.gradle.process.JavaForkOptions} would suffice). + */ +public abstract class RunProductionServer extends JavaExec { + private final ExecOperations execOperations; + + /** + * The folder where the game was installed. + */ + @InputDirectory + public abstract DirectoryProperty getInstallationDir(); + + @Inject + public RunProductionServer(ExecOperations execOperations) { + this.execOperations = execOperations; + } + + @TaskAction + @Override + public void exec() { + var installDir = getInstallationDir().getAsFile().get().toPath(); + + execOperations.javaexec(spec -> { + // The JVM args at this point may include debugging options when started through IntelliJ + spec.jvmArgs(getJvmArguments().get()); + spec.workingDir(installDir); + + spec.environment(getEnvironment()); + spec.classpath(installDir.resolve("server.jar")); + }); + + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionClient.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionClient.java new file mode 100644 index 0000000000..0c7ec7fde3 --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionClient.java @@ -0,0 +1,38 @@ +package net.neoforged.neodev.e2e; + +import org.gradle.api.GradleException; +import org.gradle.process.ExecOperations; + +import javax.inject.Inject; +import java.io.File; +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +/** + * Runs a production client using {@link RunProductionClient} and passes the environment variable + * to enable the {@link net.neoforged.neoforge.common.util.SelfTest self test}. + *

+ * Once the client exits, it validates that the self-test file was created, indicating the client successfully + * launched and started ticking. + */ +public abstract class TestProductionClient extends RunProductionClient { + @Inject + public TestProductionClient(ExecOperations execOperations) { + super(execOperations); + + getTimeout().set(Duration.of(5, ChronoUnit.MINUTES)); + } + + @Override + public void exec() { + var selfTestReport = new File(getTemporaryDir(), "client_self_test.txt"); + + environment("NEOFORGE_CLIENT_SELFTEST", selfTestReport.getAbsolutePath()); + + super.exec(); + + if (!selfTestReport.exists()) { + throw new GradleException("Missing self test report file after running client: " + selfTestReport); + } + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionServer.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionServer.java new file mode 100644 index 0000000000..9fc6ed293c --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionServer.java @@ -0,0 +1,55 @@ +package net.neoforged.neodev.e2e; + +import org.gradle.api.GradleException; +import org.gradle.process.ExecOperations; + +import javax.inject.Inject; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +/** + * Runs a production server using {@link RunProductionServer} and passes the environment variable + * to enable the {@link net.neoforged.neoforge.common.util.SelfTest self test}. + *

+ * Once the server exits, it validates that the self-test file was created, indicating the server successfully + * launched and started ticking. + */ +public abstract class TestProductionServer extends RunProductionServer { + @Inject + public TestProductionServer(ExecOperations execOperations) { + super(execOperations); + + getTimeout().set(Duration.of(5, ChronoUnit.MINUTES)); + } + + @Override + public void exec() { + var selfTestReport = new File(getTemporaryDir(), "server_self_test.txt"); + + environment("NEOFORGE_DEDICATED_SERVER_SELFTEST", selfTestReport.getAbsolutePath()); + + var eulaFile = getInstallationDir().file("eula.txt").get().getAsFile().toPath(); + try { + Files.writeString(eulaFile, "eula=true", StandardCharsets.UTF_8); + } catch (IOException e) { + throw new GradleException("Failed writing eula acceptable to eula.txt", e); + } + + try { + super.exec(); + } finally { + try { + Files.deleteIfExists(eulaFile); + } catch (IOException ignored) { + } + } + + if (!selfTestReport.exists()) { + throw new GradleException("Missing self test report file after running server: " + selfTestReport); + } + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/installer/IdentifiedFile.java b/buildSrc/src/main/java/net/neoforged/neodev/installer/IdentifiedFile.java index a7f685236a..ff75e1ba75 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/installer/IdentifiedFile.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/installer/IdentifiedFile.java @@ -21,8 +21,8 @@ * Combines a {@link File} and its {@link MavenIdentifier maven identifier}, * for usage as task inputs that will be passed to {@link LibraryCollector}. */ -abstract class IdentifiedFile { - static Provider> listFromConfiguration(Project project, Configuration configuration) { +public abstract class IdentifiedFile { + public static Provider> listFromConfiguration(Project project, Configuration configuration) { return configuration.getIncoming().getArtifacts().getResolvedArtifacts().map( artifacts -> artifacts.stream() .map(artifact -> IdentifiedFile.of(project, artifact)) @@ -41,8 +41,8 @@ public IdentifiedFile() {} @InputFile @PathSensitive(PathSensitivity.NONE) - protected abstract RegularFileProperty getFile(); + public abstract RegularFileProperty getFile(); @Input - protected abstract Property getIdentifier(); + public abstract Property getIdentifier(); } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/utils/MavenIdentifier.java b/buildSrc/src/main/java/net/neoforged/neodev/utils/MavenIdentifier.java index 6a22312fd0..21dc04655b 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/utils/MavenIdentifier.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/utils/MavenIdentifier.java @@ -10,4 +10,44 @@ public String artifactNotation() { public String repositoryPath() { return group.replace(".", "/") + "/" + artifact + "/" + version + "/" + artifact + "-" + version + (classifier.isEmpty() ? "" : "-" + classifier) + "." + extension; } + + /** + * Valid forms: + *

    + *
  • {@code groupId:artifactId:version}
  • + *
  • {@code groupId:artifactId:version:classifier}
  • + *
  • {@code groupId:artifactId:version:classifier@extension}
  • + *
  • {@code groupId:artifactId:version@extension}
  • + *
+ */ + public static MavenIdentifier parse(String coordinate) { + var coordinateAndExt = coordinate.split("@"); + String extension = "jar"; + if (coordinateAndExt.length > 2) { + throw new IllegalArgumentException("Malformed Maven coordinate: " + coordinate); + } else if (coordinateAndExt.length == 2) { + extension = coordinateAndExt[1]; + coordinate = coordinateAndExt[0]; + } + + var parts = coordinate.split(":"); + if (parts.length != 3 && parts.length != 4) { + throw new IllegalArgumentException("Malformed Maven coordinate: " + coordinate); + } + + var groupId = parts[0]; + var artifactId = parts[1]; + var version = parts[2]; + var classifier = parts.length == 4 ? parts[3] : ""; + return new MavenIdentifier(groupId, artifactId, version, classifier, extension); + } + + @Override + public String toString() { + if (classifier != null) { + return group + ":" + artifact + ":" + version + ":" + classifier + "@" + extension; + } else { + return group + ":" + artifact + ":" + version + "@" + extension; + } + } } diff --git a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java index d55c15caec..f8526f30d3 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java @@ -42,6 +42,7 @@ import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForgeMod; +import net.neoforged.neoforge.common.util.SelfTest; import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; import org.jetbrains.annotations.ApiStatus; @@ -49,6 +50,8 @@ @Mod(value = "neoforge", dist = Dist.CLIENT) public class ClientNeoForgeMod { public ClientNeoForgeMod(IEventBus modEventBus, ModContainer container) { + SelfTest.initClient(); + ClientCommandHandler.init(); TagConventionLogWarningClient.init(); diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index d9ad69fcf7..0e22d8d00d 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -123,6 +123,7 @@ import net.neoforged.neoforge.common.loot.CanItemPerformAbility; import net.neoforged.neoforge.common.loot.IGlobalLootModifier; import net.neoforged.neoforge.common.loot.LootTableIdCondition; +import net.neoforged.neoforge.common.util.SelfTest; import net.neoforged.neoforge.common.world.BiomeModifier; import net.neoforged.neoforge.common.world.BiomeModifiers; import net.neoforged.neoforge.common.world.BiomeModifiers.AddFeaturesBiomeModifier; @@ -527,6 +528,8 @@ public NeoForgeMod(IEventBus modEventBus, Dist dist, ModContainer container) { LOGGER.info(NEOFORGEMOD, "NeoForge mod loading, version {}, for MC {}", NeoForgeVersion.getVersion(), DetectedVersion.BUILT_IN.getName()); ForgeSnapshotsMod.logStartupWarning(); + SelfTest.initCommon(); + CrashReportCallables.registerCrashCallable("Crash Report UUID", () -> { final UUID uuid = UUID.randomUUID(); LOGGER.fatal("Preparing crash report with UUID {}", uuid); diff --git a/src/main/java/net/neoforged/neoforge/common/util/SelfTest.java b/src/main/java/net/neoforged/neoforge/common/util/SelfTest.java new file mode 100644 index 0000000000..734294cdf0 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/util/SelfTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.util; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.LoadingOverlay; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.loading.FMLLoader; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.tick.ServerTickEvent; +import org.jetbrains.annotations.ApiStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * We use a "self-test" to launch a client and dedicated server from within our CI and exit. + * This allows us to do an "end-to-end" test that actually uses the installer we produce to + * install a client&server and test it. + * The self-test writes a file so that the build script can detect that the game actually + * loaded up enough to start ticking the game loop. + */ +@ApiStatus.Internal +public final class SelfTest { + private static final Logger LOGGER = LoggerFactory.getLogger(SelfTest.class); + + private SelfTest() {} + + public static void initClient() { + var clientSelfTestDestination = System.getenv("NEOFORGE_CLIENT_SELFTEST"); + if (clientSelfTestDestination != null) { + NeoForge.EVENT_BUS.addListener((ClientTickEvent.Pre e) -> { + if (Minecraft.getInstance().getOverlay() instanceof LoadingOverlay) { + return; + } + writeSelfTestReport(clientSelfTestDestination); + Minecraft.getInstance().stop(); + }); + } + } + + public static void initCommon() { + var serverSelfTestDestination = System.getenv("NEOFORGE_DEDICATED_SERVER_SELFTEST"); + if (serverSelfTestDestination != null) { + if (FMLLoader.getDist() != Dist.DEDICATED_SERVER) { + LOGGER.error("The server self-test ran with a dist of {} instead of dedicated server!", FMLLoader.getDist()); + System.exit(1); + } + NeoForge.EVENT_BUS.addListener((ServerTickEvent.Pre e) -> { + writeSelfTestReport(serverSelfTestDestination); + e.getServer().halt(false); + }); + } + } + + /** + * This is used by our GitHub Actions pipeline to run an E2E test for PRs. + * It writes a small self-test report to the file indicated by the system property and exits. + */ + private static void writeSelfTestReport(String path) { + try { + Files.createFile(Paths.get(path)); + } catch (IOException e) { + LOGGER.error("Failed to write self-test to '{}'", path, e); + System.exit(1); + } + + LOGGER.info("Write self-test report to '{}'", path); + } +} From 0836a1855b1fb696ed37778d48dbf41b9991f64b Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:39:54 -0500 Subject: [PATCH 11/27] Make AttributeTemplate record public (#1708) Fixes #1691 --- patches/net/minecraft/world/effect/MobEffect.java.patch | 4 ++-- src/main/resources/META-INF/accesstransformer.cfg | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/world/effect/MobEffect.java.patch b/patches/net/minecraft/world/effect/MobEffect.java.patch index 1daf7ed3ab..ed25ba16ea 100644 --- a/patches/net/minecraft/world/effect/MobEffect.java.patch +++ b/patches/net/minecraft/world/effect/MobEffect.java.patch @@ -49,8 +49,8 @@ return this.requiredFeatures; } -- static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation) { -+ static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation, @Nullable it.unimi.dsi.fastutil.ints.Int2DoubleFunction curve) { +- public static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation) { ++ public static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation, @Nullable it.unimi.dsi.fastutil.ints.Int2DoubleFunction curve) { + + public AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation) { + this(id, amount, operation, null); diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index e50564837a..9f04978b10 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -195,6 +195,8 @@ public net.minecraft.world.damagesource.DamageSources source(Lnet/minecraft/reso public net.minecraft.world.damagesource.DamageSources source(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/entity/Entity;)Lnet/minecraft/world/damagesource/DamageSource; # source public net.minecraft.world.damagesource.DamageSources source(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity;)Lnet/minecraft/world/damagesource/DamageSource; # source public net.minecraft.world.damagesource.DamageSources damageTypes # damageTypes +public net.minecraft.world.effect.MobEffect$AttributeTemplate (Lnet/minecraft/resources/ResourceLocation;DLnet/minecraft/world/entity/ai/attributes/AttributeModifier$Operation;)V # constructor +public net.minecraft.world.effect.MobEffect$AttributeTemplate # AttributeTemplate protected net.minecraft.world.entity.Entity ENTITY_COUNTER # ENTITY_COUNTER public net.minecraft.world.entity.Entity getEncodeId()Ljava/lang/String; # getEncodeId public net.minecraft.world.entity.ExperienceOrb value # value From 9131410d3186fe162e680e2d24771839e27f467b Mon Sep 17 00:00:00 2001 From: Dennis C Date: Fri, 29 Nov 2024 04:01:33 +0100 Subject: [PATCH 12/27] Fix nametag set in RenderNameTagEvent.CanRender not being used and not being able to bypass nametag render range (#1675) --- .../renderer/entity/EntityRenderer.java.patch | 16 +++++++------- .../client/event/RenderNameTagEvent.java | 21 ++++++++++++------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch index 2e7b86b284..409ec676f6 100644 --- a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch @@ -9,20 +9,20 @@ this.renderNameTag(p_364816_, p_364816_.nameTag, p_114488_, p_114489_, p_114490_); } } -@@ -270,7 +_,12 @@ +@@ -270,9 +_,11 @@ } p_361028_.distanceToCameraSq = this.entityRenderDispatcher.distanceToSqr(p_362104_); - boolean flag = p_361028_.distanceToCameraSq < 4096.0 && this.shouldShowName(p_362104_, p_361028_.distanceToCameraSq); -+ boolean flag = p_361028_.distanceToCameraSq < 4096.0; -+ if (flag) { -+ var event = new net.neoforged.neoforge.client.event.RenderNameTagEvent.CanRender(p_362104_, p_361028_, p_362104_.getDisplayName(), this, p_362204_); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event); -+ flag = event.canRender().isTrue() || (event.canRender().isDefault() && this.shouldShowName(p_362104_, p_361028_.distanceToCameraSq)); -+ } ++ var event = new net.neoforged.neoforge.client.event.RenderNameTagEvent.CanRender(p_362104_, p_361028_, this.getNameTag(p_362104_), this, p_362204_); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event); ++ boolean flag = event.canRender().isTrue() || (event.canRender().isDefault() && p_361028_.distanceToCameraSq < 4096.0 && this.shouldShowName(p_362104_, p_361028_.distanceToCameraSq)); if (flag) { - p_361028_.nameTag = this.getNameTag(p_362104_); +- p_361028_.nameTag = this.getNameTag(p_362104_); ++ p_361028_.nameTag = event.getContent(); p_361028_.nameTagAttachment = p_362104_.getAttachments().getNullable(EntityAttachment.NAME_TAG, 0, p_362104_.getYRot(p_362204_)); + } else { + p_361028_.nameTag = null; @@ -302,5 +_,7 @@ } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderNameTagEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderNameTagEvent.java index 6e6c501f2f..a33fc96ffe 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderNameTagEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderNameTagEvent.java @@ -16,6 +16,7 @@ import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.util.TriState; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; /** * This event is fired before an entity renderer renders the nameplate of an entity. @@ -26,14 +27,12 @@ */ public abstract class RenderNameTagEvent extends Event { private final EntityRenderState renderState; - protected final Component originalContent; private final EntityRenderer entityRenderer; private final float partialTick; @ApiStatus.Internal - public RenderNameTagEvent(EntityRenderState renderState, Component content, EntityRenderer entityRenderer, float partialTick) { + public RenderNameTagEvent(EntityRenderState renderState, EntityRenderer entityRenderer, float partialTick) { this.renderState = renderState; - this.originalContent = content; this.entityRenderer = entityRenderer; this.partialTick = partialTick; } @@ -69,12 +68,16 @@ public float getPartialTick() { */ public static class CanRender extends RenderNameTagEvent { private final Entity entity; + @Nullable + private final Component originalContent; + @Nullable private Component content; private TriState canRender = TriState.DEFAULT; - public CanRender(Entity entity, EntityRenderState renderState, Component content, EntityRenderer entityRenderer, float partialTick) { - super(renderState, content, entityRenderer, partialTick); + public CanRender(Entity entity, EntityRenderState renderState, @Nullable Component content, EntityRenderer entityRenderer, float partialTick) { + super(renderState, entityRenderer, partialTick); this.entity = entity; + this.originalContent = content; this.content = content; } @@ -88,6 +91,7 @@ public Entity getEntity() { /** * {@return the original text on the nameplate} */ + @Nullable public Component getOriginalContent() { return this.originalContent; } @@ -121,6 +125,7 @@ public void setContent(Component contents) { /** * {@return the text on the nameplate that will be rendered} */ + @Nullable public Component getContent() { return this.content; } @@ -137,12 +142,14 @@ public Component getContent() { * @see EntityRenderer */ public static class DoRender extends RenderNameTagEvent implements ICancellableEvent { + private final Component content; private final PoseStack poseStack; private final MultiBufferSource multiBufferSource; private final int packedLight; public DoRender(EntityRenderState renderState, Component content, EntityRenderer entityRenderer, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight, float partialTick) { - super(renderState, content, entityRenderer, partialTick); + super(renderState, entityRenderer, partialTick); + this.content = content; this.poseStack = poseStack; this.multiBufferSource = multiBufferSource; this.packedLight = packedLight; @@ -152,7 +159,7 @@ public DoRender(EntityRenderState renderState, Component content, EntityRenderer * {@return the text on the nameplate} */ public Component getContent() { - return this.originalContent; + return this.content; } /** From 7bfef487b15a8d3191814b32bf9cf26bdb51aa62 Mon Sep 17 00:00:00 2001 From: Bruno Ploumhans <13494793+Technici4n@users.noreply.github.com> Date: Fri, 29 Nov 2024 19:19:39 +0100 Subject: [PATCH 13/27] Add ${version_name}.jar to the prod client ignoreList, fixes crashes with some launchers (#1718) --- buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java | 3 ++- .../java/net/neoforged/neodev/e2e/RunProductionClient.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java index 9595efc840..d38f91f46b 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java @@ -252,7 +252,8 @@ public void apply(Project project) { } return repos; })); - task.getIgnoreList().addAll("client-extra", "neoforge-"); + // ${version_name}.jar will be filled out by the launcher. It corresponds to the raw SRG Minecraft client jar. + task.getIgnoreList().addAll("client-extra", "${version_name}.jar"); task.setModules(configurations.modulePath); task.getLauncherProfile().set(neoDevBuildDir.map(dir -> dir.file("launcher-profile.json"))); }); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java index f279952f78..e710999e70 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java @@ -230,6 +230,7 @@ private void applyVersionManifest(Path installDir, var gameJar = installDir.resolve("versions").resolve(versionId).resolve(versionId + ".jar"); copyIfNeeded(getOriginalClientJar().get().getAsFile().toPath(), gameJar); classpathItems.add(gameJar.toAbsolutePath().toString()); + placeholders.put("version_name", versionId); var classpath = String.join(File.pathSeparator, classpathItems); placeholders.putIfAbsent("classpath", classpath); From d15b815eeb3bcf0f65b0f178cee9a91e168c15e6 Mon Sep 17 00:00:00 2001 From: ZestyBlaze <68081568+ZestyBlaze@users.noreply.github.com> Date: Fri, 29 Nov 2024 20:15:38 +0000 Subject: [PATCH 14/27] Remove some missed deprecations (#1686) --- .../resources/assets/c/lang/en_us.json | 1 - .../data/c/tags/item/slime_balls.json | 4 ---- .../data/c/tags/item/slimeballs.json | 5 ----- .../net/neoforged/neoforge/common/Tags.java | 7 ------- .../internal/NeoForgeItemTagsProvider.java | 3 +-- .../internal/NeoForgeLanguageProvider.java | 1 - .../neoforge/registries/DeferredRegister.java | 21 ------------------- 7 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 src/generated/resources/data/c/tags/item/slimeballs.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 3c27e29b49..ddba91b3e2 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -330,7 +330,6 @@ "tag.item.c.seeds.wheat": "Wheat Seeds", "tag.item.c.shulker_boxes": "Shulker Boxes", "tag.item.c.slime_balls": "Slimeballs", - "tag.item.c.slimeballs": "Slimeballs", "tag.item.c.stones": "Stones", "tag.item.c.storage_blocks": "Storage Blocks", "tag.item.c.storage_blocks.bone_meal": "Bone Meal Storage Blocks", diff --git a/src/generated/resources/data/c/tags/item/slime_balls.json b/src/generated/resources/data/c/tags/item/slime_balls.json index c5d2c7d82d..168a8c2a45 100644 --- a/src/generated/resources/data/c/tags/item/slime_balls.json +++ b/src/generated/resources/data/c/tags/item/slime_balls.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:slime_ball", - { - "id": "#c:slimeballs", - "required": false - }, { "id": "#forge:slime_balls", "required": false diff --git a/src/generated/resources/data/c/tags/item/slimeballs.json b/src/generated/resources/data/c/tags/item/slimeballs.json deleted file mode 100644 index 533c25d916..0000000000 --- a/src/generated/resources/data/c/tags/item/slimeballs.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "values": [ - "minecraft:slime_ball" - ] -} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index 8e3333d0fd..68d31d129b 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -613,13 +613,6 @@ public static class Items { */ public static final TagKey SHULKER_BOXES = tag("shulker_boxes"); public static final TagKey SLIME_BALLS = tag("slime_balls"); - /** - * Please use properly named {@link Tags.Items#SLIME_BALLS} tag and field instead - *

- * TODO: Remove in 1.21.1 - */ - @Deprecated(since = "1.21") - public static final TagKey SLIMEBALLS = tag("slimeballs"); /** * Natural stone-like blocks that can be used as a base ingredient in recipes that takes stone. */ diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index 36c67fbaba..1b0db4cfca 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -222,8 +222,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Items.SEEDS_MELON).add(Items.MELON_SEEDS); tag(Tags.Items.SEEDS_PUMPKIN).add(Items.PUMPKIN_SEEDS); tag(Tags.Items.SEEDS_WHEAT).add(Items.WHEAT_SEEDS); - tag(Tags.Items.SLIMEBALLS).add(Items.SLIME_BALL); // Deprecated - tag(Tags.Items.SLIME_BALLS).add(Items.SLIME_BALL).addOptionalTag(Tags.Items.SLIMEBALLS); + tag(Tags.Items.SLIME_BALLS).add(Items.SLIME_BALL); tag(Tags.Items.SHULKER_BOXES) .add(Items.SHULKER_BOX).add(Items.WHITE_SHULKER_BOX).add(Items.ORANGE_SHULKER_BOX) .add(Items.MAGENTA_SHULKER_BOX).add(Items.LIGHT_BLUE_SHULKER_BOX).add(Items.YELLOW_SHULKER_BOX) diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index f764016f5c..83b4cbcc2a 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -304,7 +304,6 @@ protected void addTranslations() { add(Tags.Items.SEEDS_WHEAT, "Wheat Seeds"); add(Tags.Items.SHULKER_BOXES, "Shulker Boxes"); add(Tags.Items.SLIME_BALLS, "Slimeballs"); - add(Tags.Items.SLIMEBALLS, "Slimeballs"); add(Tags.Items.STONES, "Stones"); add(Tags.Items.STORAGE_BLOCKS, "Storage Blocks"); add(Tags.Items.STORAGE_BLOCKS_BONE_MEAL, "Bone Meal Storage Blocks"); diff --git a/src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java b/src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java index f839b4c3cb..4d44f562f9 100644 --- a/src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java +++ b/src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java @@ -170,21 +170,6 @@ public static DataComponents createDataComponents(ResourceKey> registryKey; private final String namespace; private final Map, Supplier> entries = new LinkedHashMap<>(); @@ -651,12 +636,6 @@ protected DataComponents(ResourceKey>> registryKey super(registryKey, namespace); } - /** @deprecated Scheduled for removal in 1.21.2; use {@link DataComponents#DataComponents(ResourceKey, String)} */ - @Deprecated(since = "1.21.1", forRemoval = true) - protected DataComponents(String namespace) { - super(Registries.DATA_COMPONENT_TYPE, namespace); - } - /** * Convenience method that constructs a builder for use in the operator. Use this to avoid inference issues. * From 2ce05073bc05a21ff8ae3881ed78e6a0f7b64f95 Mon Sep 17 00:00:00 2001 From: dhyces <10985914+dhyces@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:56:40 -0500 Subject: [PATCH 15/27] [1.21.3] `RegisterRenderStateModifiersEvent` for appending custom data to render state objects (#1650) --- .../client/renderer/MapRenderer.java.patch | 11 +- .../renderer/entity/EntityRenderer.java.patch | 8 + .../entity/state/EntityRenderState.java.patch | 9 ++ .../renderer/state/MapRenderState.java.patch | 13 +- .../neoforge/client/ClientHooks.java | 2 + .../extensions/IRenderStateExtension.java | 66 ++++++++ .../client/renderstate/BaseRenderState.java | 43 ++++++ .../MapDecorationRenderStateModifier.java | 27 ++++ .../RegisterRenderStateModifiersEvent.java | 142 ++++++++++++++++++ .../renderstate/RenderStateExtensions.java | 83 ++++++++++ .../client/renderstate/package-info.java | 13 ++ .../debug/client/ClientEventTests.java | 63 ++++++++ .../client/MapDecorationRenderTests.java | 50 +++++- 13 files changed, 526 insertions(+), 4 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/client/extensions/IRenderStateExtension.java create mode 100644 src/main/java/net/neoforged/neoforge/client/renderstate/BaseRenderState.java create mode 100644 src/main/java/net/neoforged/neoforge/client/renderstate/MapDecorationRenderStateModifier.java create mode 100644 src/main/java/net/neoforged/neoforge/client/renderstate/RegisterRenderStateModifiersEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/renderstate/RenderStateExtensions.java create mode 100644 src/main/java/net/neoforged/neoforge/client/renderstate/package-info.java diff --git a/patches/net/minecraft/client/renderer/MapRenderer.java.patch b/patches/net/minecraft/client/renderer/MapRenderer.java.patch index 8d0c96067c..8a46ee0351 100644 --- a/patches/net/minecraft/client/renderer/MapRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/MapRenderer.java.patch @@ -11,7 +11,16 @@ p_362483_.pushPose(); p_362483_.translate( (float)maprenderstate$mapdecorationrenderstate.x / 2.0F + 64.0F, (float)maprenderstate$mapdecorationrenderstate.y / 2.0F + 64.0F, -0.02F -@@ -116,6 +_,7 @@ +@@ -109,13 +_,15 @@ + p_364922_.texture = this.mapTextureManager.prepareMapTexture(p_361383_, p_363500_); + p_364922_.decorations.clear(); + ++ net.neoforged.neoforge.client.renderstate.RenderStateExtensions.onUpdateMapRenderState(p_363500_, p_364922_); + for (MapDecoration mapdecoration : p_363500_.getDecorations()) { +- p_364922_.decorations.add(this.extractDecorationRenderState(mapdecoration)); ++ p_364922_.decorations.add(net.neoforged.neoforge.client.renderstate.RenderStateExtensions.onUpdateMapDecorationRenderState(mapdecoration.type(), p_363500_, p_364922_, this.extractDecorationRenderState(mapdecoration))); + } + } private MapRenderState.MapDecorationRenderState extractDecorationRenderState(MapDecoration p_364175_) { MapRenderState.MapDecorationRenderState maprenderstate$mapdecorationrenderstate = new MapRenderState.MapDecorationRenderState(); diff --git a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch index 409ec676f6..3a5d1e4205 100644 --- a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch @@ -9,6 +9,14 @@ this.renderNameTag(p_364816_, p_364816_.nameTag, p_114488_, p_114489_, p_114490_); } } +@@ -245,6 +_,7 @@ + public final S createRenderState(T p_361382_, float p_360885_) { + S s = this.reusedState; + this.extractRenderState(p_361382_, s, p_360885_); ++ net.neoforged.neoforge.client.renderstate.RenderStateExtensions.onUpdateEntityRenderState(this, p_361382_, s); + return s; + } + @@ -270,9 +_,11 @@ } diff --git a/patches/net/minecraft/client/renderer/entity/state/EntityRenderState.java.patch b/patches/net/minecraft/client/renderer/entity/state/EntityRenderState.java.patch index a9fd80707c..7614a11b9f 100644 --- a/patches/net/minecraft/client/renderer/entity/state/EntityRenderState.java.patch +++ b/patches/net/minecraft/client/renderer/entity/state/EntityRenderState.java.patch @@ -1,5 +1,14 @@ --- a/net/minecraft/client/renderer/entity/state/EntityRenderState.java +++ b/net/minecraft/client/renderer/entity/state/EntityRenderState.java +@@ -7,7 +_,7 @@ + import net.neoforged.api.distmarker.OnlyIn; + + @OnlyIn(Dist.CLIENT) +-public class EntityRenderState { ++public class EntityRenderState extends net.neoforged.neoforge.client.renderstate.BaseRenderState { + public double x; + public double y; + public double z; @@ -27,6 +_,7 @@ public Vec3 nameTagAttachment; @Nullable diff --git a/patches/net/minecraft/client/renderer/state/MapRenderState.java.patch b/patches/net/minecraft/client/renderer/state/MapRenderState.java.patch index 2ac034ae3d..cadb13bc87 100644 --- a/patches/net/minecraft/client/renderer/state/MapRenderState.java.patch +++ b/patches/net/minecraft/client/renderer/state/MapRenderState.java.patch @@ -1,9 +1,18 @@ --- a/net/minecraft/client/renderer/state/MapRenderState.java +++ b/net/minecraft/client/renderer/state/MapRenderState.java -@@ -17,6 +_,7 @@ +@@ -10,13 +_,14 @@ + import net.neoforged.api.distmarker.OnlyIn; + + @OnlyIn(Dist.CLIENT) +-public class MapRenderState { ++public class MapRenderState extends net.neoforged.neoforge.client.renderstate.BaseRenderState { + @Nullable + public ResourceLocation texture; + public final List decorations = new ArrayList<>(); @OnlyIn(Dist.CLIENT) - public static class MapDecorationRenderState { +- public static class MapDecorationRenderState { ++ public static class MapDecorationRenderState extends net.neoforged.neoforge.client.renderstate.BaseRenderState { + public net.minecraft.core.Holder type; @Nullable public TextureAtlasSprite atlasSprite; diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index ce6aa279b3..c7e42d8975 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -180,6 +180,7 @@ import net.neoforged.neoforge.client.gui.GuiLayerManager; import net.neoforged.neoforge.client.gui.map.MapDecorationRendererManager; import net.neoforged.neoforge.client.model.data.ModelData; +import net.neoforged.neoforge.client.renderstate.RegisterRenderStateModifiersEvent; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForgeMod; import net.neoforged.neoforge.forge.snapshots.ForgeSnapshotsModClient; @@ -990,6 +991,7 @@ public static void initClientHooks(Minecraft mc, ReloadableResourceManager resou ModLoader.postEvent(new RegisterClientReloadListenersEvent(resourceManager)); ModLoader.postEvent(new EntityRenderersEvent.RegisterLayerDefinitions()); ModLoader.postEvent(new EntityRenderersEvent.RegisterRenderers()); + ModLoader.postEvent(new RegisterRenderStateModifiersEvent()); ClientTooltipComponentManager.init(); EntitySpectatorShaderManager.init(); ClientHooks.onRegisterKeyMappings(mc.options); diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IRenderStateExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IRenderStateExtension.java new file mode 100644 index 0000000000..1170a443ac --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IRenderStateExtension.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.extensions; + +import net.minecraft.util.context.ContextKey; +import net.neoforged.neoforge.client.renderstate.BaseRenderState; +import org.jetbrains.annotations.Nullable; + +/** + * Extension class for render state objects. Implemented by {@link BaseRenderState} for + * simple class extension. + */ +public interface IRenderStateExtension { + /** + * Gets the object associated with the given key. + * + * @param key Static key reference object + * @return The object associated with the key or null if the key is not present. + * @param Type of render data + */ + @Nullable + T getRenderData(ContextKey key); + + /** + * Sets the object associated with the given key. Key should be stored statically for later retrieval of the object. + * + * @param key Static key reference object + * @param data Object to store for custom rendering + * @param Type of render data + */ + void setRenderData(ContextKey key, @Nullable T data); + + /** + * Gets the value or throws an exception. Should be used in cases where the data must be present. + * + * @param key Static key reference object + * @return The data associate with the key + * @param Type of render data + */ + default T getRenderDataOrThrow(ContextKey key) { + T data = getRenderData(key); + if (data == null) { + throw new IllegalStateException("No value associated for key " + key); + } + return data; + } + + /** + * Gets the value or returns the default object if an object is not present + * + * @param key Static key reference object + * @param defaultVal Default value if an object is not present + * @return Value from the render data or the given default value if value is not present + * @param Type of render data + */ + default T getRenderDataOrDefault(ContextKey key, T defaultVal) { + T data = getRenderData(key); + if (data == null) { + return defaultVal; + } + return data; + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/renderstate/BaseRenderState.java b/src/main/java/net/neoforged/neoforge/client/renderstate/BaseRenderState.java new file mode 100644 index 0000000000..cbdd40218d --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/renderstate/BaseRenderState.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.renderstate; + +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import java.util.Map; +import net.minecraft.client.renderer.entity.state.EntityRenderState; +import net.minecraft.util.context.ContextKey; +import net.neoforged.neoforge.client.extensions.IRenderStateExtension; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +/** + * Extension class for RenderState objects (ie {@link EntityRenderState}). + * Allows modders to add arbitrary data onto render states for use in custom rendering. + */ +public abstract class BaseRenderState implements IRenderStateExtension { + protected final Map, Object> extensions = new Reference2ObjectOpenHashMap<>(); + + @SuppressWarnings("unchecked") + @Nullable + @Override + public T getRenderData(ContextKey key) { + return (T) extensions.get(key); + } + + @Override + public void setRenderData(ContextKey key, @Nullable T data) { + if (data != null) { + extensions.put(key, data); + } else { + extensions.remove(key); + } + } + + @ApiStatus.Internal + public void resetRenderData() { + extensions.clear(); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/renderstate/MapDecorationRenderStateModifier.java b/src/main/java/net/neoforged/neoforge/client/renderstate/MapDecorationRenderStateModifier.java new file mode 100644 index 0000000000..50f8c1a1d7 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/renderstate/MapDecorationRenderStateModifier.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.renderstate; + +import net.minecraft.client.renderer.state.MapRenderState; +import net.minecraft.world.level.saveddata.maps.MapDecorationType; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import net.neoforged.neoforge.client.gui.map.IMapDecorationRenderer; + +/** + * Function interface for render state modifiers that target MapDecorations. Useful for adding custom data for rendering + * in {@link IMapDecorationRenderer}s. + */ +@FunctionalInterface +public interface MapDecorationRenderStateModifier { + /** + * Called when the registered {@link MapDecorationType} is added to a {@link MapRenderState}. + * + * @param mapItemSavedData The map SavedData. + * @param mapRenderState The render state of the map after the texture has been set and custom data is added. + * @param mapDecorationRenderState The decoration render state after vanilla has set it up. + */ + void accept(MapItemSavedData mapItemSavedData, MapRenderState mapRenderState, MapRenderState.MapDecorationRenderState mapDecorationRenderState); +} diff --git a/src/main/java/net/neoforged/neoforge/client/renderstate/RegisterRenderStateModifiersEvent.java b/src/main/java/net/neoforged/neoforge/client/renderstate/RegisterRenderStateModifiersEvent.java new file mode 100644 index 0000000000..27e30088a4 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/renderstate/RegisterRenderStateModifiersEvent.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.renderstate; + +import com.google.common.reflect.TypeParameter; +import com.google.common.reflect.TypeToken; +import java.lang.reflect.ParameterizedType; +import java.util.function.BiConsumer; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.state.EntityRenderState; +import net.minecraft.client.renderer.state.MapRenderState; +import net.minecraft.resources.ResourceKey; +import net.minecraft.util.context.ContextKey; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.saveddata.maps.MapDecorationType; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.event.IModBusEvent; +import net.neoforged.neoforge.client.extensions.IRenderStateExtension; +import org.jetbrains.annotations.ApiStatus; + +/** + * Fired for registering modifier functions for various render state objects. Useful for gathering context for + * custom rendering with objects that are not your own. + * + *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

+ */ +public class RegisterRenderStateModifiersEvent extends Event implements IModBusEvent { + @ApiStatus.Internal + public RegisterRenderStateModifiersEvent() {} + + /** + * Registers a render state modifier for {@link EntityRenderState}s which are run after all vanilla data is + * extracted. Can add custom data to the map using {@link EntityRenderState#setRenderData(ContextKey, Object)}. + * Any subclasses of the passed renderer class will also have this modifier applied. + * + *
+     * 
+     *     event.registerEntityModifier(new TypeToken>() {}, (entity, renderState) -> {
+     *         . . .
+     *     });
+     * 
+     * 
+ * + * @param baseRenderer Entity renderer class. Any subclasses will also apply this modifier. + * @param modifier The function for modifying the {@link EntityRenderState} and adding custom render data. + * @param The type of the entity + * @param The specific render state type + */ + public void registerEntityModifier(TypeToken> baseRenderer, BiConsumer modifier) { + ensureParametersMatchBounds(baseRenderer); + RenderStateExtensions.registerEntity(baseRenderer.getRawType(), modifier); + } + + /** + * Convenience method for cases where generics are not present. Registers a render state modifier for + * {@link EntityRenderState}s which are run after all vanilla data is extracted. Can add custom data to the map + * using {@link EntityRenderState#setRenderData(ContextKey, Object)}. Any subclasses of the passed renderer class + * will also have this modifier applied. + * + *
+     * 
+     *     event.registerEntityModifier(PlayerRenderer.class, (entity, renderState) -> {
+     *         . . .
+     *     });
+     * 
+     * 
+ * + * @param baseRenderer Entity renderer class. Any subclasses will also apply this modifier. + * @param modifier The function for modifying the {@link EntityRenderState} and adding custom render data. + * @param The type of the entity + * @param The specific render state type + */ + public void registerEntityModifier(Class> baseRenderer, BiConsumer modifier) { + ensureParametersMatchBounds(TypeToken.of(baseRenderer)); + RenderStateExtensions.registerEntity(baseRenderer, modifier); + } + + /** + * Registers a render state modifier for {@link MapRenderState}s which are run after the texture has been set + * and before decorations have been added. Can add custom data to the map using + * {@link IRenderStateExtension#setRenderData(ContextKey, Object)}. + * + * @param modifier The function for modifying the {@link net.minecraft.client.renderer.state.MapRenderState} and adding custom render data. + */ + public void registerMapModifier(BiConsumer modifier) { + RenderStateExtensions.registerMap(modifier); + } + + /** + * Registers a render state modifier for {@link MapRenderState.MapDecorationRenderState}s which are run after + * vanilla map decoration data has been set. Can add custom data to the map using + * {@link IRenderStateExtension#setRenderData(ContextKey, Object)}. + * + * @param mapDecorationTypeKey Key for the registered {@link MapDecorationType} + * @param modifier The function for modifying the {@link MapRenderState.MapDecorationRenderState} and adding custom render data. + */ + public void registerMapDecorationModifier(ResourceKey mapDecorationTypeKey, MapDecorationRenderStateModifier modifier) { + RenderStateExtensions.registerMapDecoration(mapDecorationTypeKey, modifier); + } + + private static void ensureParametersMatchBounds(TypeToken> baseRenderer) { + if (baseRenderer.getType() instanceof ParameterizedType parameterizedType) { + Class bound = baseRenderer.getRawType(); + ParameterizedType parameterized = parameterizedType; + do { + var userArgs = parameterized.getActualTypeArguments(); + var typeArgs = bound.getTypeParameters(); + + for (int i = 0; i < userArgs.length; i++) { + var userArg = userArgs[i]; + var userToken = Container.of(TypeToken.of(userArg)); + var typeArg = typeArgs[i]; + for (var singleBound : typeArg.getBounds()) { + var token = Container.of(TypeToken.of(singleBound)); + if (!token.isSubtypeOf(userToken)) { + throw new IllegalArgumentException("%s does not match expected type parameter %s".formatted(userArg, singleBound)); + } + } + } + + if (!(parameterized.getOwnerType() instanceof ParameterizedType parameterizedOwner)) { + break; + } + parameterized = parameterizedOwner; + bound = bound.getEnclosingClass(); + } while (bound != null); + } + } + + @SuppressWarnings("unused") + private record Container() { + private static TypeToken> of(TypeToken parameter) { + return new TypeToken>() {} + .where(new TypeParameter<>() {}, parameter); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/renderstate/RenderStateExtensions.java b/src/main/java/net/neoforged/neoforge/client/renderstate/RenderStateExtensions.java new file mode 100644 index 0000000000..76c0525f13 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/renderstate/RenderStateExtensions.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.renderstate; + +import com.google.common.collect.ImmutableList; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.state.EntityRenderState; +import net.minecraft.client.renderer.state.MapRenderState; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.saveddata.maps.MapDecorationType; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import org.jetbrains.annotations.ApiStatus; + +public final class RenderStateExtensions { + private RenderStateExtensions() {} + + private static final Map, Collection>> ENTITY = new Reference2ObjectArrayMap<>(); + private static final Map, Collection>> ENTITY_CACHE = new Reference2ObjectOpenHashMap<>(); + + private static final List> MAP = new ObjectArrayList<>(); + + private static final Map, Collection> MAP_DECORATION = new Reference2ObjectArrayMap<>(); + + @SuppressWarnings("unchecked") + @ApiStatus.Internal + public static void onUpdateEntityRenderState(EntityRenderer renderer, E entity, S renderState) { + renderState.resetRenderData(); + var modifiers = (Collection>) (Object) ENTITY_CACHE.computeIfAbsent(renderer.getClass(), aClass -> { + var builder = ImmutableList.>builder(); + for (var entry : ENTITY.entrySet()) { + if (entry.getKey().isAssignableFrom(aClass)) { + builder.addAll(entry.getValue()); + } + } + return builder.build(); + }); + for (BiConsumer modifier : modifiers) { + modifier.accept(entity, renderState); + } + } + + @ApiStatus.Internal + public static void onUpdateMapRenderState(MapItemSavedData mapItemSavedData, MapRenderState renderState) { + renderState.resetRenderData(); + for (BiConsumer modifier : MAP) { + modifier.accept(mapItemSavedData, renderState); + } + } + + @ApiStatus.Internal + public static MapRenderState.MapDecorationRenderState onUpdateMapDecorationRenderState(Holder mapDecorationTypeHolder, MapItemSavedData mapItemSavedData, MapRenderState mapRenderState, MapRenderState.MapDecorationRenderState mapDecorationRenderState) { + mapDecorationRenderState.resetRenderData(); + var modifiers = MAP_DECORATION.getOrDefault(mapDecorationTypeHolder.getKey(), List.of()); + for (var modifier : modifiers) { + modifier.accept(mapItemSavedData, mapRenderState, mapDecorationRenderState); + } + return mapDecorationRenderState; + } + + static void registerEntity(Class baseRenderer, BiConsumer modifier) { + ENTITY.computeIfAbsent(baseRenderer, aClass -> new ObjectArrayList<>()).add(modifier); + } + + static void registerMap(BiConsumer modifier) { + MAP.add(modifier); + } + + static void registerMapDecoration(ResourceKey mapDecorationTypeKey, MapDecorationRenderStateModifier modifier) { + MAP_DECORATION.computeIfAbsent(mapDecorationTypeKey, aClass -> new ObjectArrayList<>()).add(modifier); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/renderstate/package-info.java b/src/main/java/net/neoforged/neoforge/client/renderstate/package-info.java new file mode 100644 index 0000000000..c698250154 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/renderstate/package-info.java @@ -0,0 +1,13 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +@FieldsAreNonnullByDefault +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package net.neoforged.neoforge.client.renderstate; + +import javax.annotation.ParametersAreNonnullByDefault; +import net.minecraft.FieldsAreNonnullByDefault; +import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java index aebcf64746..88e0f2d82b 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java @@ -5,15 +5,27 @@ package net.neoforged.neoforge.debug.client; +import com.google.common.reflect.TypeToken; import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.math.Axis; import java.util.Map; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.AbstractHoglinRenderer; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.client.renderer.entity.player.PlayerRenderer; +import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.core.SectionPos; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.context.ContextKey; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.monster.hoglin.HoglinBase; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Blocks; @@ -24,8 +36,10 @@ import net.neoforged.neoforge.client.event.ClientPlayerChangeGameTypeEvent; import net.neoforged.neoforge.client.event.RegisterRenderBuffersEvent; import net.neoforged.neoforge.client.event.RenderLevelStageEvent; +import net.neoforged.neoforge.client.event.RenderLivingEvent; import net.neoforged.neoforge.client.event.RenderPlayerEvent; import net.neoforged.neoforge.client.model.data.ModelData; +import net.neoforged.neoforge.client.renderstate.RegisterRenderStateModifiersEvent; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; @@ -126,4 +140,53 @@ static void renderPlayerEvent(final DynamicTest test) { test.requestConfirmation(Minecraft.getInstance().player, Component.literal("Is an iron block rendered above you in third-person?")); }); } + + @TestHolder(description = { "Test render state modifier system and registration event" }) + static void updateRenderState(final DynamicTest test) { + var rotationKey = new ContextKey(ResourceLocation.fromNamespaceAndPath(test.createModId(), "rotation")); + var numRenderAttachmentKey = new ContextKey(ResourceLocation.fromNamespaceAndPath(test.createModId(), "times_to_render")); + var testAttachment = test.registrationHelper().attachments().registerSimpleAttachment("test", () -> 3); + test.framework().modEventBus().addListener((RegisterRenderStateModifiersEvent event) -> { + event.registerEntityModifier(PlayerRenderer.class, (entity, renderState) -> { + renderState.setRenderData(rotationKey, 45f); + }); + event.registerEntityModifier(new TypeToken>() {}, (entity, renderState) -> { + renderState.setRenderData(numRenderAttachmentKey, entity.getData(testAttachment)); + }); + // Test other type parameters for safety + event.registerEntityModifier(new TypeToken>() {}, (entity, renderState) -> {}); + event.registerEntityModifier(new TypeToken>() {}, (entity, renderState) -> {}); + try { + class TestBrokenHoglinRendererTypeToken extends TypeToken> {} + event.registerEntityModifier(new TestBrokenHoglinRendererTypeToken<>(), (entity, renderState) -> {}); + test.fail("Unsafe type parameter succeeded. Cannot assume T can be ?."); + } catch (IllegalArgumentException ignored) {} + }); + test.whenEnabled(listeners -> { + listeners.forge().addListener((RenderLivingEvent.Post event) -> { + int numRender = event.getRenderState().getRenderDataOrDefault(numRenderAttachmentKey, -1); + if (numRender == -1) { + test.fail("Attachment render data not set"); + return; + } + float xRotation = event.getRenderState().getRenderDataOrDefault(rotationKey, 0f); + if (event.getRenderer() instanceof PlayerRenderer && numRender == 0) { + test.fail("Custom render data not set for player"); + return; + } + var poseStack = event.getPoseStack(); + poseStack.pushPose(); + poseStack.scale(0.3f, 0.3f, 0.3f); + for (int i = 0; i < numRender; i++) { + poseStack.translate(0, 1, 0); + poseStack.pushPose(); + poseStack.mulPose(Axis.XP.rotation(xRotation)); + Minecraft.getInstance().getBlockRenderer().renderSingleBlock(Blocks.CALCITE.defaultBlockState(), poseStack, event.getMultiBufferSource(), event.getPackedLight(), OverlayTexture.NO_OVERLAY, ModelData.EMPTY, RenderType.solid()); + poseStack.popPose(); + } + poseStack.popPose(); + test.pass(); + }); + }); + } } diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/MapDecorationRenderTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/MapDecorationRenderTests.java index ad8ddb7aba..8f1ad0ab8e 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/client/MapDecorationRenderTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/MapDecorationRenderTests.java @@ -17,6 +17,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; +import net.minecraft.util.context.ContextKey; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.MapItem; @@ -25,6 +26,7 @@ import net.neoforged.api.distmarker.Dist; import net.neoforged.neoforge.client.gui.map.IMapDecorationRenderer; import net.neoforged.neoforge.client.gui.map.RegisterMapDecorationRenderersEvent; +import net.neoforged.neoforge.client.renderstate.RegisterRenderStateModifiersEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; @@ -49,7 +51,7 @@ static void customRenderer(DynamicTest test) { false)); test.framework().modEventBus().addListener((RegisterMapDecorationRenderersEvent event) -> { - event.register(decorationType.value(), new TestDecorationRenderer()); + event.register(decorationType.value(), new TestDecorationRenderer(null)); }); test.eventListeners().forge().addListener((PlayerEvent.PlayerLoggedInEvent event) -> { @@ -67,7 +69,50 @@ static void customRenderer(DynamicTest test) { }); } + @EmptyTemplate + @TestHolder(description = "Tests if custom map decoration render state data works") + static void customRenderData(DynamicTest test) { + var key = new ContextKey(ResourceLocation.fromNamespaceAndPath(test.createModId(), "custom_color")); + var decorationType = test.registrationHelper().registrar(Registries.MAP_DECORATION_TYPE).register( + "test", + () -> new MapDecorationType( + ResourceLocation.withDefaultNamespace("target_x"), + false, + -1, + false, + false)); + + test.framework().modEventBus().addListener((RegisterMapDecorationRenderersEvent event) -> { + event.register(decorationType.value(), new TestDecorationRenderer(key)); + }); + test.framework().modEventBus().addListener((RegisterRenderStateModifiersEvent event) -> { + event.registerMapDecorationModifier(decorationType.getKey(), (mapItemSavedData, mapRenderState, mapDecorationRenderState) -> { + mapDecorationRenderState.setRenderData(key, 0xFFFFAABB); + }); + }); + + test.eventListeners().forge().addListener((PlayerEvent.PlayerLoggedInEvent event) -> { + Player player = event.getEntity(); + ItemStack mapItem = MapItem.create(player.level(), player.getBlockX(), player.getBlockZ(), (byte) 0, true, false); + MapItemSavedData data = MapItem.getSavedData(mapItem, player.level()); + if (data == null) { + test.fail("Map data missing for new map"); + return; + } + String markerName = player.getName().getString() + "_test_marker"; + data.addDecoration(decorationType, player.level(), markerName, data.centerX, data.centerZ, 0, null); + player.getInventory().add(mapItem); + test.requestConfirmation(player, Component.literal("Does the map show a pink cross?")); + }); + } + private static final class TestDecorationRenderer implements IMapDecorationRenderer { + private final ContextKey customColorKey; + + TestDecorationRenderer(ContextKey customColorKey) { + this.customColorKey = customColorKey; + } + @Override public boolean render( MapRenderState.MapDecorationRenderState decoration, @@ -93,6 +138,9 @@ public boolean render( float hue = (System.currentTimeMillis() % 3000L) / 3000F; int color = Mth.hsvToArgb(hue, 1F, 1F, 0xFF); + if (decoration.getRenderData(customColorKey) != null) { + color = decoration.getRenderDataOrThrow(customColorKey); + } VertexConsumer buffer = bufferSource.getBuffer(RenderType.text(sprite.atlasLocation())); buffer.addVertex(pose, -1.0F, 1.0F, index * -0.001F).setColor(color).setUv(u0, v0).setLight(packedLight); From 8e9be9fb44826d563a865f75dbbb547a546ee1a6 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 30 Nov 2024 17:34:17 +0200 Subject: [PATCH 16/27] 1.21.3 stable --- projects/neoforge/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/neoforge/build.gradle b/projects/neoforge/build.gradle index 3912a5bd30..9227a224e7 100644 --- a/projects/neoforge/build.gradle +++ b/projects/neoforge/build.gradle @@ -18,7 +18,7 @@ evaluationDependsOn(":neoforge-coremods") gradleutils.setupSigning(project: project, signAllPublications: true) changelog { - from '21.0' + from '21.3' disableAutomaticPublicationRegistration() } From 2c7c3f2796deccf8a5df239584d8b8a93ac5f0f2 Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:48:48 +0100 Subject: [PATCH 17/27] Port to 1.21.4 Co-authored-by: coehlrich Co-authored-by: Marc Hermans Co-authored-by: Matyrobbrt Co-authored-by: Minecraftschurli Co-authored-by: Technici4n <13494793+Technici4n@users.noreply.github.com> Co-authored-by: XFactHD --- .gitignore | 2 +- .../neoforged/neodev/CreateUserDevConfig.java | 20 +- .../neoforged/neodev/NeoDevBasePlugin.java | 7 +- .../neodev/installer/CreateArgsFile.java | 2 +- .../installer/CreateLauncherProfile.java | 2 +- gradle.properties | 10 +- .../mojang/blaze3d/platform/Window.java.patch | 6 +- .../blaze3d/systems/RenderSystem.java.patch | 2 +- patches/net/minecraft/Util.java.patch | 4 +- .../minecraft/client/KeyMapping.java.patch | 20 +- .../net/minecraft/client/Minecraft.java.patch | 103 +++----- .../client/color/block/BlockColors.java.patch | 10 +- .../client/color/item/ItemColors.java.patch | 43 ---- .../color/item/ItemTintSources.java.patch | 10 + .../net/minecraft/client/data/Main.java.patch | 40 +++ .../net/minecraft/client/gui/Font.java.patch | 16 +- .../net/minecraft/client/gui/Gui.java.patch | 4 +- .../client/gui/GuiGraphics.java.patch | 18 +- .../gui/components/AbstractWidget.java.patch | 4 +- .../gui/font/glyphs/BakedGlyph.java.patch | 4 +- .../gui/screens/LoadingOverlay.java.patch | 4 +- .../client/gui/screens/Screen.java.patch | 2 +- .../client/gui/screens/TitleScreen.java.patch | 8 +- .../AbstractContainerScreen.java.patch | 30 +-- .../CreativeModeInventoryScreen.java.patch | 52 ++-- .../inventory/EnchantmentScreen.java.patch | 2 +- .../options/controls/KeyBindsList.java.patch | 4 +- .../CreateWorldScreen.java.patch | 8 +- .../ExperimentsScreen.java.patch | 2 +- .../WorldSelectionList.java.patch | 4 +- .../net/minecraft/client/main/Main.java.patch | 5 +- .../client/model/HumanoidModel.java.patch | 8 +- .../model/geom/LayerDefinitions.java.patch | 6 +- .../client/model/geom/ModelLayers.java.patch | 8 +- .../multiplayer/ClientChunkCache.java.patch | 2 +- .../client/multiplayer/ClientLevel.java.patch | 76 +++--- .../ClientPacketListener.java.patch | 14 +- .../MultiPlayerGameMode.java.patch | 26 +- .../client/multiplayer/PlayerInfo.java.patch | 2 +- .../particle/BreakingItemParticle.java.patch | 11 - .../particle/ItemPickupParticle.java.patch | 2 +- .../client/particle/Particle.java.patch | 2 +- .../client/particle/ParticleEngine.java.patch | 99 ++++++-- .../particle/ParticleRenderType.java.patch | 35 ++- .../client/player/LocalPlayer.java.patch | 50 ++-- .../client/renderer/GameRenderer.java.patch | 8 +- .../renderer/ItemBlockRenderTypes.java.patch | 18 +- .../renderer/ItemInHandRenderer.java.patch | 38 +-- .../client/renderer/LevelRenderer.java.patch | 86 ++++--- .../client/renderer/RenderType.java.patch | 2 +- .../renderer/ScreenEffectRenderer.java.patch | 40 +-- .../client/renderer/ShaderManager.java.patch | 10 +- .../client/renderer/Sheets.java.patch | 20 +- .../renderer/WeatherEffectRenderer.java.patch | 8 +- .../block/BlockRenderDispatcher.java.patch | 65 +++-- .../block/model/BakedOverrides.java.patch | 38 --- .../block/model/BlockElement.java.patch | 10 +- .../block/model/BlockModel.java.patch | 179 +++++++------- .../block/model/FaceBakery.java.patch | 2 +- .../block/model/ItemModelGenerator.java.patch | 55 ++++- .../block/model/ItemTransforms.java.patch | 69 ++---- .../block/model/MultiVariant.java.patch | 17 -- ....patch => AbstractSignRenderer.java.patch} | 18 +- .../blockentity/BannerRenderer.java.patch | 2 +- .../DecoratedPotRenderer.java.patch | 2 +- .../blockentity/ShulkerBoxRenderer.java.patch | 4 +- .../blockentity/SkullBlockRenderer.java.patch | 17 +- .../chunk/SectionRenderDispatcher.java.patch | 6 +- .../entity/EntityRenderDispatcher.java.patch | 6 +- .../renderer/entity/EntityRenderer.java.patch | 6 +- .../entity/FishingHookRenderer.java.patch | 16 +- .../entity/HumanoidMobRenderer.java.patch | 2 +- .../entity/ItemEntityRenderer.java.patch | 35 +-- .../entity/ItemFrameRenderer.java.patch | 26 +- .../renderer/entity/ItemRenderer.java.patch | 49 +--- .../entity/LivingEntityRenderer.java.patch | 24 +- .../layers/EquipmentLayerRenderer.java.patch | 26 +- .../entity/player/PlayerRenderer.java.patch | 55 +++-- .../state/ItemClusterRenderState.java.patch | 10 + .../state/ItemEntityRenderState.java.patch | 8 + .../entity/state/PlayerRenderState.java.patch | 10 - .../item/BlockModelWrapper.java.patch | 44 ++++ .../renderer/item/ItemModels.java.patch | 10 + .../renderer/item/ItemProperties.java.patch | 23 -- .../item/ItemStackRenderState.java.patch | 21 ++ .../ConditionalItemModelProperties.java.patch | 10 + .../RangeSelectItemModelProperties.java.patch | 10 + .../SelectItemModelProperties.java.patch | 10 + .../special/SpecialModelRenderers.java.patch | 11 + .../texture/AbstractTexture.java.patch | 14 +- .../texture/SpriteContents.java.patch | 18 +- .../renderer/texture/TextureAtlas.java.patch | 8 +- .../atlas/SpriteResourceLoader.java.patch | 27 +- .../resources/model/BakedModel.java.patch | 13 +- .../model/DelegateBakedModel.java.patch | 6 +- .../resources/model/ItemModel.java.patch | 16 -- .../resources/model/ModelBaker.java.patch | 9 +- .../resources/model/ModelBakery.java.patch | 120 +++++---- .../resources/model/ModelDiscovery.java.patch | 41 ++-- .../resources/model/ModelManager.java.patch | 92 ++++--- .../model/ModelResourceLocation.java.patch | 25 -- .../model/SimpleBakedModel.java.patch | 77 ++++-- .../resources/model/UnbakedModel.java.patch | 57 +++++ .../client/sounds/MusicManager.java.patch | 14 +- .../client/sounds/SoundEngine.java.patch | 12 +- .../PatchedDataComponentMap.java.patch | 4 +- .../minecraft/data/DataProvider.java.patch | 4 +- patches/net/minecraft/data/Main.java.patch | 49 ++-- .../data/loot/BlockLootSubProvider.java.patch | 2 +- .../game/ServerGamePacketListener.java.patch | 4 +- .../resources/FileToIdConverter.java.patch | 2 +- .../resources/HolderSetCodec.java.patch | 6 +- .../resources/RegistryDataLoader.java.patch | 8 +- .../net/minecraft/server/Bootstrap.java.patch | 4 +- patches/net/minecraft/server/Main.java.patch | 25 +- .../ReloadableServerRegistries.java.patch | 9 +- .../server/level/ServerEntity.java.patch | 2 +- .../server/level/ServerLevel.java.patch | 60 ++--- .../server/level/ServerPlayer.java.patch | 46 ++-- .../ServerGamePacketListenerImpl.java.patch | 111 +++++---- .../packs/AbstractPackResources.java.patch | 2 +- .../packs/OverlayMetadataSection.java.patch | 4 +- .../pack/PackMetadataSection.java.patch | 2 +- ...impleJsonResourceReloadListener.java.patch | 34 ++- .../net/minecraft/tags/ItemTags.java.patch | 2 +- .../net/minecraft/util/SpawnUtil.java.patch | 6 +- .../util/context/ContextKeySet.java.patch | 12 + .../util/context/ContextMap.java.patch | 10 + .../util/datafix/DataFixers.java.patch | 26 +- .../world/effect/PoisonMobEffect.java.patch | 2 +- .../minecraft/world/entity/Entity.java.patch | 58 ++--- .../world/entity/EntityType.java.patch | 24 +- .../world/entity/ExperienceOrb.java.patch | 8 +- .../world/entity/LivingEntity.java.patch | 146 +++++------ .../net/minecraft/world/entity/Mob.java.patch | 28 +-- .../world/entity/SpawnPlacements.java.patch | 2 +- .../world/entity/TamableAnimal.java.patch | 2 +- .../attributes/DefaultAttributes.java.patch | 2 +- .../world/entity/animal/Bee.java.patch | 4 +- .../world/entity/animal/Cat.java.patch | 4 +- .../entity/animal/MushroomCow.java.patch | 14 +- .../world/entity/animal/Parrot.java.patch | 12 +- .../world/entity/animal/Pig.java.patch | 8 +- .../world/entity/animal/Sheep.java.patch | 2 +- .../entity/animal/allay/Allay.java.patch | 2 +- .../entity/animal/frog/Tadpole.java.patch | 10 +- .../boss/enderdragon/EnderDragon.java.patch | 6 +- .../entity/boss/wither/WitherBoss.java.patch | 8 +- .../decoration/HangingEntity.java.patch | 6 +- .../monster/AbstractSkeleton.java.patch | 4 +- .../world/entity/monster/EnderMan.java.patch | 23 +- .../world/entity/monster/Pillager.java.patch | 2 +- .../world/entity/monster/Ravager.java.patch | 4 +- .../world/entity/monster/Skeleton.java.patch | 4 +- .../world/entity/monster/Slime.java.patch | 6 +- .../world/entity/monster/Zombie.java.patch | 2 +- .../monster/creaking/Creaking.java.patch | 18 +- .../entity/monster/piglin/Piglin.java.patch | 6 +- .../world/entity/npc/Villager.java.patch | 8 +- .../world/entity/player/Inventory.java.patch | 6 +- .../world/entity/player/Player.java.patch | 76 +++--- .../projectile/AbstractArrow.java.patch | 4 +- .../AbstractHurtingProjectile.java.patch | 4 +- .../entity/projectile/Projectile.java.patch | 2 +- .../world/flag/FeatureFlags.java.patch | 2 +- .../world/inventory/ArmorSlot.java.patch | 2 +- .../inventory/BrewingStandMenu.java.patch | 12 +- .../inventory/EnchantmentMenu.java.patch | 8 +- .../minecraft/world/inventory/Slot.java.patch | 15 +- .../world/item/BundleItem.java.patch | 4 +- .../world/item/CrossbowItem.java.patch | 2 +- .../minecraft/world/item/DyeColor.java.patch | 9 +- .../net/minecraft/world/item/Item.java.patch | 12 +- .../minecraft/world/item/ItemStack.java.patch | 50 ++-- .../world/item/ItemUseAnimation.java.patch | 2 +- .../net/minecraft/world/item/Items.java.patch | 2 +- .../world/item/SpawnEggItem.java.patch | 8 +- .../item/alchemy/PotionContents.java.patch | 2 +- .../world/item/crafting/Ingredient.java.patch | 51 ++-- .../item/crafting/RecipeManager.java.patch | 8 +- .../minecraft/world/level/Level.java.patch | 61 +++-- .../world/level/ServerExplosion.java.patch | 2 +- .../world/level/biome/Biome.java.patch | 12 +- .../biome/BiomeSpecialEffects.java.patch | 6 +- .../world/level/block/Block.java.patch | 15 +- .../world/level/block/Blocks.java.patch | 4 +- .../level/block/CampfireBlock.java.patch | 2 +- .../world/level/block/ChestBlock.java.patch | 2 +- .../level/block/ComposterBlock.java.patch | 12 +- .../level/block/FlowerPotBlock.java.patch | 13 +- .../level/block/SculkCatalystBlock.java.patch | 2 +- .../level/block/SculkSensorBlock.java.patch | 2 +- .../level/block/SculkShriekerBlock.java.patch | 2 +- .../world/level/block/SoundType.java.patch | 2 +- .../world/level/block/SpongeBlock.java.patch | 2 +- .../AbstractFurnaceBlockEntity.java.patch | 70 +++--- .../level/block/entity/BlockEntity.java.patch | 16 +- .../block/entity/BlockEntityType.java.patch | 6 +- .../entity/ShulkerBoxBlockEntity.java.patch | 2 +- .../trialspawner/TrialSpawner.java.patch | 2 +- .../block/state/BlockBehaviour.java.patch | 22 +- .../world/level/chunk/ChunkAccess.java.patch | 6 +- .../level/chunk/ChunkGenerator.java.patch | 2 +- .../world/level/chunk/LevelChunk.java.patch | 32 +-- .../chunk/status/ChunkStatusTasks.java.patch | 2 +- .../chunk/storage/SectionStorage.java.patch | 2 +- .../levelgen/structure/Structure.java.patch | 6 +- .../storage/DimensionDataStorage.java.patch | 32 +-- projects/base/build.gradle | 11 +- projects/neoforge/build.gradle | 4 +- .../loot_table/blocks/pale_oak_leaves.json | 132 ++++++++++ .../minecraft/recipe/pale_oak_chest_boat.json | 17 ++ .../data/minecraft/recipe/pale_oak_fence.json | 17 ++ .../minecraft/recipe/pale_oak_fence_gate.json | 17 ++ .../data/minecraft/recipe/pale_oak_sign.json | 18 ++ .../entity_type/parrot_imitations.json | 3 - .../neoforge/data_maps/item/compostables.json | 6 + src/generated/resources/pack.mcmeta | 2 +- .../neoforge/client/ClientHooks.java | 35 ++- .../neoforge/client/ClientNeoForgeMod.java | 104 ++++++-- .../client/color/item/FluidContentsTint.java | 39 +++ .../geometry => color/item}/package-info.java | 2 +- .../animation/json/AnimationLoader.java | 3 +- .../neoforge/client/event/ModelEvent.java | 83 ++++--- .../event/RegisterColorHandlersEvent.java | 79 ++---- ...sterConditionalItemModelPropertyEvent.java | 35 +++ .../client/event/RegisterItemModelsEvent.java | 35 +++ ...sterRangeSelectItemModelPropertyEvent.java | 35 +++ .../RegisterSelectItemModelPropertyEvent.java | 34 +++ .../RegisterSpecialModelRendererEvent.java | 35 +++ .../client/event/RenderItemInFrameEvent.java | 8 +- .../client/event/SelectMusicEvent.java | 17 +- .../extensions/IBakedModelExtension.java | 13 +- .../IDimensionSpecialEffectsExtension.java | 3 +- .../extensions/IModelBakerExtension.java | 37 ++- .../extensions/IUnbakedModelExtension.java | 69 ++++++ .../common/IClientFluidTypeExtensions.java | 5 +- .../common/IClientItemExtensions.java | 52 ++-- .../client/gui/ConfigurationScreen.java | 22 +- .../client/gui/LoadingErrorScreen.java | 2 +- .../neoforge/client/gui/ModListScreen.java | 11 +- .../gui/ScrollableExperimentsScreen.java | 2 +- .../client/gui/widget/ModListWidget.java | 2 +- .../model/AbstractSimpleUnbakedModel.java | 60 +++++ .../client/model/BakedModelWrapper.java | 119 --------- .../client/model/DelegateUnbakedModel.java | 67 +++++ .../model/DynamicFluidContainerModel.java | 231 ------------------ .../neoforge/client/model/EmptyModel.java | 30 ++- .../model/ExtendedBlockModelDeserializer.java | 107 -------- .../client/model/ExtendedUnbakedModel.java | 30 +++ .../neoforge/client/model/IModelBuilder.java | 21 ++ .../neoforge/client/model/ItemLayerModel.java | 126 ---------- .../client/model/NeoForgeModelProperties.java | 29 +++ .../client/model/SeparateTransformsModel.java | 162 ------------ ...eModel.java => UnbakedCompositeModel.java} | 116 ++++----- ...Helper.java => UnbakedElementsHelper.java} | 105 +++----- .../client/model/UnbakedModelLoader.java | 36 +++ .../client/model/UnbakedModelParser.java | 80 ++++++ .../model/generators/CustomLoaderBuilder.java | 1 - .../client/model/generators/ModelBuilder.java | 7 +- .../geometry/BlockGeometryBakingContext.java | 161 ------------ .../model/geometry/GeometryLoaderManager.java | 51 ---- .../geometry/IGeometryBakingContext.java | 92 ------- .../model/geometry/IGeometryLoader.java | 26 -- .../model/geometry/IUnbakedGeometry.java | 44 ---- .../model/geometry/SimpleUnbakedGeometry.java | 40 --- .../StandaloneGeometryBakingContext.java | 213 ---------------- .../item/DynamicFluidContainerModel.java | 206 ++++++++++++++++ .../{renderable => item}/package-info.java | 2 +- .../neoforge/client/model/obj/ObjLoader.java | 26 +- .../neoforge/client/model/obj/ObjModel.java | 156 ++++-------- .../renderable/BakedModelRenderable.java | 86 ------- .../model/renderable/CompositeRenderable.java | 153 ------------ .../client/model/renderable/IRenderable.java | 42 ---- .../renderable/ITextureRenderTypeLookup.java | 17 -- .../neoforge/common/CommonHooks.java | 4 +- .../neoforge/common/NeoForgeMod.java | 52 ---- .../common/crafting/CompoundIngredient.java | 2 +- .../crafting/CustomDisplayIngredient.java | 2 +- .../common/crafting/DifferenceIngredient.java | 2 +- .../crafting/IntersectionIngredient.java | 2 +- .../GeneratingOverlayMetadataSection.java | 4 +- .../common/extensions/IBlockExtension.java | 7 +- .../extensions/IBlockStateExtension.java | 6 +- .../common/extensions/IEntityExtension.java | 13 - .../common/extensions/IItemExtension.java | 25 +- .../common/extensions/ILevelExtension.java | 11 - .../common/loot/LootModifierManager.java | 3 +- .../neoforge/common/util/FakePlayer.java | 4 - .../world/BiomeSpecialEffectsBuilder.java | 3 +- .../neoforge/data/event/GatherDataEvent.java | 68 +++--- .../data/loading/DatagenModLoader.java | 18 +- .../resource/ContextAwareReloadListener.java | 12 + .../neoforge/resource/EmptyPackResources.java | 7 +- .../neoforge/resource/ResourcePackLoader.java | 2 +- .../resources/META-INF/accesstransformer.cfg | 25 +- .../client/AbstractTestScreen.java | 4 +- .../condition/TestEnabledIngredient.java | 2 +- .../gametest/ExtendedGameTestHelper.java | 3 +- .../impl/reg/RegistrationHelperImpl.java | 37 ++- .../registration/DeferredBlockBuilder.java | 61 ++++- .../DeferredEntityTypeBuilder.java | 2 +- .../registration/DeferredItemBuilder.java | 4 +- .../registration/RegistrationHelper.java | 8 +- tests/build.gradle | 2 +- tests/src/generated/resources/pack.mcmeta | 2 +- .../unittest/CustomFeatureFlagsTest.java | 20 +- .../neoforge/unittest/IngredientTests.java | 4 +- .../neoforge/debug/ConditionalRecipeTest.java | 2 +- .../neoforge/debug/block/BlockTests.java | 2 +- .../debug/client/ClientEventTests.java | 6 +- .../neoforge/debug/client/ClientTests.java | 2 +- .../debug/crafting/IngredientTests.java | 8 +- .../debug/damagesource/DamageTypeTests.java | 2 +- .../debug/data/CustomFeatureFlagsTests.java | 2 +- .../neoforge/debug/data/DataMapTests.java | 20 +- .../data/registries/DatapackEntryTests.java | 2 +- .../debug/entity/player/AdvancementTests.java | 2 +- .../debug/fluid/ClientFluidTests.java | 2 +- .../neoforge/debug/item/ItemTests.java | 6 +- .../debug/loot/GlobalLootModifiersTest.java | 8 +- .../neoforge/debug/loot/LootPoolTest.java | 8 +- .../debug/registry/BiomeModifierSyncTest.java | 2 +- .../debug/resources/ModDatapackTest.java | 2 +- .../neoforge/oldtest/DataGeneratorTest.java | 24 +- .../oldtest/DeferredRegistryTest.java | 4 +- .../oldtest/RemoveTagDatagenTest.java | 6 +- .../oldtest/block/FullPotsAccessorDemo.java | 39 ++- .../oldtest/block/ScaffoldingTest.java | 4 +- .../oldtest/client/CustomArmorModelTest.java | 30 +-- .../client/CustomPresetEditorTest.java | 4 +- .../model/CustomItemDisplayContextTest.java | 17 +- .../oldtest/client/model/MegaModelTest.java | 6 +- .../client/model/NewModelLoaderTest.java | 44 ++-- .../client/model/TRSRTransformerTest.java | 17 +- .../rendering/CustomParticleTypeTest.java | 31 +-- .../client/rendering/RenderableTest.java | 186 -------------- .../oldtest/item/CustomElytraTest.java | 6 +- .../item/RangedMobsUseModdedWeaponsTest.java | 41 ---- .../oldtest/misc/DataPackRegistriesTest.java | 4 +- .../oldtest/world/BiomeModifierTest.java | 4 +- .../oldtest/world/LoginPacketSplitTest.java | 10 +- .../oldtest/world/StructureModifierTest.java | 2 +- .../items/custom_fluid_container.json | 10 + .../models/item/custom_fluid_container.json | 11 - 345 files changed, 3904 insertions(+), 4667 deletions(-) delete mode 100644 patches/net/minecraft/client/color/item/ItemColors.java.patch create mode 100644 patches/net/minecraft/client/color/item/ItemTintSources.java.patch create mode 100644 patches/net/minecraft/client/data/Main.java.patch delete mode 100644 patches/net/minecraft/client/particle/BreakingItemParticle.java.patch delete mode 100644 patches/net/minecraft/client/renderer/block/model/BakedOverrides.java.patch delete mode 100644 patches/net/minecraft/client/renderer/block/model/MultiVariant.java.patch rename patches/net/minecraft/client/renderer/blockentity/{SignRenderer.java.patch => AbstractSignRenderer.java.patch} (52%) create mode 100644 patches/net/minecraft/client/renderer/entity/state/ItemClusterRenderState.java.patch create mode 100644 patches/net/minecraft/client/renderer/entity/state/ItemEntityRenderState.java.patch delete mode 100644 patches/net/minecraft/client/renderer/entity/state/PlayerRenderState.java.patch create mode 100644 patches/net/minecraft/client/renderer/item/BlockModelWrapper.java.patch create mode 100644 patches/net/minecraft/client/renderer/item/ItemModels.java.patch delete mode 100644 patches/net/minecraft/client/renderer/item/ItemProperties.java.patch create mode 100644 patches/net/minecraft/client/renderer/item/ItemStackRenderState.java.patch create mode 100644 patches/net/minecraft/client/renderer/item/properties/conditional/ConditionalItemModelProperties.java.patch create mode 100644 patches/net/minecraft/client/renderer/item/properties/numeric/RangeSelectItemModelProperties.java.patch create mode 100644 patches/net/minecraft/client/renderer/item/properties/select/SelectItemModelProperties.java.patch create mode 100644 patches/net/minecraft/client/renderer/special/SpecialModelRenderers.java.patch delete mode 100644 patches/net/minecraft/client/resources/model/ItemModel.java.patch delete mode 100644 patches/net/minecraft/client/resources/model/ModelResourceLocation.java.patch create mode 100644 patches/net/minecraft/client/resources/model/UnbakedModel.java.patch create mode 100644 patches/net/minecraft/util/context/ContextKeySet.java.patch create mode 100644 src/generated/resources/data/minecraft/loot_table/blocks/pale_oak_leaves.json create mode 100644 src/generated/resources/data/minecraft/recipe/pale_oak_chest_boat.json create mode 100644 src/generated/resources/data/minecraft/recipe/pale_oak_fence.json create mode 100644 src/generated/resources/data/minecraft/recipe/pale_oak_fence_gate.json create mode 100644 src/generated/resources/data/minecraft/recipe/pale_oak_sign.json create mode 100644 src/main/java/net/neoforged/neoforge/client/color/item/FluidContentsTint.java rename src/main/java/net/neoforged/neoforge/client/{model/geometry => color/item}/package-info.java (86%) create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterConditionalItemModelPropertyEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterItemModelsEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterRangeSelectItemModelPropertyEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterSelectItemModelPropertyEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterSpecialModelRendererEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/extensions/IUnbakedModelExtension.java create mode 100644 src/main/java/net/neoforged/neoforge/client/model/AbstractSimpleUnbakedModel.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/BakedModelWrapper.java create mode 100644 src/main/java/net/neoforged/neoforge/client/model/DelegateUnbakedModel.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/DynamicFluidContainerModel.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/ExtendedBlockModelDeserializer.java create mode 100644 src/main/java/net/neoforged/neoforge/client/model/ExtendedUnbakedModel.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/ItemLayerModel.java create mode 100644 src/main/java/net/neoforged/neoforge/client/model/NeoForgeModelProperties.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/SeparateTransformsModel.java rename src/main/java/net/neoforged/neoforge/client/model/{CompositeModel.java => UnbakedCompositeModel.java} (74%) rename src/main/java/net/neoforged/neoforge/client/model/{geometry/UnbakedGeometryHelper.java => UnbakedElementsHelper.java} (64%) create mode 100644 src/main/java/net/neoforged/neoforge/client/model/UnbakedModelLoader.java create mode 100644 src/main/java/net/neoforged/neoforge/client/model/UnbakedModelParser.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/geometry/BlockGeometryBakingContext.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/geometry/GeometryLoaderManager.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/geometry/IGeometryBakingContext.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/geometry/IGeometryLoader.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/geometry/IUnbakedGeometry.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/geometry/SimpleUnbakedGeometry.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/geometry/StandaloneGeometryBakingContext.java create mode 100644 src/main/java/net/neoforged/neoforge/client/model/item/DynamicFluidContainerModel.java rename src/main/java/net/neoforged/neoforge/client/model/{renderable => item}/package-info.java (85%) delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/renderable/BakedModelRenderable.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/renderable/CompositeRenderable.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/renderable/IRenderable.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/renderable/ITextureRenderTypeLookup.java delete mode 100644 tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/RenderableTest.java create mode 100644 tests/src/main/resources/assets/custom_fluid_container_test/items/custom_fluid_container.json delete mode 100644 tests/src/main/resources/assets/custom_fluid_container_test/models/item/custom_fluid_container.json diff --git a/.gitignore b/.gitignore index 883731fee7..b5c5b10b6f 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,4 @@ build **/eclipse/ **/runs/ -**/out/ \ No newline at end of file +**/out/ diff --git a/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java b/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java index aa61592371..e046bf09c9 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java @@ -79,10 +79,11 @@ public void writeUserDevConfig() throws IOException { for (var runType : RunType.values()) { var launchTarget = switch (runType) { - case CLIENT -> "forgeclientdev"; - case DATA -> "forgedatadev"; - case GAME_TEST_SERVER, SERVER -> "forgeserverdev"; - case JUNIT -> "forgejunitdev"; + case CLIENT -> "neoforgeclientdev"; + case CLIENT_DATA -> "neoforgeclientdatadev"; + case SERVER_DATA -> "neoforgeserverdatadev"; + case GAME_TEST_SERVER, SERVER -> "neoforgeserverdev"; + case JUNIT -> "neoforgejunitdev"; }; List args = new ArrayList<>(); @@ -95,7 +96,7 @@ public void writeUserDevConfig() throws IOException { "--version", getNeoForgeVersion().get()); } - if (runType == RunType.CLIENT || runType == RunType.DATA || runType == RunType.JUNIT) { + if (runType == RunType.CLIENT || runType == RunType.CLIENT_DATA || runType == RunType.JUNIT) { Collections.addAll(args, "--assetIndex", "{asset_index}", "--assetsDir", "{assets_root}"); @@ -132,9 +133,9 @@ public void writeUserDevConfig() throws IOException { "--add-opens", "java.base/java.lang.invoke=cpw.mods.securejarhandler", "--add-exports", "java.base/sun.security.util=cpw.mods.securejarhandler", "--add-exports", "jdk.naming.dns/com.sun.jndi.dns=java.naming"), - runType == RunType.CLIENT || runType == RunType.JUNIT, - runType == RunType.GAME_TEST_SERVER || runType == RunType.SERVER, - runType == RunType.DATA, + runType == RunType.CLIENT || runType == RunType.JUNIT || runType == RunType.CLIENT_DATA, + runType == RunType.GAME_TEST_SERVER || runType == RunType.SERVER || runType == RunType.SERVER_DATA, + runType == RunType.CLIENT_DATA || runType == RunType.SERVER_DATA, runType == RunType.CLIENT || runType == RunType.GAME_TEST_SERVER, runType == RunType.JUNIT, Map.of( @@ -152,7 +153,8 @@ public void writeUserDevConfig() throws IOException { private enum RunType { CLIENT("client"), - DATA("data"), + CLIENT_DATA("clientData"), + SERVER_DATA("serverData"), GAME_TEST_SERVER("gameTestServer"), SERVER("server"), JUNIT("junit"); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java index c6e3e8ea6d..de480b5682 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java @@ -19,6 +19,10 @@ public void apply(Project project) { var tasks = project.getTasks(); var neoDevBuildDir = project.getLayout().getBuildDirectory().dir("neodev"); + var rawNeoFormVersion = project.getProviders().gradleProperty("neoform_version"); + var minecraftVersion = project.getProviders().gradleProperty("minecraft_version"); + var mcAndNeoFormVersion = minecraftVersion.zip(rawNeoFormVersion, (mc, nf) -> mc + "-" + nf); + var extension = project.getExtensions().create(NeoDevExtension.NAME, NeoDevExtension.class); var createSources = NeoDevPlugin.configureMinecraftDecompilation(project); @@ -54,7 +58,8 @@ public void apply(Project project) { project.files(), modulePath -> {}, legacyClasspath -> {}, - downloadAssets.flatMap(DownloadAssets::getAssetPropertiesFile) + downloadAssets.flatMap(DownloadAssets::getAssetPropertiesFile), + mcAndNeoFormVersion ); } } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateArgsFile.java b/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateArgsFile.java index 6b403d5b94..cbae005d4a 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateArgsFile.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateArgsFile.java @@ -111,7 +111,7 @@ public void createArgsFile() throws IOException { replacements.put("@PLUGIN_LAYER_LIBRARIES@", ""); replacements.put("@GAME_LAYER_LIBRARIES@", ""); replacements.put("@CLASS_PATH@", resolveClasspath()); - replacements.put("@TASK@", "forgeserver"); + replacements.put("@TASK@", "neoforgeserver"); replacements.put("@FORGE_VERSION@", getNeoForgeVersion().get()); replacements.put("@FML_VERSION@", getFmlVersion().get()); replacements.put("@MC_VERSION@", getMinecraftVersion().get()); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateLauncherProfile.java b/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateLauncherProfile.java index 5968190304..c81a547564 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateLauncherProfile.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateLauncherProfile.java @@ -78,7 +78,7 @@ public void createLauncherProfile() throws IOException { "--fml.fmlVersion", getFmlVersion().get(), "--fml.mcVersion", getMinecraftVersion().get(), "--fml.neoFormVersion", getRawNeoFormVersion().get(), - "--launchTarget", "forgeclient")); + "--launchTarget", "neoforgeclient")); var jvmArguments = new ArrayList<>(List.of( "-Djava.net.preferIPv6Addresses=system", diff --git a/gradle.properties b/gradle.properties index d6e5d02ae1..3ab3c77e91 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,16 +9,16 @@ org.gradle.debug=false #org.gradle.warning.mode=fail # renovate: net.neoforged:moddev-gradle -moddevgradle_plugin_version=2.0.47-beta +moddevgradle_plugin_version=2.0.48-beta # renovate: io.codechicken:DiffPatch diffpatch_version=2.0.0.35 java_version=21 -minecraft_version=1.21.3 -neoform_version=20241023.131943 +minecraft_version=1.21.4 +neoform_version=20241203.161809 # on snapshot versions, used to prefix the version -neoforge_snapshot_next_stable=21.4 +neoforge_snapshot_next_stable=21.5 # renovate: net.neoforged.jst:jst-cli-bundle jst_version=1.0.45 @@ -43,7 +43,7 @@ jetbrains_annotations_version=24.0.1 slf4j_api_version=2.0.7 apache_maven_artifact_version=3.8.5 jarjar_version=0.4.1 -fancy_mod_loader_version=5.0.6 +fancy_mod_loader_version=6.0.4 mojang_logging_version=1.1.1 log4j_version=2.22.1 guava_version=31.1.2-jre diff --git a/patches/com/mojang/blaze3d/platform/Window.java.patch b/patches/com/mojang/blaze3d/platform/Window.java.patch index f211b35fad..043b11d2cb 100644 --- a/patches/com/mojang/blaze3d/platform/Window.java.patch +++ b/patches/com/mojang/blaze3d/platform/Window.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/platform/Window.java +++ b/com/mojang/blaze3d/platform/Window.java -@@ -90,7 +_,8 @@ +@@ -91,7 +_,8 @@ GLFW.glfwWindowHint(139267, 2); GLFW.glfwWindowHint(139272, 204801); GLFW.glfwWindowHint(139270, 1); @@ -10,7 +10,7 @@ if (monitor != null) { VideoMode videomode = monitor.getPreferredVidMode(this.fullscreen ? this.preferredFullscreenVideoMode : Optional.empty()); this.windowedX = this.x = monitor.getX() + videomode.getWidth() / 2 - this.width / 2; -@@ -102,6 +_,7 @@ +@@ -103,6 +_,7 @@ this.windowedX = this.x = aint1[0]; this.windowedY = this.y = aint[0]; } @@ -18,7 +18,7 @@ GLFW.glfwMakeContextCurrent(this.window); GL.createCapabilities(); -@@ -269,6 +_,7 @@ +@@ -273,6 +_,7 @@ GLFW.glfwGetFramebufferSize(this.window, aint, aint1); this.framebufferWidth = aint[0] > 0 ? aint[0] : 1; this.framebufferHeight = aint1[0] > 0 ? aint1[0] : 1; diff --git a/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch b/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch index 756e40c7c9..28061afef1 100644 --- a/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch +++ b/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/systems/RenderSystem.java +++ b/com/mojang/blaze3d/systems/RenderSystem.java -@@ -822,4 +_,14 @@ +@@ -818,4 +_,14 @@ void accept(it.unimi.dsi.fastutil.ints.IntConsumer p_157488_, int p_157489_); } } diff --git a/patches/net/minecraft/Util.java.patch b/patches/net/minecraft/Util.java.patch index 06262a76e0..96bc929990 100644 --- a/patches/net/minecraft/Util.java.patch +++ b/patches/net/minecraft/Util.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/Util.java +++ b/net/minecraft/Util.java -@@ -264,8 +_,8 @@ +@@ -268,8 +_,8 @@ .getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().getDataVersion().getVersion())) .getChoiceType(p_137552_, p_137553_); } catch (IllegalArgumentException illegalargumentexception) { @@ -11,7 +11,7 @@ throw illegalargumentexception; } } -@@ -630,20 +_,20 @@ +@@ -634,20 +_,20 @@ public static void logAndPauseIfInIde(String p_143786_) { LOGGER.error(p_143786_); diff --git a/patches/net/minecraft/client/KeyMapping.java.patch b/patches/net/minecraft/client/KeyMapping.java.patch index 05cdbda228..3fb1afaedf 100644 --- a/patches/net/minecraft/client/KeyMapping.java.patch +++ b/patches/net/minecraft/client/KeyMapping.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/KeyMapping.java +++ b/net/minecraft/client/KeyMapping.java -@@ -14,9 +_,9 @@ +@@ -15,9 +_,9 @@ import net.neoforged.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) @@ -12,7 +12,7 @@ private static final Set CATEGORIES = Sets.newHashSet(); public static final String CATEGORY_MOVEMENT = "key.categories.movement"; public static final String CATEGORY_MISC = "key.categories.misc"; -@@ -42,17 +_,17 @@ +@@ -43,17 +_,17 @@ private int clickCount; public static void click(InputConstants.Key p_90836_) { @@ -35,7 +35,7 @@ } public static void setAll() { -@@ -100,7 +_,7 @@ +@@ -101,7 +_,7 @@ } public boolean isDown() { @@ -44,7 +44,7 @@ } public String getCategory() { -@@ -134,9 +_,13 @@ +@@ -135,9 +_,13 @@ } public int compareTo(KeyMapping p_90841_) { @@ -61,7 +61,7 @@ } public static Supplier createNameSupplier(String p_90843_) { -@@ -145,6 +_,20 @@ +@@ -146,6 +_,20 @@ } public boolean same(KeyMapping p_90851_) { @@ -82,7 +82,7 @@ return this.key.equals(p_90851_.key); } -@@ -163,11 +_,13 @@ +@@ -164,11 +_,13 @@ } public Component getTranslatedKeyMessage() { @@ -97,10 +97,10 @@ } public String saveString() { -@@ -176,5 +_,86 @@ - - public void setDown(boolean p_90846_) { - this.isDown = p_90846_; +@@ -182,5 +_,86 @@ + @Nullable + public static KeyMapping get(String p_389468_) { + return ALL.get(p_389468_); + } + + // Neo: Injected Key Mapping controls diff --git a/patches/net/minecraft/client/Minecraft.java.patch b/patches/net/minecraft/client/Minecraft.java.patch index d73618ac55..c43825a350 100644 --- a/patches/net/minecraft/client/Minecraft.java.patch +++ b/patches/net/minecraft/client/Minecraft.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/Minecraft.java +++ b/net/minecraft/client/Minecraft.java -@@ -253,7 +_,7 @@ +@@ -250,7 +_,7 @@ import org.slf4j.Logger; @OnlyIn(Dist.CLIENT) @@ -9,7 +9,7 @@ static Minecraft instance; private static final Logger LOGGER = LogUtils.getLogger(); public static final boolean ON_OSX = Util.getPlatform() == Util.OS.OSX; -@@ -437,7 +_,6 @@ +@@ -432,7 +_,6 @@ } }, Util.nonCriticalIoPool()); LOGGER.info("Setting user: {}", this.user.getName()); @@ -17,7 +17,7 @@ this.demo = p_91084_.game.demo; this.allowsMultiplayer = !p_91084_.game.disableMultiplayer; this.allowsChat = !p_91084_.game.disableChat; -@@ -488,15 +_,15 @@ +@@ -483,15 +_,17 @@ LOGGER.error("Couldn't set icon", (Throwable)ioexception); } @@ -32,18 +32,20 @@ this.mainRenderTarget.clear(); this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES); + net.neoforged.neoforge.client.loading.ClientModLoader.begin(this, this.resourcePackRepository, this.resourceManager); ++ //Move client bootstrap to after mod loading so that events can be fired for it. ++ ClientBootstrap.bootstrap(); this.resourcePackRepository.reload(); this.options.loadSelectedResourcePacks(this.resourcePackRepository); this.languageManager = new LanguageManager(this.options.languageCode, p_344151_ -> { -@@ -582,6 +_,7 @@ +@@ -571,6 +_,7 @@ ); - this.resourceManager.registerReloadListener(this.entityRenderDispatcher); + this.resourceManager.registerReloadListener(this.blockEntityRenderDispatcher); this.particleEngine = new ParticleEngine(this.level, this.textureManager); + net.neoforged.neoforge.client.ClientHooks.onRegisterParticleProviders(this.particleEngine); this.resourceManager.registerReloadListener(this.particleEngine); this.paintingTextures = new PaintingTextureManager(this.textureManager); this.resourceManager.registerReloadListener(this.paintingTextures); -@@ -591,11 +_,15 @@ +@@ -580,11 +_,15 @@ this.resourceManager.registerReloadListener(this.guiSprites); this.gameRenderer = new GameRenderer(this, this.entityRenderDispatcher.getItemInHandRenderer(), this.resourceManager, this.renderBuffers); this.levelRenderer = new LevelRenderer(this, this.entityRenderDispatcher, this.blockEntityRenderDispatcher, this.renderBuffers); @@ -59,7 +61,7 @@ this.gui = new Gui(this); this.debugRenderer = new DebugRenderer(this); RealmsClient realmsclient = RealmsClient.create(this); -@@ -620,6 +_,7 @@ +@@ -609,6 +_,7 @@ this.options.fullscreen().set(this.window.isFullscreen()); } @@ -67,7 +69,7 @@ this.window.updateVsync(this.options.enableVsync().get()); this.window.updateRawMouseInput(this.options.rawMouseInput().get()); this.window.setDefaultErrorCallback(); -@@ -641,16 +_,18 @@ +@@ -631,16 +_,18 @@ GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS); Minecraft.GameLoadCookie minecraft$gameloadcookie = new Minecraft.GameLoadCookie(realmsclient, p_91084_.quickPlay); this.setOverlay( @@ -90,7 +92,7 @@ ); this.quickPlayLog = QuickPlayLog.of(p_91084_.quickPlay.path()); this.framerateLimitTracker = new FramerateLimitTracker(this.options, this); -@@ -696,6 +_,8 @@ +@@ -686,6 +_,8 @@ runnable = () -> this.setScreen(screen); } @@ -99,7 +101,7 @@ return runnable; } -@@ -744,7 +_,7 @@ +@@ -734,7 +_,7 @@ private String createTitle() { StringBuilder stringbuilder = new StringBuilder("Minecraft"); if (checkModStatus().shouldReportAsModified()) { @@ -108,7 +110,7 @@ } stringbuilder.append(" "); -@@ -776,7 +_,7 @@ +@@ -766,7 +_,7 @@ } private void rollbackResourcePacks(Throwable p_91240_, @Nullable Minecraft.GameLoadCookie p_299846_) { @@ -117,7 +119,7 @@ this.clearResourcePacksOnError(p_91240_, null, p_299846_); } else { Util.throwAsRuntime(p_91240_); -@@ -935,7 +_,7 @@ +@@ -925,7 +_,7 @@ p_307414_.soundManager.emergencyShutdown(); } @@ -126,7 +128,7 @@ } public boolean isEnforceUnicode() { -@@ -1062,9 +_,7 @@ +@@ -1052,9 +_,7 @@ LOGGER.error("setScreen called from non-game thread"); } @@ -137,7 +139,7 @@ this.setLastInputType(InputType.NONE); } -@@ -1081,6 +_,19 @@ +@@ -1071,6 +_,19 @@ } } @@ -157,7 +159,7 @@ this.screen = p_91153_; if (this.screen != null) { this.screen.added(); -@@ -1234,9 +_,11 @@ +@@ -1224,9 +_,11 @@ this.mouseHandler.handleAccumulatedMovement(); profilerfiller.pop(); if (!this.noRender) { @@ -169,7 +171,7 @@ } profilerfiller.push("blit"); -@@ -1264,9 +_,13 @@ +@@ -1257,9 +_,13 @@ profilerfiller.pop(); this.window.setErrorSection("Post render"); this.frames++; @@ -184,7 +186,7 @@ this.deltaTracker.updatePauseState(this.pause); this.deltaTracker.updateFrozenState(!this.isLevelRunningNormally()); long l = Util.getNanos(); -@@ -1358,10 +_,12 @@ +@@ -1351,10 +_,12 @@ this.window.setGuiScale((double)i); if (this.screen != null) { this.screen.resize(this, this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight()); @@ -197,7 +199,7 @@ this.gameRenderer.resize(this.window.getWidth(), this.window.getHeight()); this.mouseHandler.setIgnoreFirstMove(); } -@@ -1502,6 +_,7 @@ +@@ -1495,6 +_,7 @@ } public void stop() { @@ -205,7 +207,7 @@ this.running = false; } -@@ -1531,9 +_,17 @@ +@@ -1524,9 +_,17 @@ BlockHitResult blockhitresult = (BlockHitResult)this.hitResult; BlockPos blockpos = blockhitresult.getBlockPos(); if (!this.level.getBlockState(blockpos).isAir()) { @@ -225,7 +227,7 @@ this.player.swing(InteractionHand.MAIN_HAND); } } -@@ -1561,6 +_,8 @@ +@@ -1554,6 +_,8 @@ return false; } else { boolean flag = false; @@ -234,7 +236,7 @@ switch (this.hitResult.getType()) { case ENTITY: this.gameMode.attack(this.player, ((EntityHitResult)this.hitResult).getEntity()); -@@ -1581,8 +_,10 @@ +@@ -1574,8 +_,10 @@ } this.player.resetAttackStrengthTicker(); @@ -245,7 +247,7 @@ this.player.swing(InteractionHand.MAIN_HAND); return flag; } -@@ -1598,6 +_,11 @@ +@@ -1591,6 +_,11 @@ } for (InteractionHand interactionhand : InteractionHand.values()) { @@ -257,7 +259,7 @@ ItemStack itemstack = this.player.getItemInHand(interactionhand); if (!itemstack.isItemEnabled(this.level.enabledFeatures())) { return; -@@ -1618,7 +_,7 @@ +@@ -1611,7 +_,7 @@ } if (interactionresult instanceof InteractionResult.Success interactionresult$success2) { @@ -266,7 +268,7 @@ this.player.swing(interactionhand); } -@@ -1630,7 +_,7 @@ +@@ -1623,7 +_,7 @@ int i = itemstack.getCount(); InteractionResult interactionresult1 = this.gameMode.useItemOn(this.player, interactionhand, blockhitresult); if (interactionresult1 instanceof InteractionResult.Success interactionresult$success) { @@ -275,7 +277,7 @@ this.player.swing(interactionhand); if (!itemstack.isEmpty() && (itemstack.getCount() != i || this.gameMode.hasInfiniteItems())) { this.gameRenderer.itemInHandRenderer.itemUsed(interactionhand); -@@ -1646,6 +_,9 @@ +@@ -1639,6 +_,9 @@ } } @@ -285,7 +287,7 @@ if (!itemstack.isEmpty() && this.gameMode.useItem(this.player, interactionhand) instanceof InteractionResult.Success interactionresult$success1) { if (interactionresult$success1.swingSource() == InteractionResult.SwingSource.CLIENT) { -@@ -1666,6 +_,8 @@ +@@ -1659,6 +_,8 @@ public void tick() { this.clientTickCount++; @@ -294,7 +296,7 @@ if (this.level != null && !this.pause) { this.level.tickRateManager().tick(); } -@@ -1764,6 +_,7 @@ +@@ -1757,6 +_,7 @@ this.tutorial.tick(); @@ -302,7 +304,7 @@ try { this.level.tick(() -> true); } catch (Throwable throwable1) { -@@ -1777,6 +_,7 @@ +@@ -1770,6 +_,7 @@ throw new ReportedException(crashreport1); } @@ -310,7 +312,7 @@ } profilerfiller.popPush("animateTick"); -@@ -1801,6 +_,8 @@ +@@ -1794,6 +_,8 @@ profilerfiller.popPush("keyboard"); this.keyboardHandler.tick(); profilerfiller.pop(); @@ -319,7 +321,7 @@ } private boolean isLevelRunningNormally() { -@@ -2000,7 +_,8 @@ +@@ -1993,7 +_,8 @@ } public void setLevel(ClientLevel p_91157_, ReceivingLevelScreen.Reason p_341652_) { @@ -329,7 +331,7 @@ this.level = p_91157_; this.updateLevelInEngines(p_91157_); if (!this.isLocalServer) { -@@ -2037,6 +_,7 @@ +@@ -2030,6 +_,7 @@ IntegratedServer integratedserver = this.singleplayerServer; this.singleplayerServer = null; this.gameRenderer.resetData(); @@ -337,7 +339,7 @@ this.gameMode = null; this.narrator.clear(); this.clientLevelTeardownInProgress = true; -@@ -2044,6 +_,7 @@ +@@ -2037,6 +_,7 @@ try { this.updateScreenAndTick(p_320248_); if (this.level != null) { @@ -345,40 +347,11 @@ if (integratedserver != null) { ProfilerFiller profilerfiller = Profiler.get(); profilerfiller.push("waitForServer"); -@@ -2204,6 +_,7 @@ +@@ -2197,6 +_,7 @@ private void pickBlock() { if (this.hitResult != null && this.hitResult.getType() != HitResult.Type.MISS) { + if (net.neoforged.neoforge.client.ClientHooks.onClickInput(2, this.options.keyPickItem, InteractionHand.MAIN_HAND).isCanceled()) return; - boolean flag = this.player.getAbilities().instabuild; - BlockEntity blockentity = null; - HitResult.Type hitresult$type = this.hitResult.getType(); -@@ -2216,7 +_,7 @@ - } - - Block block = blockstate.getBlock(); -- itemstack = block.getCloneItemStack(this.level, blockpos, blockstate); -+ itemstack = blockstate.getCloneItemStack(this.hitResult, this.level, blockpos, this.player); - if (itemstack.isEmpty()) { - return; - } -@@ -2230,7 +_,7 @@ - } - - Entity entity = ((EntityHitResult)this.hitResult).getEntity(); -- itemstack = entity.getPickResult(); -+ itemstack = entity.getPickedResult(this.hitResult); - if (itemstack == null) { - return; - } -@@ -2757,6 +_,10 @@ - - public void updateMaxMipLevel(int p_91313_) { - this.modelManager.updateMaxMipLevel(p_91313_); -+ } -+ -+ public ItemColors getItemColors() { -+ return this.itemColors; - } - - public EntityModelSet getEntityModels() { + boolean flag = Screen.hasControlDown(); + HitResult hitresult = this.hitResult; + Objects.requireNonNull(this.hitResult); diff --git a/patches/net/minecraft/client/color/block/BlockColors.java.patch b/patches/net/minecraft/client/color/block/BlockColors.java.patch index 32c2a2e76b..9305fe8d82 100644 --- a/patches/net/minecraft/client/color/block/BlockColors.java.patch +++ b/patches/net/minecraft/client/color/block/BlockColors.java.patch @@ -1,16 +1,16 @@ --- a/net/minecraft/client/color/block/BlockColors.java +++ b/net/minecraft/client/color/block/BlockColors.java -@@ -29,7 +_,8 @@ - @OnlyIn(Dist.CLIENT) - public class BlockColors { +@@ -30,7 +_,8 @@ private static final int DEFAULT = -1; + public static final int LILY_PAD_IN_WORLD = -14647248; + public static final int LILY_PAD_DEFAULT = -9321636; - private final IdMapper blockColors = new IdMapper<>(32); + // Neo: Use the block instance directly as non-Vanilla block ids are not constant + private final java.util.Map blockColors = new java.util.IdentityHashMap<>(); private final Map>> coloringStates = Maps.newHashMap(); public static BlockColors createDefault() { -@@ -94,11 +_,12 @@ +@@ -95,11 +_,12 @@ }, Blocks.MELON_STEM, Blocks.PUMPKIN_STEM); blockcolors.addColoringState(StemBlock.AGE, Blocks.MELON_STEM, Blocks.PUMPKIN_STEM); blockcolors.register((p_92596_, p_92597_, p_92598_, p_92599_) -> p_92597_ != null && p_92598_ != null ? -14647248 : -9321636, Blocks.LILY_PAD); @@ -24,7 +24,7 @@ if (blockcolor != null) { return blockcolor.getColor(p_92583_, null, null, 0); } else { -@@ -108,13 +_,15 @@ +@@ -109,13 +_,15 @@ } public int getColor(BlockState p_92578_, @Nullable BlockAndTintGetter p_92579_, @Nullable BlockPos p_92580_, int p_92581_) { diff --git a/patches/net/minecraft/client/color/item/ItemColors.java.patch b/patches/net/minecraft/client/color/item/ItemColors.java.patch deleted file mode 100644 index e98475f291..0000000000 --- a/patches/net/minecraft/client/color/item/ItemColors.java.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- a/net/minecraft/client/color/item/ItemColors.java -+++ b/net/minecraft/client/color/item/ItemColors.java -@@ -26,7 +_,8 @@ - @OnlyIn(Dist.CLIENT) - public class ItemColors { - private static final int DEFAULT = -1; -- private final IdMapper itemColors = new IdMapper<>(32); -+ // Neo: Use the item instance directly as non-Vanilla item ids are not constant -+ private final java.util.Map itemColors = new java.util.IdentityHashMap<>(); - - public static ItemColors createDefault(BlockColors p_92684_) { - ItemColors itemcolors = new ItemColors(); -@@ -101,17 +_,28 @@ - (p_359075_, p_359076_) -> p_359076_ == 0 ? -1 : ARGB.opaque(p_359075_.getOrDefault(DataComponents.MAP_COLOR, MapItemColor.DEFAULT).rgb()), - Items.FILLED_MAP - ); -+ net.neoforged.neoforge.client.ClientHooks.onItemColorsInit(itemcolors, p_92684_); - return itemcolors; - } - - public int getColor(ItemStack p_92677_, int p_92678_) { -- ItemColor itemcolor = this.itemColors.byId(BuiltInRegistries.ITEM.getId(p_92677_.getItem())); -+ ItemColor itemcolor = this.itemColors.get(p_92677_.getItem()); - return itemcolor == null ? -1 : itemcolor.getColor(p_92677_, p_92678_); - } - -+ /** -+ * Neo: returns the color handler for the given {@code item}, or {@code null} if one isn't registered. -+ */ -+ @org.jetbrains.annotations.Nullable -+ public ItemColor get(Item item) { -+ return itemColors.get(item); -+ } -+ -+ /** @deprecated Register via {@link net.neoforged.neoforge.client.event.RegisterColorHandlersEvent.Item} */ -+ @Deprecated - public void register(ItemColor p_92690_, ItemLike... p_92691_) { - for (ItemLike itemlike : p_92691_) { -- this.itemColors.addMapping(p_92690_, Item.getId(itemlike.asItem())); -+ this.itemColors.put(itemlike.asItem(), p_92690_); - } - } - } diff --git a/patches/net/minecraft/client/color/item/ItemTintSources.java.patch b/patches/net/minecraft/client/color/item/ItemTintSources.java.patch new file mode 100644 index 0000000000..d240b059e1 --- /dev/null +++ b/patches/net/minecraft/client/color/item/ItemTintSources.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/color/item/ItemTintSources.java ++++ b/net/minecraft/client/color/item/ItemTintSources.java +@@ -21,5 +_,7 @@ + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("potion"), Potion.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("map_color"), MapColor.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("team"), TeamColor.MAP_CODEC); ++ ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterColorHandlersEvent.ItemTintSources(ID_MAPPER)); + } + } diff --git a/patches/net/minecraft/client/data/Main.java.patch b/patches/net/minecraft/client/data/Main.java.patch new file mode 100644 index 0000000000..5aa2dc3ded --- /dev/null +++ b/patches/net/minecraft/client/data/Main.java.patch @@ -0,0 +1,40 @@ +--- a/net/minecraft/client/data/Main.java ++++ b/net/minecraft/client/data/Main.java +@@ -30,16 +_,33 @@ + OptionSpec optionspec1 = optionparser.accepts("client", "Include client generators"); + OptionSpec optionspec2 = optionparser.accepts("all", "Include all generators"); + OptionSpec optionspec3 = optionparser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated"); ++ OptionSpec existing = optionparser.accepts("existing", "Existing resource packs that generated resources can reference").withRequiredArg(); ++ OptionSpec existingMod = optionparser.accepts("existing-mod", "Existing mods that generated resources can reference the resource packs of").withRequiredArg(); ++ OptionSpec gameDir = optionparser.accepts("gameDir").withRequiredArg().ofType(java.io.File.class).defaultsTo(new java.io.File(".")).required(); //Need by modlauncher, so lets just eat it ++ OptionSpec mod = optionparser.accepts("mod", "A modid to dump").withRequiredArg().withValuesSeparatedBy(","); ++ OptionSpec flat = optionparser.accepts("flat", "Do not append modid prefix to output directory when generating for multiple mods"); ++ OptionSpec assetIndex = optionparser.accepts("assetIndex").withRequiredArg(); ++ OptionSpec assetsDir = optionparser.accepts("assetsDir").withRequiredArg().ofType(java.io.File.class); ++ OptionSpec validateSpec = optionparser.accepts("validate", "Validate inputs"); + OptionSet optionset = optionparser.parse(p_388033_); + if (!optionset.has(optionspec) && optionset.hasOptions()) { + Path path = Paths.get(optionspec3.value(optionset)); + boolean flag = optionset.has(optionspec2); + boolean flag1 = flag || optionset.has(optionspec1); +- Bootstrap.bootStrap(); +- ClientBootstrap.bootstrap(); +- DataGenerator datagenerator = new DataGenerator(path, SharedConstants.getCurrentVersion(), true); ++ java.util.Collection existingPacks = optionset.valuesOf(existing).stream().map(Paths::get).toList(); ++ java.util.Set existingMods = new java.util.HashSet<>(optionset.valuesOf(existingMod)); ++ java.util.Set mods = new java.util.HashSet<>(optionset.valuesOf(mod)); ++ boolean isFlat = mods.isEmpty() || optionset.has(flat); ++ boolean validate = optionset.has(validateSpec); ++ DataGenerator datagenerator = new DataGenerator(isFlat ? path : path.resolve("minecraft"), SharedConstants.getCurrentVersion(), true); ++ if (mods.contains("minecraft") || mods.isEmpty()) { + addClientProviders(datagenerator, flag1); +- datagenerator.run(); ++ } ++ net.neoforged.neoforge.data.loading.DatagenModLoader.begin(mods, path, java.util.List.of(), existingPacks, existingMods, false, false, validate, isFlat, optionset.valueOf(assetIndex), optionset.valueOf(assetsDir), () -> { ++ ClientBootstrap.bootstrap(); ++ net.neoforged.neoforge.client.ClientHooks.registerSpriteSourceTypes(); ++ net.neoforged.neoforge.client.entity.animation.json.AnimationTypeManager.init(); ++ }, net.neoforged.neoforge.data.event.GatherDataEvent.Client::new, datagenerator); + } else { + optionparser.printHelpOn(System.out); + } diff --git a/patches/net/minecraft/client/gui/Font.java.patch b/patches/net/minecraft/client/gui/Font.java.patch index a45603a940..f147a8bcdc 100644 --- a/patches/net/minecraft/client/gui/Font.java.patch +++ b/patches/net/minecraft/client/gui/Font.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/client/gui/Font.java +++ b/net/minecraft/client/gui/Font.java -@@ -33,7 +_,7 @@ - import org.joml.Vector3f; +@@ -32,7 +_,7 @@ + import org.joml.Matrix4f; @OnlyIn(Dist.CLIENT) -public class Font { +public class Font implements net.neoforged.neoforge.client.extensions.IFontExtension { private static final float EFFECT_DEPTH = 0.01F; - private static final Vector3f SHADOW_OFFSET = new Vector3f(0.0F, 0.0F, 0.03F); - public static final int ALPHA_CUTOFF = 8; + public static final float SHADOW_DEPTH = 0.03F; + public static final int NO_SHADOW = 0; @@ -42,6 +_,8 @@ private final Function fonts; final boolean filterFishyGlyphs; @@ -18,7 +18,7 @@ public Font(Function p_243253_, boolean p_243245_) { this.fonts = p_243253_; -@@ -310,6 +_,8 @@ +@@ -298,6 +_,8 @@ return this.splitter; } @@ -27,7 +27,7 @@ @OnlyIn(Dist.CLIENT) public static enum DisplayMode { NORMAL, -@@ -417,7 +_,7 @@ +@@ -403,7 +_,7 @@ p_381032_ - 1.0F, this.y + 9.0F, this.x, this.y - 1.0F, this.getUnderTextEffectDepth(), this.backgroundColor ); bakedglyph = Font.this.getFontSet(Style.DEFAULT_FONT).whiteGlyph(); @@ -36,7 +36,7 @@ bakedglyph.renderEffect(bakedglyph$effect, this.pose, vertexconsumer, this.packedLightCoords); } -@@ -427,7 +_,7 @@ +@@ -413,7 +_,7 @@ bakedglyph = Font.this.getFontSet(Style.DEFAULT_FONT).whiteGlyph(); } @@ -45,7 +45,7 @@ for (BakedGlyph.Effect bakedglyph$effect1 : this.effects) { bakedglyph.renderEffect(bakedglyph$effect1, this.pose, vertexconsumer1, this.packedLightCoords); -@@ -440,7 +_,7 @@ +@@ -447,7 +_,7 @@ void renderCharacters() { for (BakedGlyph.GlyphInstance bakedglyph$glyphinstance : this.glyphInstances) { BakedGlyph bakedglyph = bakedglyph$glyphinstance.glyph(); diff --git a/patches/net/minecraft/client/gui/Gui.java.patch b/patches/net/minecraft/client/gui/Gui.java.patch index 57ea34601f..333bdeda69 100644 --- a/patches/net/minecraft/client/gui/Gui.java.patch +++ b/patches/net/minecraft/client/gui/Gui.java.patch @@ -386,7 +386,7 @@ this.toolHighlightTimer = (int)(40.0 * this.minecraft.options.notificationDisplayTime().get()); } else if (this.toolHighlightTimer > 0) { this.toolHighlightTimer--; -@@ -1319,8 +_,17 @@ +@@ -1321,8 +_,17 @@ } } @@ -405,7 +405,7 @@ CONTAINER( ResourceLocation.withDefaultNamespace("hud/heart/container"), ResourceLocation.withDefaultNamespace("hud/heart/container_blinking"), -@@ -1436,8 +_,13 @@ +@@ -1438,8 +_,13 @@ } else { gui$hearttype = NORMAL; } diff --git a/patches/net/minecraft/client/gui/GuiGraphics.java.patch b/patches/net/minecraft/client/gui/GuiGraphics.java.patch index caca78e363..472cc1b836 100644 --- a/patches/net/minecraft/client/gui/GuiGraphics.java.patch +++ b/patches/net/minecraft/client/gui/GuiGraphics.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/GuiGraphics.java +++ b/net/minecraft/client/gui/GuiGraphics.java -@@ -53,7 +_,7 @@ +@@ -52,7 +_,7 @@ import org.joml.Vector2ic; @OnlyIn(Dist.CLIENT) @@ -9,7 +9,7 @@ public static final float MAX_GUI_Z = 10000.0F; public static final float MIN_GUI_Z = -10000.0F; private static final int EXTRA_SPACE_AFTER_FIRST_TOOLTIP_LINE = 2; -@@ -227,6 +_,11 @@ +@@ -229,6 +_,11 @@ } public int drawString(Font p_283343_, @Nullable String p_281896_, int p_283569_, int p_283418_, int p_281560_, boolean p_282130_) { @@ -21,7 +21,7 @@ return p_281896_ == null ? 0 : p_283343_.drawInBatch( -@@ -248,6 +_,11 @@ +@@ -250,6 +_,11 @@ } public int drawString(Font p_282636_, FormattedCharSequence p_281596_, int p_281586_, int p_282816_, int p_281743_, boolean p_282394_) { @@ -33,7 +33,7 @@ return p_282636_.drawInBatch( p_281596_, (float)p_281586_, -@@ -870,10 +_,15 @@ +@@ -859,10 +_,15 @@ this.renderItemCount(p_282005_, p_283349_, p_282641_, p_282146_, p_282803_); this.renderItemCooldown(p_283349_, p_282641_, p_282146_); this.pose.popPose(); @@ -49,7 +49,7 @@ this.renderTooltip( p_282308_, Screen.getTooltipFromItem(this.minecraft, p_282781_), -@@ -882,6 +_,17 @@ +@@ -871,6 +_,17 @@ p_282292_, p_282781_.get(DataComponents.TOOLTIP_STYLE) ); @@ -67,7 +67,7 @@ } public void renderTooltip(Font p_283128_, List p_282716_, Optional p_281682_, int p_283678_, int p_281696_) { -@@ -891,11 +_,7 @@ +@@ -880,11 +_,7 @@ public void renderTooltip( Font p_371715_, List p_371741_, Optional p_371604_, int p_371500_, int p_371755_, @Nullable ResourceLocation p_371766_ ) { @@ -80,7 +80,7 @@ this.renderTooltipInternal(p_371715_, list, p_371500_, p_371755_, DefaultTooltipPositioner.INSTANCE, p_371766_); } -@@ -908,13 +_,14 @@ +@@ -897,13 +_,14 @@ } public void renderComponentTooltip(Font p_282739_, List p_281832_, int p_282191_, int p_282446_) { @@ -97,7 +97,7 @@ p_371314_, p_371389_, DefaultTooltipPositioner.INSTANCE, -@@ -922,6 +_,28 @@ +@@ -911,6 +_,28 @@ ); } @@ -126,7 +126,7 @@ public void renderTooltip(Font p_282192_, List p_282297_, int p_281680_, int p_283325_) { this.renderTooltip(p_282192_, p_282297_, p_281680_, p_283325_, null); } -@@ -954,41 +_,45 @@ +@@ -943,41 +_,45 @@ @Nullable ResourceLocation p_371327_ ) { if (!p_282615_.isEmpty()) { diff --git a/patches/net/minecraft/client/gui/components/AbstractWidget.java.patch b/patches/net/minecraft/client/gui/components/AbstractWidget.java.patch index 256cef46f4..6022c53dcf 100644 --- a/patches/net/minecraft/client/gui/components/AbstractWidget.java.patch +++ b/patches/net/minecraft/client/gui/components/AbstractWidget.java.patch @@ -19,7 +19,7 @@ } @@ -139,7 +_,7 @@ - boolean flag = this.clicked(p_93641_, p_93642_); + boolean flag = this.isMouseOver(p_93641_, p_93642_); if (flag) { this.playDownSound(Minecraft.getInstance().getSoundManager()); - this.onClick(p_93641_, p_93642_); @@ -27,7 +27,7 @@ return true; } } -@@ -257,6 +_,19 @@ +@@ -248,6 +_,19 @@ @Override public void setFocused(boolean p_93693_) { this.focused = p_93693_; diff --git a/patches/net/minecraft/client/gui/font/glyphs/BakedGlyph.java.patch b/patches/net/minecraft/client/gui/font/glyphs/BakedGlyph.java.patch index 44c6510a6f..207270ffd3 100644 --- a/patches/net/minecraft/client/gui/font/glyphs/BakedGlyph.java.patch +++ b/patches/net/minecraft/client/gui/font/glyphs/BakedGlyph.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/gui/font/glyphs/BakedGlyph.java +++ b/net/minecraft/client/gui/font/glyphs/BakedGlyph.java -@@ -75,6 +_,15 @@ - p_95223_.addVertex(p_254370_, p_95221_.x0, p_95221_.y1, p_95221_.depth).setColor(p_95221_.color).setUv(this.u1, this.v0).setLight(p_95224_); +@@ -139,6 +_,15 @@ + .setLight(p_382874_); } + /** diff --git a/patches/net/minecraft/client/gui/screens/LoadingOverlay.java.patch b/patches/net/minecraft/client/gui/screens/LoadingOverlay.java.patch index b607643c50..d0c1f86d70 100644 --- a/patches/net/minecraft/client/gui/screens/LoadingOverlay.java.patch +++ b/patches/net/minecraft/client/gui/screens/LoadingOverlay.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/LoadingOverlay.java +++ b/net/minecraft/client/gui/screens/LoadingOverlay.java -@@ -123,6 +_,7 @@ +@@ -122,6 +_,7 @@ } if (this.fadeOutStart == -1L && this.reload.isDone() && (!this.fadeIn || f1 >= 2.0F)) { @@ -8,7 +8,7 @@ try { this.reload.checkExceptions(); this.onFinish.accept(Optional.empty()); -@@ -130,7 +_,6 @@ +@@ -129,7 +_,6 @@ this.onFinish.accept(Optional.of(throwable)); } diff --git a/patches/net/minecraft/client/gui/screens/Screen.java.patch b/patches/net/minecraft/client/gui/screens/Screen.java.patch index e7d7751d22..8f599df40b 100644 --- a/patches/net/minecraft/client/gui/screens/Screen.java.patch +++ b/patches/net/minecraft/client/gui/screens/Screen.java.patch @@ -69,7 +69,7 @@ private void scheduleNarration(long p_169381_, boolean p_169382_) { this.nextNarrationTime = Util.getMillis() + p_169381_; if (p_169382_) { -@@ -642,5 +_,13 @@ +@@ -643,5 +_,13 @@ this.index = p_169425_; this.priority = p_169426_; } diff --git a/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch b/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch index 2038b23682..7ded730c48 100644 --- a/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/TitleScreen.java +++ b/net/minecraft/client/gui/screens/TitleScreen.java -@@ -114,11 +_,17 @@ +@@ -110,11 +_,17 @@ int i = this.font.width(COPYRIGHT_TEXT); int j = this.width - i - 2; int k = 24; @@ -19,7 +19,7 @@ } l = this.createTestWorldButton(l, 24); -@@ -160,7 +_,7 @@ +@@ -156,7 +_,7 @@ if (SharedConstants.IS_RUNNING_IN_IDE) { this.addRenderableWidget( Button.builder(Component.literal("Create Test World"), p_372504_ -> CreateWorldScreen.testWorld(this.minecraft, this)) @@ -28,7 +28,7 @@ .build() ); } -@@ -304,6 +_,7 @@ +@@ -300,6 +_,7 @@ if ((i & -67108864) != 0) { super.render(p_282860_, p_281753_, p_283539_, p_282628_); this.logoRenderer.renderLogo(p_282860_, this.width, f); @@ -36,7 +36,7 @@ if (this.splash != null && !this.minecraft.options.hideSplashTexts().get()) { this.splash.render(p_282860_, this.width, this.font, i); } -@@ -319,7 +_,13 @@ +@@ -315,7 +_,13 @@ s = s + I18n.get("menu.modded"); } diff --git a/patches/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch index be4ec4baf1..872e89fb06 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java +++ b/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java -@@ -107,7 +_,12 @@ +@@ -105,7 +_,12 @@ public void render(GuiGraphics p_283479_, int p_283661_, int p_281248_, float p_281886_) { int i = this.leftPos; int j = this.topPos; @@ -14,7 +14,7 @@ p_283479_.pose().pushPose(); p_283479_.pose().translate((float)i, (float)j, 0.0F); Slot slot = this.hoveredSlot; -@@ -120,6 +_,7 @@ +@@ -118,6 +_,7 @@ } this.renderLabels(p_283479_, p_283661_, p_281248_); @@ -22,7 +22,7 @@ ItemStack itemstack = this.draggingItem.isEmpty() ? this.menu.getCarried() : this.draggingItem; if (!itemstack.isEmpty()) { int k = 8; -@@ -202,6 +_,7 @@ +@@ -200,6 +_,7 @@ this.font, this.getTooltipFromContainerItem(itemstack), itemstack.getTooltipImage(), @@ -30,7 +30,7 @@ p_282171_, p_281909_, itemstack.get(DataComponents.TOOLTIP_STYLE) -@@ -222,7 +_,8 @@ +@@ -220,7 +_,8 @@ p_282567_.pose().pushPose(); p_282567_.pose().translate(0.0F, 0.0F, 232.0F); p_282567_.renderItem(p_281330_, p_281772_, p_281689_); @@ -40,7 +40,7 @@ p_282567_.pose().popPose(); } -@@ -281,6 +_,14 @@ +@@ -278,6 +_,14 @@ p_281607_.fill(i, j, i + 16, j + 16, -2130706433); } @@ -55,7 +55,7 @@ int j1 = p_282613_.x + p_282613_.y * this.imageWidth; if (p_282613_.isFake()) { p_281607_.renderFakeItem(itemstack, i, j, j1); -@@ -289,9 +_,6 @@ +@@ -286,9 +_,6 @@ } p_281607_.renderItemDecorations(this.font, itemstack, i, j, s); @@ -65,7 +65,7 @@ } private void recalculateQuickCraftRemaining() { -@@ -329,7 +_,8 @@ +@@ -326,7 +_,8 @@ if (super.mouseClicked(p_97748_, p_97749_, p_97750_)) { return true; } else { @@ -75,7 +75,7 @@ Slot slot = this.getHoveredSlot(p_97748_, p_97749_); long i = Util.getMillis(); this.doubleclick = this.lastClickSlot == slot && i - this.lastClickTime < 250L && this.lastClickButton == p_97750_; -@@ -340,6 +_,7 @@ +@@ -337,6 +_,7 @@ int j = this.leftPos; int k = this.topPos; boolean flag1 = this.hasClickedOutside(p_97748_, p_97749_, j, k, p_97750_); @@ -83,7 +83,7 @@ int l = -1; if (slot != null) { l = slot.index; -@@ -365,7 +_,7 @@ +@@ -362,7 +_,7 @@ } } else if (!this.isQuickCrafting) { if (this.menu.getCarried().isEmpty()) { @@ -92,7 +92,7 @@ this.slotClicked(slot, l, p_97750_, ClickType.CLONE); } else { boolean flag2 = l != -999 -@@ -393,7 +_,7 @@ +@@ -390,7 +_,7 @@ this.quickCraftingType = 0; } else if (p_97750_ == 1) { this.quickCraftingType = 1; @@ -101,7 +101,7 @@ this.quickCraftingType = 2; } } -@@ -472,10 +_,13 @@ +@@ -469,10 +_,13 @@ @Override public boolean mouseReleased(double p_97812_, double p_97813_, int p_97814_) { @@ -115,7 +115,7 @@ int k = -1; if (slot != null) { k = slot.index; -@@ -492,7 +_,7 @@ +@@ -489,7 +_,7 @@ if (slot2 != null && slot2.mayPickup(this.minecraft.player) && slot2.hasItem() @@ -124,7 +124,7 @@ && AbstractContainerMenu.canItemQuickReplace(slot2, this.lastQuickMoved, true)) { this.slotClicked(slot2, slot2.index, p_97814_, ClickType.QUICK_MOVE); } -@@ -556,7 +_,7 @@ +@@ -553,7 +_,7 @@ this.slotClicked(null, -999, AbstractContainerMenu.getQuickcraftMask(2, this.quickCraftingType), ClickType.QUICK_CRAFT); } else if (!this.menu.getCarried().isEmpty()) { @@ -133,7 +133,7 @@ this.slotClicked(slot, k, p_97814_, ClickType.CLONE); } else { boolean flag1 = k != -999 -@@ -636,34 +_,39 @@ +@@ -633,34 +_,39 @@ @Override public boolean keyPressed(int p_97765_, int p_97766_, int p_97767_) { @@ -180,7 +180,7 @@ this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, i, ClickType.SWAP); return true; } -@@ -701,6 +_,18 @@ +@@ -698,6 +_,18 @@ @Override public T getMenu() { return this.menu; diff --git a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch index e590cf0739..309b303ed2 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java +++ b/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java -@@ -115,6 +_,8 @@ +@@ -114,6 +_,8 @@ private final Set> visibleTags = new HashSet<>(); private final boolean displayOperatorCreativeTab; private final EffectsInInventory effects; @@ -9,7 +9,7 @@ public CreativeModeInventoryScreen(LocalPlayer p_346290_, FeatureFlagSet p_260074_, boolean p_259569_) { super(new CreativeModeInventoryScreen.ItemPickerMenu(p_346290_), p_346290_.getInventory(), CommonComponents.EMPTY); -@@ -151,9 +_,11 @@ +@@ -150,9 +_,11 @@ return false; } else { if (p_345591_ != null) { @@ -24,7 +24,7 @@ } return true; -@@ -163,7 +_,7 @@ +@@ -162,7 +_,7 @@ private void refreshCurrentTabContents(Collection p_261591_) { int i = this.menu.getRowIndexForScroll(this.scrollOffs); this.menu.items.clear(); @@ -33,7 +33,7 @@ this.refreshSearchResults(); } else { this.menu.items.addAll(p_261591_); -@@ -337,6 +_,34 @@ +@@ -336,6 +_,34 @@ protected void init() { if (this.minecraft.gameMode.hasInfiniteItems()) { super.init(); @@ -68,7 +68,7 @@ this.searchBox = new EditBox(this.font, this.leftPos + 82, this.topPos + 6, 80, 9, Component.translatable("itemGroup.search")); this.searchBox.setMaxLength(50); this.searchBox.setBordered(false); -@@ -383,7 +_,7 @@ +@@ -382,7 +_,7 @@ public boolean charTyped(char p_98521_, int p_98522_) { if (this.ignoreTextInput) { return false; @@ -77,7 +77,7 @@ return false; } else { String s = this.searchBox.getValue(); -@@ -402,7 +_,7 @@ +@@ -401,7 +_,7 @@ @Override public boolean keyPressed(int p_98547_, int p_98548_, int p_98549_) { this.ignoreTextInput = false; @@ -86,7 +86,7 @@ if (this.minecraft.options.keyChat.matches(p_98547_, p_98548_)) { this.ignoreTextInput = true; this.selectTab(CreativeModeTabs.searchTab()); -@@ -438,6 +_,7 @@ +@@ -437,6 +_,7 @@ } private void refreshSearchResults() { @@ -94,7 +94,7 @@ this.menu.items.clear(); this.visibleTags.clear(); String s = this.searchBox.getValue(); -@@ -450,10 +_,10 @@ +@@ -449,10 +_,10 @@ SearchTree searchtree; if (s.startsWith("#")) { s = s.substring(1); @@ -107,7 +107,7 @@ } this.menu.items.addAll(searchtree.search(s.toLowerCase(Locale.ROOT))); -@@ -481,7 +_,8 @@ +@@ -480,7 +_,8 @@ @Override protected void renderLabels(GuiGraphics p_283168_, int p_281774_, int p_281466_) { if (selectedTab.showTitle()) { @@ -117,7 +117,7 @@ } } -@@ -491,7 +_,7 @@ +@@ -490,7 +_,7 @@ double d0 = p_98531_ - (double)this.leftPos; double d1 = p_98532_ - (double)this.topPos; @@ -126,7 +126,7 @@ if (this.checkTabClicked(creativemodetab, d0, d1)) { return true; } -@@ -513,7 +_,7 @@ +@@ -512,7 +_,7 @@ double d1 = p_98623_ - (double)this.topPos; this.scrolling = false; @@ -135,7 +135,7 @@ if (this.checkTabClicked(creativemodetab, d0, d1)) { this.selectTab(creativemodetab); return true; -@@ -531,6 +_,7 @@ +@@ -530,6 +_,7 @@ private void selectTab(CreativeModeTab p_98561_) { CreativeModeTab creativemodetab = selectedTab; selectedTab = p_98561_; @@ -143,7 +143,7 @@ this.quickCraftSlots.clear(); this.menu.items.clear(); this.clearDraggingState(); -@@ -607,13 +_,15 @@ +@@ -606,13 +_,15 @@ this.originalSlots = null; } @@ -160,7 +160,7 @@ this.refreshSearchResults(); } else { -@@ -679,18 +_,27 @@ +@@ -678,18 +_,27 @@ super.render(p_283000_, p_281317_, p_282770_, p_281295_); this.effects.render(p_283000_, p_281317_, p_282770_, p_281295_); @@ -194,7 +194,7 @@ this.renderTooltip(p_283000_, p_281317_, p_282770_); } -@@ -703,10 +_,10 @@ +@@ -702,10 +_,10 @@ public List getTooltipFromContainerItem(ItemStack p_281769_) { boolean flag = this.hoveredSlot != null && this.hoveredSlot instanceof CreativeModeInventoryScreen.CustomCreativeSlot; boolean flag1 = selectedTab.getType() == CreativeModeTab.Type.CATEGORY; @@ -207,7 +207,7 @@ if (flag1 && flag) { return list; } else { -@@ -722,7 +_,7 @@ +@@ -721,7 +_,7 @@ int i = 1; for (CreativeModeTab creativemodetab : CreativeModeTabs.tabs()) { @@ -216,7 +216,7 @@ list1.add(i++, creativemodetab.getDisplayName().copy().withStyle(ChatFormatting.BLUE)); } } -@@ -733,7 +_,7 @@ +@@ -732,7 +_,7 @@ @Override protected void renderBg(GuiGraphics p_282663_, float p_282504_, int p_282089_, int p_282249_) { @@ -225,7 +225,7 @@ if (creativemodetab != selectedTab) { this.renderTabButton(p_282663_, creativemodetab); } -@@ -747,10 +_,11 @@ +@@ -746,10 +_,11 @@ int k = this.topPos + 18; int i = k + 112; if (selectedTab.canScroll()) { @@ -238,7 +238,7 @@ this.renderTabButton(p_282663_, selectedTab); if (selectedTab.getType() == CreativeModeTab.Type.INVENTORY) { InventoryScreen.renderEntityInInventoryFollowsMouse( -@@ -769,7 +_,7 @@ +@@ -768,7 +_,7 @@ } private int getTabX(CreativeModeTab p_260136_) { @@ -247,7 +247,7 @@ int j = 27; int k = 27 * i; if (p_260136_.isAlignedRight()) { -@@ -781,7 +_,7 @@ +@@ -780,7 +_,7 @@ private int getTabY(CreativeModeTab p_260181_) { int i = 0; @@ -256,7 +256,7 @@ i -= 32; } else { i += this.imageHeight; -@@ -809,8 +_,8 @@ +@@ -808,8 +_,8 @@ protected void renderTabButton(GuiGraphics p_283590_, CreativeModeTab p_283489_) { boolean flag = p_283489_ == selectedTab; @@ -267,7 +267,7 @@ int j = this.leftPos + this.getTabX(p_283489_); int k = this.topPos - (flag1 ? 28 : -(this.imageHeight - 4)); ResourceLocation[] aresourcelocation; -@@ -820,6 +_,7 @@ +@@ -819,6 +_,7 @@ aresourcelocation = flag ? SELECTED_BOTTOM_TABS : UNSELECTED_BOTTOM_TABS; } @@ -275,7 +275,7 @@ p_283590_.blitSprite(RenderType::guiTextured, aresourcelocation[Mth.clamp(i, 0, aresourcelocation.length)], j, k, 26, 32); p_283590_.pose().pushPose(); p_283590_.pose().translate(0.0F, 0.0F, 100.0F); -@@ -861,6 +_,14 @@ +@@ -860,6 +_,14 @@ } } @@ -290,7 +290,7 @@ @OnlyIn(Dist.CLIENT) static class CustomCreativeSlot extends Slot { public CustomCreativeSlot(Container p_98633_, int p_98634_, int p_98635_, int p_98636_) { -@@ -1042,6 +_,22 @@ +@@ -1041,6 +_,22 @@ @Override public boolean mayPickup(Player p_98665_) { return this.target.mayPickup(p_98665_); @@ -307,8 +307,8 @@ + } + + @Override -+ public Slot setBackground(ResourceLocation atlas, ResourceLocation sprite) { -+ this.target.setBackground(atlas, sprite); ++ public Slot setBackground(ResourceLocation sprite) { ++ this.target.setBackground(sprite); + return this; } } diff --git a/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch index 66f9e706cc..0369823bed 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch @@ -8,7 +8,7 @@ + if (((k < l + 1 || this.minecraft.player.experienceLevel < k1) && !this.minecraft.player.getAbilities().instabuild) || this.menu.enchantClue[l] == -1) { // Forge: render buttons as disabled when enchantable but enchantability not met on lower levels p_282430_.blitSprite(RenderType::guiTextured, ENCHANTMENT_SLOT_DISABLED_SPRITE, i1, j + 14 + 19 * l, 108, 19); p_282430_.blitSprite(RenderType::guiTextured, DISABLED_LEVEL_SPRITES[l], i1 + 1, j + 15 + 19 * l, 16, 16); - p_282430_.drawWordWrap(this.font, formattedtext, j1, j + 16 + 19 * l, l1, (i2 & 16711422) >> 1); + p_282430_.drawWordWrap(this.font, formattedtext, j1, j + 16 + 19 * l, l1, (i2 & 16711422) >> 1, false); @@ -179,13 +_,16 @@ .registryAccess() .lookupOrThrow(Registries.ENCHANTMENT) diff --git a/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch b/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch index 789a7732ae..844e9dadbd 100644 --- a/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch +++ b/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java +++ b/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java -@@ -158,6 +_,7 @@ +@@ -156,6 +_,7 @@ ) .build(); this.resetButton = Button.builder(RESET_BUTTON_TITLE, p_359096_ -> { @@ -8,7 +8,7 @@ p_345998_.setKey(p_345998_.getDefaultKey()); KeyBindsList.this.resetMappingAndUpdateButtons(); }).bounds(0, 0, 50, 20).createNarration(p_344899_ -> Component.translatable("narrator.controls.reset", p_345196_)).build(); -@@ -210,7 +_,7 @@ +@@ -208,7 +_,7 @@ MutableComponent mutablecomponent = Component.empty(); if (!this.key.isUnbound()) { for (KeyMapping keymapping : KeyBindsList.this.minecraft.options.keyMappings) { diff --git a/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch index 55fa739634..1e9418a335 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java +++ b/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java -@@ -169,6 +_,7 @@ +@@ -168,6 +_,7 @@ ) { queueLoadScreen(p_372818_, PREPARING_WORLD_DATA); PackRepository packrepository = new PackRepository(new ServerPacksSource(p_372818_.directoryValidator())); @@ -8,7 +8,7 @@ WorldLoader.InitConfig worldloader$initconfig = createDefaultLoadConfig(packrepository, WorldDataConfiguration.DEFAULT); CompletableFuture completablefuture = WorldLoader.load( worldloader$initconfig, -@@ -307,6 +_,10 @@ +@@ -306,6 +_,10 @@ SystemToast.onPackCopyFailure(this.minecraft, s); return false; } else { @@ -19,7 +19,7 @@ this.minecraft .createWorldOpenFlows() .createLevelFromExistingSettings(optional.get(), worldcreationcontext.dataPackResources(), p_249152_, p_374211_); -@@ -491,7 +_,7 @@ +@@ -480,7 +_,7 @@ if (p_269627_) { p_270552_.accept(this.uiState.getSettings().dataConfiguration()); } else { @@ -28,7 +28,7 @@ } }, Component.translatable("dataPack.validation.failed"), -@@ -605,6 +_,7 @@ +@@ -594,6 +_,7 @@ if (path != null) { if (this.tempDataPackRepository == null) { this.tempDataPackRepository = ServerPacksSource.createPackRepository(path, this.packValidator); diff --git a/patches/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java.patch index e9a46ff939..c34df49406 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java +++ b/net/minecraft/client/gui/screens/worldselection/ExperimentsScreen.java -@@ -50,6 +_,11 @@ +@@ -62,6 +_,11 @@ @Override protected void init() { diff --git a/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch index bd2c7fd8b2..ff9e5dff5c 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch @@ -9,8 +9,8 @@ static final Component FROM_NEWER_TOOLTIP_1 = Component.translatable("selectWorld.tooltip.fromNewerVersion1").withStyle(ChatFormatting.RED); static final Component FROM_NEWER_TOOLTIP_2 = Component.translatable("selectWorld.tooltip.fromNewerVersion2").withStyle(ChatFormatting.RED); @@ -403,6 +_,7 @@ - p_281612_.drawString(this.minecraft.font, s1, p_282820_ + 32 + 3, p_283181_ + 9 + 3, -8355712, false); - p_281612_.drawString(this.minecraft.font, component, p_282820_ + 32 + 3, p_283181_ + 9 + 9 + 3, -8355712, false); + p_281612_.drawString(this.minecraft.font, s1, p_282820_ + 32 + 3, p_283181_ + 9 + 3, -8355712); + p_281612_.drawString(this.minecraft.font, component, p_282820_ + 32 + 3, p_283181_ + 9 + 9 + 3, -8355712); p_281612_.blit(RenderType::guiTextured, this.icon.textureLocation(), p_282820_, p_283181_, 0.0F, 0.0F, 32, 32, 32, 32); + renderExperimentalWarning(p_281612_, p_283204_, p_283025_, p_283181_, p_282820_); if (this.minecraft.options.touchscreen().get() || p_283396_) { diff --git a/patches/net/minecraft/client/main/Main.java.patch b/patches/net/minecraft/client/main/Main.java.patch index c66fe4ba49..af5d923dcf 100644 --- a/patches/net/minecraft/client/main/Main.java.patch +++ b/patches/net/minecraft/client/main/Main.java.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/client/main/Main.java +++ b/net/minecraft/client/main/Main.java -@@ -120,7 +_,7 @@ +@@ -121,8 +_,7 @@ CrashReport.preload(); logger = LogUtils.getLogger(); s1 = "Bootstrap"; - Bootstrap.bootStrap(); -+ net.neoforged.fml.loading.BackgroundWaiter.runAndTick(()->Bootstrap.bootStrap(), net.neoforged.fml.loading.FMLLoader.progressWindowTick); +- ClientBootstrap.bootstrap(); ++ net.neoforged.fml.loading.BackgroundWaiter.runAndTick(() -> Bootstrap.bootStrap(), net.neoforged.fml.loading.FMLLoader.progressWindowTick); GameLoadTimesEvent.INSTANCE.setBootstrapTime(Bootstrap.bootstrapDuration.get()); Bootstrap.validate(); s1 = "Argument parsing"; diff --git a/patches/net/minecraft/client/model/HumanoidModel.java.patch b/patches/net/minecraft/client/model/HumanoidModel.java.patch index 5d2e521e41..94cf1ee81c 100644 --- a/patches/net/minecraft/client/model/HumanoidModel.java.patch +++ b/patches/net/minecraft/client/model/HumanoidModel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/model/HumanoidModel.java +++ b/net/minecraft/client/model/HumanoidModel.java -@@ -257,6 +_,8 @@ +@@ -253,6 +_,8 @@ case BRUSH: this.rightArm.xRot = this.rightArm.xRot * 0.5F - (float) (Math.PI / 5); this.rightArm.yRot = 0.0F; @@ -9,7 +9,7 @@ } } -@@ -299,6 +_,8 @@ +@@ -295,6 +_,8 @@ case BRUSH: this.leftArm.xRot = this.leftArm.xRot * 0.5F - (float) (Math.PI / 5); this.leftArm.yRot = 0.0F; @@ -18,7 +18,7 @@ } } -@@ -376,7 +_,7 @@ +@@ -372,7 +_,7 @@ } @OnlyIn(Dist.CLIENT) @@ -27,7 +27,7 @@ EMPTY(false), ITEM(false), BLOCK(false), -@@ -389,13 +_,31 @@ +@@ -385,13 +_,31 @@ BRUSH(false); private final boolean twoHanded; diff --git a/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch b/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch index de5171aeea..3e54603301 100644 --- a/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch +++ b/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/client/model/geom/LayerDefinitions.java +++ b/net/minecraft/client/model/geom/LayerDefinitions.java -@@ -454,6 +_,7 @@ - builder.put(ModelLayers.createWallSignModelName(p_359128_), layerdefinition54); - builder.put(ModelLayers.createHangingSignModelName(p_359128_), layerdefinition55); +@@ -468,6 +_,7 @@ + builder.put(ModelLayers.createHangingSignModelName(p_382521_, hangingsignrenderer$attachmenttype), layerdefinition55); + } }); + net.neoforged.neoforge.client.ClientHooks.loadLayerDefinitions(builder); ImmutableMap immutablemap = builder.build(); diff --git a/patches/net/minecraft/client/model/geom/ModelLayers.java.patch b/patches/net/minecraft/client/model/geom/ModelLayers.java.patch index 9b9691073a..2e84c89ca5 100644 --- a/patches/net/minecraft/client/model/geom/ModelLayers.java.patch +++ b/patches/net/minecraft/client/model/geom/ModelLayers.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/model/geom/ModelLayers.java +++ b/net/minecraft/client/model/geom/ModelLayers.java -@@ -301,15 +_,18 @@ +@@ -308,15 +_,18 @@ } public static ModelLayerLocation createStandingSignModelName(WoodType p_171292_) { @@ -15,10 +15,10 @@ + return new ModelLayerLocation(location.withPrefix("sign/wall/"), "main"); } - public static ModelLayerLocation createHangingSignModelName(WoodType p_252225_) { -- return createLocation("hanging_sign/" + p_252225_.name(), "main"); + public static ModelLayerLocation createHangingSignModelName(WoodType p_252225_, HangingSignRenderer.AttachmentType p_382987_) { +- return createLocation("hanging_sign/" + p_252225_.name() + "/" + p_382987_.getSerializedName(), "main"); + ResourceLocation location = ResourceLocation.parse(p_252225_.name()); -+ return new ModelLayerLocation(location.withPrefix("hanging_sign/"), "main"); ++ return new ModelLayerLocation(location.withPrefix("hanging_sign/").withSuffix("/" + p_382987_.getSerializedName()), "main"); } public static Stream getKnownLocations() { diff --git a/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch b/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch index 768dd4d9eb..3aa9874e4a 100644 --- a/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch @@ -8,7 +8,7 @@ this.storage.drop(i, levelchunk); } } -@@ -125,6 +_,7 @@ +@@ -126,6 +_,7 @@ } this.level.onChunkLoaded(chunkpos); diff --git a/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch b/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch index a1d3332be3..34cbc348c3 100644 --- a/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch @@ -1,6 +1,15 @@ --- a/net/minecraft/client/multiplayer/ClientLevel.java +++ b/net/minecraft/client/multiplayer/ClientLevel.java -@@ -126,6 +_,7 @@ +@@ -115,7 +_,7 @@ + private final TickRateManager tickRateManager; + private final Minecraft minecraft = Minecraft.getInstance(); + final List players = Lists.newArrayList(); +- final List dragonParts = Lists.newArrayList(); ++ final List> dragonParts = Lists.newArrayList(); + private final Map mapData = Maps.newHashMap(); + private static final int CLOUD_COLOR = -1; + private int skyFlashTime; +@@ -131,6 +_,7 @@ p_194170_.put( BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache(p_194168_ -> this.calculateBlockTint(p_194168_, BiomeColors.WATER_COLOR_RESOLVER)) ); @@ -8,16 +17,15 @@ } ); private final ClientChunkCache chunkSource; -@@ -135,6 +_,8 @@ +@@ -140,6 +_,7 @@ private final int seaLevel; private boolean tickDayTime; private static final Set MARKER_PARTICLE_ITEMS = Set.of(Items.BARRIER, Items.LIGHT); -+ private final it.unimi.dsi.fastutil.ints.Int2ObjectMap> partEntities = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); + private final net.neoforged.neoforge.client.model.data.ModelDataManager modelDataManager = new net.neoforged.neoforge.client.model.data.ModelDataManager(this); public void handleBlockChangedAck(int p_233652_) { this.blockStatePredictionHandler.endPredictionsUpTo(p_233652_, this); -@@ -164,10 +_,15 @@ +@@ -169,10 +_,15 @@ @Override public boolean setBlock(BlockPos p_233643_, BlockState p_233644_, int p_233645_, int p_233646_) { if (this.blockStatePredictionHandler.isPredicting()) { @@ -33,7 +41,7 @@ } return flag; -@@ -201,6 +_,7 @@ +@@ -206,6 +_,7 @@ this.serverSimulationDistance = p_363776_; this.updateSkyBrightness(); this.prepareWeather(); @@ -41,7 +49,7 @@ } public void queueLightUpdate(Runnable p_194172_) { -@@ -244,7 +_,7 @@ +@@ -249,7 +_,7 @@ private void tickTime() { this.clientLevelData.setGameTime(this.clientLevelData.getGameTime() + 1L); if (this.tickDayTime) { @@ -50,7 +58,7 @@ } } -@@ -283,7 +_,11 @@ +@@ -288,7 +_,11 @@ p_104640_.setOldPosAndRot(); p_104640_.tickCount++; Profiler.get().push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_104640_.getType()).toString()); @@ -63,7 +71,7 @@ Profiler.get().pop(); for (Entity entity : p_104640_.getPassengers()) { -@@ -335,8 +_,10 @@ +@@ -339,8 +_,10 @@ } public void addEntity(Entity p_104741_) { @@ -74,7 +82,7 @@ } public void removeEntity(int p_171643_, Entity.RemovalReason p_171644_) { -@@ -507,6 +_,13 @@ +@@ -511,6 +_,13 @@ float p_263349_, long p_263408_ ) { @@ -88,7 +96,7 @@ if (p_263381_ == this.minecraft.player) { this.playSound(p_263372_, p_263404_, p_263365_, p_263335_.value(), p_263417_, p_263416_, p_263349_, false, p_263408_); } -@@ -516,6 +_,12 @@ +@@ -520,6 +_,12 @@ public void playSeededSound( @Nullable Player p_263514_, Entity p_263536_, Holder p_263518_, SoundSource p_263487_, float p_263538_, float p_263524_, long p_263509_ ) { @@ -101,7 +109,16 @@ if (p_263514_ == this.minecraft.player) { this.minecraft.getSoundManager().play(new EntityBoundSoundInstance(p_263518_.value(), p_263487_, p_263538_, p_263524_, p_263536_, p_263509_)); } -@@ -1045,6 +_,7 @@ +@@ -731,7 +_,7 @@ + return this.players; + } + +- public List dragonParts() { ++ public List> dragonParts() { + return this.dragonParts; + } + +@@ -1056,6 +_,7 @@ } public void setDifficulty(Difficulty p_104852_) { @@ -109,29 +126,27 @@ this.difficulty = p_104852_; } -@@ -1081,14 +_,75 @@ - if (p_171712_ instanceof AbstractClientPlayer) { - ClientLevel.this.players.add((AbstractClientPlayer)p_171712_); +@@ -1098,6 +_,9 @@ + ClientLevel.this.dragonParts.addAll(Arrays.asList(enderdragon.getSubEntities())); + break; + default: ++ if (p_171712_.isMultipartEntity()) { ++ ClientLevel.this.dragonParts.addAll(Arrays.asList(p_171712_.getParts())); ++ } } -+ if (p_171712_.isMultipartEntity()) { -+ for (net.neoforged.neoforge.entity.PartEntity part : p_171712_.getParts()) { -+ ClientLevel.this.partEntities.put(part.getId(), part); -+ } -+ } } - public void onTrackingEnd(Entity p_171716_) { - p_171716_.unRide(); - ClientLevel.this.players.remove(p_171716_); +@@ -1112,10 +_,58 @@ + ClientLevel.this.dragonParts.removeAll(Arrays.asList(enderdragon.getSubEntities())); + break; + default: ++ if (p_171716_.isMultipartEntity()) { ++ ClientLevel.this.dragonParts.removeAll(Arrays.asList(p_171716_.getParts())); ++ } + } + + p_171716_.onRemovedFromLevel(); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.EntityLeaveLevelEvent(p_171716_, ClientLevel.this)); -+ -+ if (p_171716_.isMultipartEntity()) { -+ for (net.neoforged.neoforge.entity.PartEntity part : p_171716_.getParts()) { -+ ClientLevel.this.partEntities.remove(part.getId()); -+ } -+ } } public void onSectionChange(Entity p_233660_) { @@ -139,11 +154,6 @@ + } + + @Override -+ public java.util.Collection> getPartEntities() { -+ return this.partEntities.values(); -+ } -+ -+ @Override + public net.neoforged.neoforge.client.model.data.ModelDataManager getModelDataManager() { + return modelDataManager; + } diff --git a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch index a1ad4df3f6..dab1a825b8 100644 --- a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/ClientPacketListener.java +++ b/net/minecraft/client/multiplayer/ClientPacketListener.java -@@ -367,6 +_,7 @@ +@@ -368,6 +_,7 @@ private final ChunkBatchSizeCalculator chunkBatchSizeCalculator = new ChunkBatchSizeCalculator(); private final PingDebugMonitor pingDebugMonitor; private final DebugSampleSubscriber debugSampleSubscriber; @@ -8,7 +8,7 @@ @Nullable private LevelLoadStatusManager levelLoadStatusManager; private boolean serverEnforcesSecureChat; -@@ -388,7 +_,8 @@ +@@ -389,7 +_,8 @@ p_253924_.gui.getChat().restoreState(p_295121_.chatState()); } @@ -18,7 +18,7 @@ this.fuelValues = FuelValues.vanillaBurnTimes(p_295121_.receivedRegistries(), this.enabledFeatures); } -@@ -451,12 +_,13 @@ +@@ -452,12 +_,13 @@ this.minecraft.debugRenderer.clear(); this.minecraft.player.resetPos(); @@ -33,7 +33,7 @@ this.minecraft.player.setReducedDebugInfo(p_105030_.reducedDebugInfo()); this.minecraft.player.setShowDeathScreen(p_105030_.showDeathScreen()); this.minecraft.player.setDoLimitedCrafting(p_105030_.doLimitedCrafting()); -@@ -900,7 +_,8 @@ +@@ -902,7 +_,8 @@ this.serverCookies, chatcomponent$state, this.customReportDetails, @@ -126,7 +126,7 @@ } @Override -@@ -2526,6 +_,8 @@ +@@ -2540,6 +_,8 @@ } public void sendChat(String p_249888_) { @@ -135,7 +135,7 @@ Instant instant = Instant.now(); long i = Crypt.SaltSupplier.getLong(); LastSeenMessagesTracker.Update lastseenmessagestracker$update = this.lastSeenMessages.generateAndApplyUpdate(); -@@ -2535,6 +_,7 @@ +@@ -2549,6 +_,7 @@ } public void sendCommand(String p_250092_) { @@ -143,7 +143,7 @@ SignableCommand signablecommand = SignableCommand.of(this.parseCommand(p_250092_)); if (signablecommand.arguments().isEmpty()) { this.send(new ServerboundChatCommandPacket(p_250092_)); -@@ -2622,6 +_,10 @@ +@@ -2640,6 +_,10 @@ public Scoreboard scoreboard() { return this.scoreboard; diff --git a/patches/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch b/patches/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch index 4a88a77d66..128eb6a4de 100644 --- a/patches/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch +++ b/patches/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/MultiPlayerGameMode.java +++ b/net/minecraft/client/multiplayer/MultiPlayerGameMode.java -@@ -120,11 +_,12 @@ +@@ -121,11 +_,12 @@ } else if (blockstate.isAir()) { return false; } else { @@ -15,7 +15,7 @@ } return flag; -@@ -143,6 +_,7 @@ +@@ -144,6 +_,7 @@ BlockState blockstate = this.minecraft.level.getBlockState(p_105270_); this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, p_105270_, blockstate, 1.0F); this.startPrediction(this.minecraft.level, p_233757_ -> { @@ -23,7 +23,7 @@ this.destroyBlock(p_105270_); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, p_105270_, p_105271_, p_233757_); }); -@@ -152,15 +_,19 @@ +@@ -153,15 +_,19 @@ this.connection .send(new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, this.destroyBlockPos, p_105271_)); } @@ -43,7 +43,7 @@ if (flag && blockstate1.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), p_105270_) >= 1.0F) { this.destroyBlock(p_105270_); } else { -@@ -172,7 +_,7 @@ +@@ -173,7 +_,7 @@ this.minecraft.level.destroyBlockProgress(this.minecraft.player.getId(), this.destroyBlockPos, this.getDestroyStage()); } @@ -52,7 +52,7 @@ }); } -@@ -203,6 +_,7 @@ +@@ -204,6 +_,7 @@ BlockState blockstate1 = this.minecraft.level.getBlockState(p_105284_); this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, p_105284_, blockstate1, 1.0F); this.startPrediction(this.minecraft.level, p_233753_ -> { @@ -60,7 +60,7 @@ this.destroyBlock(p_105284_); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, p_105284_, p_105285_, p_233753_); }); -@@ -215,7 +_,7 @@ +@@ -216,7 +_,7 @@ } else { this.destroyProgress = this.destroyProgress + blockstate.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), p_105284_); if (this.destroyTicks % 4.0F == 0.0F) { @@ -69,7 +69,7 @@ this.minecraft .getSoundManager() .play( -@@ -232,6 +_,7 @@ +@@ -233,6 +_,7 @@ this.destroyTicks++; this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, p_105284_, blockstate, Mth.clamp(this.destroyProgress, 0.0F, 1.0F)); @@ -77,7 +77,7 @@ if (this.destroyProgress >= 1.0F) { this.isDestroying = false; this.startPrediction(this.minecraft.level, p_233739_ -> { -@@ -270,7 +_,7 @@ +@@ -271,7 +_,7 @@ private boolean sameDestroyTarget(BlockPos p_105282_) { ItemStack itemstack = this.minecraft.player.getMainHandItem(); @@ -86,7 +86,7 @@ } private void ensureHasSentCarriedItem() { -@@ -298,12 +_,23 @@ +@@ -299,12 +_,23 @@ private InteractionResult performUseItemOn(LocalPlayer p_233747_, InteractionHand p_233748_, BlockHitResult p_233749_) { BlockPos blockpos = p_233749_.getBlockPos(); ItemStack itemstack = p_233747_.getItemInHand(p_233748_); @@ -112,7 +112,7 @@ BlockState blockstate = this.minecraft.level.getBlockState(blockpos); if (!this.connection.isFeatureEnabled(blockstate.getBlock().requiredFeatures())) { return InteractionResult.FAIL; -@@ -324,8 +_,10 @@ +@@ -325,8 +_,10 @@ } } @@ -125,7 +125,7 @@ InteractionResult interactionresult2; if (this.localPlayerMode.isCreative()) { int i = itemstack.getCount(); -@@ -359,6 +_,11 @@ +@@ -360,6 +_,11 @@ mutableobject.setValue(InteractionResult.PASS); return serverbounduseitempacket; } else { @@ -137,7 +137,7 @@ InteractionResult interactionresult = itemstack.use(this.minecraft.level, p_233722_, p_233723_); ItemStack itemstack1; if (interactionresult instanceof InteractionResult.Success interactionresult$success) { -@@ -371,6 +_,8 @@ +@@ -372,6 +_,8 @@ if (itemstack1 != itemstack) { p_233722_.setItemInHand(p_233723_, itemstack1); @@ -146,7 +146,7 @@ } mutableobject.setValue(interactionresult); -@@ -409,6 +_,9 @@ +@@ -410,6 +_,9 @@ this.ensureHasSentCarriedItem(); Vec3 vec3 = p_105233_.getLocation().subtract(p_105232_.getX(), p_105232_.getY(), p_105232_.getZ()); this.connection.send(ServerboundInteractPacket.createInteractionPacket(p_105232_, p_105231_.isShiftKeyDown(), p_105234_, vec3)); diff --git a/patches/net/minecraft/client/multiplayer/PlayerInfo.java.patch b/patches/net/minecraft/client/multiplayer/PlayerInfo.java.patch index 27972460ce..0be4333b3b 100644 --- a/patches/net/minecraft/client/multiplayer/PlayerInfo.java.patch +++ b/patches/net/minecraft/client/multiplayer/PlayerInfo.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/PlayerInfo.java +++ b/net/minecraft/client/multiplayer/PlayerInfo.java -@@ -86,6 +_,7 @@ +@@ -88,6 +_,7 @@ } protected void setGameMode(GameType p_105318_) { diff --git a/patches/net/minecraft/client/particle/BreakingItemParticle.java.patch b/patches/net/minecraft/client/particle/BreakingItemParticle.java.patch deleted file mode 100644 index 3d9b32361f..0000000000 --- a/patches/net/minecraft/client/particle/BreakingItemParticle.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/client/particle/BreakingItemParticle.java -+++ b/net/minecraft/client/particle/BreakingItemParticle.java -@@ -33,7 +_,7 @@ - - protected BreakingItemParticle(ClientLevel p_105665_, double p_105666_, double p_105667_, double p_105668_, ItemStack p_105669_) { - super(p_105665_, p_105666_, p_105667_, p_105668_, 0.0, 0.0, 0.0); -- this.setSprite(Minecraft.getInstance().getItemRenderer().getModel(p_105669_, p_105665_, null, 0).getParticleIcon()); -+ this.setSprite(Minecraft.getInstance().getItemRenderer().getModel(p_105669_, p_105665_, null, 0).getParticleIcon(net.neoforged.neoforge.client.model.data.ModelData.EMPTY)); - this.gravity = 1.0F; - this.quadSize /= 2.0F; - this.uo = this.random.nextFloat() * 3.0F; diff --git a/patches/net/minecraft/client/particle/ItemPickupParticle.java.patch b/patches/net/minecraft/client/particle/ItemPickupParticle.java.patch index fbf0a1e746..8cea2aa848 100644 --- a/patches/net/minecraft/client/particle/ItemPickupParticle.java.patch +++ b/patches/net/minecraft/client/particle/ItemPickupParticle.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/particle/ItemPickupParticle.java +++ b/net/minecraft/client/particle/ItemPickupParticle.java -@@ -102,4 +_,11 @@ +@@ -99,4 +_,11 @@ this.targetYOld = this.targetY; this.targetZOld = this.targetZ; } diff --git a/patches/net/minecraft/client/particle/Particle.java.patch b/patches/net/minecraft/client/particle/Particle.java.patch index a3587365f5..b74356986f 100644 --- a/patches/net/minecraft/client/particle/Particle.java.patch +++ b/patches/net/minecraft/client/particle/Particle.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/particle/Particle.java +++ b/net/minecraft/client/particle/Particle.java -@@ -245,6 +_,18 @@ +@@ -250,6 +_,18 @@ return Optional.empty(); } diff --git a/patches/net/minecraft/client/particle/ParticleEngine.java.patch b/patches/net/minecraft/client/particle/ParticleEngine.java.patch index de43669f57..cb59bf982d 100644 --- a/patches/net/minecraft/client/particle/ParticleEngine.java.patch +++ b/patches/net/minecraft/client/particle/ParticleEngine.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/particle/ParticleEngine.java +++ b/net/minecraft/client/particle/ParticleEngine.java -@@ -77,11 +_,11 @@ - ParticleRenderType.TERRAIN_SHEET, ParticleRenderType.PARTICLE_SHEET_OPAQUE, ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT, ParticleRenderType.CUSTOM +@@ -74,11 +_,11 @@ + ParticleRenderType.TERRAIN_SHEET, ParticleRenderType.PARTICLE_SHEET_OPAQUE, ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT ); protected ClientLevel level; - private final Map> particles = Maps.newIdentityHashMap(); @@ -14,7 +14,7 @@ private final Queue particlesToAdd = Queues.newArrayDeque(); private final Map spriteSets = Maps.newHashMap(); private final TextureAtlas textureAtlas; -@@ -214,10 +_,14 @@ +@@ -207,10 +_,14 @@ this.register(ParticleTypes.BLOCK_CRUMBLE, new TerrainParticle.CrumblingProvider()); } @@ -30,7 +30,7 @@ public void register(ParticleType p_273423_, ParticleProvider.Sprite p_273134_) { this.register( p_273423_, -@@ -234,10 +_,12 @@ +@@ -227,10 +_,12 @@ ); } @@ -44,7 +44,7 @@ } @Override -@@ -357,7 +_,7 @@ +@@ -350,7 +_,7 @@ private Particle makeParticle( T p_107396_, double p_107397_, double p_107398_, double p_107399_, double p_107400_, double p_107401_, double p_107402_ ) { @@ -53,36 +53,81 @@ return particleprovider == null ? null : particleprovider.createParticle(p_107396_, this.level, p_107397_, p_107398_, p_107399_, p_107400_, p_107401_, p_107402_); -@@ -433,17 +_,27 @@ +@@ -426,28 +_,48 @@ } } + @Deprecated - public void render(LightTexture p_107339_, Camera p_107340_, float p_107341_) { -+ render(p_107339_, p_107340_, p_107341_, null, type -> true); + public void render(Camera p_107340_, float p_107341_, MultiBufferSource.BufferSource p_383193_) { +- for (ParticleRenderType particlerendertype : RENDER_ORDER) { ++ render(p_107340_, p_107341_, p_383193_, null, type -> true); + } + -+ public void render(LightTexture p_107339_, Camera p_107340_, float p_107341_, @Nullable net.minecraft.client.renderer.culling.Frustum frustum, java.util.function.Predicate renderTypePredicate) { - p_107339_.turnOnLightLayer(); - RenderSystem.enableDepthTest(); ++ public void render(Camera p_107340_, float p_107341_, MultiBufferSource.BufferSource p_383193_, @Nullable net.minecraft.client.renderer.culling.Frustum frustum, java.util.function.Predicate renderTypePredicate) { + //TODO porting: is this even needed with the particle render order fix??? -+ RenderSystem.activeTexture(org.lwjgl.opengl.GL13.GL_TEXTURE2); -+ RenderSystem.activeTexture(org.lwjgl.opengl.GL13.GL_TEXTURE0); - -- for (ParticleRenderType particlerendertype : RENDER_ORDER) { ++ com.mojang.blaze3d.systems.RenderSystem.activeTexture(org.lwjgl.opengl.GL13.GL_TEXTURE2); ++ com.mojang.blaze3d.systems.RenderSystem.activeTexture(org.lwjgl.opengl.GL13.GL_TEXTURE0); + for (ParticleRenderType particlerendertype : this.particles.keySet()) { // Neo: allow custom IParticleRenderType's -+ if (particlerendertype == ParticleRenderType.NO_RENDER || !renderTypePredicate.test(particlerendertype)) continue; ++ if (particlerendertype == ParticleRenderType.NO_RENDER || particlerendertype == ParticleRenderType.CUSTOM || !renderTypePredicate.test(particlerendertype)) continue; Queue queue = this.particles.get(particlerendertype); if (queue != null && !queue.isEmpty()) { - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder bufferbuilder = particlerendertype.begin(tesselator, this.textureManager); - if (bufferbuilder != null) { - for (Particle particle : queue) { -+ if (frustum != null && !frustum.isVisible(particle.getRenderBoundingBox(p_107341_))) continue; - try { - particle.render(bufferbuilder, p_107340_, p_107341_); - } catch (Throwable throwable) { -@@ -475,7 +_,7 @@ +- renderParticleType(p_107340_, p_107341_, p_383193_, particlerendertype, queue); ++ renderParticleType(p_107340_, p_107341_, p_383193_, particlerendertype, queue, frustum); + } + } + + Queue queue1 = this.particles.get(ParticleRenderType.CUSTOM); + if (queue1 != null && !queue1.isEmpty()) { +- renderCustomParticles(p_107340_, p_107341_, p_383193_, queue1); ++ renderCustomParticles(p_107340_, p_107341_, p_383193_, queue1, frustum); + } + + p_383193_.endBatch(); + } + +- private static void renderParticleType( +- Camera p_382847_, float p_383032_, MultiBufferSource.BufferSource p_383105_, ParticleRenderType p_383179_, Queue p_383046_ ++ /** ++ * @deprecated Neo: use {@link #renderParticleType(Camera, float, MultiBufferSource.BufferSource, ParticleRenderType, Queue, net.minecraft.client.renderer.culling.Frustum)} instead ++ */ ++ @Deprecated ++ private static void renderParticleType( ++ Camera p_382847_, float p_383032_, MultiBufferSource.BufferSource p_383105_, ParticleRenderType p_383179_, Queue p_383046_ ++ ) { ++ renderParticleType(p_382847_, p_383032_, p_383105_, p_383179_, p_383046_, null); ++ } ++ ++ private static void renderParticleType( ++ Camera p_382847_, float p_383032_, MultiBufferSource.BufferSource p_383105_, ParticleRenderType p_383179_, Queue p_383046_, @Nullable net.minecraft.client.renderer.culling.Frustum frustum + ) { + VertexConsumer vertexconsumer = p_383105_.getBuffer(Objects.requireNonNull(p_383179_.renderType())); + + for (Particle particle : p_383046_) { ++ if (frustum != null && !frustum.isVisible(particle.getRenderBoundingBox(p_383032_))) continue; + try { + particle.render(vertexconsumer, p_382847_, p_383032_); + } catch (Throwable throwable) { +@@ -460,10 +_,19 @@ + } + } + ++ /** ++ * @deprecated Neo: use {@link #renderCustomParticles(Camera, float, MultiBufferSource.BufferSource, Queue, net.minecraft.client.renderer.culling.Frustum)} instead ++ */ ++ @Deprecated + private static void renderCustomParticles(Camera p_383089_, float p_383167_, MultiBufferSource.BufferSource p_382990_, Queue p_383010_) { ++ renderCustomParticles(p_383089_, p_383167_, p_382990_, p_383010_, null); ++ } ++ ++ private static void renderCustomParticles(Camera p_383089_, float p_383167_, MultiBufferSource.BufferSource p_382990_, Queue p_383010_, @Nullable net.minecraft.client.renderer.culling.Frustum frustum) { + PoseStack posestack = new PoseStack(); + + for (Particle particle : p_383010_) { ++ if (frustum != null && !frustum.isVisible(particle.getRenderBoundingBox(p_383167_))) continue; + try { + particle.renderCustom(posestack, p_382990_, p_383089_, p_383167_); + } catch (Throwable throwable) { +@@ -483,7 +_,7 @@ } public void destroy(BlockPos p_107356_, BlockState p_107357_) { @@ -91,7 +136,7 @@ VoxelShape voxelshape = p_107357_.getShape(this.level, p_107356_); double d0 = 0.25; voxelshape.forAllBoxes( -@@ -507,7 +_,7 @@ +@@ -515,7 +_,7 @@ d6 - 0.5, p_107357_, p_107356_ @@ -100,7 +145,7 @@ ); } } -@@ -552,12 +_,28 @@ +@@ -560,12 +_,28 @@ d0 = (double)i + aabb.maxX + 0.1F; } diff --git a/patches/net/minecraft/client/particle/ParticleRenderType.java.patch b/patches/net/minecraft/client/particle/ParticleRenderType.java.patch index e3d114e526..9066738f82 100644 --- a/patches/net/minecraft/client/particle/ParticleRenderType.java.patch +++ b/patches/net/minecraft/client/particle/ParticleRenderType.java.patch @@ -1,24 +1,23 @@ --- a/net/minecraft/client/particle/ParticleRenderType.java +++ b/net/minecraft/client/particle/ParticleRenderType.java -@@ -44,6 +_,11 @@ - public String toString() { - return "PARTICLE_SHEET_OPAQUE"; - } -+ -+ @Override -+ public boolean isTranslucent() { -+ return false; -+ } - }; - ParticleRenderType PARTICLE_SHEET_TRANSLUCENT = new ParticleRenderType() { - @Override -@@ -89,4 +_,9 @@ +@@ -7,14 +_,18 @@ + import net.neoforged.api.distmarker.OnlyIn; - @Nullable - BufferBuilder begin(Tesselator p_350949_, TextureManager p_107437_); + @OnlyIn(Dist.CLIENT) +-public record ParticleRenderType(String name, @Nullable RenderType renderType) { ++public record ParticleRenderType(String name, @Nullable RenderType renderType, boolean translucent) { + public static final ParticleRenderType TERRAIN_SHEET = new ParticleRenderType("TERRAIN_SHEET", RenderType.translucentParticle(TextureAtlas.LOCATION_BLOCKS)); + public static final ParticleRenderType PARTICLE_SHEET_OPAQUE = new ParticleRenderType( +- "PARTICLE_SHEET_OPAQUE", RenderType.opaqueParticle(TextureAtlas.LOCATION_PARTICLES) ++ "PARTICLE_SHEET_OPAQUE", RenderType.opaqueParticle(TextureAtlas.LOCATION_PARTICLES), false + ); + public static final ParticleRenderType PARTICLE_SHEET_TRANSLUCENT = new ParticleRenderType( + "PARTICLE_SHEET_TRANSLUCENT", RenderType.translucentParticle(TextureAtlas.LOCATION_PARTICLES) + ); + public static final ParticleRenderType CUSTOM = new ParticleRenderType("CUSTOM", null); + public static final ParticleRenderType NO_RENDER = new ParticleRenderType("NO_RENDER", null); + -+ /** {@return whether this type renders before or after the translucent chunk layer} */ -+ default boolean isTranslucent() { -+ return true; ++ public ParticleRenderType(String name, @Nullable RenderType renderType) { ++ this(name, renderType, true); + } } diff --git a/patches/net/minecraft/client/player/LocalPlayer.java.patch b/patches/net/minecraft/client/player/LocalPlayer.java.patch index d772181669..7d98bb110e 100644 --- a/patches/net/minecraft/client/player/LocalPlayer.java.patch +++ b/patches/net/minecraft/client/player/LocalPlayer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/player/LocalPlayer.java +++ b/net/minecraft/client/player/LocalPlayer.java -@@ -302,6 +_,7 @@ +@@ -307,6 +_,7 @@ ServerboundPlayerActionPacket.Action serverboundplayeractionpacket$action = p_108701_ ? ServerboundPlayerActionPacket.Action.DROP_ALL_ITEMS : ServerboundPlayerActionPacket.Action.DROP_ITEM; @@ -8,7 +8,7 @@ ItemStack itemstack = this.getInventory().removeFromSelected(p_108701_); this.connection.send(new ServerboundPlayerActionPacket(serverboundplayeractionpacket$action, BlockPos.ZERO, Direction.DOWN)); return !itemstack.isEmpty(); -@@ -482,7 +_,14 @@ +@@ -487,7 +_,14 @@ @Override public void playSound(SoundEvent p_108651_, float p_108652_, float p_108653_) { @@ -24,43 +24,43 @@ } @Override -@@ -676,6 +_,7 @@ +@@ -680,6 +_,7 @@ + && this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING) && (this.isShiftKeyDown() || !this.isSleeping() && !this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.STANDING)); - float f = (float)this.getAttributeValue(Attributes.SNEAKING_SPEED); - this.input.tick(this.isMovingSlowly(), f); + this.input.tick(); + net.neoforged.neoforge.client.ClientHooks.onMovementInputUpdate(this, this.input); this.minecraft.getTutorial().onInput(this.input); - if (this.isUsingItem() && !this.isPassenger()) { - this.input.leftImpulse *= 0.2F; -@@ -704,7 +_,7 @@ - boolean flag4 = this.canStartSprinting(); - boolean flag5 = this.isPassenger() ? this.getVehicle().onGround() : this.onGround(); - boolean flag6 = !flag1 && !flag2; -- if ((flag5 || this.isUnderWater()) && flag6 && flag4) { -+ if ((flag5 || this.isUnderWater() || this.canStartSwimming()) && flag6 && flag4) { + if (this.shouldStopSprinting()) { + this.setSprinting(false); +@@ -718,7 +_,7 @@ + boolean flag3 = this.canStartSprinting(); + boolean flag4 = this.isPassenger() ? this.getVehicle().onGround() : this.onGround(); + boolean flag5 = !flag1 && !flag2; +- if ((flag4 || this.isUnderWater()) && flag5 && flag3) { ++ if ((flag4 || this.isUnderWater() || this.canStartSwimming()) && flag5 && flag3) { if (this.sprintTriggerTime <= 0 && !this.minecraft.options.keySprint.isDown()) { this.sprintTriggerTime = 7; } else { -@@ -712,15 +_,15 @@ +@@ -726,15 +_,15 @@ } } -- if ((!this.isInWater() || this.isUnderWater()) && flag4 && this.minecraft.options.keySprint.isDown()) { -+ if (!this.isSprinting() && (!(this.isInWater() || this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType))) || (this.isUnderWater() || this.canStartSwimming())) && this.hasEnoughImpulseToStartSprinting() && flag4 && !this.isUsingItem() && !this.hasEffect(MobEffects.BLINDNESS) && this.minecraft.options.keySprint.isDown()) { +- if ((!this.isInWater() || this.isUnderWater()) && flag3 && this.minecraft.options.keySprint.isDown()) { ++ if (!this.isSprinting() && (!(this.isInWater() || this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType))) || (this.isUnderWater() || this.canStartSwimming())) && this.hasEnoughImpulseToStartSprinting() && flag3 && !this.isUsingItem() && !this.hasEffect(MobEffects.BLINDNESS) && this.minecraft.options.keySprint.isDown()) { this.setSprinting(true); } if (this.isSprinting()) { - boolean flag7 = !this.input.hasForwardImpulse() || !this.hasEnoughFoodToStartSprinting(); -- boolean flag8 = flag7 || this.horizontalCollision && !this.minorHorizontalCollision || this.isInWater() && !this.isUnderWater(); -+ boolean flag8 = flag7 || this.horizontalCollision && !this.minorHorizontalCollision || this.isInWater() && !this.isUnderWater() || (this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)) && !this.canStartSwimming()); + boolean flag6 = !this.input.hasForwardImpulse() || !this.hasEnoughFoodToStartSprinting(); +- boolean flag7 = flag6 || this.horizontalCollision && !this.minorHorizontalCollision || this.isInWater() && !this.isUnderWater(); ++ boolean flag7 = flag6 || this.horizontalCollision && !this.minorHorizontalCollision || this.isInWater() && !this.isUnderWater() || (this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)) && !this.canStartSwimming()); if (this.isSwimming()) { -- if (!this.onGround() && !this.input.keyPresses.shift() && flag7 || !this.isInWater()) { -+ if (!this.onGround() && !this.input.keyPresses.shift() && flag7 || !(this.isInWater() || this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)))) { +- if (!this.onGround() && !this.input.keyPresses.shift() && flag6 || !this.isInWater()) { ++ if (!this.onGround() && !this.input.keyPresses.shift() && flag6 || !(this.isInWater() || this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)))) { this.setSprinting(false); } - } else if (flag8) { -@@ -729,7 +_,7 @@ + } else if (flag7) { +@@ -743,7 +_,7 @@ } boolean flag9 = false; @@ -69,7 +69,7 @@ if (this.minecraft.gameMode.isAlwaysFlying()) { if (!abilities.flying) { abilities.flying = true; -@@ -866,6 +_,10 @@ +@@ -896,6 +_,10 @@ @Override public void rideTick() { super.rideTick(); @@ -80,7 +80,7 @@ this.handsBusy = false; if (this.getControlledVehicle() instanceof AbstractBoat abstractboat) { abstractboat.setInput( -@@ -1063,7 +_,7 @@ +@@ -1094,7 +_,7 @@ } private boolean hasEnoughFoodToStartSprinting() { diff --git a/patches/net/minecraft/client/renderer/GameRenderer.java.patch b/patches/net/minecraft/client/renderer/GameRenderer.java.patch index db82c7ecba..783162e3ba 100644 --- a/patches/net/minecraft/client/renderer/GameRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/GameRenderer.java.patch @@ -29,7 +29,7 @@ f2 /= (float)livingentity.hurtDuration; f2 = Mth.sin(f2 * f2 * f2 * f2 * (float) Math.PI); float f3 = livingentity.getHurtDir(); -@@ -474,12 +_,12 @@ +@@ -476,12 +_,12 @@ (float)((double)window.getHeight() / window.getGuiScale()), 0.0F, 1000.0F, @@ -44,7 +44,7 @@ Lighting.setupFor3DItems(); GuiGraphics guigraphics = new GuiGraphics(this.minecraft, this.renderBuffers.bufferSource()); if (flag && p_109096_ && this.minecraft.level != null) { -@@ -505,7 +_,8 @@ +@@ -507,7 +_,8 @@ } } else if (flag && this.minecraft.screen != null) { try { @@ -54,10 +54,10 @@ } catch (Throwable throwable1) { CrashReport crashreport1 = CrashReport.forThrowable(throwable1, "Rendering screen"); CrashReportCategory crashreportcategory1 = crashreport1.addCategory("Screen render details"); -@@ -687,6 +_,8 @@ +@@ -689,6 +_,8 @@ this.minecraft.levelRenderer.prepareCullFrustum(camera.getPosition(), matrix4f2, matrix4f1); this.minecraft.getMainRenderTarget().bindWrite(true); - this.minecraft.levelRenderer.renderLevel(this.resourcePool, p_348589_, flag, camera, this, this.lightTexture, matrix4f2, matrix4f); + this.minecraft.levelRenderer.renderLevel(this.resourcePool, p_348589_, flag, camera, this, matrix4f2, matrix4f); + profilerfiller.popPush("neoforge_render_last"); + net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_LEVEL, this.minecraft.levelRenderer, null, matrix4f1, matrix4f, this.minecraft.levelRenderer.getTicks(), camera, this.minecraft.levelRenderer.getFrustum()); profilerfiller.popPush("hand"); diff --git a/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch b/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch index 1bf5aead8b..81aaa5cdef 100644 --- a/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch +++ b/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch @@ -5,18 +5,18 @@ @OnlyIn(Dist.CLIENT) public class ItemBlockRenderTypes { + @Deprecated - private static final Map TYPE_BY_BLOCK = Util.make(Maps.newHashMap(), p_378824_ -> { + private static final Map TYPE_BY_BLOCK = Util.make(Maps.newHashMap(), p_382527_ -> { RenderType rendertype = RenderType.tripwire(); - p_378824_.put(Blocks.TRIPWIRE, rendertype); -@@ -340,6 +_,7 @@ - p_378824_.put(Blocks.BUBBLE_COLUMN, rendertype3); - p_378824_.put(Blocks.TINTED_GLASS, rendertype3); + p_382527_.put(Blocks.TRIPWIRE, rendertype); +@@ -345,6 +_,7 @@ + p_382527_.put(Blocks.BUBBLE_COLUMN, rendertype3); + p_382527_.put(Blocks.TINTED_GLASS, rendertype3); }); + @Deprecated private static final Map TYPE_BY_FLUID = Util.make(Maps.newHashMap(), p_109290_ -> { RenderType rendertype = RenderType.translucent(); p_109290_.put(Fluids.FLOWING_WATER, rendertype); -@@ -347,6 +_,8 @@ +@@ -352,6 +_,8 @@ }); private static boolean renderCutout; @@ -25,7 +25,7 @@ public static RenderType getChunkRenderType(BlockState p_109283_) { Block block = p_109283_.getBlock(); if (block instanceof LeavesBlock) { -@@ -357,6 +_,8 @@ +@@ -362,6 +_,8 @@ } } @@ -34,7 +34,7 @@ public static RenderType getMovingBlockRenderType(BlockState p_109294_) { Block block = p_109294_.getBlock(); if (block instanceof LeavesBlock) { -@@ -371,11 +_,15 @@ +@@ -376,11 +_,15 @@ } } @@ -50,7 +50,7 @@ public static RenderType getRenderType(ItemStack p_366701_) { if (p_366701_.getItem() instanceof BlockItem blockitem) { Block block = blockitem.getBlock(); -@@ -392,5 +_,78 @@ +@@ -397,5 +_,78 @@ public static void setFancy(boolean p_109292_) { renderCutout = p_109292_; diff --git a/patches/net/minecraft/client/renderer/ItemInHandRenderer.java.patch b/patches/net/minecraft/client/renderer/ItemInHandRenderer.java.patch index 50e02aa55f..cc0c374d6d 100644 --- a/patches/net/minecraft/client/renderer/ItemInHandRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/ItemInHandRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/ItemInHandRenderer.java +++ b/net/minecraft/client/renderer/ItemInHandRenderer.java -@@ -168,11 +_,11 @@ +@@ -172,11 +_,11 @@ ResourceLocation resourcelocation = this.minecraft.player.getSkin().texture(); if (p_109365_ == HumanoidArm.RIGHT) { playerrenderer.renderRightHand( @@ -14,7 +14,7 @@ ); } -@@ -234,7 +_,7 @@ +@@ -238,7 +_,7 @@ p_109367_.translate(-0.5F, -0.5F, 0.0F); p_109367_.scale(0.0078125F, 0.0078125F, 0.0078125F); MapId mapid = p_109370_.get(DataComponents.MAP_ID); @@ -23,7 +23,7 @@ VertexConsumer vertexconsumer = p_109368_.getBuffer(mapitemsaveddata == null ? MAP_BACKGROUND : MAP_BACKGROUND_CHECKERBOARD); Matrix4f matrix4f = p_109367_.last().pose(); vertexconsumer.addVertex(matrix4f, -7.0F, 135.0F, 0.0F).setColor(-1).setUv(0.0F, 1.0F).setLight(p_109369_); -@@ -271,10 +_,10 @@ +@@ -275,10 +_,10 @@ ResourceLocation resourcelocation = abstractclientplayer.getSkin().texture(); if (flag) { playerrenderer.renderRightHand( @@ -36,7 +36,7 @@ } } -@@ -347,12 +_,14 @@ +@@ -351,12 +_,14 @@ if (iteminhandrenderer$handrenderselection.renderMainHand) { float f4 = interactionhand == InteractionHand.MAIN_HAND ? f : 0.0F; float f5 = 1.0F - Mth.lerp(p_109315_, this.oMainHandHeight, this.mainHandHeight); @@ -51,7 +51,7 @@ this.renderArmWithItem(p_109318_, p_109315_, f1, InteractionHand.OFF_HAND, f6, this.offHandItem, f7, p_109316_, p_109317_, p_109319_); } -@@ -412,13 +_,13 @@ +@@ -416,13 +_,13 @@ if (flag && !p_109372_.isInvisible()) { this.renderPlayerArm(p_109379_, p_109380_, p_109381_, p_109378_, p_109376_, humanoidarm); } @@ -67,30 +67,12 @@ boolean flag1 = CrossbowItem.isCharged(p_109377_); boolean flag2 = humanoidarm == HumanoidArm.RIGHT; int i = flag2 ? 1 : -1; -@@ -468,6 +_,7 @@ - ); +@@ -468,6 +_,8 @@ } else { boolean flag3 = humanoidarm == HumanoidArm.RIGHT; -+ if (!net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_109377_).applyForgeHandTransform(p_109379_, minecraft.player, humanoidarm, p_109377_, p_109373_, p_109378_, p_109376_)) // FORGE: Allow items to define custom arm animation + int j = flag3 ? 1 : -1; ++ // Neo: Allow items to define custom arm animation ++ if (!net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_109377_).applyForgeHandTransform(p_109379_, minecraft.player, humanoidarm, p_109377_, p_109373_, p_109378_, p_109376_)) if (p_109372_.isUsingItem() && p_109372_.getUseItemRemainingTicks() > 0 && p_109372_.getUsedItemHand() == p_109375_) { - int k = flag3 ? 1 : -1; switch (p_109377_.getUseAnimation()) { -@@ -582,8 +_,16 @@ - this.offHandHeight = Mth.clamp(this.offHandHeight - 0.4F, 0.0F, 1.0F); - } else { - float f = localplayer.getAttackStrengthScale(1.0F); -- this.mainHandHeight = this.mainHandHeight + Mth.clamp((this.mainHandItem == itemstack ? f * f * f : 0.0F) - this.mainHandHeight, -0.4F, 0.4F); -- this.offHandHeight = this.offHandHeight + Mth.clamp((float)(this.offHandItem == itemstack1 ? 1 : 0) - this.offHandHeight, -0.4F, 0.4F); -+ boolean requipM = net.neoforged.neoforge.client.ClientHooks.shouldCauseReequipAnimation(this.mainHandItem, itemstack, localplayer.getInventory().selected); -+ boolean requipO = net.neoforged.neoforge.client.ClientHooks.shouldCauseReequipAnimation(this.offHandItem, itemstack1, -1); -+ -+ if (!requipM && this.mainHandItem != itemstack) -+ this.mainHandItem = itemstack; -+ if (!requipO && this.offHandItem != itemstack1) -+ this.offHandItem = itemstack1; -+ -+ this.mainHandHeight += Mth.clamp((!requipM ? f * f * f : 0.0F) - this.mainHandHeight, -0.4F, 0.4F); -+ this.offHandHeight += Mth.clamp((float)(!requipO ? 1 : 0) - this.offHandHeight, -0.4F, 0.4F); - } - - if (this.mainHandHeight < 0.1F) { + case NONE: diff --git a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch index f5f9a14c0d..8bb0f0e49c 100644 --- a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/LevelRenderer.java +++ b/net/minecraft/client/renderer/LevelRenderer.java -@@ -485,7 +_,7 @@ +@@ -480,7 +_,7 @@ RenderSystem.clear(16640); }); if (!flag1) { @@ -9,25 +9,25 @@ } this.addMainPass(framegraphbuilder, frustum, p_109604_, p_254120_, p_323920_, fogparameters, p_109603_, flag2, p_348530_, profilerfiller); -@@ -494,7 +_,7 @@ +@@ -489,7 +_,7 @@ postchain1.addToFrame(framegraphbuilder, i, j, this.targets); } -- this.addParticlesPass(framegraphbuilder, p_109604_, p_109606_, f, fogparameters); -+ this.addParticlesPass(framegraphbuilder, p_109604_, p_109606_, f, fogparameters, frustum, p_254120_, p_323920_); +- this.addParticlesPass(framegraphbuilder, p_109604_, f, fogparameters); ++ this.addParticlesPass(framegraphbuilder, p_109604_, f, fogparameters, frustum, p_254120_, p_323920_); CloudStatus cloudstatus = this.minecraft.options.getCloudsType(); if (cloudstatus != CloudStatus.OFF) { float f2 = this.level.effects().getCloudHeight(); -@@ -505,7 +_,7 @@ +@@ -500,7 +_,7 @@ } } -- this.addWeatherPass(framegraphbuilder, p_109606_, p_109604_.getPosition(), f, fogparameters); -+ this.addWeatherPass(framegraphbuilder, p_109606_, p_109604_.getPosition(), f, fogparameters, p_254120_, p_323920_, p_109604_); +- this.addWeatherPass(framegraphbuilder, p_109604_.getPosition(), f, fogparameters); ++ this.addWeatherPass(framegraphbuilder, p_109604_.getPosition(), f, fogparameters, p_254120_, p_323920_, p_109604_); if (postchain != null) { postchain.addToFrame(framegraphbuilder, i, j, this.targets); } -@@ -576,7 +_,9 @@ +@@ -571,7 +_,9 @@ double d2 = vec3.z(); p_362234_.push("terrain"); this.renderSectionLayer(RenderType.solid(), d0, d1, d2, p_362420_, p_361272_); @@ -37,7 +37,7 @@ this.renderSectionLayer(RenderType.cutout(), d0, d1, d2, p_362420_, p_361272_); if (this.level.effects().constantAmbientLight()) { Lighting.setupNetherLevel(); -@@ -608,6 +_,7 @@ +@@ -603,6 +_,7 @@ p_362234_.popPush("entities"); this.renderEntities(posestack, multibuffersource$buffersource, p_363453_, p_360931_, this.visibleEntities); multibuffersource$buffersource.endLastBatch(); @@ -45,7 +45,7 @@ this.checkPoseStack(posestack); p_362234_.popPush("blockentities"); this.renderBlockEntities(posestack, multibuffersource$buffersource, multibuffersource$buffersource1, p_363453_, f); -@@ -624,6 +_,7 @@ +@@ -619,6 +_,7 @@ multibuffersource$buffersource.endBatch(Sheets.hangingSignSheet()); multibuffersource$buffersource.endBatch(Sheets.chestSheet()); this.renderBuffers.outlineBufferSource().endOutlineBatch(); @@ -53,45 +53,43 @@ if (p_363964_) { this.renderBlockOutline(p_363453_, multibuffersource$buffersource, posestack, false); } -@@ -644,6 +_,11 @@ +@@ -639,6 +_,11 @@ multibuffersource$buffersource1.endBatch(); this.checkPoseStack(posestack); multibuffersource$buffersource.endBatch(RenderType.waterMask()); + // Neo: in Fast/Fancy, render solid particles before translucent geometry so they don't disappear underwater (MC-161917) + if (this.targets.particles == null) { + p_362234_.popPush("solid_particles"); -+ this.minecraft.particleEngine.render(this.minecraft.gameRenderer.lightTexture(), p_363453_, f, p_366590_, type -> !type.isTranslucent()); ++ this.minecraft.particleEngine.render(p_363453_, f, this.renderBuffers.bufferSource(), p_366590_, type -> !type.translucent()); + } multibuffersource$buffersource.endBatch(); if (resourcehandle1 != null) { resourcehandle1.get().setClearColor(0.0F, 0.0F, 0.0F, 0.0F); -@@ -664,7 +_,15 @@ +@@ -659,7 +_,15 @@ }); } + /** -+ * @deprecated Neo: use {@link #addParticlesPass(FrameGraphBuilder, Camera, LightTexture, float, FogParameters, Frustum, Matrix4f, Matrix4f)} instead ++ * @deprecated Neo: use {@link #addParticlesPass(FrameGraphBuilder, Camera, float, FogParameters, Frustum, Matrix4f, Matrix4f)} instead + */ + @Deprecated - private void addParticlesPass(FrameGraphBuilder p_363357_, Camera p_365299_, LightTexture p_364308_, float p_364282_, FogParameters p_362149_) { -+ addParticlesPass(p_363357_, p_365299_, p_364308_, p_364282_, p_362149_, this.capturedFrustum != null ? this.capturedFrustum : this.cullingFrustum, RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix()); + private void addParticlesPass(FrameGraphBuilder p_363357_, Camera p_365299_, float p_364282_, FogParameters p_362149_) { ++ addParticlesPass(p_363357_, p_365299_, p_364282_, p_362149_, this.capturedFrustum != null ? this.capturedFrustum : this.cullingFrustum, RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix()); + } + -+ private void addParticlesPass(FrameGraphBuilder p_363357_, Camera p_365299_, LightTexture p_364308_, float p_364282_, FogParameters p_362149_, Frustum frustum, Matrix4f modelViewMatrix, Matrix4f projectionMatrix) { ++ private void addParticlesPass(FrameGraphBuilder p_363357_, Camera p_365299_, float p_364282_, FogParameters p_362149_, Frustum frustum, Matrix4f modelViewMatrix, Matrix4f projectionMatrix) { FramePass framepass = p_363357_.addPass("particles"); if (this.targets.particles != null) { this.targets.particles = framepass.readsAndWrites(this.targets.particles); -@@ -684,7 +_,8 @@ +@@ -679,6 +_,7 @@ } - RenderStateShard.PARTICLES_TARGET.setupRenderState(); -- this.minecraft.particleEngine.render(p_364308_, p_365299_, p_364282_); -+ this.minecraft.particleEngine.render(p_364308_, p_365299_, p_364282_, frustum, resourcehandle1 == null ? type -> type.isTranslucent() : type -> true); // Neo: only render translucent particles here in Fast/Fancy + this.minecraft.particleEngine.render(p_365299_, p_364282_, this.renderBuffers.bufferSource()); + net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_PARTICLES, this, null, modelViewMatrix, projectionMatrix, this.ticks, p_365299_, getFrustum()); - RenderStateShard.PARTICLES_TARGET.clearRenderState(); }); } -@@ -713,11 +_,20 @@ + +@@ -706,11 +_,20 @@ resourcehandle.get().clear(); } @@ -101,26 +99,26 @@ } + /** -+ * @deprecated Neo: use {@link #addWeatherPass(FrameGraphBuilder, LightTexture, Vec3, float, FogParameters, Matrix4f, Matrix4f, Camera)} instead ++ * @deprecated Neo: use {@link #addWeatherPass(FrameGraphBuilder, Vec3, float, FogParameters, Matrix4f, Matrix4f, Camera)} instead + */ + @Deprecated - private void addWeatherPass(FrameGraphBuilder p_364025_, LightTexture p_361536_, Vec3 p_360771_, float p_362434_, FogParameters p_360974_) { -+ addWeatherPass(p_364025_, p_361536_, p_360771_, p_362434_, p_360974_, RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix(), this.minecraft.gameRenderer.getMainCamera()); + private void addWeatherPass(FrameGraphBuilder p_364025_, Vec3 p_360771_, float p_362434_, FogParameters p_360974_) { ++ addWeatherPass(p_364025_, p_360771_, p_362434_, p_360974_, RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix(), this.minecraft.gameRenderer.getMainCamera()); + } + -+ private void addWeatherPass(FrameGraphBuilder p_364025_, LightTexture p_361536_, Vec3 p_360771_, float p_362434_, FogParameters p_360974_, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, Camera camera) { ++ private void addWeatherPass(FrameGraphBuilder p_364025_, Vec3 p_360771_, float p_362434_, FogParameters p_360974_, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, Camera camera) { int i = this.minecraft.options.getEffectiveRenderDistance() * 16; float f = this.minecraft.gameRenderer.getDepthFar(); FramePass framepass = p_364025_.addPass("weather"); -@@ -731,6 +_,7 @@ +@@ -724,6 +_,7 @@ RenderSystem.setShaderFog(p_360974_); - RenderStateShard.WEATHER_TARGET.setupRenderState(); - this.weatherEffectRenderer.render(this.minecraft.level, p_361536_, this.ticks, p_362434_, p_360771_); + MultiBufferSource.BufferSource multibuffersource$buffersource = this.renderBuffers.bufferSource(); + this.weatherEffectRenderer.render(this.minecraft.level, multibuffersource$buffersource, this.ticks, p_362434_, p_360771_); + net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_WEATHER, this, null, modelViewMatrix, projectionMatrix, this.ticks, camera, getFrustum()); this.worldBorderRenderer.render(this.level.getWorldBorder(), p_360771_, (double)i, (double)f); - RenderStateShard.WEATHER_TARGET.clearRenderState(); + multibuffersource$buffersource.endBatch(); }); -@@ -775,11 +_,14 @@ +@@ -768,11 +_,14 @@ || p_363510_.isDetached() || p_363510_.getEntity() instanceof LivingEntity && ((LivingEntity)p_363510_.getEntity()).isSleeping() ) @@ -136,7 +134,7 @@ } } } -@@ -825,10 +_,12 @@ +@@ -818,10 +_,12 @@ double d1 = vec3.y(); double d2 = vec3.z(); @@ -149,7 +147,7 @@ BlockPos blockpos = blockentity.getBlockPos(); MultiBufferSource multibuffersource = p_363819_; p_362832_.pushPose(); -@@ -856,6 +_,7 @@ +@@ -849,6 +_,7 @@ synchronized (this.globalBlockEntities) { for (BlockEntity blockentity1 : this.globalBlockEntities) { @@ -157,7 +155,7 @@ BlockPos blockpos1 = blockentity1.getBlockPos(); p_362832_.pushPose(); p_362832_.translate((double)blockpos1.getX() - d0, (double)blockpos1.getY() - d1, (double)blockpos1.getZ() - d2); -@@ -883,9 +_,10 @@ +@@ -876,9 +_,10 @@ VertexConsumer vertexconsumer = new SheetedDecalTextureGenerator( p_365216_.getBuffer(ModelBakery.DESTROY_TYPES.get(i)), posestack$pose, 1.0F ); @@ -169,7 +167,7 @@ p_363901_.popPose(); } } -@@ -897,8 +_,9 @@ +@@ -890,8 +_,9 @@ if (blockhitresult.getType() != HitResult.Type.MISS) { BlockPos blockpos = blockhitresult.getBlockPos(); BlockState blockstate = this.level.getBlockState(blockpos); @@ -180,7 +178,7 @@ if (flag != p_361698_) { return; } -@@ -1026,6 +_,7 @@ +@@ -1019,6 +_,7 @@ compiledshaderprogram.clear(); VertexBuffer.unbind(); zone.close(); @@ -188,7 +186,7 @@ p_294513_.clearRenderState(); } } -@@ -1066,7 +_,15 @@ +@@ -1059,7 +_,15 @@ } } @@ -204,15 +202,15 @@ FogType fogtype = p_362177_.getFluidInCamera(); if (fogtype != FogType.POWDER_SNOW && fogtype != FogType.LAVA && !this.doesMobEffectBlockSky(p_362177_)) { DimensionSpecialEffects dimensionspecialeffects = this.level.effects(); -@@ -1075,6 +_,7 @@ +@@ -1068,6 +_,7 @@ FramePass framepass = p_362870_.addPass("sky"); this.targets.main = framepass.readsAndWrites(this.targets.main); framepass.executes(() -> { + if (!level.effects().renderSky(level, ticks, p_363799_, modelViewMatrix, p_362177_, projectionMatrix, () -> RenderSystem.setShaderFog(p_364999_))) { RenderSystem.setShaderFog(p_364999_); - RenderStateShard.MAIN_TARGET.setupRenderState(); - PoseStack posestack = new PoseStack(); -@@ -1102,6 +_,8 @@ + if (dimensionspecialeffects$skytype == DimensionSpecialEffects.SkyType.END) { + this.skyRenderer.renderEndSky(); +@@ -1095,6 +_,8 @@ this.skyRenderer.renderDarkDisc(posestack); } } @@ -221,7 +219,7 @@ }); } } -@@ -1413,7 +_,7 @@ +@@ -1387,7 +_,7 @@ } else { int i = p_109538_.getBrightness(LightLayer.SKY, p_109540_); int j = p_109538_.getBrightness(LightLayer.BLOCK, p_109540_); @@ -230,7 +228,7 @@ if (j < k) { j = k; } -@@ -1475,5 +_,22 @@ +@@ -1449,5 +_,22 @@ public CloudRenderer getCloudRenderer() { return this.cloudRenderer; diff --git a/patches/net/minecraft/client/renderer/RenderType.java.patch b/patches/net/minecraft/client/renderer/RenderType.java.patch index 9f4bd0f613..cff5c841ea 100644 --- a/patches/net/minecraft/client/renderer/RenderType.java.patch +++ b/patches/net/minecraft/client/renderer/RenderType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/RenderType.java +++ b/net/minecraft/client/renderer/RenderType.java -@@ -1623,4 +_,16 @@ +@@ -1847,4 +_,16 @@ return this.name; } } diff --git a/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch b/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch index 901854e375..e2f0f92603 100644 --- a/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch @@ -1,32 +1,32 @@ --- a/net/minecraft/client/renderer/ScreenEffectRenderer.java +++ b/net/minecraft/client/renderer/ScreenEffectRenderer.java -@@ -30,18 +_,22 @@ - public static void renderScreenEffect(Minecraft p_110719_, PoseStack p_110720_) { +@@ -26,18 +_,22 @@ + public static void renderScreenEffect(Minecraft p_110719_, PoseStack p_110720_, MultiBufferSource p_382889_) { Player player = p_110719_.player; if (!player.noPhysics) { - BlockState blockstate = getViewBlockingState(player); - if (blockstate != null) { -- renderTex(p_110719_.getBlockRenderer().getBlockModelShaper().getParticleIcon(blockstate), p_110720_); +- renderTex(p_110719_.getBlockRenderer().getBlockModelShaper().getParticleIcon(blockstate), p_110720_, p_382889_); + org.apache.commons.lang3.tuple.Pair overlay = getOverlayBlock(player); + if (overlay != null) { + if (!net.neoforged.neoforge.client.ClientHooks.renderBlockOverlay(player, p_110720_, net.neoforged.neoforge.client.event.RenderBlockScreenEffectEvent.OverlayType.BLOCK, overlay.getLeft(), overlay.getRight())) -+ renderTex(p_110719_.getBlockRenderer().getBlockModelShaper().getTexture(overlay.getLeft(), p_110719_.level, overlay.getRight()), p_110720_); ++ renderTex(p_110719_.getBlockRenderer().getBlockModelShaper().getTexture(overlay.getLeft(), p_110719_.level, overlay.getRight()), p_110720_, p_382889_); } } if (!p_110719_.player.isSpectator()) { if (p_110719_.player.isEyeInFluid(FluidTags.WATER)) { + if (!net.neoforged.neoforge.client.ClientHooks.renderWaterOverlay(player, p_110720_)) - renderWater(p_110719_, p_110720_); + renderWater(p_110719_, p_110720_, p_382889_); } -+ else if (!player.getEyeInFluidType().isAir()) net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions.of(player.getEyeInFluidType()).renderOverlay(p_110719_, p_110720_); ++ else if (!player.getEyeInFluidType().isAir()) net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions.of(player.getEyeInFluidType()).renderOverlay(p_110719_, p_110720_, p_382889_); if (p_110719_.player.isOnFire()) { + if (!net.neoforged.neoforge.client.ClientHooks.renderFireOverlay(player, p_110720_)) - renderFire(p_110719_, p_110720_); + renderFire(p_110720_, p_382889_); } } -@@ -49,6 +_,11 @@ +@@ -45,6 +_,11 @@ @Nullable private static BlockState getViewBlockingState(Player p_110717_) { @@ -38,7 +38,7 @@ BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); for (int i = 0; i < 8; i++) { -@@ -58,7 +_,7 @@ +@@ -54,7 +_,7 @@ blockpos$mutableblockpos.set(d0, d1, d2); BlockState blockstate = p_110717_.level().getBlockState(blockpos$mutableblockpos); if (blockstate.getRenderShape() != RenderShape.INVISIBLE && blockstate.isViewBlocking(p_110717_.level(), blockpos$mutableblockpos)) { @@ -47,17 +47,23 @@ } } -@@ -88,8 +_,12 @@ +@@ -82,6 +_,10 @@ } - private static void renderWater(Minecraft p_110726_, PoseStack p_110727_) { -+ renderFluid(p_110726_, p_110727_, UNDERWATER_LOCATION); + private static void renderWater(Minecraft p_110726_, PoseStack p_110727_, MultiBufferSource p_383128_) { ++ renderFluid(p_110726_, p_110727_, p_383128_, UNDERWATER_LOCATION); + } + -+ public static void renderFluid(Minecraft p_110726_, PoseStack p_110727_, ResourceLocation texture) { - RenderSystem.setShader(CoreShaders.POSITION_TEX); -- RenderSystem.setShaderTexture(0, UNDERWATER_LOCATION); -+ RenderSystem.setShaderTexture(0, texture); ++ public static void renderFluid(Minecraft p_110726_, PoseStack p_110727_, MultiBufferSource p_383128_, ResourceLocation texture) { BlockPos blockpos = BlockPos.containing(p_110726_.player.getX(), p_110726_.player.getEyeY(), p_110726_.player.getZ()); float f = LightTexture.getBrightness(p_110726_.player.level().dimensionType(), p_110726_.player.level().getMaxLocalRawBrightness(blockpos)); - RenderSystem.enableBlend(); + int i = ARGB.colorFromFloat(0.1F, f, f, f); +@@ -94,7 +_,7 @@ + float f7 = -p_110726_.player.getYRot() / 64.0F; + float f8 = p_110726_.player.getXRot() / 64.0F; + Matrix4f matrix4f = p_110727_.last().pose(); +- VertexConsumer vertexconsumer = p_383128_.getBuffer(RenderType.blockScreenEffect(UNDERWATER_LOCATION)); ++ VertexConsumer vertexconsumer = p_383128_.getBuffer(RenderType.blockScreenEffect(texture)); + vertexconsumer.addVertex(matrix4f, -1.0F, -1.0F, -0.5F).setUv(4.0F + f7, 4.0F + f8).setColor(i); + vertexconsumer.addVertex(matrix4f, 1.0F, -1.0F, -0.5F).setUv(0.0F + f7, 4.0F + f8).setColor(i); + vertexconsumer.addVertex(matrix4f, 1.0F, 1.0F, -0.5F).setUv(0.0F + f7, 0.0F + f8).setColor(i); diff --git a/patches/net/minecraft/client/renderer/ShaderManager.java.patch b/patches/net/minecraft/client/renderer/ShaderManager.java.patch index 4e634d23e7..d6621b2f20 100644 --- a/patches/net/minecraft/client/renderer/ShaderManager.java.patch +++ b/patches/net/minecraft/client/renderer/ShaderManager.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/client/renderer/ShaderManager.java +++ b/net/minecraft/client/renderer/ShaderManager.java @@ -169,7 +_,7 @@ + protected void apply(ShaderManager.Configs p_366597_, ResourceManager p_366533_, ProfilerFiller p_366866_) { ShaderManager.CompilationCache shadermanager$compilationcache = new ShaderManager.CompilationCache(p_366597_); Map map = new HashMap<>(); +- Set set = new HashSet<>(CoreShaders.getProgramsToPreload()); ++ Set set = new HashSet<>(net.neoforged.neoforge.client.CoreShaderManager.getProgramsToPreload()); -- for (ShaderProgram shaderprogram : CoreShaders.getProgramsToPreload()) { -+ for (ShaderProgram shaderprogram : net.neoforged.neoforge.client.CoreShaderManager.getProgramsToPreload()) { - try { - shadermanager$compilationcache.programs.put(shaderprogram, Optional.of(shadermanager$compilationcache.compileProgram(shaderprogram))); - } catch (ShaderManager.CompilationException shadermanager$compilationexception) { + for (PostChainConfig postchainconfig : p_366597_.postChains.values()) { + for (PostChainConfig.Pass postchainconfig$pass : postchainconfig.passes()) { diff --git a/patches/net/minecraft/client/renderer/Sheets.java.patch b/patches/net/minecraft/client/renderer/Sheets.java.patch index cb01eb86db..16c8df9f7a 100644 --- a/patches/net/minecraft/client/renderer/Sheets.java.patch +++ b/patches/net/minecraft/client/renderer/Sheets.java.patch @@ -1,22 +1,24 @@ --- a/net/minecraft/client/renderer/Sheets.java +++ b/net/minecraft/client/renderer/Sheets.java -@@ -141,11 +_,13 @@ +@@ -156,7 +_,7 @@ } private static Material createSignMaterial(WoodType p_173386_) { -- return new Material(SIGN_SHEET, ResourceLocation.withDefaultNamespace("entity/signs/" + p_173386_.name())); -+ ResourceLocation location = ResourceLocation.parse(p_173386_.name()); -+ return new Material(SIGN_SHEET, ResourceLocation.fromNamespaceAndPath(location.getNamespace(), "entity/signs/" + location.getPath())); +- return createSignMaterial(ResourceLocation.withDefaultNamespace(p_173386_.name())); ++ return createSignMaterial(ResourceLocation.parse(p_173386_.name())); + } + + public static Material createSignMaterial(ResourceLocation p_389416_) { +@@ -164,7 +_,7 @@ } private static Material createHangingSignMaterial(WoodType p_251735_) { -- return new Material(SIGN_SHEET, ResourceLocation.withDefaultNamespace("entity/signs/hanging/" + p_251735_.name())); -+ ResourceLocation location = ResourceLocation.parse(p_251735_.name()); -+ return new Material(SIGN_SHEET, ResourceLocation.fromNamespaceAndPath(location.getNamespace(), "entity/signs/hanging/" + location.getPath())); +- return createHangingSignMaterial(ResourceLocation.withDefaultNamespace(p_251735_.name())); ++ return createHangingSignMaterial(ResourceLocation.parse(p_251735_.name())); } - public static Material getSignMaterial(WoodType p_173382_) { -@@ -204,6 +_,23 @@ + public static Material createHangingSignMaterial(ResourceLocation p_389413_) { +@@ -231,6 +_,23 @@ case SINGLE: default: return p_110773_; diff --git a/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch b/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch index 180f282591..9d71f4e7ca 100644 --- a/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/client/renderer/WeatherEffectRenderer.java +++ b/net/minecraft/client/renderer/WeatherEffectRenderer.java -@@ -61,6 +_,8 @@ +@@ -56,6 +_,8 @@ } - public void render(Level p_364994_, LightTexture p_363130_, int p_363664_, float p_361655_, Vec3 p_363375_) { -+ if (((ClientLevel) p_364994_).effects().renderSnowAndRain((ClientLevel) p_364994_, p_363664_, p_361655_, p_363130_, p_363375_.x, p_363375_.y, p_363375_.z)) + public void render(Level p_364994_, MultiBufferSource p_383071_, int p_363664_, float p_361655_, Vec3 p_363375_) { ++ if (((ClientLevel) p_364994_).effects().renderSnowAndRain((ClientLevel) p_364994_, p_363664_, p_361655_, p_363375_.x, p_363375_.y, p_363375_.z)) + return; float f = p_364994_.getRainLevel(p_361655_); if (!(f <= 0.0F)) { int i = Minecraft.useFancyGraphics() ? 10 : 5; -@@ -201,6 +_,8 @@ +@@ -180,6 +_,8 @@ } public void tickRainParticles(ClientLevel p_361823_, Camera p_364990_, int p_361788_, ParticleStatus p_363302_) { diff --git a/patches/net/minecraft/client/renderer/block/BlockRenderDispatcher.java.patch b/patches/net/minecraft/client/renderer/block/BlockRenderDispatcher.java.patch index 5ee7f47292..144c236c6b 100644 --- a/patches/net/minecraft/client/renderer/block/BlockRenderDispatcher.java.patch +++ b/patches/net/minecraft/client/renderer/block/BlockRenderDispatcher.java.patch @@ -2,7 +2,7 @@ +++ b/net/minecraft/client/renderer/block/BlockRenderDispatcher.java @@ -37,7 +_,7 @@ this.blockModelShaper = p_173399_; - this.blockEntityRenderer = p_173400_; + this.specialBlockModelRenderer = p_386717_; this.blockColors = p_173401_; - this.modelRenderer = new ModelBlockRenderer(this.blockColors); + this.modelRenderer = new net.neoforged.neoforge.client.model.lighting.LightPipelineAwareModelBlockRenderer(this.blockColors); @@ -71,7 +71,7 @@ this.liquidBlockRenderer.tesselate(p_234365_, p_234364_, p_234366_, p_234367_, p_234368_); } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Tesselating liquid in world"); -@@ -104,7 +_,11 @@ +@@ -104,25 +_,33 @@ return this.blockModelShaper.getBlockModel(p_110911_); } @@ -79,41 +79,38 @@ public void renderSingleBlock(BlockState p_110913_, PoseStack p_110914_, MultiBufferSource p_110915_, int p_110916_, int p_110917_) { + renderSingleBlock(p_110913_, p_110914_, p_110915_, p_110916_, p_110917_, net.neoforged.neoforge.client.model.data.ModelData.EMPTY, null); + } -+ public void renderSingleBlock(BlockState p_110913_, PoseStack p_110914_, MultiBufferSource p_110915_, int p_110916_, int p_110917_, net.neoforged.neoforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) { ++ ++ public void renderSingleBlock(BlockState p_110913_, PoseStack p_110914_, MultiBufferSource p_110915_, int p_110916_, int p_110917_, net.neoforged.neoforge.client.model.data.ModelData modelData, @org.jetbrains.annotations.Nullable net.minecraft.client.renderer.RenderType renderType) { RenderShape rendershape = p_110913_.getRenderShape(); if (rendershape != RenderShape.INVISIBLE) { - switch (rendershape) { -@@ -114,22 +_,25 @@ - float f = (float)(i >> 16 & 0xFF) / 255.0F; - float f1 = (float)(i >> 8 & 0xFF) / 255.0F; - float f2 = (float)(i & 0xFF) / 255.0F; -+ for (net.minecraft.client.renderer.RenderType rt : bakedmodel.getRenderTypes(p_110913_, RandomSource.create(42), modelData)) - this.modelRenderer - .renderModel( - p_110914_.last(), -- p_110915_.getBuffer(ItemBlockRenderTypes.getRenderType(p_110913_)), -+ p_110915_.getBuffer(renderType != null ? renderType : net.neoforged.neoforge.client.RenderTypeHelper.getEntityRenderType(rt)), - p_110913_, - bakedmodel, - f, - f1, - f2, - p_110916_, -- p_110917_ -+ p_110917_, -+ modelData, -+ rt - ); - break; - case ENTITYBLOCK_ANIMATED: -- this.blockEntityRenderer -- .renderByItem(new ItemStack(p_110913_.getBlock()), ItemDisplayContext.NONE, p_110914_, p_110915_, p_110916_, p_110917_); -+ ItemStack stack = new ItemStack(p_110913_.getBlock()); -+ net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(stack).getCustomRenderer().renderByItem(stack, ItemDisplayContext.NONE, p_110914_, p_110915_, p_110916_, p_110917_); - } + BakedModel bakedmodel = this.getBlockModel(p_110913_); + int i = this.blockColors.getColor(p_110913_, null, null, 0); +- float f = (float)(i >> 16 & 0xFF) / 255.0F; +- float f1 = (float)(i >> 8 & 0xFF) / 255.0F; +- float f2 = (float)(i & 0xFF) / 255.0F; ++ float f = (float) (i >> 16 & 0xFF) / 255.0F; ++ float f1 = (float) (i >> 8 & 0xFF) / 255.0F; ++ float f2 = (float) (i & 0xFF) / 255.0F; ++ for (net.minecraft.client.renderer.RenderType rt : bakedmodel.getRenderTypes(p_110913_, RandomSource.create(42), modelData)) + this.modelRenderer + .renderModel( + p_110914_.last(), +- p_110915_.getBuffer(ItemBlockRenderTypes.getRenderType(p_110913_)), ++ p_110915_.getBuffer(renderType != null ? renderType : net.neoforged.neoforge.client.RenderTypeHelper.getEntityRenderType(rt)), + p_110913_, + bakedmodel, + f, + f1, + f2, + p_110916_, +- p_110917_ ++ p_110917_, ++ modelData, ++ rt + ); + this.specialBlockModelRenderer.get().renderByBlock(p_110913_.getBlock(), ItemDisplayContext.NONE, p_110914_, p_110915_, p_110916_, p_110917_); } - } -@@ -137,5 +_,9 @@ +@@ -131,5 +_,9 @@ @Override public void onResourceManagerReload(ResourceManager p_110909_) { this.liquidBlockRenderer.setupSprites(); diff --git a/patches/net/minecraft/client/renderer/block/model/BakedOverrides.java.patch b/patches/net/minecraft/client/renderer/block/model/BakedOverrides.java.patch deleted file mode 100644 index 60cb1a713d..0000000000 --- a/patches/net/minecraft/client/renderer/block/model/BakedOverrides.java.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- a/net/minecraft/client/renderer/block/model/BakedOverrides.java -+++ b/net/minecraft/client/renderer/block/model/BakedOverrides.java -@@ -29,7 +_,15 @@ - this.properties = new ResourceLocation[0]; - } - -+ /** -+ * @deprecated Neo: Use {@link #BakedOverrides(ModelBaker, List, java.util.function.Function)} -+ */ -+ @Deprecated - public BakedOverrides(ModelBaker p_371950_, List p_371198_) { -+ this(p_371950_, p_371198_, p_371950_.getModelTextureGetter()); -+ } -+ -+ public BakedOverrides(ModelBaker p_371950_, List p_371198_, java.util.function.Function spriteGetter) { - this.properties = p_371198_.stream() - .flatMap(p_371945_ -> p_371945_.predicates().stream()) - .map(ItemOverride.Predicate::property) -@@ -45,7 +_,7 @@ - - for (int j = p_371198_.size() - 1; j >= 0; j--) { - ItemOverride itemoverride = p_371198_.get(j); -- BakedModel bakedmodel = p_371950_.bake(itemoverride.model(), BlockModelRotation.X0_Y0); -+ BakedModel bakedmodel = p_371950_.bake(itemoverride.model(), BlockModelRotation.X0_Y0, spriteGetter); - BakedOverrides.PropertyMatcher[] abakedoverrides$propertymatcher = itemoverride.predicates().stream().map(p_371644_ -> { - int k = object2intmap.getInt(p_371644_.property()); - return new BakedOverrides.PropertyMatcher(k, p_371644_.value()); -@@ -80,6 +_,10 @@ - } - - return null; -+ } -+ -+ public com.google.common.collect.ImmutableList getOverrides() { -+ return com.google.common.collect.ImmutableList.copyOf(overrides); - } - - @OnlyIn(Dist.CLIENT) diff --git a/patches/net/minecraft/client/renderer/block/model/BlockElement.java.patch b/patches/net/minecraft/client/renderer/block/model/BlockElement.java.patch index c19fb03a3e..fbef04d799 100644 --- a/patches/net/minecraft/client/renderer/block/model/BlockElement.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/BlockElement.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/model/BlockElement.java +++ b/net/minecraft/client/renderer/block/model/BlockElement.java -@@ -30,6 +_,7 @@ +@@ -31,6 +_,7 @@ public final BlockElementRotation rotation; public final boolean shade; public final int lightEmission; @@ -8,7 +8,7 @@ public BlockElement(Vector3f p_253626_, Vector3f p_254426_, Map p_254454_) { this(p_253626_, p_254426_, p_254454_, null, true, 0); -@@ -43,6 +_,10 @@ +@@ -44,6 +_,10 @@ boolean p_361372_, int p_361908_ ) { @@ -19,7 +19,7 @@ this.from = p_361324_; this.to = p_363867_; this.faces = p_362722_; -@@ -50,6 +_,8 @@ +@@ -51,6 +_,8 @@ this.shade = p_361372_; this.lightEmission = p_361908_; this.fillUvs(); @@ -28,7 +28,7 @@ } private void fillUvs() { -@@ -104,7 +_,8 @@ +@@ -98,7 +_,8 @@ } } @@ -38,7 +38,7 @@ } } -@@ -215,5 +_,13 @@ +@@ -209,5 +_,13 @@ return new Vector3f(afloat[0], afloat[1], afloat[2]); } } diff --git a/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch b/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch index 767bdb3611..cfe8c768a8 100644 --- a/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch @@ -1,104 +1,119 @@ --- a/net/minecraft/client/renderer/block/model/BlockModel.java +++ b/net/minecraft/client/renderer/block/model/BlockModel.java -@@ -72,9 +_,10 @@ - public BlockModel parent; - @Nullable - protected ResourceLocation parentLocation; -+ public final net.neoforged.neoforge.client.model.geometry.BlockGeometryBakingContext customData = new net.neoforged.neoforge.client.model.geometry.BlockGeometryBakingContext(this); +@@ -26,15 +_,17 @@ + import net.neoforged.api.distmarker.OnlyIn; - public static BlockModel fromStream(Reader p_111462_) { -- return GsonHelper.fromJson(GSON, p_111462_, BlockModel.class); -+ return GsonHelper.fromJson(net.neoforged.neoforge.client.model.ExtendedBlockModelDeserializer.INSTANCE, p_111462_, BlockModel.class); - } - - public BlockModel( -@@ -95,10 +_,15 @@ - this.overrides = p_273099_; - } + @OnlyIn(Dist.CLIENT) +-public class BlockModel implements UnbakedModel { ++public class BlockModel implements UnbakedModel, net.neoforged.neoforge.client.model.ExtendedUnbakedModel { + @VisibleForTesting + public static final Gson GSON = new GsonBuilder() ++ .registerTypeHierarchyAdapter(UnbakedModel.class, new net.neoforged.neoforge.client.model.UnbakedModelParser.Deserializer()) + .registerTypeAdapter(BlockModel.class, new BlockModel.Deserializer()) + .registerTypeAdapter(BlockElement.class, new BlockElement.Deserializer()) + .registerTypeAdapter(BlockElementFace.class, new BlockElementFace.Deserializer()) + .registerTypeAdapter(BlockFaceUV.class, new BlockFaceUV.Deserializer()) + .registerTypeAdapter(ItemTransform.class, new ItemTransform.Deserializer()) + .registerTypeAdapter(ItemTransforms.class, new ItemTransforms.Deserializer()) ++ .registerTypeAdapter(com.mojang.math.Transformation.class, new net.neoforged.neoforge.common.util.TransformationHelper.Deserializer()) + .create(); + private final List elements; + @Nullable +@@ -49,7 +_,14 @@ + private UnbakedModel parent; + @Nullable + private final ResourceLocation parentLocation; ++ @Nullable ++ private final com.mojang.math.Transformation transformation; ++ private final net.neoforged.neoforge.client.RenderTypeGroup renderTypeGroup; ++ /** ++ * @deprecated Neo: use {@link net.neoforged.neoforge.client.model.UnbakedModelParser#parse(Reader)} instead ++ */ + @Deprecated - public List getElements() { -+ if (customData.hasCustomGeometry()) return java.util.Collections.emptyList(); - return this.elements.isEmpty() && this.parent != null ? this.parent.getElements() : this.elements; + public static BlockModel fromStream(Reader p_111462_) { + return GsonHelper.fromJson(GSON, p_111462_, BlockModel.class); } - -+ @Nullable -+ public ResourceLocation getParentLocation() { return parentLocation; } +@@ -62,12 +_,27 @@ + @Nullable UnbakedModel.GuiLight p_387948_, + @Nullable ItemTransforms p_273480_ + ) { ++ this(p_273263_, p_272668_, p_386899_, p_272676_, p_387948_, p_273480_, null, net.neoforged.neoforge.client.RenderTypeGroup.EMPTY); ++ } + - public boolean hasAmbientOcclusion() { - if (this.hasAmbientOcclusion != null) { - return this.hasAmbientOcclusion; -@@ -132,10 +_,18 @@ ++ public BlockModel( ++ @Nullable ResourceLocation p_273263_, ++ List p_272668_, ++ TextureSlots.Data p_386899_, ++ @Nullable Boolean p_272676_, ++ @Nullable UnbakedModel.GuiLight p_387948_, ++ @Nullable ItemTransforms p_273480_, ++ @Nullable com.mojang.math.Transformation transformation, ++ net.neoforged.neoforge.client.RenderTypeGroup renderTypeGroup ++ ) { + this.elements = p_272668_; + this.hasAmbientOcclusion = p_272676_; + this.guiLight = p_387948_; + this.textureSlots = p_386899_; + this.parentLocation = p_273263_; + this.transforms = p_273480_; ++ this.transformation = transformation; ++ this.renderTypeGroup = renderTypeGroup; + } - this.parent = blockmodel; - } -+ -+ if (customData.hasCustomGeometry()) { -+ customData.getCustomGeometry().resolveDependencies(p_361203_, customData); -+ } + @Nullable +@@ -107,10 +_,12 @@ } @Override - public BakedModel bake(ModelBaker p_252120_, Function p_250023_, ModelState p_251130_) { -+ var customGeometry = this.customData.getCustomGeometry(); -+ if (customGeometry != null) { -+ return customGeometry.bake(this.customData, p_252120_, p_250023_, p_251130_, this.overrides); -+ } - return this.bake(p_250023_, p_251130_, true); +- public BakedModel bake(TextureSlots p_387258_, ModelBaker p_388168_, ModelState p_111453_, boolean p_111455_, boolean p_387632_, ItemTransforms p_386577_) { ++ public BakedModel bake(TextureSlots p_387258_, ModelBaker p_388168_, ModelState p_111453_, boolean p_111455_, boolean p_387632_, ItemTransforms p_386577_, net.minecraft.util.context.ContextMap additionalProperties) { + return this.elements.isEmpty() && this.parent != null +- ? this.parent.bake(p_387258_, p_388168_, p_111453_, p_111455_, p_387632_, p_386577_) +- : SimpleBakedModel.bakeElements(this.elements, p_387258_, p_388168_.sprites(), p_111453_, p_111455_, p_387632_, true, p_386577_); ++ ? this.parent.bake(p_387258_, p_388168_, p_111453_, p_111455_, p_387632_, p_386577_, additionalProperties) ++ : SimpleBakedModel.bakeElements(this.elements, p_387258_, p_388168_.sprites(), p_111453_, p_111455_, p_387632_, true, p_386577_, ++ additionalProperties.getOrDefault(net.neoforged.neoforge.client.model.NeoForgeModelProperties.TRANSFORM, com.mojang.math.Transformation.identity()), ++ additionalProperties.getOrDefault(net.neoforged.neoforge.client.model.NeoForgeModelProperties.RENDER_TYPE, net.neoforged.neoforge.client.RenderTypeGroup.EMPTY)); } -@@ -146,6 +_,10 @@ - } else { - SimpleBakedModel.Builder simplebakedmodel$builder = new SimpleBakedModel.Builder(this, p_111455_).particle(textureatlassprite); + @Nullable +@@ -125,6 +_,16 @@ + return this.parentLocation; + } -+ if (!this.customData.getRootTransform().isIdentity()) { -+ p_111453_ = net.neoforged.neoforge.client.model.geometry.UnbakedGeometryHelper.composeRootTransformIntoModelState(p_111453_, this.customData.getRootTransform()); -+ } ++ @Override ++ public void fillAdditionalProperties(net.minecraft.util.context.ContextMap.Builder propertiesBuilder) { ++ if (this.transformation != null) { ++ propertiesBuilder.withParameter(net.neoforged.neoforge.client.model.NeoForgeModelProperties.TRANSFORM, this.transformation); ++ } ++ if (!this.renderTypeGroup.isEmpty()) { ++ propertiesBuilder.withParameter(net.neoforged.neoforge.client.model.NeoForgeModelProperties.RENDER_TYPE, this.renderTypeGroup); ++ } ++ } + - for (BlockElement blockelement : this.getElements()) { - for (Direction direction : blockelement.faces.keySet()) { - BlockElementFace blockelementface = blockelement.faces.get(direction); -@@ -161,7 +_,11 @@ - } + @OnlyIn(Dist.CLIENT) + public static class Deserializer implements JsonDeserializer { + public BlockModel deserialize(JsonElement p_111498_, Type p_111499_, JsonDeserializationContext p_111500_) throws JsonParseException { +@@ -145,7 +_,20 @@ } -- return simplebakedmodel$builder.build(); -+ var renderTypes = net.neoforged.neoforge.client.RenderTypeGroup.EMPTY; -+ if (this.customData.getRenderTypeHint() != null) { -+ renderTypes = this.customData.getRenderType(this.customData.getRenderTypeHint()); -+ } -+ return simplebakedmodel$builder.build(renderTypes); - } - } - -@@ -229,7 +_,18 @@ - ItemTransform itemtransform5 = this.getTransform(ItemDisplayContext.GUI); - ItemTransform itemtransform6 = this.getTransform(ItemDisplayContext.GROUND); - ItemTransform itemtransform7 = this.getTransform(ItemDisplayContext.FIXED); -- return new ItemTransforms(itemtransform, itemtransform1, itemtransform2, itemtransform3, itemtransform4, itemtransform5, itemtransform6, itemtransform7); + ResourceLocation resourcelocation = s.isEmpty() ? null : ResourceLocation.parse(s); +- return new BlockModel(resourcelocation, list, textureslots$data, obool, unbakedmodel$guilight, itemtransforms); + -+ var builder = com.google.common.collect.ImmutableMap.builder(); -+ for(ItemDisplayContext type : ItemDisplayContext.values()) { -+ if (type.isModded()) { -+ var transform = this.getTransform(type); -+ if (transform != ItemTransform.NO_TRANSFORM) { -+ builder.put(type, transform); -+ } ++ com.mojang.math.Transformation rootTransform = null; ++ if (jsonobject.has("transform")) { ++ JsonElement transform = jsonobject.get("transform"); ++ rootTransform = p_111500_.deserialize(transform, com.mojang.math.Transformation.class); + } -+ } + -+ return new ItemTransforms(itemtransform, itemtransform1, itemtransform2, itemtransform3, itemtransform4, itemtransform5, itemtransform6, itemtransform7, builder.build()); - } - - private ItemTransform getTransform(ItemDisplayContext p_270662_) { -@@ -347,6 +_,10 @@ - - public boolean lightLikeBlock() { - return this == SIDE; -+ } ++ var renderTypeGroup = net.neoforged.neoforge.client.RenderTypeGroup.EMPTY; ++ if (jsonobject.has("render_type")) { ++ var renderTypeHintName = GsonHelper.getAsString(jsonobject, "render_type"); ++ renderTypeGroup = net.neoforged.neoforge.client.NamedRenderTypeManager.get(ResourceLocation.parse(renderTypeHintName)); ++ } + -+ public String getSerializedName() { -+ return name; ++ return new BlockModel(resourcelocation, list, textureslots$data, obool, unbakedmodel$guilight, itemtransforms, rootTransform, renderTypeGroup); } - } - } + + private TextureSlots.Data getTextureMap(JsonObject p_111510_) { diff --git a/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch b/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch index 71b9c9943e..bcf2bbca9c 100644 --- a/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/renderer/block/model/FaceBakery.java +++ b/net/minecraft/client/renderer/block/model/FaceBakery.java @@ -58,7 +_,14 @@ - this.recalculateWinding(aint, direction); + recalculateWinding(aint, direction); } - return new BakedQuad(aint, p_111603_.tintIndex(), direction, p_111604_, p_111608_, p_364857_); diff --git a/patches/net/minecraft/client/renderer/block/model/ItemModelGenerator.java.patch b/patches/net/minecraft/client/renderer/block/model/ItemModelGenerator.java.patch index 199561dd6b..4028b1df80 100644 --- a/patches/net/minecraft/client/renderer/block/model/ItemModelGenerator.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/ItemModelGenerator.java.patch @@ -1,21 +1,52 @@ --- a/net/minecraft/client/renderer/block/model/ItemModelGenerator.java +++ b/net/minecraft/client/renderer/block/model/ItemModelGenerator.java -@@ -32,13 +_,16 @@ +@@ -20,7 +_,7 @@ + import org.joml.Vector3f; - Material material = p_111672_.getMaterial(s); - map.put(s, Either.left(material)); -- SpriteContents spritecontents = p_111671_.apply(material).contents(); + @OnlyIn(Dist.CLIENT) +-public class ItemModelGenerator implements UnbakedModel { ++public class ItemModelGenerator implements UnbakedModel, net.neoforged.neoforge.client.model.ExtendedUnbakedModel { + public static final ResourceLocation GENERATED_ITEM_MODEL_ID = ResourceLocation.withDefaultNamespace("builtin/generated"); + public static final List LAYERS = List.of("layer0", "layer1", "layer2", "layer3", "layer4"); + private static final float MIN_Z = 7.5F; +@@ -43,13 +_,23 @@ + } + + @Override +- public BakedModel bake(TextureSlots p_386773_, ModelBaker p_386770_, ModelState p_386536_, boolean p_388612_, boolean p_387457_, ItemTransforms p_388565_) { +- return this.bake(p_386773_, p_386770_.sprites(), p_386536_, p_388612_, p_387457_, p_388565_); ++ public BakedModel bake(TextureSlots p_386773_, ModelBaker p_386770_, ModelState p_386536_, boolean p_388612_, boolean p_387457_, ItemTransforms p_388565_, net.minecraft.util.context.ContextMap additionalProperties) { ++ return this.bake(p_386773_, p_386770_.sprites(), p_386536_, p_388612_, p_387457_, p_388565_, additionalProperties.getOrDefault(net.neoforged.neoforge.client.model.NeoForgeModelProperties.RENDER_TYPE, net.neoforged.neoforge.client.RenderTypeGroup.EMPTY)); + } + ++ /** ++ * @deprecated Neo: use {@link #bake(TextureSlots, SpriteGetter, ModelState, boolean, boolean, ItemTransforms, net.neoforged.neoforge.client.RenderTypeGroup)} instead ++ */ ++ @Deprecated + private BakedModel bake( + TextureSlots p_387202_, SpriteGetter p_387257_, ModelState p_387172_, boolean p_388328_, boolean p_387288_, ItemTransforms p_388238_ + ) { ++ return this.bake(p_387202_, p_387257_, p_387172_, p_388328_, p_387288_, p_388238_, net.neoforged.neoforge.client.RenderTypeGroup.EMPTY); ++ } ++ ++ private BakedModel bake( ++ TextureSlots p_387202_, SpriteGetter p_387257_, ModelState p_387172_, boolean p_388328_, boolean p_387288_, ItemTransforms p_388238_, net.neoforged.neoforge.client.RenderTypeGroup renderTypes ++ ) { + TextureSlots.Data.Builder textureslots$data$builder = new TextureSlots.Data.Builder(); + List list = new ArrayList<>(); + +@@ -61,11 +_,11 @@ + } + + textureslots$data$builder.addTexture(s, material); +- SpriteContents spritecontents = p_387257_.get(material).contents(); - list.addAll(this.processFrames(i, s, spritecontents)); -+ TextureAtlasSprite sprite = p_111671_.apply(material); -+ // Neo: fix MC-73186 on generated item models ++ net.minecraft.client.renderer.texture.TextureAtlasSprite sprite = p_387257_.get(material); + list.addAll(net.neoforged.neoforge.client.ClientHooks.fixItemModelSeams(this.processFrames(i, s, sprite.contents()), sprite)); } - map.put("particle", p_111672_.hasTexture("particle") ? Either.left(p_111672_.getMaterial("particle")) : map.get("layer0")); - BlockModel blockmodel = new BlockModel(null, list, map, false, p_111672_.getGuiLight(), p_111672_.getTransforms(), p_111672_.getOverrides()); - blockmodel.name = p_111672_.name; -+ blockmodel.customData.copyFrom(p_111672_.customData); -+ blockmodel.customData.setGui3d(false); - return blockmodel; +- return SimpleBakedModel.bakeElements(list, p_387202_, p_387257_, p_387172_, p_388328_, p_387288_, false, p_388238_); ++ return SimpleBakedModel.bakeElements(list, p_387202_, p_387257_, p_387172_, p_388328_, p_387288_, false, p_388238_, com.mojang.math.Transformation.identity(), renderTypes); } + public List processFrames(int p_111639_, String p_111640_, SpriteContents p_251768_) { diff --git a/patches/net/minecraft/client/renderer/block/model/ItemTransforms.java.patch b/patches/net/minecraft/client/renderer/block/model/ItemTransforms.java.patch index a341611fbb..9ca5df5e9c 100644 --- a/patches/net/minecraft/client/renderer/block/model/ItemTransforms.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/ItemTransforms.java.patch @@ -1,51 +1,32 @@ --- a/net/minecraft/client/renderer/block/model/ItemTransforms.java +++ b/net/minecraft/client/renderer/block/model/ItemTransforms.java -@@ -21,6 +_,7 @@ - public final ItemTransform gui; - public final ItemTransform ground; - public final ItemTransform fixed; -+ public final com.google.common.collect.ImmutableMap moddedTransforms; - - private ItemTransforms() { - this( -@@ -44,8 +_,10 @@ - this.gui = p_111807_.gui; - this.ground = p_111807_.ground; - this.fixed = p_111807_.fixed; -+ this.moddedTransforms = p_111807_.moddedTransforms; - } - +@@ -19,8 +_,23 @@ + ItemTransform head, + ItemTransform gui, + ItemTransform ground, +- ItemTransform fixed ++ ItemTransform fixed, ++ com.google.common.collect.ImmutableMap moddedTransforms + ) { + @Deprecated - public ItemTransforms( - ItemTransform p_111798_, - ItemTransform p_111799_, -@@ -56,6 +_,20 @@ - ItemTransform p_111804_, - ItemTransform p_111805_ - ) { -+ this(p_111798_, p_111799_, p_111800_, p_111801_, p_111802_, p_111803_, p_111804_, p_111805_, com.google.common.collect.ImmutableMap.of()); -+ } -+ + public ItemTransforms( -+ ItemTransform p_111798_, -+ ItemTransform p_111799_, -+ ItemTransform p_111800_, -+ ItemTransform p_111801_, -+ ItemTransform p_111802_, -+ ItemTransform p_111803_, -+ ItemTransform p_111804_, -+ ItemTransform p_111805_, -+ com.google.common.collect.ImmutableMap moddedTransforms ++ ItemTransform thirdPersonLeftHand, ++ ItemTransform thirdPersonRightHand, ++ ItemTransform firstPersonLeftHand, ++ ItemTransform firstPersonRightHand, ++ ItemTransform head, ++ ItemTransform gui, ++ ItemTransform ground, ++ ItemTransform fixed + ) { - this.thirdPersonLeftHand = p_111798_; - this.thirdPersonRightHand = p_111799_; - this.firstPersonLeftHand = p_111800_; -@@ -64,9 +_,21 @@ - this.gui = p_111803_; - this.ground = p_111804_; - this.fixed = p_111805_; -+ this.moddedTransforms = moddedTransforms; - } ++ this(thirdPersonLeftHand, thirdPersonRightHand, firstPersonLeftHand, firstPersonRightHand, head, gui, ground, fixed, com.google.common.collect.ImmutableMap.of()); ++ } ++ + public static final ItemTransforms NO_TRANSFORMS = new ItemTransforms( + ItemTransform.NO_TRANSFORM, + ItemTransform.NO_TRANSFORM, +@@ -33,6 +_,17 @@ + ); public ItemTransform getTransform(ItemDisplayContext p_270619_) { + if (p_270619_.isModded()) { @@ -62,7 +43,7 @@ return switch (p_270619_) { case THIRD_PERSON_LEFT_HAND -> this.thirdPersonLeftHand; case THIRD_PERSON_RIGHT_HAND -> this.thirdPersonRightHand; -@@ -104,9 +_,23 @@ +@@ -66,9 +_,23 @@ ItemTransform itemtransform5 = this.getTransform(p_111822_, jsonobject, ItemDisplayContext.GUI); ItemTransform itemtransform6 = this.getTransform(p_111822_, jsonobject, ItemDisplayContext.GROUND); ItemTransform itemtransform7 = this.getTransform(p_111822_, jsonobject, ItemDisplayContext.FIXED); diff --git a/patches/net/minecraft/client/renderer/block/model/MultiVariant.java.patch b/patches/net/minecraft/client/renderer/block/model/MultiVariant.java.patch deleted file mode 100644 index bd74eaf20d..0000000000 --- a/patches/net/minecraft/client/renderer/block/model/MultiVariant.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/net/minecraft/client/renderer/block/model/MultiVariant.java -+++ b/net/minecraft/client/renderer/block/model/MultiVariant.java -@@ -45,12 +_,12 @@ - public BakedModel bake(ModelBaker p_249016_, Function p_111851_, ModelState p_111852_) { - if (this.variants.size() == 1) { - Variant variant1 = this.variants.getFirst(); -- return p_249016_.bake(variant1.getModelLocation(), variant1); -+ return p_249016_.bake(variant1.getModelLocation(), variant1, p_111851_); - } else { - SimpleWeightedRandomList.Builder builder = SimpleWeightedRandomList.builder(); - - for (Variant variant : this.variants) { -- BakedModel bakedmodel = p_249016_.bake(variant.getModelLocation(), variant); -+ BakedModel bakedmodel = p_249016_.bake(variant.getModelLocation(), variant, p_111851_); - builder.add(bakedmodel, variant.getWeight()); - } - diff --git a/patches/net/minecraft/client/renderer/blockentity/SignRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/AbstractSignRenderer.java.patch similarity index 52% rename from patches/net/minecraft/client/renderer/blockentity/SignRenderer.java.patch rename to patches/net/minecraft/client/renderer/blockentity/AbstractSignRenderer.java.patch index 23ffcf89c2..658b82318d 100644 --- a/patches/net/minecraft/client/renderer/blockentity/SignRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/AbstractSignRenderer.java.patch @@ -1,18 +1,16 @@ ---- a/net/minecraft/client/renderer/blockentity/SignRenderer.java -+++ b/net/minecraft/client/renderer/blockentity/SignRenderer.java -@@ -251,6 +_,15 @@ - return LayerDefinition.create(meshdefinition, 64, 32); +--- a/net/minecraft/client/renderer/blockentity/AbstractSignRenderer.java ++++ b/net/minecraft/client/renderer/blockentity/AbstractSignRenderer.java +@@ -195,4 +_,13 @@ + return ARGB.color(0, j, k, l); + } } - ++ + @Override + public net.minecraft.world.phys.AABB getRenderBoundingBox(SignBlockEntity blockEntity) { -+ if (blockEntity.getBlockState().getBlock() instanceof StandingSignBlock) { ++ if (blockEntity.getBlockState().getBlock() instanceof net.minecraft.world.level.block.StandingSignBlock) { + net.minecraft.core.BlockPos pos = blockEntity.getBlockPos(); + return new net.minecraft.world.phys.AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1.0, pos.getY() + 1.125, pos.getZ() + 1.0); + } + return BlockEntityRenderer.super.getRenderBoundingBox(blockEntity); + } -+ - @OnlyIn(Dist.CLIENT) - static record Models(Model standing, Model wall) { - } + } diff --git a/patches/net/minecraft/client/renderer/blockentity/BannerRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/BannerRenderer.java.patch index 81cc3164d7..43ec30aece 100644 --- a/patches/net/minecraft/client/renderer/blockentity/BannerRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/BannerRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/blockentity/BannerRenderer.java +++ b/net/minecraft/client/renderer/blockentity/BannerRenderer.java -@@ -141,4 +_,11 @@ +@@ -135,4 +_,11 @@ int i = p_332728_.getTextureDiffuseColor(); p_332732_.render(p_332737_, p_332704_.buffer(p_332758_, RenderType::entityNoOutline), p_332821_, p_332828_, i); } diff --git a/patches/net/minecraft/client/renderer/blockentity/DecoratedPotRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/DecoratedPotRenderer.java.patch index 279790622c..54c1ba440f 100644 --- a/patches/net/minecraft/client/renderer/blockentity/DecoratedPotRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/DecoratedPotRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/blockentity/DecoratedPotRenderer.java +++ b/net/minecraft/client/renderer/blockentity/DecoratedPotRenderer.java -@@ -141,4 +_,10 @@ +@@ -153,4 +_,10 @@ private void renderSide(ModelPart p_273495_, PoseStack p_272899_, MultiBufferSource p_273582_, int p_273242_, int p_273108_, Material p_273173_) { p_273495_.render(p_272899_, p_273173_.buffer(p_273582_, RenderType::entitySolid), p_273242_, p_273108_); } diff --git a/patches/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java.patch index b1bd51f952..c5bdbc66de 100644 --- a/patches/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java +++ b/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java -@@ -55,6 +_,12 @@ - p_112480_.popPose(); +@@ -57,6 +_,12 @@ + p_388735_.popPose(); } + @Override diff --git a/patches/net/minecraft/client/renderer/blockentity/SkullBlockRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/SkullBlockRenderer.java.patch index d738262caa..2d8d009060 100644 --- a/patches/net/minecraft/client/renderer/blockentity/SkullBlockRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/SkullBlockRenderer.java.patch @@ -1,18 +1,9 @@ --- a/net/minecraft/client/renderer/blockentity/SkullBlockRenderer.java +++ b/net/minecraft/client/renderer/blockentity/SkullBlockRenderer.java -@@ -55,6 +_,7 @@ - builder.put(SkullBlock.Types.CREEPER, new SkullModel(p_173662_.bakeLayer(ModelLayers.CREEPER_HEAD))); - builder.put(SkullBlock.Types.DRAGON, new DragonHeadModel(p_173662_.bakeLayer(ModelLayers.DRAGON_SKULL))); - builder.put(SkullBlock.Types.PIGLIN, new PiglinHeadModel(p_173662_.bakeLayer(ModelLayers.PIGLIN_HEAD))); -+ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.EntityRenderersEvent.CreateSkullModels(builder, p_173662_)); - return builder.build(); +@@ -115,4 +_,14 @@ + ) + : RenderType.entityCutoutNoCullZOffset(p_389624_ != null ? p_389624_ : SKIN_BY_TYPE.get(p_389566_)); } - -@@ -108,5 +_,15 @@ - } else { - return RenderType.entityCutoutNoCullZOffset(resourcelocation); - } -+ } + + @Override + public net.minecraft.world.phys.AABB getRenderBoundingBox(SkullBlockEntity blockEntity) { @@ -22,5 +13,5 @@ + return new net.minecraft.world.phys.AABB(pos.getX() - .75, pos.getY() - .35, pos.getZ() - .75, pos.getX() + 1.75, pos.getY() + 1.0, pos.getZ() + 1.75); + } + return BlockEntityRenderer.super.getRenderBoundingBox(blockEntity); - } ++ } } diff --git a/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch b/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch index 83ea06baae..5b7ff9be4f 100644 --- a/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch +++ b/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java +++ b/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java -@@ -393,9 +_,10 @@ +@@ -399,9 +_,10 @@ public SectionRenderDispatcher.RenderSection.CompileTask createCompileTask(RenderRegionCache p_295324_) { this.cancelTasks(); @@ -13,7 +13,7 @@ return this.lastRebuildTask; } -@@ -464,10 +_,17 @@ +@@ -470,10 +_,17 @@ class RebuildTask extends SectionRenderDispatcher.RenderSection.CompileTask { @Nullable protected volatile RenderChunkRegion region; @@ -31,7 +31,7 @@ } @Override -@@ -498,7 +_,7 @@ +@@ -499,7 +_,7 @@ SectionCompiler.Results sectioncompiler$results; try (Zone zone = Profiler.get().zone("Compile Section")) { sectioncompiler$results = SectionRenderDispatcher.this.sectionCompiler diff --git a/patches/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch b/patches/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch index 49c5906036..aaca1f7592 100644 --- a/patches/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch +++ b/patches/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java +++ b/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java -@@ -243,12 +_,12 @@ +@@ -246,12 +_,12 @@ ) { AABB aabb = p_114444_.getBoundingBox().move(-p_114444_.getX(), -p_114444_.getY(), -p_114444_.getZ()); ShapeRenderer.renderLineBox(p_114442_, p_114443_, aabb, p_353064_, p_353059_, p_353042_, 1.0F); @@ -15,7 +15,7 @@ p_114442_.pushPose(); double d3 = d0 + Mth.lerp((double)p_114445_, enderdragonpart.xOld, enderdragonpart.getX()); double d4 = d1 + Mth.lerp((double)p_114445_, enderdragonpart.yOld, enderdragonpart.getY()); -@@ -474,6 +_,10 @@ +@@ -477,6 +_,10 @@ return this.itemInHandRenderer; } @@ -26,7 +26,7 @@ @Override public void onResourceManagerReload(ResourceManager p_174004_) { EntityRendererProvider.Context entityrendererprovider$context = new EntityRendererProvider.Context( -@@ -481,5 +_,6 @@ +@@ -484,5 +_,6 @@ ); this.renderers = EntityRenderers.createEntityRenderers(entityrendererprovider$context); this.playerRenderers = EntityRenderers.createPlayerRenderers(entityrendererprovider$context); diff --git a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch index 3a5d1e4205..4381fedeb5 100644 --- a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch @@ -9,7 +9,7 @@ this.renderNameTag(p_364816_, p_364816_.nameTag, p_114488_, p_114489_, p_114490_); } } -@@ -245,6 +_,7 @@ +@@ -249,6 +_,7 @@ public final S createRenderState(T p_361382_, float p_360885_) { S s = this.reusedState; this.extractRenderState(p_361382_, s, p_360885_); @@ -17,7 +17,7 @@ return s; } -@@ -270,9 +_,11 @@ +@@ -274,9 +_,11 @@ } p_361028_.distanceToCameraSq = this.entityRenderDispatcher.distanceToSqr(p_362104_); @@ -31,7 +31,7 @@ p_361028_.nameTagAttachment = p_362104_.getAttachments().getNullable(EntityAttachment.NAME_TAG, 0, p_362104_.getYRot(p_362204_)); } else { p_361028_.nameTag = null; -@@ -302,5 +_,7 @@ +@@ -306,5 +_,7 @@ } p_361028_.displayFireAnimation = p_362104_.displayFireAnimation(); diff --git a/patches/net/minecraft/client/renderer/entity/FishingHookRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/FishingHookRenderer.java.patch index 6747d9fda7..fead956b8d 100644 --- a/patches/net/minecraft/client/renderer/entity/FishingHookRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/FishingHookRenderer.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/client/renderer/entity/FishingHookRenderer.java +++ b/net/minecraft/client/renderer/entity/FishingHookRenderer.java -@@ -63,7 +_,7 @@ - private Vec3 getPlayerHandPos(Player p_340935_, float p_340872_, float p_341261_) { - int i = p_340935_.getMainArm() == HumanoidArm.RIGHT ? 1 : -1; - ItemStack itemstack = p_340935_.getMainHandItem(); -- if (!itemstack.is(Items.FISHING_ROD)) { -+ if (!itemstack.canPerformAction(net.neoforged.neoforge.common.ItemAbilities.FISHING_ROD_CAST)) { - i = -i; - } +@@ -60,7 +_,7 @@ + } + + public static HumanoidArm getHoldingArm(Player p_386900_) { +- return p_386900_.getMainHandItem().getItem() instanceof FishingRodItem ? p_386900_.getMainArm() : p_386900_.getMainArm().getOpposite(); ++ return p_386900_.getMainHandItem().canPerformAction(net.neoforged.neoforge.common.ItemAbilities.FISHING_ROD_CAST) ? p_386900_.getMainArm() : p_386900_.getMainArm().getOpposite(); + } + private Vec3 getPlayerHandPos(Player p_340935_, float p_340872_, float p_341261_) { diff --git a/patches/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch index fa5624769b..e9e02707fe 100644 --- a/patches/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java +++ b/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java -@@ -40,7 +_,7 @@ +@@ -51,7 +_,7 @@ p_362998_.isCrouching = p_365104_.isCrouching(); p_362998_.isFallFlying = p_365104_.isFallFlying(); p_362998_.isVisuallySwimming = p_365104_.isVisuallySwimming(); diff --git a/patches/net/minecraft/client/renderer/entity/ItemEntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/ItemEntityRenderer.java.patch index 52951841f3..1e35d7dac3 100644 --- a/patches/net/minecraft/client/renderer/entity/ItemEntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/ItemEntityRenderer.java.patch @@ -1,24 +1,29 @@ --- a/net/minecraft/client/renderer/entity/ItemEntityRenderer.java +++ b/net/minecraft/client/renderer/entity/ItemEntityRenderer.java -@@ -54,7 +_,8 @@ - this.random.setSeed((long)getSeedForItemStack(itemstack)); - boolean flag = bakedmodel.isGui3d(); +@@ -38,6 +_,8 @@ + super.extractRenderState(p_362393_, p_361441_, p_360849_); + p_361441_.ageInTicks = (float)p_362393_.getAge() + p_360849_; + p_361441_.bobOffset = p_362393_.bobOffs; ++ p_361441_.shouldBob = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_362393_.getItem()).shouldBobAsEntity(p_362393_.getItem()); ++ p_361441_.shouldSpread = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_362393_.getItem()).shouldSpreadAsEntity(p_362393_.getItem()); + p_361441_.extractItemGroupRenderState(p_362393_, p_362393_.getItem(), this.itemModelResolver); + } + +@@ -45,7 +_,7 @@ + if (!p_362172_.item.isEmpty()) { + p_115030_.pushPose(); float f = 0.25F; - float f1 = Mth.sin(p_362172_.ageInTicks / 10.0F + p_362172_.bobOffset) * 0.1F + 0.1F; -+ boolean shouldBob = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack).shouldBobAsEntity(itemstack); -+ float f1 = shouldBob ? Mth.sin(p_362172_.ageInTicks / 10.0F + p_362172_.bobOffset) * 0.1F + 0.1F : 0; - float f2 = bakedmodel.getTransforms().getTransform(ItemDisplayContext.GROUND).scale.y(); ++ float f1 = p_362172_.shouldBob ? Mth.sin(p_362172_.ageInTicks / 10.0F + p_362172_.bobOffset) * 0.1F + 0.1F : 0; + float f2 = p_362172_.item.transform().scale.y(); p_115030_.translate(0.0F, f1 + 0.25F * f2, 0.0F); float f3 = ItemEntity.getSpin(p_362172_.ageInTicks, p_362172_.bobOffset); -@@ -110,9 +_,10 @@ - p_323733_.translate(f3, f4, f5); - } +@@ -75,7 +_,7 @@ -+ boolean shouldSpread = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_323718_).shouldSpreadAsEntity(p_323718_); for (int j = 0; j < i; j++) { - p_323733_.pushPose(); + p_323763_.pushPose(); - if (j > 0) { -+ if (j > 0 && shouldSpread) { - if (p_324462_) { - float f7 = (p_324565_.nextFloat() * 2.0F - 1.0F) * 0.15F; - float f9 = (p_324565_.nextFloat() * 2.0F - 1.0F) * 0.15F; ++ if (j > 0 && p_388704_.shouldSpread) { + if (flag) { + float f7 = (p_324507_.nextFloat() * 2.0F - 1.0F) * 0.15F; + float f9 = (p_324507_.nextFloat() * 2.0F - 1.0F) * 0.15F; diff --git a/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch index 7fe0bf497d..02db78f347 100644 --- a/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch @@ -1,23 +1,23 @@ --- a/net/minecraft/client/renderer/entity/ItemFrameRenderer.java +++ b/net/minecraft/client/renderer/entity/ItemFrameRenderer.java -@@ -100,6 +_,7 @@ +@@ -95,6 +_,7 @@ + p_115079_.translate(0.0F, 0.0F, 0.4375F); + } - int j = mapid != null ? p_364723_.rotation % 4 * 2 : p_364723_.rotation; ++ if (!net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderItemInFrameEvent(p_364723_, this, p_115079_, p_115080_, p_115081_)).isCanceled()) { + if (p_364723_.mapId != null) { + int j = p_364723_.rotation % 4 * 2; p_115079_.mulPose(Axis.ZP.rotationDegrees((float)j * 360.0F / 8.0F)); -+ if (!net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderItemInFrameEvent(p_364723_, this, p_115079_, p_115080_, p_115081_)).isCanceled()) { - if (mapid != null) { - p_115079_.mulPose(Axis.ZP.rotationDegrees(180.0F)); - float f2 = 0.0078125F; -@@ -113,6 +_,7 @@ - p_115079_.scale(0.5F, 0.5F, 0.5F); - this.itemRenderer.render(itemstack, ItemDisplayContext.FIXED, false, p_115079_, p_115080_, k, OverlayTexture.NO_OVERLAY, p_364723_.itemModel); - } -+ } +@@ -111,6 +_,7 @@ + p_115079_.scale(0.5F, 0.5F, 0.5F); + p_364723_.item.render(p_115079_, p_115080_, k, OverlayTexture.NO_OVERLAY); } ++ } p_115079_.popPose(); -@@ -161,7 +_,7 @@ - if (!p_362907_.itemStack.isEmpty()) { + } +@@ -154,7 +_,7 @@ + if (!itemstack.isEmpty()) { MapId mapid = p_363125_.getFramedMapId(itemstack); if (mapid != null) { - MapItemSavedData mapitemsaveddata = p_363125_.level().getMapData(mapid); diff --git a/patches/net/minecraft/client/renderer/entity/ItemRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/ItemRenderer.java.patch index a53ce7e08e..714221b7bc 100644 --- a/patches/net/minecraft/client/renderer/entity/ItemRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/ItemRenderer.java.patch @@ -1,54 +1,11 @@ --- a/net/minecraft/client/renderer/entity/ItemRenderer.java +++ b/net/minecraft/client/renderer/entity/ItemRenderer.java -@@ -156,7 +_,7 @@ - float p_371782_ - ) { - p_371635_.pushPose(); -- p_371384_.getTransforms().getTransform(p_371250_).apply(p_371248_, p_371635_); -+ p_371384_ = net.neoforged.neoforge.client.ClientHooks.handleCameraTransforms(p_371635_, p_371384_, p_371250_, p_371248_); - p_371635_.translate(-0.5F, -0.5F, p_371782_); - this.renderItem(p_371318_, p_371250_, p_371635_, p_371946_, p_371752_, p_371508_, p_371384_, p_371718_); - p_371635_.popPose(); -@@ -173,7 +_,8 @@ - boolean p_364829_ - ) { - if (!p_363970_.isCustomRenderer() && (!p_361397_.is(Items.TRIDENT) || p_364829_)) { -- RenderType rendertype = ItemBlockRenderTypes.getRenderType(p_361397_); -+ for (var model : p_363970_.getRenderPasses(p_361397_)) { -+ for (var rendertype : model.getRenderTypes(p_361397_)) { - VertexConsumer vertexconsumer; - if (hasAnimatedTexture(p_361397_) && p_361397_.hasFoil()) { - PoseStack.Pose posestack$pose = p_360423_.last().copy(); -@@ -188,9 +_,11 @@ - vertexconsumer = getFoilBuffer(p_360415_, rendertype, true, p_361397_.hasFoil()); +@@ -132,7 +_,7 @@ + f3 = 1.0F; } -- this.renderModelLists(p_363970_, p_361397_, p_361265_, p_364771_, p_360423_, vertexconsumer); -+ this.renderModelLists(model, p_361397_, p_361265_, p_364771_, p_360423_, vertexconsumer); -+ } -+ } - } else { -- this.blockEntityRenderer.renderByItem(p_361397_, p_361627_, p_360423_, p_360415_, p_361265_, p_364771_); -+ net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_361397_).getCustomRenderer().renderByItem(p_361397_, p_361627_, p_360423_, p_360415_, p_361265_, p_364771_); - } - } - -@@ -238,7 +_,7 @@ - float f1 = (float)ARGB.red(i) / 255.0F; - float f2 = (float)ARGB.green(i) / 255.0F; - float f3 = (float)ARGB.blue(i) / 255.0F; - p_115164_.putBulkData(posestack$pose, bakedquad, f1, f2, f3, f, p_115167_, p_115168_); -+ p_115164_.putBulkData(posestack$pose, bakedquad, f1, f2, f3, f, p_115167_, p_115168_, true); // Neo: pass readExistingColor=true ++ p_115164_.putBulkData(posestack$pose, bakedquad, f1, f2, f3, f, p_115167_, p_115168_, true); } } -@@ -294,5 +_,9 @@ - ClientLevel clientlevel = p_372942_ instanceof ClientLevel ? (ClientLevel)p_372942_ : null; - BakedModel bakedmodel = p_373094_.overrides().findOverride(p_372923_, clientlevel, p_373099_, p_372933_); - return bakedmodel == null ? p_373094_ : bakedmodel; -+ } -+ -+ public BlockEntityWithoutLevelRenderer getBlockEntityRenderer() { -+ return blockEntityRenderer; - } - } diff --git a/patches/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch index 8322d59b63..8998226b08 100644 --- a/patches/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/entity/LivingEntityRenderer.java +++ b/net/minecraft/client/renderer/entity/LivingEntityRenderer.java -@@ -69,6 +_,7 @@ +@@ -73,6 +_,7 @@ } public void render(S p_361886_, PoseStack p_115311_, MultiBufferSource p_115312_, int p_115313_) { @@ -8,7 +8,7 @@ p_115311_.pushPose(); if (p_361886_.hasPose(Pose.SLEEPING)) { Direction direction = p_361886_.bedOrientation; -@@ -104,6 +_,7 @@ +@@ -108,6 +_,7 @@ p_115311_.popPose(); super.render(p_361886_, p_115311_, p_115312_, p_115313_); @@ -16,7 +16,7 @@ } protected boolean shouldRenderLayers(S p_364697_) { -@@ -201,7 +_,7 @@ +@@ -205,7 +_,7 @@ protected boolean shouldShowName(T p_363517_, double p_365448_) { if (p_363517_.isDiscrete()) { float f = 32.0F; @@ -25,12 +25,12 @@ return false; } } -@@ -284,7 +_,7 @@ - - p_360515_.isFullyFrozen = p_362733_.isFullyFrozen(); - p_360515_.isBaby = p_362733_.isBaby(); -- p_360515_.isInWater = p_362733_.isInWater(); -+ p_360515_.isInWater = p_362733_.isInWater() || p_362733_.isInFluidType((fluidType, height) -> p_362733_.canSwimInFluidType(fluidType)); - p_360515_.isAutoSpinAttack = p_362733_.isAutoSpinAttack(); - p_360515_.hasRedOverlay = p_362733_.hurtTime > 0 || p_362733_.deathTime > 0; - ItemStack itemstack1 = p_362733_.getItemBySlot(EquipmentSlot.HEAD); +@@ -289,7 +_,7 @@ + label48: { + p_360515_.isFullyFrozen = p_362733_.isFullyFrozen(); + p_360515_.isBaby = p_362733_.isBaby(); +- p_360515_.isInWater = p_362733_.isInWater(); ++ p_360515_.isInWater = p_362733_.isInWater() || p_362733_.isInFluidType((fluidType, height) -> p_362733_.canSwimInFluidType(fluidType)); + p_360515_.isAutoSpinAttack = p_362733_.isAutoSpinAttack(); + p_360515_.hasRedOverlay = p_362733_.hurtTime > 0 || p_362733_.deathTime > 0; + ItemStack itemstack = p_362733_.getItemBySlot(EquipmentSlot.HEAD); diff --git a/patches/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java.patch index d9bc50306b..54ebe1b713 100644 --- a/patches/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java +++ b/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java -@@ -65,21 +_,26 @@ +@@ -66,21 +_,26 @@ int p_371309_, - @Nullable ResourceLocation p_371587_ + @Nullable ResourceLocation p_371639_ ) { -+ p_371731_ = getArmorModelHook(p_371670_, p_371854_, p_371731_); - List list = this.equipmentModels.get(p_371639_).getLayers(p_371854_); ++ p_371731_ = getArmorModelHook(p_371670_, p_387484_, p_371731_); + List list = this.equipmentAssets.get(p_387603_).getLayers(p_387484_); if (!list.isEmpty()) { - int i = p_371670_.is(ItemTags.DYEABLE) ? DyedItemColor.getOrDefault(p_371670_, 0) : 0; + net.neoforged.neoforge.client.extensions.common.IClientItemExtensions extensions = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_371670_); @@ -13,14 +13,14 @@ boolean flag = p_371670_.hasFoil(); + int idx = 0; - for (EquipmentModel.Layer equipmentmodel$layer : list) { -- int j = getColorForLayer(equipmentmodel$layer, i); -+ int j = extensions.getArmorLayerTintColor(p_371670_, equipmentmodel$layer, idx, i); + for (EquipmentClientInfo.Layer equipmentclientinfo$layer : list) { +- int j = getColorForLayer(equipmentclientinfo$layer, i); ++ int j = extensions.getArmorLayerTintColor(p_371670_, equipmentclientinfo$layer, idx, i); if (j != 0) { - ResourceLocation resourcelocation = equipmentmodel$layer.usePlayerTexture() && p_371587_ != null - ? p_371587_ - : this.layerTextureLookup.apply(new EquipmentLayerRenderer.LayerTextureKey(p_371854_, equipmentmodel$layer)); -+ resourcelocation = net.neoforged.neoforge.client.ClientHooks.getArmorTexture(p_371670_, p_371854_, equipmentmodel$layer, resourcelocation); + ResourceLocation resourcelocation = equipmentclientinfo$layer.usePlayerTexture() && p_371639_ != null + ? p_371639_ + : this.layerTextureLookup.apply(new EquipmentLayerRenderer.LayerTextureKey(p_387484_, equipmentclientinfo$layer)); ++ resourcelocation = net.neoforged.neoforge.client.ClientHooks.getArmorTexture(p_371670_, p_387484_, equipmentclientinfo$layer, resourcelocation); VertexConsumer vertexconsumer = ItemRenderer.getArmorFoilBuffer(p_371286_, RenderType.armorCutoutNoCull(resourcelocation), flag); p_371731_.renderToBuffer(p_371767_, vertexconsumer, p_371309_, OverlayTexture.NO_OVERLAY, j); flag = false; @@ -29,7 +29,7 @@ } ArmorTrim armortrim = p_371670_.get(DataComponents.TRIM); -@@ -99,6 +_,13 @@ +@@ -100,6 +_,13 @@ } else { return -1; } @@ -38,7 +38,7 @@ + /** + * Hook to allow item-sensitive armor model. for HumanoidArmorLayer. + */ -+ protected net.minecraft.client.model.Model getArmorModelHook(ItemStack itemStack, EquipmentModel.LayerType layerType, Model model) { ++ protected net.minecraft.client.model.Model getArmorModelHook(ItemStack itemStack, EquipmentClientInfo.LayerType layerType, Model model) { + return net.neoforged.neoforge.client.ClientHooks.getArmorModel(itemStack, layerType, model); } diff --git a/patches/net/minecraft/client/renderer/entity/player/PlayerRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/player/PlayerRenderer.java.patch index d2fb4f4901..a36dc98a5e 100644 --- a/patches/net/minecraft/client/renderer/entity/player/PlayerRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/player/PlayerRenderer.java.patch @@ -1,16 +1,39 @@ --- a/net/minecraft/client/renderer/entity/player/PlayerRenderer.java +++ b/net/minecraft/client/renderer/entity/player/PlayerRenderer.java -@@ -127,6 +_,9 @@ - } else if (!p_363098_.swinging && p_364742_.holdsChargedCrossbow) { - return HumanoidModel.ArmPose.CROSSBOW_HOLD; - } -+ if (p_364742_.customArmPose != null) { -+ return p_364742_.customArmPose; -+ } - - return HumanoidModel.ArmPose.ITEM; +@@ -86,8 +_,10 @@ + private static HumanoidModel.ArmPose getArmPose(AbstractClientPlayer p_386861_, HumanoidArm p_373044_) { + ItemStack itemstack = p_386861_.getItemInHand(InteractionHand.MAIN_HAND); + ItemStack itemstack1 = p_386861_.getItemInHand(InteractionHand.OFF_HAND); +- HumanoidModel.ArmPose humanoidmodel$armpose = getArmPose(p_386861_, itemstack, InteractionHand.MAIN_HAND); +- HumanoidModel.ArmPose humanoidmodel$armpose1 = getArmPose(p_386861_, itemstack1, InteractionHand.OFF_HAND); ++ var extensionsMainHand = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack); ++ var extensionsOffHand = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack1); ++ HumanoidModel.ArmPose humanoidmodel$armpose = getArmPose(p_386861_, itemstack, InteractionHand.MAIN_HAND, extensionsMainHand.getArmPose(p_386861_, InteractionHand.MAIN_HAND, itemstack)); ++ HumanoidModel.ArmPose humanoidmodel$armpose1 = getArmPose(p_386861_, itemstack1, InteractionHand.OFF_HAND, extensionsOffHand.getArmPose(p_386861_, InteractionHand.OFF_HAND, itemstack1)); + if (humanoidmodel$armpose.isTwoHanded()) { + humanoidmodel$armpose1 = itemstack1.isEmpty() ? HumanoidModel.ArmPose.EMPTY : HumanoidModel.ArmPose.ITEM; } -@@ -141,6 +_,13 @@ +@@ -95,7 +_,19 @@ + return p_386861_.getMainArm() == p_373044_ ? humanoidmodel$armpose : humanoidmodel$armpose1; + } + ++ /** ++ * @deprecated Neo: use {@link #getArmPose(Player, ItemStack, InteractionHand, HumanoidModel.ArmPose)} instead ++ */ ++ @Deprecated + private static HumanoidModel.ArmPose getArmPose(Player p_386775_, ItemStack p_388403_, InteractionHand p_117796_) { ++ return getArmPose(p_386775_, p_388403_, p_117796_, null); ++ } ++ ++ private static HumanoidModel.ArmPose getArmPose(Player p_386775_, ItemStack p_388403_, InteractionHand p_117796_, @Nullable HumanoidModel.ArmPose pose) { ++ if (pose != null) { ++ return pose; ++ } ++ + if (p_388403_.isEmpty()) { + return HumanoidModel.ArmPose.EMPTY; + } else { +@@ -145,6 +_,13 @@ p_117799_.scale(0.9375F, 0.9375F, 0.9375F); } @@ -24,17 +47,7 @@ protected void renderNameTag(PlayerRenderState p_363185_, Component p_117809_, PoseStack p_117810_, MultiBufferSource p_117811_, int p_117812_) { p_117810_.pushPose(); if (p_363185_.scoreText != null) { -@@ -217,7 +_,8 @@ - ItemStack itemstack = p_364516_.getItemInHand(p_364304_); - p_360817_.isEmpty = itemstack.isEmpty(); - p_360817_.useAnimation = !itemstack.isEmpty() ? itemstack.getUseAnimation() : null; -- p_360817_.holdsChargedCrossbow = itemstack.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemstack); -+ p_360817_.holdsChargedCrossbow = itemstack.getItem() instanceof CrossbowItem && CrossbowItem.isCharged(itemstack); -+ p_360817_.customArmPose = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack).getArmPose(p_364516_, p_364304_, itemstack); - } - - private static void extractCapeState(AbstractClientPlayer p_364691_, PlayerRenderState p_360814_, float p_364460_) { -@@ -247,11 +_,29 @@ +@@ -251,11 +_,29 @@ : null; } diff --git a/patches/net/minecraft/client/renderer/entity/state/ItemClusterRenderState.java.patch b/patches/net/minecraft/client/renderer/entity/state/ItemClusterRenderState.java.patch new file mode 100644 index 0000000000..1de5b0c358 --- /dev/null +++ b/patches/net/minecraft/client/renderer/entity/state/ItemClusterRenderState.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/renderer/entity/state/ItemClusterRenderState.java ++++ b/net/minecraft/client/renderer/entity/state/ItemClusterRenderState.java +@@ -14,6 +_,7 @@ + public final ItemStackRenderState item = new ItemStackRenderState(); + public int count; + public int seed; ++ public boolean shouldSpread; + + public void extractItemGroupRenderState(Entity p_386526_, ItemStack p_386486_, ItemModelResolver p_387036_) { + p_387036_.updateForNonLiving(this.item, p_386486_, ItemDisplayContext.GROUND, p_386526_); diff --git a/patches/net/minecraft/client/renderer/entity/state/ItemEntityRenderState.java.patch b/patches/net/minecraft/client/renderer/entity/state/ItemEntityRenderState.java.patch new file mode 100644 index 0000000000..7b3eb62dce --- /dev/null +++ b/patches/net/minecraft/client/renderer/entity/state/ItemEntityRenderState.java.patch @@ -0,0 +1,8 @@ +--- a/net/minecraft/client/renderer/entity/state/ItemEntityRenderState.java ++++ b/net/minecraft/client/renderer/entity/state/ItemEntityRenderState.java +@@ -6,4 +_,5 @@ + @OnlyIn(Dist.CLIENT) + public class ItemEntityRenderState extends ItemClusterRenderState { + public float bobOffset; ++ public boolean shouldBob; + } diff --git a/patches/net/minecraft/client/renderer/entity/state/PlayerRenderState.java.patch b/patches/net/minecraft/client/renderer/entity/state/PlayerRenderState.java.patch deleted file mode 100644 index 870f5bd850..0000000000 --- a/patches/net/minecraft/client/renderer/entity/state/PlayerRenderState.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/client/renderer/entity/state/PlayerRenderState.java -+++ b/net/minecraft/client/renderer/entity/state/PlayerRenderState.java -@@ -52,5 +_,7 @@ - @Nullable - public ItemUseAnimation useAnimation; - public boolean holdsChargedCrossbow; -+ @Nullable -+ public net.minecraft.client.model.HumanoidModel.ArmPose customArmPose; - } - } diff --git a/patches/net/minecraft/client/renderer/item/BlockModelWrapper.java.patch b/patches/net/minecraft/client/renderer/item/BlockModelWrapper.java.patch new file mode 100644 index 0000000000..0ffe05b0dc --- /dev/null +++ b/patches/net/minecraft/client/renderer/item/BlockModelWrapper.java.patch @@ -0,0 +1,44 @@ +--- a/net/minecraft/client/renderer/item/BlockModelWrapper.java ++++ b/net/minecraft/client/renderer/item/BlockModelWrapper.java +@@ -41,22 +_,25 @@ + @Nullable LivingEntity p_387263_, + int p_388300_ + ) { +- ItemStackRenderState.LayerRenderState itemstackrenderstate$layerrenderstate = p_386488_.newLayer(); +- if (p_386443_.hasFoil()) { +- itemstackrenderstate$layerrenderstate.setFoilType( +- hasSpecialAnimatedTexture(p_386443_) ? ItemStackRenderState.FoilType.SPECIAL : ItemStackRenderState.FoilType.STANDARD +- ); +- } +- +- int i = this.tints.size(); +- int[] aint = itemstackrenderstate$layerrenderstate.prepareTintLayers(i); +- +- for (int j = 0; j < i; j++) { +- aint[j] = this.tints.get(j).calculate(p_386443_, p_387522_, p_387263_); +- } +- +- RenderType rendertype = ItemBlockRenderTypes.getRenderType(p_386443_); +- itemstackrenderstate$layerrenderstate.setupBlockModel(this.model, rendertype); ++ final int[] tints = new int[this.tints.size()]; ++ for (int j = 0; j < tints.length; j++) { ++ tints[j] = this.tints.get(j).calculate(p_386443_, p_387522_, p_387263_); ++ } ++ final ItemStackRenderState.FoilType foilType = hasSpecialAnimatedTexture(p_386443_) ? ItemStackRenderState.FoilType.SPECIAL : ItemStackRenderState.FoilType.STANDARD; ++ ++ this.model.getRenderPasses(p_386443_).forEach(pass -> { ++ ItemStackRenderState.LayerRenderState itemstackrenderstate$layerrenderstate = p_386488_.newLayer(); ++ if (p_386443_.hasFoil()) { ++ itemstackrenderstate$layerrenderstate.setFoilType( ++ foilType ++ ); ++ } ++ ++ int[] aint = itemstackrenderstate$layerrenderstate.prepareTintLayers(tints.length); ++ System.arraycopy(tints, 0, aint, 0, tints.length); ++ ++ itemstackrenderstate$layerrenderstate.setupBlockModel(this.model, pass.getRenderType(p_386443_)); ++ }); + } + + private static boolean hasSpecialAnimatedTexture(ItemStack p_387217_) { diff --git a/patches/net/minecraft/client/renderer/item/ItemModels.java.patch b/patches/net/minecraft/client/renderer/item/ItemModels.java.patch new file mode 100644 index 0000000000..7e2649b4c9 --- /dev/null +++ b/patches/net/minecraft/client/renderer/item/ItemModels.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/renderer/item/ItemModels.java ++++ b/net/minecraft/client/renderer/item/ItemModels.java +@@ -21,5 +_,7 @@ + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("bundle/selected_item"), BundleSelectedItemSpecialRenderer.Unbaked.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("select"), SelectItemModel.Unbaked.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("condition"), ConditionalItemModel.Unbaked.MAP_CODEC); ++ ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterItemModelsEvent(ID_MAPPER)); + } + } diff --git a/patches/net/minecraft/client/renderer/item/ItemProperties.java.patch b/patches/net/minecraft/client/renderer/item/ItemProperties.java.patch deleted file mode 100644 index 95f1563e80..0000000000 --- a/patches/net/minecraft/client/renderer/item/ItemProperties.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/net/minecraft/client/renderer/item/ItemProperties.java -+++ b/net/minecraft/client/renderer/item/ItemProperties.java -@@ -42,6 +_,9 @@ - private static final Map> PROPERTIES = Maps.newHashMap(); - - private static ClampedItemPropertyFunction registerGeneric(ResourceLocation p_174582_, ClampedItemPropertyFunction p_174583_) { -+ return (ClampedItemPropertyFunction) registerGeneric(p_174582_, (ItemPropertyFunction) p_174583_); -+ } -+ public static ItemPropertyFunction registerGeneric(ResourceLocation p_174582_, ItemPropertyFunction p_174583_) { - GENERIC_PROPERTIES.put(p_174582_, p_174583_); - return p_174583_; - } -@@ -51,6 +_,10 @@ - } - - private static void register(Item p_174571_, ResourceLocation p_174572_, ClampedItemPropertyFunction p_174573_) { -+ register(p_174571_, p_174572_, (ItemPropertyFunction) p_174573_); -+ } -+ -+ public static void register(Item p_174571_, ResourceLocation p_174572_, ItemPropertyFunction p_174573_) { - PROPERTIES.computeIfAbsent(p_174571_, p_117828_ -> Maps.newHashMap()).put(p_174572_, p_174573_); - } - diff --git a/patches/net/minecraft/client/renderer/item/ItemStackRenderState.java.patch b/patches/net/minecraft/client/renderer/item/ItemStackRenderState.java.patch new file mode 100644 index 0000000000..9f4cd214c1 --- /dev/null +++ b/patches/net/minecraft/client/renderer/item/ItemStackRenderState.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/client/renderer/item/ItemStackRenderState.java ++++ b/net/minecraft/client/renderer/item/ItemStackRenderState.java +@@ -72,7 +_,7 @@ + return null; + } else { + BakedModel bakedmodel = this.layers[p_387539_.nextInt(this.activeLayerCount)].model; +- return bakedmodel == null ? null : bakedmodel.getParticleIcon(); ++ return bakedmodel == null ? null : bakedmodel.getParticleIcon(net.neoforged.neoforge.client.model.data.ModelData.EMPTY); + } + } + +@@ -149,6 +_,9 @@ + + void render(PoseStack p_387607_, MultiBufferSource p_386763_, int p_387589_, int p_388775_) { + p_387607_.pushPose(); ++ if (model != null) ++ net.neoforged.neoforge.client.ClientHooks.handleCameraTransforms(p_387607_, model, displayContext, ItemStackRenderState.this.isLeftHand); ++ else + this.transform().apply(ItemStackRenderState.this.isLeftHand, p_387607_); + p_387607_.translate(-0.5F, -0.5F, -0.5F); + if (this.specialRenderer != null) { diff --git a/patches/net/minecraft/client/renderer/item/properties/conditional/ConditionalItemModelProperties.java.patch b/patches/net/minecraft/client/renderer/item/properties/conditional/ConditionalItemModelProperties.java.patch new file mode 100644 index 0000000000..080464ae1f --- /dev/null +++ b/patches/net/minecraft/client/renderer/item/properties/conditional/ConditionalItemModelProperties.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/renderer/item/properties/conditional/ConditionalItemModelProperties.java ++++ b/net/minecraft/client/renderer/item/properties/conditional/ConditionalItemModelProperties.java +@@ -25,5 +_,7 @@ + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("extended_view"), ExtendedView.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("keybind_down"), IsKeybindDown.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("view_entity"), IsViewEntity.MAP_CODEC); ++ ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterConditionalItemModelPropertyEvent(ID_MAPPER)); + } + } diff --git a/patches/net/minecraft/client/renderer/item/properties/numeric/RangeSelectItemModelProperties.java.patch b/patches/net/minecraft/client/renderer/item/properties/numeric/RangeSelectItemModelProperties.java.patch new file mode 100644 index 0000000000..cd56d12d98 --- /dev/null +++ b/patches/net/minecraft/client/renderer/item/properties/numeric/RangeSelectItemModelProperties.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/renderer/item/properties/numeric/RangeSelectItemModelProperties.java ++++ b/net/minecraft/client/renderer/item/properties/numeric/RangeSelectItemModelProperties.java +@@ -23,5 +_,7 @@ + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("use_cycle"), UseCycle.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("use_duration"), UseDuration.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("count"), Count.MAP_CODEC); ++ ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterRangeSelectItemModelPropertyEvent(ID_MAPPER)); + } + } diff --git a/patches/net/minecraft/client/renderer/item/properties/select/SelectItemModelProperties.java.patch b/patches/net/minecraft/client/renderer/item/properties/select/SelectItemModelProperties.java.patch new file mode 100644 index 0000000000..7ba6478101 --- /dev/null +++ b/patches/net/minecraft/client/renderer/item/properties/select/SelectItemModelProperties.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/renderer/item/properties/select/SelectItemModelProperties.java ++++ b/net/minecraft/client/renderer/item/properties/select/SelectItemModelProperties.java +@@ -21,5 +_,7 @@ + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("local_time"), LocalTime.TYPE); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("context_entity_type"), ContextEntityType.TYPE); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("context_dimension"), ContextDimension.TYPE); ++ ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterSelectItemModelPropertyEvent(ID_MAPPER)); + } + } diff --git a/patches/net/minecraft/client/renderer/special/SpecialModelRenderers.java.patch b/patches/net/minecraft/client/renderer/special/SpecialModelRenderers.java.patch new file mode 100644 index 0000000000..ea6de530f0 --- /dev/null +++ b/patches/net/minecraft/client/renderer/special/SpecialModelRenderers.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/client/renderer/special/SpecialModelRenderers.java ++++ b/net/minecraft/client/renderer/special/SpecialModelRenderers.java +@@ -171,6 +_,8 @@ + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("decorated_pot"), DecoratedPotSpecialRenderer.Unbaked.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("standing_sign"), StandingSignSpecialRenderer.Unbaked.MAP_CODEC); + ID_MAPPER.put(ResourceLocation.withDefaultNamespace("hanging_sign"), HangingSignSpecialRenderer.Unbaked.MAP_CODEC); ++ ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterSpecialModelRendererEvent(ID_MAPPER)); + } + + public static Map> createBlockRenderers(EntityModelSet p_387779_) { diff --git a/patches/net/minecraft/client/renderer/texture/AbstractTexture.java.patch b/patches/net/minecraft/client/renderer/texture/AbstractTexture.java.patch index ce14e13dcf..ad9784c4ea 100644 --- a/patches/net/minecraft/client/renderer/texture/AbstractTexture.java.patch +++ b/patches/net/minecraft/client/renderer/texture/AbstractTexture.java.patch @@ -1,11 +1,15 @@ --- a/net/minecraft/client/renderer/texture/AbstractTexture.java +++ b/net/minecraft/client/renderer/texture/AbstractTexture.java -@@ -15,9 +_,13 @@ +@@ -12,6 +_,8 @@ public static final int NOT_ASSIGNED = -1; protected int id = -1; protected boolean defaultBlur; + protected boolean blur; + protected boolean mipmap; + private int wrapS = 10497; + private int wrapT = 10497; + private int minFilter = 9986; +@@ -51,6 +_,8 @@ public void setFilter(boolean p_117961_, boolean p_117962_) { RenderSystem.assertOnRenderThreadOrInit(); @@ -14,10 +18,10 @@ int i; int j; if (p_117961_) { -@@ -31,6 +_,20 @@ - this.bind(); - GlStateManager._texParameter(3553, 10241, i); - GlStateManager._texParameter(3553, 10240, j); +@@ -75,6 +_,20 @@ + this.magFilter = j; + } + } + } + + // FORGE: This seems to have been stripped out, but we need it diff --git a/patches/net/minecraft/client/renderer/texture/SpriteContents.java.patch b/patches/net/minecraft/client/renderer/texture/SpriteContents.java.patch index 115bee7e58..5505e4800a 100644 --- a/patches/net/minecraft/client/renderer/texture/SpriteContents.java.patch +++ b/patches/net/minecraft/client/renderer/texture/SpriteContents.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/texture/SpriteContents.java +++ b/net/minecraft/client/renderer/texture/SpriteContents.java -@@ -46,6 +_,10 @@ +@@ -47,6 +_,10 @@ this.byMipLevel = new NativeImage[]{this.originalImage}; } @@ -11,18 +11,16 @@ public void increaseMipLevel(int p_248864_) { try { this.byMipLevel = MipmapGenerator.generateMipLevels(this.byMipLevel, p_248864_); -@@ -120,6 +_,10 @@ +@@ -130,6 +_,8 @@ void upload(int p_248895_, int p_250245_, int p_250458_, int p_251337_, NativeImage[] p_248825_) { for (int i = 0; i < this.byMipLevel.length; i++) { -+ // Forge: Skip uploading if the texture would be made invalid by mip level -+ if ((this.width >> i) <= 0 || (this.height >> i) <= 0) -+ break; -+ - p_248825_[i] - .upload(i, p_248895_ >> i, p_250245_ >> i, p_250458_ >> i, p_251337_ >> i, this.width >> i, this.height >> i, this.byMipLevel.length > 1, false); ++ // NeoForge: Skip uploading if the texture would be made invalid by mip level ++ if ((this.width >> i) <= 0 || (this.height >> i) <= 0) break; + p_248825_[i].upload(i, p_248895_ >> i, p_250245_ >> i, p_250458_ >> i, p_251337_ >> i, this.width >> i, this.height >> i, false); } -@@ -242,7 +_,8 @@ + } +@@ -244,7 +_,8 @@ for (int i = 0; i < this.activeFrame.length; i++) { int j = SpriteContents.this.width >> i; int k = SpriteContents.this.height >> i; @@ -32,7 +30,7 @@ } } -@@ -257,6 +_,9 @@ +@@ -259,6 +_,9 @@ for (int k = 0; k < this.activeFrame.length; k++) { int l = SpriteContents.this.width >> k; int i1 = SpriteContents.this.height >> k; diff --git a/patches/net/minecraft/client/renderer/texture/TextureAtlas.java.patch b/patches/net/minecraft/client/renderer/texture/TextureAtlas.java.patch index ffc654c26a..f0b8aec905 100644 --- a/patches/net/minecraft/client/renderer/texture/TextureAtlas.java.patch +++ b/patches/net/minecraft/client/renderer/texture/TextureAtlas.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/texture/TextureAtlas.java +++ b/net/minecraft/client/renderer/texture/TextureAtlas.java -@@ -87,6 +_,8 @@ +@@ -82,6 +_,8 @@ this.sprites = List.copyOf(list); this.animatedTextures = List.copyOf(list1); } @@ -9,10 +9,10 @@ } @Override -@@ -168,5 +_,9 @@ +@@ -159,5 +_,9 @@ - public void updateFilter(SpriteLoader.Preparations p_251993_) { - this.setFilter(false, p_251993_.mipLevel() > 0); + int getHeight() { + return this.height; + } + + public Map getTextures() { diff --git a/patches/net/minecraft/client/renderer/texture/atlas/SpriteResourceLoader.java.patch b/patches/net/minecraft/client/renderer/texture/atlas/SpriteResourceLoader.java.patch index 9051e59ca1..c281c0ab4b 100644 --- a/patches/net/minecraft/client/renderer/texture/atlas/SpriteResourceLoader.java.patch +++ b/patches/net/minecraft/client/renderer/texture/atlas/SpriteResourceLoader.java.patch @@ -1,24 +1,21 @@ --- a/net/minecraft/client/renderer/texture/atlas/SpriteResourceLoader.java +++ b/net/minecraft/client/renderer/texture/atlas/SpriteResourceLoader.java -@@ -24,7 +_,7 @@ +@@ -25,7 +_,7 @@ Logger LOGGER = LogUtils.getLogger(); - static SpriteResourceLoader create(Collection> p_296204_) { -- return (p_293680_, p_293681_) -> { -+ return (p_293680_, p_293681_, constructor) -> { + static SpriteResourceLoader create(Collection> p_296204_) { +- return (p_389362_, p_389363_) -> { ++ return (p_389362_, p_389363_, constructor) -> { ResourceMetadata resourcemetadata; try { - resourcemetadata = p_293681_.metadata().copySections(p_296204_); -@@ -45,7 +_,7 @@ - .orElse(AnimationMetadataSection.EMPTY); - FrameSize framesize = animationmetadatasection.calculateFrameSize(nativeimage.getWidth(), nativeimage.getHeight()); - if (Mth.isMultipleOf(nativeimage.getWidth(), framesize.width()) && Mth.isMultipleOf(nativeimage.getHeight(), framesize.height())) { -- return new SpriteContents(p_293680_, framesize, nativeimage, resourcemetadata); -+ return constructor.create(p_293680_, framesize, nativeimage, resourcemetadata); - } else { - LOGGER.error( - "Image {} size {},{} is not multiple of frame size {},{}", -@@ -62,5 +_,10 @@ + resourcemetadata = p_389363_.metadata().copySections(p_296204_); +@@ -62,10 +_,15 @@ + framesize = new FrameSize(nativeimage.getWidth(), nativeimage.getHeight()); + } + +- return new SpriteContents(p_389362_, framesize, nativeimage, resourcemetadata); ++ return constructor.create(p_389362_, framesize, nativeimage, resourcemetadata); + }; } @Nullable diff --git a/patches/net/minecraft/client/resources/model/BakedModel.java.patch b/patches/net/minecraft/client/resources/model/BakedModel.java.patch index 15490942f9..e2ff981485 100644 --- a/patches/net/minecraft/client/resources/model/BakedModel.java.patch +++ b/patches/net/minecraft/client/resources/model/BakedModel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/resources/model/BakedModel.java +++ b/net/minecraft/client/resources/model/BakedModel.java -@@ -13,7 +_,9 @@ +@@ -12,7 +_,9 @@ import net.neoforged.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) @@ -11,18 +11,15 @@ List getQuads(@Nullable BlockState p_235039_, @Nullable Direction p_235040_, RandomSource p_235041_); boolean useAmbientOcclusion(); -@@ -24,9 +_,13 @@ +@@ -21,7 +_,11 @@ - boolean isCustomRenderer(); + boolean usesBlockLight(); + /**@deprecated Forge: Use {@link #getParticleIcon(net.neoforged.neoforge.client.model.data.ModelData)}*/ + @Deprecated TextureAtlasSprite getParticleIcon(); -- ItemTransforms getTransforms(); + /**@deprecated Forge: Use {@link #applyTransform(net.minecraft.world.item.ItemDisplayContext, com.mojang.blaze3d.vertex.PoseStack, boolean)} instead */ + @Deprecated -+ default ItemTransforms getTransforms() { return ItemTransforms.NO_TRANSFORMS; } - - default BakedOverrides overrides() { - return BakedOverrides.EMPTY; + ItemTransforms getTransforms(); + } diff --git a/patches/net/minecraft/client/resources/model/DelegateBakedModel.java.patch b/patches/net/minecraft/client/resources/model/DelegateBakedModel.java.patch index 5c8eacbbe9..572e01296c 100644 --- a/patches/net/minecraft/client/resources/model/DelegateBakedModel.java.patch +++ b/patches/net/minecraft/client/resources/model/DelegateBakedModel.java.patch @@ -28,7 +28,7 @@ public boolean isGui3d() { return this.parent.isGui3d(); } -@@ -45,12 +_,44 @@ +@@ -40,12 +_,44 @@ } @Override @@ -64,8 +64,8 @@ + } + + @Override -+ public List getRenderTypes(net.minecraft.world.item.ItemStack itemStack) { -+ return this.parent.getRenderTypes(itemStack); ++ public net.minecraft.client.renderer.RenderType getRenderType(net.minecraft.world.item.ItemStack itemStack) { ++ return this.parent.getRenderType(itemStack); + } + + @Override diff --git a/patches/net/minecraft/client/resources/model/ItemModel.java.patch b/patches/net/minecraft/client/resources/model/ItemModel.java.patch deleted file mode 100644 index 10d96b4e0a..0000000000 --- a/patches/net/minecraft/client/resources/model/ItemModel.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/net/minecraft/client/resources/model/ItemModel.java -+++ b/net/minecraft/client/resources/model/ItemModel.java -@@ -29,11 +_,11 @@ - - @Override - public BakedModel bake(ModelBaker p_371426_, Function p_371750_, ModelState p_371674_) { -- BakedModel bakedmodel = p_371426_.bake(this.id, p_371674_); -+ BakedModel bakedmodel = p_371426_.bake(this.id, p_371674_, p_371750_); - if (this.overrides.isEmpty()) { - return bakedmodel; - } else { -- BakedOverrides bakedoverrides = new BakedOverrides(p_371426_, this.overrides); -+ BakedOverrides bakedoverrides = new BakedOverrides(p_371426_, this.overrides, p_371750_); - return new ItemModel.BakedModelWithOverrides(bakedmodel, bakedoverrides); - } - } diff --git a/patches/net/minecraft/client/resources/model/ModelBaker.java.patch b/patches/net/minecraft/client/resources/model/ModelBaker.java.patch index 36016793f0..db7b52b0bf 100644 --- a/patches/net/minecraft/client/resources/model/ModelBaker.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelBaker.java.patch @@ -1,14 +1,11 @@ --- a/net/minecraft/client/resources/model/ModelBaker.java +++ b/net/minecraft/client/resources/model/ModelBaker.java -@@ -5,6 +_,10 @@ +@@ -6,7 +_,7 @@ import net.neoforged.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) -public interface ModelBaker { +public interface ModelBaker extends net.neoforged.neoforge.client.extensions.IModelBakerExtension { -+ /** -+ * @deprecated Forge: Use {@link #bake(ResourceLocation, ModelState, java.util.function.Function)} instead. -+ */ -+ @Deprecated BakedModel bake(ResourceLocation p_250776_, ModelState p_251280_); - } + + SpriteGetter sprites(); diff --git a/patches/net/minecraft/client/resources/model/ModelBakery.java.patch b/patches/net/minecraft/client/resources/model/ModelBakery.java.patch index ed116d3ffe..694309384e 100644 --- a/patches/net/minecraft/client/resources/model/ModelBakery.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelBakery.java.patch @@ -1,52 +1,84 @@ --- a/net/minecraft/client/resources/model/ModelBakery.java +++ b/net/minecraft/client/resources/model/ModelBakery.java -@@ -94,25 +_,46 @@ - } - - @Override -+ @org.jetbrains.annotations.Nullable -+ public UnbakedModel getTopLevelModel(ModelResourceLocation location) { -+ return topModels.get(location); -+ } -+ -+ @Override -+ public Function getModelTextureGetter() { -+ return this.modelTextureGetter; -+ } +@@ -46,19 +_,36 @@ + private final Map clientInfos; + final Map unbakedPlainModels; + final UnbakedModel missingModel; ++ private final Map standaloneModels; + -+ @Override - public BakedModel bake(ResourceLocation p_252176_, ModelState p_249765_) { -+ return bake(p_252176_, p_249765_, this.modelTextureGetter); -+ } -+ -+ @Override -+ public BakedModel bake(ResourceLocation p_252176_, ModelState p_249765_, Function sprites) { - ModelBakery.BakedCacheKey modelbakery$bakedcachekey = new ModelBakery.BakedCacheKey(p_252176_, p_249765_.getRotation(), p_249765_.isUvLocked()); - BakedModel bakedmodel = ModelBakery.this.bakedCache.get(modelbakery$bakedcachekey); - if (bakedmodel != null) { - return bakedmodel; - } else { - UnbakedModel unbakedmodel = this.getModel(p_252176_); -- BakedModel bakedmodel1 = this.bakeUncached(unbakedmodel, p_249765_); -+ BakedModel bakedmodel1 = this.bakeUncached(unbakedmodel, p_249765_, sprites); - ModelBakery.this.bakedCache.put(modelbakery$bakedcachekey, bakedmodel1); - return bakedmodel1; - } - } ++ /** ++ * @deprecated Neo: use {@link #ModelBakery(EntityModelSet, Map, Map, Map, UnbakedModel, Map)} ModelBakery instead} ++ */ ++ @Deprecated ++ public ModelBakery( ++ EntityModelSet p_388903_, ++ Map p_251087_, ++ Map p_250416_, ++ Map p_388404_, ++ UnbakedModel p_360944_ ++ ) { ++ this(p_388903_, p_251087_, p_250416_, p_388404_, p_360944_, Map.of()); ++ } - BakedModel bakeUncached(UnbakedModel p_352386_, ModelState p_352194_) { -+ return bakeUncached(p_352386_, p_352194_, this.modelTextureGetter); -+ } -+ -+ @Override -+ public BakedModel bakeUncached(UnbakedModel p_352386_, ModelState p_352194_, Function sprites) { - if (p_352386_ instanceof BlockModel blockmodel && blockmodel.getRootModel() == SpecialModels.GENERATED_MARKER) { -- return ModelBakery.ITEM_MODEL_GENERATOR.generateBlockModel(this.modelTextureGetter, blockmodel).bake(this.modelTextureGetter, p_352194_, false); -+ return ModelBakery.ITEM_MODEL_GENERATOR.generateBlockModel(sprites, blockmodel).bake(sprites, p_352194_, false); + public ModelBakery( + EntityModelSet p_388903_, + Map p_251087_, + Map p_250416_, + Map p_388404_, +- UnbakedModel p_360944_ ++ UnbakedModel p_360944_, ++ Map standaloneModels + ) { + this.entityModelSet = p_388903_; + this.unbakedBlockStateModels = p_251087_; + this.clientInfos = p_250416_; + this.unbakedPlainModels = p_388404_; + this.missingModel = p_360944_; ++ this.standaloneModels = standaloneModels; + } + + public ModelBakery.BakingResult bakeModels(ModelBakery.TextureGetter p_352431_) { +@@ -92,7 +_,18 @@ + LOGGER.warn("Unable to bake item model: '{}'", p_390101_, exception); } + }); +- return new ModelBakery.BakingResult(bakedmodel, map, itemmodel, map1, map2); ++ Map bakedStandaloneModels = new HashMap<>(this.standaloneModels.size()); ++ this.standaloneModels.forEach((location, model) -> { ++ try { ++ ModelDebugName debugName = () -> location + "#standalone"; ++ ModelBakerImpl modelBaker = new ModelBakerImpl(p_352431_, debugName); ++ BakedModel bakedModel = UnbakedModel.bakeWithTopModelValues(model, modelBaker, BlockModelRotation.X0_Y0); ++ bakedStandaloneModels.put(location, bakedModel); ++ } catch (Exception exception) { ++ LOGGER.warn("Unable to bake standalone model: '{}': {}", location, exception); ++ } ++ }); ++ return new ModelBakery.BakingResult(bakedmodel, map, itemmodel, map1, map2, bakedStandaloneModels); + } -- return p_352386_.bake(this, this.modelTextureGetter, p_352194_); -+ return p_352386_.bake(this, sprites, p_352194_); - } + @OnlyIn(Dist.CLIENT) +@@ -105,8 +_,22 @@ + Map blockStateModels, + ItemModel missingItemModel, + Map itemStackModels, +- Map itemProperties ++ Map itemProperties, ++ Map standaloneModels + ) { ++ /** ++ * @deprecated Neo: use {@link #BakingResult(BakedModel, Map, ItemModel, Map, Map, Map)}} instead ++ */ ++ @Deprecated ++ public BakingResult( ++ BakedModel missingModel, ++ Map blockStateModels, ++ ItemModel missingItemModel, ++ Map itemStackModels, ++ Map itemProperties ++ ) { ++ this(missingModel, blockStateModels, missingItemModel, itemStackModels, itemProperties, Map.of()); ++ } } + @OnlyIn(Dist.CLIENT) diff --git a/patches/net/minecraft/client/resources/model/ModelDiscovery.java.patch b/patches/net/minecraft/client/resources/model/ModelDiscovery.java.patch index 7c9de8482a..dba9824817 100644 --- a/patches/net/minecraft/client/resources/model/ModelDiscovery.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelDiscovery.java.patch @@ -1,26 +1,23 @@ --- a/net/minecraft/client/resources/model/ModelDiscovery.java +++ b/net/minecraft/client/resources/model/ModelDiscovery.java -@@ -49,6 +_,7 @@ - }); - set.add(ItemRenderer.TRIDENT_MODEL); - set.add(ItemRenderer.SPYGLASS_MODEL); -+ net.neoforged.neoforge.client.ClientHooks.onRegisterAdditionalModels(set); - return set; +@@ -22,6 +_,7 @@ + final UnbakedModel missingModel; + private final List topModels = new ArrayList<>(); + private final Map referencedModels = new HashMap<>(); ++ final Map standaloneModels = new HashMap<>(); + + public ModelDiscovery(Map p_360750_, UnbakedModel p_365355_) { + this.inputModels = p_360750_; +@@ -31,6 +_,12 @@ + + public void registerSpecialModels() { + this.referencedModels.put(ItemModelGenerator.GENERATED_ITEM_MODEL_ID, new ItemModelGenerator()); ++ ++ net.neoforged.neoforge.client.ClientHooks.onRegisterAdditionalModels(path -> { ++ UnbakedModel model = getBlockModel(path); ++ this.addRoot(model); ++ this.standaloneModels.put(path, model); ++ }); } -@@ -77,6 +_,15 @@ - } - } - ); -+ // Neo: ensure standalone models registered in ModelEvent.RegisterAdditional are loaded -+ var it = set.iterator(); -+ while (it.hasNext()) { -+ ModelResourceLocation mrl = it.next(); -+ if (mrl.getVariant().equals(ModelResourceLocation.STANDALONE_VARIANT)) { -+ registerTopModel(mrl, getBlockModel(mrl.id())); -+ it.remove(); -+ } -+ } - if (!set.isEmpty()) { - LOGGER.warn("Missing mandatory models: {}", set.stream().map(p_370354_ -> "\n\t" + p_370354_).collect(Collectors.joining())); - } + public void addRoot(ResolvableModel p_388596_) { diff --git a/patches/net/minecraft/client/resources/model/ModelManager.java.patch b/patches/net/minecraft/client/resources/model/ModelManager.java.patch index 8896f83c2e..0586b6732f 100644 --- a/patches/net/minecraft/client/resources/model/ModelManager.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelManager.java.patch @@ -1,18 +1,10 @@ --- a/net/minecraft/client/resources/model/ModelManager.java +++ b/net/minecraft/client/resources/model/ModelManager.java -@@ -71,18 +_,20 @@ - TextureAtlas.LOCATION_BLOCKS, - ResourceLocation.withDefaultNamespace("blocks") - ); -- private Map bakedRegistry; -+ private Map bakedRegistry = new java.util.HashMap<>(); - private final AtlasSet atlases; - private final BlockModelShaper blockModelShaper; - private final BlockColors blockColors; - private int maxMipmapLevels; +@@ -83,11 +_,13 @@ private BakedModel missingModel; - private Object2IntMap modelGroups; -+ private ModelBakery modelBakery; + private ItemModel missingItemModel; + private Object2IntMap modelGroups = Object2IntMaps.emptyMap(); ++ private final java.util.concurrent.atomic.AtomicReference modelBakery = new java.util.concurrent.atomic.AtomicReference<>(null); public ModelManager(TextureManager p_119406_, BlockColors p_119407_, int p_119408_) { this.blockColors = p_119407_; @@ -22,33 +14,62 @@ this.atlases = new AtlasSet(VANILLA_ATLASES, p_119406_); } -@@ -102,6 +_,7 @@ +@@ -115,6 +_,7 @@ public final CompletableFuture reload( PreparableReloadListener.PreparationBarrier p_249079_, ResourceManager p_251134_, Executor p_250550_, Executor p_249221_ ) { -+ net.neoforged.neoforge.client.model.geometry.GeometryLoaderManager.init(); ++ net.neoforged.neoforge.client.model.UnbakedModelParser.init(); UnbakedModel unbakedmodel = MissingBlockModel.missingModel(); - BlockStateModelLoader blockstatemodelloader = new BlockStateModelLoader(unbakedmodel); - CompletableFuture> completablefuture = loadBlockModels(p_251134_, p_250550_); -@@ -258,6 +_,8 @@ - .collect(Collectors.joining("\n")) + CompletableFuture completablefuture = CompletableFuture.supplyAsync(EntityModelSet::vanilla, p_250550_); + CompletableFuture completablefuture1 = completablefuture.thenApplyAsync(SpecialBlockModelRenderer::vanilla, p_250550_); +@@ -154,8 +_,10 @@ + completablefuture3.join().plainModels(), + completablefuture4.join().contents(), + modeldiscovery.getReferencedModels(), +- unbakedmodel ++ unbakedmodel, ++ modeldiscovery.standaloneModels + ); ++ this.modelBakery.set(modelbakery); + return loadModels(Profiler.get(), map1, modelbakery, object2intmap, completablefuture.join(), completablefuture1.join()); + }, + p_250550_ +@@ -169,7 +_,7 @@ + return CompletableFuture.>supplyAsync(() -> MODEL_LISTER.listMatchingResources(p_251361_), p_252189_) + .thenCompose( + p_250597_ -> { +- List>> list = new ArrayList<>(p_250597_.size()); ++ List>> list = new ArrayList<>(p_250597_.size()); + + for (Entry entry : p_250597_.entrySet()) { + list.add(CompletableFuture.supplyAsync(() -> { +@@ -178,7 +_,7 @@ + try { + Pair pair; + try (Reader reader = entry.getValue().openAsReader()) { +- pair = Pair.of(resourcelocation, BlockModel.fromStream(reader)); ++ pair = Pair.of(resourcelocation, net.neoforged.neoforge.client.model.UnbakedModelParser.parse(reader)); + } + + return pair; +@@ -261,6 +_,8 @@ + p_386267_.stream().sorted().map(p_386265_ -> " " + p_386265_).collect(Collectors.joining("\n")) ) ); -+ p_252136_.popPush("forge_modify_baking_result"); -+ net.neoforged.neoforge.client.ClientHooks.onModifyBakingResult(p_248945_.getBakedTopLevelModels(), p_250646_, p_248945_); ++ p_252136_.push("neoforge_modify_baking_result"); ++ net.neoforged.neoforge.client.ClientHooks.onModifyBakingResult(modelbakery$bakingresult, p_250646_, p_248945_); p_252136_.popPush("dispatch"); - Map map = p_248945_.getBakedTopLevelModels(); - BakedModel bakedmodel = map.get(MissingBlockModel.VARIANT); -@@ -289,6 +_,8 @@ - this.bakedRegistry = modelbakery.getBakedTopLevelModels(); + Map map = createBlockStateToModelDispatch(modelbakery$bakingresult.blockStateModels(), modelbakery$bakingresult.missingModel()); + CompletableFuture completablefuture = CompletableFuture.allOf( +@@ -304,6 +_,7 @@ this.modelGroups = p_248996_.modelGroups; - this.missingModel = p_248996_.missingModel; -+ this.modelBakery = modelbakery; -+ net.neoforged.neoforge.client.ClientHooks.onModelBake(this, this.bakedRegistry, modelbakery); + this.missingModel = modelbakery$bakingresult.missingModel(); + this.missingItemModel = modelbakery$bakingresult.missingItemModel(); ++ net.neoforged.neoforge.client.ClientHooks.onModelBake(this, modelbakery$bakingresult, this.modelBakery.get()); p_251960_.popPush("cache"); this.blockModelShaper.replaceCache(p_248996_.modelCache); - p_251960_.pop(); -@@ -313,6 +_,7 @@ + this.specialBlockModelRenderer = p_248996_.specialBlockModelRenderer; +@@ -330,6 +_,7 @@ } public TextureAtlas getAtlas(ResourceLocation p_119429_) { @@ -56,14 +77,13 @@ return this.atlases.getAtlas(p_119429_); } -@@ -323,6 +_,10 @@ - - public void updateMaxMipLevel(int p_119411_) { - this.maxMipmapLevels = p_119411_; +@@ -360,5 +_,9 @@ + SpecialBlockModelRenderer specialBlockModelRenderer, + CompletableFuture readyForUpload + ) { + } + + public ModelBakery getModelBakery() { -+ return com.google.common.base.Preconditions.checkNotNull(modelBakery, "Attempted to query model bakery before it has been initialized."); ++ return this.modelBakery.get(); } - - @OnlyIn(Dist.CLIENT) + } diff --git a/patches/net/minecraft/client/resources/model/ModelResourceLocation.java.patch b/patches/net/minecraft/client/resources/model/ModelResourceLocation.java.patch deleted file mode 100644 index 85d4fc00bc..0000000000 --- a/patches/net/minecraft/client/resources/model/ModelResourceLocation.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/net/minecraft/client/resources/model/ModelResourceLocation.java -+++ b/net/minecraft/client/resources/model/ModelResourceLocation.java -@@ -8,6 +_,7 @@ - @OnlyIn(Dist.CLIENT) - public record ModelResourceLocation(ResourceLocation id, String variant) { - public static final String INVENTORY_VARIANT = "inventory"; -+ public static final String STANDALONE_VARIANT = "standalone"; - - public ModelResourceLocation(ResourceLocation id, String variant) { - variant = lowercaseVariant(variant); -@@ -17,6 +_,14 @@ - - public static ModelResourceLocation inventory(ResourceLocation p_352141_) { - return new ModelResourceLocation(p_352141_, "inventory"); -+ } -+ -+ /** -+ * Construct a {@code ModelResourceLocation} for use in the {@link net.neoforged.neoforge.client.event.ModelEvent.RegisterAdditional} -+ * to load a model at the given path directly instead of going through blockstates or item model auto-prefixing. -+ */ -+ public static ModelResourceLocation standalone(ResourceLocation id) { -+ return new ModelResourceLocation(id, STANDALONE_VARIANT); - } - - private static String lowercaseVariant(String p_248567_) { diff --git a/patches/net/minecraft/client/resources/model/SimpleBakedModel.java.patch b/patches/net/minecraft/client/resources/model/SimpleBakedModel.java.patch index 41044226e2..2e6c64d644 100644 --- a/patches/net/minecraft/client/resources/model/SimpleBakedModel.java.patch +++ b/patches/net/minecraft/client/resources/model/SimpleBakedModel.java.patch @@ -1,18 +1,18 @@ --- a/net/minecraft/client/resources/model/SimpleBakedModel.java +++ b/net/minecraft/client/resources/model/SimpleBakedModel.java -@@ -25,7 +_,11 @@ - protected final boolean usesBlockLight; - protected final TextureAtlasSprite particleIcon; - protected final ItemTransforms transforms; +@@ -29,7 +_,11 @@ + private final boolean usesBlockLight; + private final TextureAtlasSprite particleIcon; + private final ItemTransforms transforms; + @Nullable protected final net.neoforged.neoforge.client.ChunkRenderTypeSet blockRenderTypes; -+ @Nullable protected final List itemRenderTypes; ++ @Nullable protected final net.minecraft.client.renderer.RenderType itemRenderType; + /** @deprecated Forge: Use {@linkplain #SimpleBakedModel(List, Map, boolean, boolean, boolean, TextureAtlasSprite, ItemTransforms, net.neoforged.neoforge.client.RenderTypeGroup) variant with RenderTypeGroup} **/ + @Deprecated public SimpleBakedModel( List p_119489_, Map> p_119490_, -@@ -35,6 +_,19 @@ +@@ -39,6 +_,19 @@ TextureAtlasSprite p_119494_, ItemTransforms p_119495_ ) { @@ -32,16 +32,61 @@ this.unculledFaces = p_119489_; this.culledFaces = p_119490_; this.hasAmbientOcclusion = p_119491_; -@@ -42,6 +_,8 @@ +@@ -46,8 +_,14 @@ this.usesBlockLight = p_119492_; this.particleIcon = p_119494_; this.transforms = p_119495_; + this.blockRenderTypes = !renderTypes.isEmpty() ? net.neoforged.neoforge.client.ChunkRenderTypeSet.of(renderTypes.block()) : null; -+ this.itemRenderTypes = !renderTypes.isEmpty() ? List.of(renderTypes.entity()) : null; ++ this.itemRenderType = !renderTypes.isEmpty() ? renderTypes.entity() : null; } - @Override -@@ -79,6 +_,20 @@ ++ /** ++ * @deprecated Neo: Use {@linkplain #bakeElements(List, TextureSlots, SpriteGetter, ModelState, boolean, boolean, boolean, ItemTransforms, com.mojang.math.Transformation, net.neoforged.neoforge.client.RenderTypeGroup) variant with Transformation and RenderTypeGroup support} ++ */ ++ @Deprecated + public static BakedModel bakeElements( + List p_387963_, + TextureSlots p_388507_, +@@ -58,10 +_,29 @@ + boolean p_386706_, + ItemTransforms p_388032_ + ) { ++ return bakeElements(p_387963_, p_388507_, p_387357_, p_388846_, p_386975_, p_388143_, p_386706_, p_388032_, com.mojang.math.Transformation.identity(), net.neoforged.neoforge.client.RenderTypeGroup.EMPTY); ++ } ++ ++ public static BakedModel bakeElements( ++ List p_387963_, ++ TextureSlots p_388507_, ++ SpriteGetter p_387357_, ++ ModelState p_388846_, ++ boolean p_386975_, ++ boolean p_388143_, ++ boolean p_386706_, ++ ItemTransforms p_388032_, ++ com.mojang.math.Transformation rootTransform, ++ net.neoforged.neoforge.client.RenderTypeGroup renderTypes ++ ) { + TextureAtlasSprite textureatlassprite = findSprite(p_387357_, p_388507_, "particle"); + SimpleBakedModel.Builder simplebakedmodel$builder = new SimpleBakedModel.Builder(p_386975_, p_388143_, p_386706_, p_388032_) + .particle(textureatlassprite); + ++ if (!rootTransform.isIdentity()) { ++ p_388846_ = net.neoforged.neoforge.client.model.UnbakedElementsHelper.composeRootTransformIntoModelState(p_388846_, rootTransform); ++ } ++ + for (BlockElement blockelement : p_387963_) { + for (Direction direction : blockelement.faces.keySet()) { + BlockElementFace blockelementface = blockelement.faces.get(direction); +@@ -77,7 +_,7 @@ + } + } + +- return simplebakedmodel$builder.build(); ++ return simplebakedmodel$builder.build(renderTypes); + } + + public static BakedQuad bakeFace( +@@ -123,6 +_,20 @@ return this.transforms; } @@ -53,16 +98,16 @@ + } + + @Override -+ public List getRenderTypes(net.minecraft.world.item.ItemStack itemStack) { -+ if (itemRenderTypes != null) -+ return itemRenderTypes; -+ return BakedModel.super.getRenderTypes(itemStack); ++ public net.minecraft.client.renderer.RenderType getRenderType(net.minecraft.world.item.ItemStack itemStack) { ++ if (itemRenderType != null) ++ return itemRenderType; ++ return BakedModel.super.getRenderType(itemStack); + } + @OnlyIn(Dist.CLIENT) public static class Builder { private final ImmutableList.Builder unculledFaces = ImmutableList.builder(); -@@ -124,7 +_,13 @@ +@@ -164,7 +_,13 @@ return this; } @@ -76,7 +121,7 @@ if (this.particleIcon == null) { throw new RuntimeException("Missing particle!"); } else { -@@ -136,7 +_,8 @@ +@@ -176,7 +_,8 @@ this.usesBlockLight, this.isGui3d, this.particleIcon, diff --git a/patches/net/minecraft/client/resources/model/UnbakedModel.java.patch b/patches/net/minecraft/client/resources/model/UnbakedModel.java.patch new file mode 100644 index 0000000000..965a6a6304 --- /dev/null +++ b/patches/net/minecraft/client/resources/model/UnbakedModel.java.patch @@ -0,0 +1,57 @@ +--- a/net/minecraft/client/resources/model/UnbakedModel.java ++++ b/net/minecraft/client/resources/model/UnbakedModel.java +@@ -9,10 +_,14 @@ + import net.neoforged.api.distmarker.OnlyIn; + + @OnlyIn(Dist.CLIENT) +-public interface UnbakedModel extends ResolvableModel { ++public interface UnbakedModel extends ResolvableModel, net.neoforged.neoforge.client.extensions.IUnbakedModelExtension { + boolean DEFAULT_AMBIENT_OCCLUSION = true; + UnbakedModel.GuiLight DEFAULT_GUI_LIGHT = UnbakedModel.GuiLight.SIDE; + ++ /** ++ * @deprecated Neo: use {@link #bake(TextureSlots, ModelBaker, ModelState, boolean, boolean, ItemTransforms, net.minecraft.util.context.ContextMap)} instead ++ */ ++ @Deprecated + BakedModel bake(TextureSlots p_386641_, ModelBaker p_250133_, ModelState p_119536_, boolean p_387129_, boolean p_388638_, ItemTransforms p_386911_); + + @Nullable +@@ -44,7 +_,8 @@ + boolean flag = getTopAmbientOcclusion(p_388418_); + boolean flag1 = getTopGuiLight(p_388418_).lightLikeBlock(); + ItemTransforms itemtransforms = getTopTransforms(p_388418_); +- return p_388418_.bake(textureslots, p_388525_, p_386740_, flag, flag1, itemtransforms); ++ var additionalProperties = net.neoforged.neoforge.client.extensions.IUnbakedModelExtension.getTopAdditionalProperties(p_388418_); ++ return p_388418_.bake(textureslots, p_388525_, p_386740_, flag, flag1, itemtransforms, additionalProperties); + } + + static TextureSlots getTopTextureSlots(UnbakedModel p_387784_, ModelDebugName p_388419_) { +@@ -109,7 +_,16 @@ + ItemTransform itemtransform5 = getTopTransform(p_388720_, ItemDisplayContext.GUI); + ItemTransform itemtransform6 = getTopTransform(p_388720_, ItemDisplayContext.GROUND); + ItemTransform itemtransform7 = getTopTransform(p_388720_, ItemDisplayContext.FIXED); +- return new ItemTransforms(itemtransform, itemtransform1, itemtransform2, itemtransform3, itemtransform4, itemtransform5, itemtransform6, itemtransform7); ++ com.google.common.collect.ImmutableMap.Builder moddedTransforms = com.google.common.collect.ImmutableMap.builder(); ++ for (ItemDisplayContext context : ItemDisplayContext.values()) { ++ if (context.isModded()) { ++ ItemTransform transform = getTopTransform(p_388720_, context); ++ if (transform != ItemTransform.NO_TRANSFORM) { ++ moddedTransforms.put(context, transform); ++ } ++ } ++ } ++ return new ItemTransforms(itemtransform, itemtransform1, itemtransform2, itemtransform3, itemtransform4, itemtransform5, itemtransform6, itemtransform7, moddedTransforms.build()); + } + + @OnlyIn(Dist.CLIENT) +@@ -135,6 +_,10 @@ + + public boolean lightLikeBlock() { + return this == SIDE; ++ } ++ ++ public String getSerializedName() { ++ return name; + } + } + } diff --git a/patches/net/minecraft/client/sounds/MusicManager.java.patch b/patches/net/minecraft/client/sounds/MusicManager.java.patch index 578bcd60a4..3fb24324f8 100644 --- a/patches/net/minecraft/client/sounds/MusicManager.java.patch +++ b/patches/net/minecraft/client/sounds/MusicManager.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/client/sounds/MusicManager.java +++ b/net/minecraft/client/sounds/MusicManager.java -@@ -24,7 +_,15 @@ +@@ -25,7 +_,15 @@ } public void tick() { -- Music music = this.minecraft.getSituationalMusic(); -+ Music music = net.neoforged.neoforge.client.ClientHooks.selectMusic(this.minecraft.getSituationalMusic(), this.currentMusic); -+ if (music == null) { +- MusicInfo musicinfo = this.minecraft.getSituationalMusic(); ++ MusicInfo musicinfo = net.neoforged.neoforge.client.ClientHooks.selectMusic(this.minecraft.getSituationalMusic(), this.currentMusic); ++ if (musicinfo == null) { + if (this.currentMusic != null) { + this.stopPlaying(); + } @@ -14,6 +14,6 @@ + return; + } + - if (this.currentMusic != null) { - if (!music.getEvent().value().location().equals(this.currentMusic.getLocation()) && music.replaceCurrentMusic()) { - this.minecraft.getSoundManager().stop(this.currentMusic); + float f = musicinfo.volume(); + if (this.currentMusic != null && this.currentGain != f) { + boolean flag = this.fadePlaying(f); diff --git a/patches/net/minecraft/client/sounds/SoundEngine.java.patch b/patches/net/minecraft/client/sounds/SoundEngine.java.patch index 29678b9899..9f7bec62bb 100644 --- a/patches/net/minecraft/client/sounds/SoundEngine.java.patch +++ b/patches/net/minecraft/client/sounds/SoundEngine.java.patch @@ -16,7 +16,7 @@ } private synchronized void loadLibrary() { -@@ -327,7 +_,8 @@ +@@ -336,7 +_,8 @@ public void play(SoundInstance p_120313_) { if (this.loaded) { @@ -26,7 +26,7 @@ WeighedSoundEvents weighedsoundevents = p_120313_.resolve(this.soundManager); ResourceLocation resourcelocation = p_120313_.getLocation(); if (weighedsoundevents == null) { -@@ -391,19 +_,22 @@ +@@ -400,19 +_,22 @@ p_194488_.setSelfPosition(vec3); p_194488_.setRelative(flag); }); @@ -34,8 +34,8 @@ if (!flag2) { this.soundBuffers .getCompleteBuffer(sound.getPath()) - .thenAccept(p_194501_ -> channelaccess$channelhandle.execute(p_194495_ -> { - p_194495_.attachStaticBuffer(p_194501_); + .thenAccept(p_383126_ -> channelaccess$channelhandle.execute(p_194495_ -> { + p_194495_.attachStaticBuffer(p_383126_); p_194495_.play(); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.sound.PlaySoundSourceEvent(this, soundinstance, p_194495_)); })); @@ -44,8 +44,8 @@ - .getStream(sound.getPath(), flag1) + soundinstance + .getStream(this.soundBuffers, sound, flag1) - .thenAccept(p_194504_ -> channelaccess$channelhandle.execute(p_194498_ -> { - p_194498_.attachBufferStream(p_194504_); + .thenAccept(p_383033_ -> channelaccess$channelhandle.execute(p_194498_ -> { + p_194498_.attachBufferStream(p_383033_); p_194498_.play(); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.sound.PlayStreamingSourceEvent(this, soundinstance, p_194498_)); })); diff --git a/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch b/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch index dfea9ede8a..5335c0034d 100644 --- a/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch +++ b/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/component/PatchedDataComponentMap.java +++ b/net/minecraft/core/component/PatchedDataComponentMap.java -@@ -64,6 +_,7 @@ +@@ -68,6 +_,7 @@ @Nullable public T set(DataComponentType p_330791_, @Nullable T p_330369_) { @@ -8,7 +8,7 @@ this.ensureMapOwnership(); T t = this.prototype.get((DataComponentType)p_330791_); Optional optional; -@@ -197,6 +_,10 @@ +@@ -201,6 +_,10 @@ } return i; diff --git a/patches/net/minecraft/data/DataProvider.java.patch b/patches/net/minecraft/data/DataProvider.java.patch index 05ad535d98..6e4fbb1176 100644 --- a/patches/net/minecraft/data/DataProvider.java.patch +++ b/patches/net/minecraft/data/DataProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/DataProvider.java +++ b/net/minecraft/data/DataProvider.java -@@ -27,7 +_,15 @@ +@@ -28,7 +_,15 @@ import org.slf4j.Logger; public interface DataProvider { @@ -16,7 +16,7 @@ p_236070_.put("type", 0); p_236070_.put("parent", 1); p_236070_.defaultReturnValue(2); -@@ -72,7 +_,7 @@ +@@ -80,7 +_,7 @@ try (JsonWriter jsonwriter = new JsonWriter(new OutputStreamWriter(hashingoutputstream, StandardCharsets.UTF_8))) { jsonwriter.setSerializeNulls(false); diff --git a/patches/net/minecraft/data/Main.java.patch b/patches/net/minecraft/data/Main.java.patch index 4e6c37a6e7..eed2934cc4 100644 --- a/patches/net/minecraft/data/Main.java.patch +++ b/patches/net/minecraft/data/Main.java.patch @@ -1,46 +1,41 @@ --- a/net/minecraft/data/Main.java +++ b/net/minecraft/data/Main.java -@@ -86,8 +_,15 @@ - OptionSpec optionspec6 = optionparser.accepts("all", "Include all generators"); - OptionSpec optionspec7 = optionparser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated"); - OptionSpec optionspec8 = optionparser.accepts("input", "Input folder").withRequiredArg(); +@@ -73,21 +_,34 @@ + OptionSpec optionspec1 = optionparser.accepts("server", "Include server generators"); + OptionSpec optionspec2 = optionparser.accepts("dev", "Include development tools"); + OptionSpec optionspec3 = optionparser.accepts("reports", "Include data reports"); +- optionparser.accepts("validate", "Validate inputs"); ++ OptionSpec validateSpec = optionparser.accepts("validate", "Validate inputs"); + OptionSpec optionspec4 = optionparser.accepts("all", "Include all generators"); + OptionSpec optionspec5 = optionparser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated"); + OptionSpec optionspec6 = optionparser.accepts("input", "Input folder").withRequiredArg(); + OptionSpec existing = optionparser.accepts("existing", "Existing resource packs that generated resources can reference").withRequiredArg(); + OptionSpec existingMod = optionparser.accepts("existing-mod", "Existing mods that generated resources can reference the resource packs of").withRequiredArg(); + OptionSpec gameDir = optionparser.accepts("gameDir").withRequiredArg().ofType(java.io.File.class).defaultsTo(new java.io.File(".")).required(); //Need by modlauncher, so lets just eat it + OptionSpec mod = optionparser.accepts("mod", "A modid to dump").withRequiredArg().withValuesSeparatedBy(","); + OptionSpec flat = optionparser.accepts("flat", "Do not append modid prefix to output directory when generating for multiple mods"); -+ OptionSpec assetIndex = optionparser.accepts("assetIndex").withRequiredArg(); -+ OptionSpec assetsDir = optionparser.accepts("assetsDir").withRequiredArg().ofType(java.io.File.class); OptionSet optionset = optionparser.parse(p_129669_); - if (!optionset.has(optionspec) && optionset.hasOptions()) { + if (!optionset.has(optionspec) && optionset.hasOptions() && !(optionset.specs().size() == 1 && optionset.has(gameDir))) { - Path path = Paths.get(optionspec7.value(optionset)); - boolean flag = optionset.has(optionspec6); - boolean flag1 = flag || optionset.has(optionspec2); -@@ -95,9 +_,16 @@ + Path path = Paths.get(optionspec5.value(optionset)); + boolean flag = optionset.has(optionspec4); + boolean flag1 = flag || optionset.has(optionspec1); + boolean flag2 = flag || optionset.has(optionspec2); boolean flag3 = flag || optionset.has(optionspec3); - boolean flag4 = flag || optionset.has(optionspec4); - boolean flag5 = flag || optionset.has(optionspec5); -+ Collection inputs = optionset.valuesOf(optionspec8).stream().map(Paths::get).collect(Collectors.toList()); -+ Collection existingPacks = optionset.valuesOf(existing).stream().map(Paths::get).collect(Collectors.toList()); + Collection collection = optionset.valuesOf(optionspec6).stream().map(p_129659_ -> Paths.get(p_129659_)).toList(); +- DataGenerator datagenerator = new DataGenerator(path, SharedConstants.getCurrentVersion(), true); ++ Collection existingPacks = optionset.valuesOf(existing).stream().map(Paths::get).toList(); + java.util.Set existingMods = new java.util.HashSet<>(optionset.valuesOf(existingMod)); + java.util.Set mods = new java.util.HashSet<>(optionset.valuesOf(mod)); + boolean isFlat = mods.isEmpty() || optionset.has(flat); -+ net.neoforged.neoforge.data.loading.DatagenModLoader.begin(mods, path, inputs, existingPacks, existingMods, flag2, flag1, flag3, flag4, flag5, isFlat, optionset.valueOf(assetIndex), optionset.valueOf(assetsDir)); ++ boolean validate = optionset.has(validateSpec); ++ DataGenerator datagenerator = new DataGenerator(isFlat ? path : path.resolve("minecraft"), SharedConstants.getCurrentVersion(), true); + if (mods.contains("minecraft") || mods.isEmpty()) { - DataGenerator datagenerator = createStandardGenerator( -- path, -- optionset.valuesOf(optionspec8).stream().map(p_129659_ -> Paths.get(p_129659_)).collect(Collectors.toList()), -+ isFlat ? path : path.resolve("minecraft"), -+ inputs, - flag1, - flag2, - flag3, -@@ -107,6 +_,7 @@ - true - ); - datagenerator.run(); + addServerProviders(datagenerator, collection, flag1, flag2, flag3); +- datagenerator.run(); + } ++ net.neoforged.neoforge.data.loading.DatagenModLoader.begin(mods, path, collection, existingPacks, existingMods, flag2, flag3, validate, isFlat, null, null, () -> {}, ++ net.neoforged.neoforge.data.event.GatherDataEvent.Server::new, datagenerator); } else { optionparser.printHelpOn(System.out); } diff --git a/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch b/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch index 2bd05fb51a..616ad56710 100644 --- a/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch +++ b/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/loot/BlockLootSubProvider.java +++ b/net/minecraft/data/loot/BlockLootSubProvider.java -@@ -684,12 +_,16 @@ +@@ -709,12 +_,16 @@ protected abstract void generate(); diff --git a/patches/net/minecraft/network/protocol/game/ServerGamePacketListener.java.patch b/patches/net/minecraft/network/protocol/game/ServerGamePacketListener.java.patch index f24f3d2b43..141ddf719f 100644 --- a/patches/net/minecraft/network/protocol/game/ServerGamePacketListener.java.patch +++ b/patches/net/minecraft/network/protocol/game/ServerGamePacketListener.java.patch @@ -4,8 +4,8 @@ import net.minecraft.network.protocol.common.ServerCommonPacketListener; import net.minecraft.network.protocol.ping.ServerPingPacketListener; --public interface ServerGamePacketListener extends ServerCommonPacketListener, ServerPingPacketListener { -+public interface ServerGamePacketListener extends ServerCommonPacketListener, ServerPingPacketListener, net.neoforged.neoforge.common.extensions.IServerGamePacketListenerExtension { +-public interface ServerGamePacketListener extends ServerPingPacketListener, ServerCommonPacketListener { ++public interface ServerGamePacketListener extends ServerPingPacketListener, ServerCommonPacketListener, net.neoforged.neoforge.common.extensions.IServerGamePacketListenerExtension { @Override default ConnectionProtocol protocol() { return ConnectionProtocol.PLAY; diff --git a/patches/net/minecraft/resources/FileToIdConverter.java.patch b/patches/net/minecraft/resources/FileToIdConverter.java.patch index f908144107..43421d7973 100644 --- a/patches/net/minecraft/resources/FileToIdConverter.java.patch +++ b/patches/net/minecraft/resources/FileToIdConverter.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/resources/FileToIdConverter.java +++ b/net/minecraft/resources/FileToIdConverter.java -@@ -34,4 +_,26 @@ +@@ -40,4 +_,26 @@ public Map> listMatchingResourceStacks(ResourceManager p_249881_) { return p_249881_.listResourceStacks(this.prefix, p_248700_ -> p_248700_.getPath().endsWith(this.extension)); } diff --git a/patches/net/minecraft/resources/HolderSetCodec.java.patch b/patches/net/minecraft/resources/HolderSetCodec.java.patch index 6c9fbdaec3..7d384fbff8 100644 --- a/patches/net/minecraft/resources/HolderSetCodec.java.patch +++ b/patches/net/minecraft/resources/HolderSetCodec.java.patch @@ -9,7 +9,7 @@ private static Codec>> homogenousList(Codec> p_206668_, boolean p_206669_) { Codec>> codec = p_206668_.listOf().validate(ExtraCodecs.ensureHomogenous(Holder::kind)); -@@ -42,6 +_,10 @@ +@@ -36,6 +_,10 @@ this.elementCodec = p_206661_; this.homogenousListCodec = homogenousList(p_206661_, p_206662_); this.registryAwareCodec = Codec.either(TagKey.hashedCodec(p_206660_), this.homogenousListCodec); @@ -20,7 +20,7 @@ } @Override -@@ -50,14 +_,17 @@ +@@ -44,14 +_,17 @@ Optional> optional = registryops.getter(this.registryKey); if (optional.isPresent()) { HolderGetter holdergetter = optional.get(); @@ -40,7 +40,7 @@ ); return dataresult.map(p_332563_ -> Pair.of((HolderSet)p_332563_, (T)p_337522_.getSecond())); } -@@ -82,6 +_,9 @@ +@@ -76,6 +_,9 @@ return DataResult.error(() -> "HolderSet " + p_206674_ + " is not valid in current registry set"); } diff --git a/patches/net/minecraft/resources/RegistryDataLoader.java.patch b/patches/net/minecraft/resources/RegistryDataLoader.java.patch index 4a24d6d0f3..9cfc3b7659 100644 --- a/patches/net/minecraft/resources/RegistryDataLoader.java.patch +++ b/patches/net/minecraft/resources/RegistryDataLoader.java.patch @@ -37,16 +37,16 @@ } } -@@ -264,7 +_,7 @@ +@@ -263,7 +_,7 @@ + Map, Exception> p_321649_ ) { - String s = Registries.elementsDirPath(p_321557_.key()); - FileToIdConverter filetoidconverter = FileToIdConverter.json(s); + FileToIdConverter filetoidconverter = FileToIdConverter.registry(p_321557_.key()); - RegistryOps registryops = RegistryOps.create(JsonOps.INSTANCE, p_321612_); + RegistryOps registryops = new net.neoforged.neoforge.common.conditions.ConditionalOps<>(RegistryOps.create(JsonOps.INSTANCE, p_321612_), net.neoforged.neoforge.common.conditions.ICondition.IContext.TAGS_INVALID); for (Entry entry : filetoidconverter.listMatchingResources(p_321535_).entrySet()) { ResourceLocation resourcelocation = entry.getKey(); -@@ -354,13 +_,20 @@ +@@ -352,13 +_,20 @@ public static record NetworkedRegistryData(List elements, TagNetworkSerialization.NetworkPayload tags) { } diff --git a/patches/net/minecraft/server/Bootstrap.java.patch b/patches/net/minecraft/server/Bootstrap.java.patch index e775eb5eea..cb98d9043b 100644 --- a/patches/net/minecraft/server/Bootstrap.java.patch +++ b/patches/net/minecraft/server/Bootstrap.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/Bootstrap.java +++ b/net/minecraft/server/Bootstrap.java -@@ -53,6 +_,8 @@ +@@ -57,6 +_,8 @@ CauldronInteraction.bootStrap(); BuiltInRegistries.bootStrap(); CreativeModeTabs.validate(); @@ -9,7 +9,7 @@ wrapStreams(); bootstrapDuration.set(Duration.between(instant, Instant.now()).toMillis()); } -@@ -119,7 +_,6 @@ +@@ -123,7 +_,6 @@ Commands.validate(); } diff --git a/patches/net/minecraft/server/Main.java.patch b/patches/net/minecraft/server/Main.java.patch index 08f6bb71e1..dfa781bb50 100644 --- a/patches/net/minecraft/server/Main.java.patch +++ b/patches/net/minecraft/server/Main.java.patch @@ -1,15 +1,6 @@ --- a/net/minecraft/server/Main.java +++ b/net/minecraft/server/Main.java -@@ -64,7 +_,7 @@ - private static final Logger LOGGER = LogUtils.getLogger(); - - @DontObfuscate -- public static void main(String[] p_129699_) { -+ public static void main(String[] p_129699_) throws Exception { - SharedConstants.tryDetectVersion(); - OptionParser optionparser = new OptionParser(); - OptionSpec optionspec = optionparser.accepts("nogui"); -@@ -83,6 +_,15 @@ +@@ -87,6 +_,15 @@ OptionSpec optionspec13 = optionparser.accepts("jfrProfile"); OptionSpec optionspec14 = optionparser.accepts("pidFile").withRequiredArg().withValuesConvertedBy(new PathConverter()); OptionSpec optionspec15 = optionparser.nonOptions(); @@ -25,7 +16,7 @@ try { OptionSet optionset = optionparser.parse(p_129699_); -@@ -90,6 +_,13 @@ +@@ -94,6 +_,13 @@ optionparser.printHelpOn(System.err); return; } @@ -39,7 +30,7 @@ Path path = optionset.valueOf(optionspec14); if (path != null) { -@@ -105,24 +_,22 @@ +@@ -109,24 +_,22 @@ Bootstrap.validate(); Util.startTimerHackThread(); Path path1 = Paths.get("server.properties"); @@ -69,7 +60,7 @@ LevelStorageSource levelstoragesource = LevelStorageSource.createDefault(file1.toPath()); LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = levelstoragesource.validateAndCreateAccess(s); Dynamic dynamic; -@@ -131,6 +_,7 @@ +@@ -135,6 +_,7 @@ try { dynamic = levelstoragesource$levelstorageaccess.getDataTag(); levelsummary = levelstoragesource$levelstorageaccess.getSummary(dynamic); @@ -77,7 +68,7 @@ } catch (NbtException | ReportedNbtException | IOException ioexception1) { LevelStorageSource.LevelDirectory levelstoragesource$leveldirectory = levelstoragesource$levelstorageaccess.getLevelDirectory(); LOGGER.warn("Failed to load world data from {}", levelstoragesource$leveldirectory.dataFile(), ioexception1); -@@ -139,6 +_,7 @@ +@@ -143,6 +_,7 @@ try { dynamic = levelstoragesource$levelstorageaccess.getDataTagFallback(); levelsummary = levelstoragesource$levelstorageaccess.getSummary(dynamic); @@ -85,7 +76,7 @@ } catch (NbtException | ReportedNbtException | IOException ioexception) { LOGGER.error("Failed to load world data from {}", levelstoragesource$leveldirectory.oldDataFile(), ioexception); LOGGER.error( -@@ -173,6 +_,15 @@ +@@ -177,6 +_,15 @@ PackRepository packrepository = ServerPacksSource.createPackRepository(levelstoragesource$levelstorageaccess); @@ -101,7 +92,7 @@ WorldStem worldstem; try { WorldLoader.InitConfig worldloader$initconfig = loadOrCreateConfig(dedicatedserversettings.getProperties(), dynamic1, flag, packrepository); -@@ -214,6 +_,9 @@ +@@ -218,6 +_,9 @@ worlddimensions = dedicatedserverproperties.createDimensions(p_359487_.datapackWorldgen()); } @@ -111,7 +102,7 @@ WorldDimensions.Complete worlddimensions$complete = worlddimensions.bake(registry); Lifecycle lifecycle = worlddimensions$complete.lifecycle().add(p_359487_.datapackWorldgen().allRegistriesLifecycle()); return new WorldLoader.DataLoadOutput<>( -@@ -273,6 +_,7 @@ +@@ -277,6 +_,7 @@ @Override public void run() { dedicatedserver.halt(true); diff --git a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch index ff31d3b5cf..7fb8e44291 100644 --- a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch +++ b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -1,19 +1,18 @@ --- a/net/minecraft/server/ReloadableServerRegistries.java +++ b/net/minecraft/server/ReloadableServerRegistries.java -@@ -61,8 +_,16 @@ +@@ -61,7 +_,15 @@ () -> { WritableRegistry writableregistry = new MappedRegistry<>(p_335741_.registryKey(), Lifecycle.experimental()); Map map = new HashMap<>(); +- SimpleJsonResourceReloadListener.scanDirectory(p_335893_, p_335741_.registryKey(), p_336173_, p_335741_.codec(), map); + Map> optionalMap = new HashMap<>(); - String s = Registries.elementsDirPath(p_335741_.registryKey()); -- SimpleJsonResourceReloadListener.scanDirectory(p_335893_, s, p_336173_, p_335741_.codec(), map); -+ SimpleJsonResourceReloadListener.scanDirectory(p_335893_, s, p_336173_, p_335741_.conditionalCodec(), optionalMap); ++ SimpleJsonResourceReloadListener.scanDirectoryWithOptionalValues(p_335893_, p_335741_.registryKey(), p_336173_, p_335741_.conditionalCodec(), optionalMap); + optionalMap.forEach((rl, optionalEntry) -> { + optionalEntry.ifPresent(entry -> p_335741_.idSetter().accept(entry, rl)); + T value = optionalEntry.orElse(p_335741_.defaultValue()); + if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable); + if (value != null) -+ map.put(rl, value); ++ map.put(rl, value); + }); map.forEach( (p_335721_, p_335683_) -> writableregistry.register( diff --git a/patches/net/minecraft/server/level/ServerEntity.java.patch b/patches/net/minecraft/server/level/ServerEntity.java.patch index 8df4830e9a..4f957b4d61 100644 --- a/patches/net/minecraft/server/level/ServerEntity.java.patch +++ b/patches/net/minecraft/server/level/ServerEntity.java.patch @@ -12,7 +12,7 @@ if (mapitemsaveddata != null) { for (ServerPlayer serverplayer : this.level.players()) { mapitemsaveddata.tickCarriedBy(serverplayer, itemstack); -@@ -274,22 +_,25 @@ +@@ -273,22 +_,25 @@ public void removePairing(ServerPlayer p_8535_) { this.entity.stopSeenByPlayer(p_8535_); p_8535_.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId())); diff --git a/patches/net/minecraft/server/level/ServerLevel.java.patch b/patches/net/minecraft/server/level/ServerLevel.java.patch index 64e787851b..bce6a22dcc 100644 --- a/patches/net/minecraft/server/level/ServerLevel.java.patch +++ b/patches/net/minecraft/server/level/ServerLevel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -202,7 +_,7 @@ +@@ -203,7 +_,7 @@ private final List customSpawners; @Nullable private EndDragonFight dragonFight; @@ -9,7 +9,7 @@ private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; -@@ -225,7 +_,6 @@ +@@ -226,7 +_,6 @@ super(p_215002_, p_215003_, p_214999_.registryAccess(), p_215004_.type(), false, p_215006_, p_215007_, p_214999_.getMaxChainedNeighborUpdates()); this.tickTime = p_215009_; this.server = p_214999_; @@ -17,7 +17,7 @@ this.serverLevelData = p_215002_; ChunkGenerator chunkgenerator = p_215004_.generator(); boolean flag = p_214999_.forceSynchronousWrites(); -@@ -291,6 +_,11 @@ +@@ -292,6 +_,11 @@ this.randomSequences = Objects.requireNonNullElseGet( p_288977_, () -> this.getDataStorage().computeIfAbsent(RandomSequences.factory(i), "random_sequences") ); @@ -29,7 +29,7 @@ } @Deprecated -@@ -336,7 +_,7 @@ +@@ -337,7 +_,7 @@ if (this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { if (this.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { long j = this.levelData.getDayTime() + 24000L; @@ -38,7 +38,7 @@ } this.wakeUpAllPlayers(); -@@ -374,7 +_,7 @@ +@@ -375,7 +_,7 @@ this.handlingTick = false; profilerfiller.pop(); @@ -47,7 +47,7 @@ if (flag1) { this.resetEmptyTime(); } -@@ -407,7 +_,9 @@ +@@ -408,7 +_,9 @@ } profilerfiller.push("tick"); @@ -58,7 +58,7 @@ profilerfiller.pop(); } } -@@ -436,7 +_,7 @@ +@@ -437,7 +_,7 @@ this.serverLevelData.getScheduledEvents().tick(this.server, i); Profiler.get().pop(); if (this.serverLevelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { @@ -67,7 +67,7 @@ } } } -@@ -534,6 +_,7 @@ +@@ -535,6 +_,7 @@ BlockPos blockpos = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, p_295060_); BlockPos blockpos1 = blockpos.below(); Biome biome = this.getBiome(blockpos).value(); @@ -75,7 +75,7 @@ if (biome.shouldFreeze(this, blockpos1)) { this.setBlockAndUpdate(blockpos1, Blocks.ICE.defaultBlockState()); } -@@ -706,15 +_,19 @@ +@@ -707,15 +_,19 @@ .broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, this.thunderLevel), this.dimension()); } @@ -99,7 +99,7 @@ } } -@@ -751,7 +_,11 @@ +@@ -752,7 +_,11 @@ p_8648_.tickCount++; profilerfiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_8648_.getType()).toString()); profilerfiller.incrementCounter("tickNonPassenger"); @@ -112,7 +112,7 @@ profilerfiller.pop(); for (Entity entity : p_8648_.getPassengers()) { -@@ -800,6 +_,7 @@ +@@ -801,6 +_,7 @@ } else { this.entityManager.autoSave(); } @@ -120,7 +120,7 @@ } } -@@ -894,6 +_,7 @@ +@@ -895,6 +_,7 @@ } private void addPlayer(ServerPlayer p_8854_) { @@ -128,7 +128,7 @@ Entity entity = this.getEntities().get(p_8854_.getUUID()); if (entity != null) { LOGGER.warn("Force-added player with duplicate UUID {}", p_8854_.getUUID()); -@@ -901,7 +_,8 @@ +@@ -902,7 +_,8 @@ this.removePlayerImmediately((ServerPlayer)entity, Entity.RemovalReason.DISCARDED); } @@ -138,7 +138,7 @@ } private boolean addEntity(Entity p_8873_) { -@@ -909,7 +_,12 @@ +@@ -910,7 +_,12 @@ LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityType.getKey(p_8873_.getType())); return false; } else { @@ -152,7 +152,7 @@ } } -@@ -957,6 +_,12 @@ +@@ -958,6 +_,12 @@ float p_263390_, long p_263403_ ) { @@ -165,7 +165,7 @@ this.server .getPlayerList() .broadcast( -@@ -974,6 +_,12 @@ +@@ -975,6 +_,12 @@ public void playSeededSound( @Nullable Player p_263545_, Entity p_263544_, Holder p_263491_, SoundSource p_263542_, float p_263530_, float p_263520_, long p_263490_ ) { @@ -178,7 +178,7 @@ this.server .getPlayerList() .broadcast( -@@ -1032,6 +_,7 @@ +@@ -1033,6 +_,7 @@ @Override public void gameEvent(Holder p_316597_, Vec3 p_215042_, GameEvent.Context p_215043_) { @@ -186,7 +186,7 @@ this.gameEventDispatcher.post(p_316597_, p_215042_, p_215043_); } -@@ -1070,6 +_,7 @@ +@@ -1071,6 +_,7 @@ @Override public void updateNeighborsAt(BlockPos p_215045_, Block p_215046_) { @@ -194,7 +194,7 @@ this.updateNeighborsAt(p_215045_, p_215046_, ExperimentalRedstoneUtils.initialOrientation(this, null, null)); } -@@ -1080,6 +_,10 @@ +@@ -1081,6 +_,10 @@ @Override public void updateNeighborsAtExceptFromFacing(BlockPos p_215052_, Block p_215053_, Direction p_215054_, @Nullable Orientation p_365231_) { @@ -205,7 +205,7 @@ this.neighborUpdater.updateNeighborsAtExceptFromFacing(p_215052_, p_215053_, p_215054_, p_365231_); } -@@ -1125,7 +_,7 @@ +@@ -1126,7 +_,7 @@ Explosion.BlockInteraction explosion$blockinteraction = switch (p_255827_) { case NONE -> Explosion.BlockInteraction.KEEP; case BLOCK -> this.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY); @@ -214,7 +214,7 @@ ? this.getDestroyType(GameRules.RULE_MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP; case TNT -> this.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY); -@@ -1133,6 +_,7 @@ +@@ -1134,6 +_,7 @@ }; Vec3 vec3 = new Vec3(p_256067_, p_256370_, p_256153_); ServerExplosion serverexplosion = new ServerExplosion(this, p_256039_, p_255778_, p_256002_, vec3, p_256045_, p_255686_, explosion$blockinteraction); @@ -222,7 +222,16 @@ serverexplosion.explode(); ParticleOptions particleoptions = serverexplosion.isSmall() ? p_312436_ : p_312391_; -@@ -1740,8 +_,8 @@ +@@ -1295,7 +_,7 @@ + } + + @Override +- public Collection dragonParts() { ++ public Collection> dragonParts() { + return this.dragonParts.values(); + } + +@@ -1763,8 +_,8 @@ ServerLevel.this.navigatingMobs.add(mob); } @@ -233,7 +242,7 @@ ServerLevel.this.dragonParts.put(enderdragonpart.getId(), enderdragonpart); } } -@@ -1760,24 +_,106 @@ +@@ -1783,24 +_,101 @@ if (ServerLevel.this.isUpdatingNavigations) { String s = "onTrackingStart called during navigation iteration"; Util.logAndPauseIfInIde( @@ -264,11 +273,6 @@ } } + -+ @Override -+ public java.util.Collection> getPartEntities() { -+ return this.dragonParts.values(); -+ } -+ + private final net.neoforged.neoforge.capabilities.CapabilityListenerHolder capListenerHolder = new net.neoforged.neoforge.capabilities.CapabilityListenerHolder(); + + @Override diff --git a/patches/net/minecraft/server/level/ServerPlayer.java.patch b/patches/net/minecraft/server/level/ServerPlayer.java.patch index db56f6eebe..11b750dab8 100644 --- a/patches/net/minecraft/server/level/ServerPlayer.java.patch +++ b/patches/net/minecraft/server/level/ServerPlayer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -278,6 +_,10 @@ +@@ -276,6 +_,10 @@ } private void broadcastDataValue(AbstractContainerMenu p_143455_, int p_143456_, int p_143457_) { @@ -11,7 +11,7 @@ ServerPlayer.this.connection.send(new ClientboundContainerSetDataPacket(p_143455_.containerId, p_143456_, p_143457_)); } }; -@@ -768,6 +_,11 @@ +@@ -766,6 +_,11 @@ this.connection.send(new ClientboundSetExperiencePacket(this.experienceProgress, this.totalExperience, this.experienceLevel)); } @@ -23,7 +23,7 @@ if (this.tickCount % 20 == 0) { CriteriaTriggers.LOCATION.trigger(this); } -@@ -781,7 +_,7 @@ +@@ -779,7 +_,7 @@ private void synchronizeSpecialItemUpdates(ItemStack p_372884_) { MapId mapid = p_372884_.get(DataComponents.MAP_ID); @@ -32,7 +32,7 @@ if (mapitemsaveddata != null) { Packet packet = mapitemsaveddata.getUpdatePacket(mapid, this); if (packet != null) { -@@ -850,6 +_,7 @@ +@@ -848,6 +_,7 @@ @Override public void die(DamageSource p_9035_) { this.gameEvent(GameEvent.ENTITY_DIE); @@ -40,7 +40,7 @@ boolean flag = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); if (flag) { Component component = this.getCombatTracker().getDeathMessage(); -@@ -1019,7 +_,7 @@ +@@ -1012,7 +_,7 @@ return BedBlock.findStandUpPosition(EntityType.PLAYER, p_348505_, p_348607_, blockstate.getValue(BedBlock.FACING), p_348481_) .map(p_348148_ -> ServerPlayer.RespawnPosAngle.of(p_348148_, p_348607_)); } else if (!p_348513_) { @@ -49,7 +49,7 @@ } else { boolean flag = block.isPossibleToRespawnInThis(blockstate); BlockState blockstate1 = p_348505_.getBlockState(p_348607_.above()); -@@ -1046,6 +_,7 @@ +@@ -1039,6 +_,7 @@ @Nullable public ServerPlayer teleport(TeleportTransition p_379854_) { @@ -57,7 +57,7 @@ if (this.isRemoved()) { return null; } else { -@@ -1073,7 +_,7 @@ +@@ -1066,7 +_,7 @@ PlayerList playerlist = this.server.getPlayerList(); playerlist.sendPlayerPermissionLevel(this); serverlevel1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); @@ -66,7 +66,7 @@ ProfilerFiller profilerfiller = Profiler.get(); profilerfiller.push("moving"); if (resourcekey == Level.OVERWORLD && serverlevel.dimension() == Level.NETHER) { -@@ -1093,10 +_,12 @@ +@@ -1086,10 +_,12 @@ playerlist.sendLevelInfo(this, serverlevel); playerlist.sendAllPlayerInfo(this); playerlist.sendActivePlayerEffects(this); @@ -79,7 +79,7 @@ return this; } } -@@ -1137,6 +_,15 @@ +@@ -1130,6 +_,15 @@ @Override public Either startSleepInBed(BlockPos p_9115_) { @@ -95,7 +95,7 @@ Direction direction = this.level().getBlockState(p_9115_).getValue(HorizontalDirectionalBlock.FACING); if (this.isSleeping() || !this.isAlive()) { return Either.left(Player.BedSleepingProblem.OTHER_PROBLEM); -@@ -1165,7 +_,21 @@ +@@ -1158,7 +_,21 @@ return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } @@ -118,7 +118,7 @@ Either either = super.startSleepInBed(p_9115_).ifRight(p_9029_ -> { this.awardStat(Stats.SLEEP_IN_BED); CriteriaTriggers.SLEPT_IN_BED.trigger(this); -@@ -1187,6 +_,7 @@ +@@ -1180,6 +_,7 @@ } private boolean bedInRange(BlockPos p_9117_, Direction p_9118_) { @@ -126,7 +126,7 @@ return this.isReachableBedBlock(p_9117_) || this.isReachableBedBlock(p_9117_.relative(p_9118_.getOpposite())); } -@@ -1277,11 +_,19 @@ +@@ -1262,11 +_,19 @@ @Override public OptionalInt openMenu(@Nullable MenuProvider p_9033_) { @@ -146,7 +146,7 @@ } this.nextContainerCounter(); -@@ -1293,10 +_,16 @@ +@@ -1278,10 +_,16 @@ return OptionalInt.empty(); } else { @@ -163,7 +163,7 @@ return OptionalInt.of(this.containerCounter); } } -@@ -1318,6 +_,7 @@ +@@ -1303,6 +_,7 @@ this.connection.send(new ClientboundHorseScreenOpenPacket(this.containerCounter, i, p_9059_.getId())); this.containerMenu = new HorseInventoryMenu(this.containerCounter, this.getInventory(), p_9060_, p_9059_, i); this.initMenu(this.containerMenu); @@ -171,7 +171,7 @@ } @Override -@@ -1346,6 +_,7 @@ +@@ -1331,6 +_,7 @@ public void doCloseContainer() { this.containerMenu.removed(this); this.inventoryMenu.transferState(this.containerMenu); @@ -179,7 +179,7 @@ this.containerMenu = this.inventoryMenu; } -@@ -1569,6 +_,15 @@ +@@ -1554,6 +_,15 @@ this.setShoulderEntityLeft(p_9016_.getShoulderEntityLeft()); this.setShoulderEntityRight(p_9016_.getShoulderEntityRight()); this.setLastDeathLocation(p_9016_.getLastDeathLocation()); @@ -195,7 +195,7 @@ } @Override -@@ -1674,6 +_,8 @@ +@@ -1657,6 +_,8 @@ public boolean setGameMode(GameType p_143404_) { boolean flag = this.isSpectator(); @@ -204,7 +204,7 @@ if (!this.gameMode.changeGameModeForPlayer(p_143404_)) { return false; } else { -@@ -1848,6 +_,7 @@ +@@ -1831,6 +_,7 @@ public void setCamera(@Nullable Entity p_9214_) { Entity entity = this.getCamera(); this.camera = (Entity)(p_9214_ == null ? this : p_9214_); @@ -212,7 +212,7 @@ if (entity != this.camera) { if (this.camera.level() instanceof ServerLevel serverlevel) { this.teleportTo(serverlevel, this.camera.getX(), this.camera.getY(), this.camera.getZ(), Set.of(), this.getYRot(), this.getXRot(), false); -@@ -1884,7 +_,11 @@ +@@ -1867,7 +_,11 @@ @Nullable public Component getTabListDisplayName() { @@ -225,7 +225,7 @@ } public int getTabListOrder() { -@@ -1933,6 +_,7 @@ +@@ -1916,6 +_,7 @@ } public void setRespawnPosition(ResourceKey p_9159_, @Nullable BlockPos p_9160_, float p_9161_, boolean p_9162_, boolean p_9163_) { @@ -233,7 +233,7 @@ if (p_9160_ != null) { boolean flag = p_9160_.equals(this.respawnPosition) && p_9159_.equals(this.respawnDimension); if (p_9163_ && !flag) { -@@ -1990,6 +_,8 @@ +@@ -1973,6 +_,8 @@ if (itementity == null) { return null; } else { @@ -242,7 +242,7 @@ this.level().addFreshEntity(itementity); ItemStack itemstack = itementity.getItem(); if (p_9087_) { -@@ -2039,6 +_,75 @@ +@@ -2022,6 +_,75 @@ } } @@ -318,7 +318,7 @@ public TextFilter getTextFilter() { return this.textFilter; } -@@ -2099,9 +_,12 @@ +@@ -2082,9 +_,12 @@ public boolean drop(boolean p_182295_) { Inventory inventory = this.getInventory(); diff --git a/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 74247bc5af..8575501ec9 100644 --- a/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -439,9 +_,11 @@ +@@ -441,9 +_,11 @@ } entity.absMoveTo(d3, d4, d5, f, f1); @@ -9,10 +9,10 @@ if (flag && (flag2 || !flag3)) { entity.absMoveTo(d0, d1, d2, f, f1); + resyncPlayerWithVehicle(entity); // Neo - Resync player position on vehicle moving - this.send(new ClientboundMoveVehiclePacket(entity)); + this.send(ClientboundMoveVehiclePacket.fromEntity(entity)); return; } -@@ -463,6 +_,23 @@ +@@ -467,6 +_,23 @@ } } @@ -36,7 +36,16 @@ private boolean noBlocksAround(Entity p_9794_) { return p_9794_.level() .getBlockStates(p_9794_.getBoundingBox().inflate(0.0625).expandTowards(0.0, -0.55, 0.0)) -@@ -930,7 +_,7 @@ +@@ -646,7 +_,7 @@ + if (serverlevel.isLoaded(blockpos)) { + BlockState blockstate = serverlevel.getBlockState(blockpos); + boolean flag = this.player.hasInfiniteMaterials() && p_382999_.includeData(); +- ItemStack itemstack = blockstate.getCloneItemStack(serverlevel, blockpos, flag); ++ ItemStack itemstack = blockstate.getCloneItemStack(blockpos, serverlevel, flag, player); + if (!itemstack.isEmpty()) { + if (flag) { + addBlockDataToItem(blockstate, serverlevel, blockpos, itemstack); +@@ -990,7 +_,7 @@ && !flag1 && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR && !this.server.isFlightAllowed() @@ -45,38 +54,39 @@ && !this.player.hasEffect(MobEffects.LEVITATION) && !flag && !flag3 -@@ -1041,8 +_,10 @@ - case SWAP_ITEM_WITH_OFFHAND: - if (!this.player.isSpectator()) { - ItemStack itemstack = this.player.getItemInHand(InteractionHand.OFF_HAND); -- this.player.setItemInHand(InteractionHand.OFF_HAND, this.player.getItemInHand(InteractionHand.MAIN_HAND)); -- this.player.setItemInHand(InteractionHand.MAIN_HAND, itemstack); -+ var event = net.neoforged.neoforge.common.CommonHooks.onLivingSwapHandItems(this.player); -+ if (event.isCanceled()) return; -+ this.player.setItemInHand(InteractionHand.OFF_HAND, event.getItemSwappedToOffHand()); -+ this.player.setItemInHand(InteractionHand.MAIN_HAND, event.getItemSwappedToMainHand()); - this.player.stopUsingItem(); - } +@@ -1101,9 +_,10 @@ + switch (serverboundplayeractionpacket$action) { + case SWAP_ITEM_WITH_OFFHAND: + if (!this.player.isSpectator()) { +- ItemStack itemstack = this.player.getItemInHand(InteractionHand.OFF_HAND); +- this.player.setItemInHand(InteractionHand.OFF_HAND, this.player.getItemInHand(InteractionHand.MAIN_HAND)); +- this.player.setItemInHand(InteractionHand.MAIN_HAND, itemstack); ++ var event = net.neoforged.neoforge.common.CommonHooks.onLivingSwapHandItems(this.player); ++ if (event.isCanceled()) return; ++ this.player.setItemInHand(InteractionHand.OFF_HAND, event.getItemSwappedToOffHand()); ++ this.player.setItemInHand(InteractionHand.MAIN_HAND, event.getItemSwappedToMainHand()); + this.player.stopUsingItem(); + } -@@ -1070,7 +_,7 @@ - .handleBlockBreakAction( - blockpos, serverboundplayeractionpacket$action, p_9889_.getDirection(), this.player.level().getMaxY(), p_9889_.getSequence() - ); -- this.player.connection.ackBlockChangesUpTo(p_9889_.getSequence()); -+ this.player.connection.ackBlockChangesUpTo =p_9889_.getSequence(); - return; - default: - throw new IllegalArgumentException("Invalid player action"); -@@ -1089,7 +_,7 @@ - @Override +@@ -1131,7 +_,7 @@ + .handleBlockBreakAction( + blockpos, serverboundplayeractionpacket$action, p_9889_.getDirection(), this.player.level().getMaxY(), p_9889_.getSequence() + ); +- this.player.connection.ackBlockChangesUpTo(p_9889_.getSequence()); ++ this.player.connection.ackBlockChangesUpTo = p_9889_.getSequence(); + return; + default: + throw new IllegalArgumentException("Invalid player action"); +@@ -1152,7 +_,7 @@ public void handleUseItemOn(ServerboundUseItemOnPacket p_9930_) { PacketUtils.ensureRunningOnSameThread(p_9930_, this, this.player.serverLevel()); -- this.player.connection.ackBlockChangesUpTo(p_9930_.getSequence()); -+ this.player.connection.ackBlockChangesUpTo = p_9930_.getSequence(); - ServerLevel serverlevel = this.player.serverLevel(); - InteractionHand interactionhand = p_9930_.getHand(); - ItemStack itemstack = this.player.getItemInHand(interactionhand); -@@ -1242,8 +_,9 @@ + if (this.player.hasClientLoaded()) { +- this.player.connection.ackBlockChangesUpTo(p_9930_.getSequence()); ++ this.player.connection.ackBlockChangesUpTo = p_9930_.getSequence(); + ServerLevel serverlevel = this.player.serverLevel(); + InteractionHand interactionhand = p_9930_.getHand(); + ItemStack itemstack = this.player.getItemInHand(interactionhand); +@@ -1308,8 +_,9 @@ } CompletableFuture completablefuture = this.filterTextPacket(playerchatmessage.signedContent()); @@ -87,20 +97,20 @@ PlayerChatMessage playerchatmessage1 = playerchatmessage.withUnsignedContent(component).filter(p_300785_.mask()); this.broadcastChatMessage(playerchatmessage1); }); -@@ -1569,7 +_,11 @@ +@@ -1638,7 +_,11 @@ - @Override - public void onInteraction(InteractionHand p_143682_, Vec3 p_143683_) { -- this.performInteraction(p_143682_, (p_143686_, p_143687_, p_143688_) -> p_143687_.interactAt(p_143686_, p_143683_, p_143688_)); -+ this.performInteraction(p_143682_, (p_143686_, p_143687_, p_143688_) -> { -+ InteractionResult onInteractEntityAtResult = net.neoforged.neoforge.common.CommonHooks.onInteractEntityAt(player, entity, p_143683_, p_143682_); -+ if (onInteractEntityAtResult != null) return onInteractEntityAtResult; -+ return p_143687_.interactAt(p_143686_, p_143683_, p_143688_); -+ }); - } + @Override + public void onInteraction(InteractionHand p_143682_, Vec3 p_143683_) { +- this.performInteraction(p_143682_, (p_143686_, p_143687_, p_143688_) -> p_143687_.interactAt(p_143686_, p_143683_, p_143688_)); ++ this.performInteraction(p_143682_, (p_143686_, p_143687_, p_143688_) -> { ++ InteractionResult onInteractEntityAtResult = net.neoforged.neoforge.common.CommonHooks.onInteractEntityAt(player, entity, p_143683_, p_143682_); ++ if (onInteractEntityAtResult != null) return onInteractEntityAtResult; ++ return p_143687_.interactAt(p_143686_, p_143683_, p_143688_); ++ }); + } - @Override -@@ -1785,13 +_,15 @@ + @Override +@@ -1845,14 +_,16 @@ @Override public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket p_9887_) { PacketUtils.ensureRunningOnSameThread(p_9887_, this, this.player.serverLevel()); @@ -111,13 +121,14 @@ @Override public void handleClientInformation(ServerboundClientInformationPacket p_301979_) { PacketUtils.ensureRunningOnSameThread(p_301979_, this, this.player.serverLevel()); + boolean flag = this.player.isModelPartShown(PlayerModelPart.HAT); + net.minecraft.server.level.ClientInformation oldInfo = this.player.clientInformation(); this.player.updateOptions(p_301979_.information()); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.player.ClientInformationUpdatedEvent(this.player, oldInfo, p_301979_.information())); - } - - @Override -@@ -1844,7 +_,7 @@ + if (this.player.isModelPartShown(PlayerModelPart.HAT) != flag) { + this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player)); + } +@@ -1908,7 +_,7 @@ this.connection .setupInboundProtocol( ConfigurationProtocols.SERVERBOUND, @@ -126,7 +137,7 @@ ); } } -@@ -1879,6 +_,7 @@ +@@ -1943,6 +_,7 @@ @Override public void handleCustomPayload(ServerboundCustomPayloadPacket p_333887_) { diff --git a/patches/net/minecraft/server/packs/AbstractPackResources.java.patch b/patches/net/minecraft/server/packs/AbstractPackResources.java.patch index 226fe4b923..f30c56201a 100644 --- a/patches/net/minecraft/server/packs/AbstractPackResources.java.patch +++ b/patches/net/minecraft/server/packs/AbstractPackResources.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/packs/AbstractPackResources.java +++ b/net/minecraft/server/packs/AbstractPackResources.java -@@ -63,4 +_,9 @@ +@@ -62,4 +_,9 @@ public PackLocationInfo location() { return this.location; } diff --git a/patches/net/minecraft/server/packs/OverlayMetadataSection.java.patch b/patches/net/minecraft/server/packs/OverlayMetadataSection.java.patch index 4e52d4269f..e34b9d3ba2 100644 --- a/patches/net/minecraft/server/packs/OverlayMetadataSection.java.patch +++ b/patches/net/minecraft/server/packs/OverlayMetadataSection.java.patch @@ -8,10 +8,10 @@ + p_294898_ -> p_294898_.group(net.neoforged.neoforge.common.conditions.ConditionalOps.decodeListWithElementConditions(OverlayMetadataSection.OverlayEntry.CODEC).fieldOf("entries").forGetter(OverlayMetadataSection::overlays)) .apply(p_294898_, OverlayMetadataSection::new) ); - public static final MetadataSectionType TYPE = MetadataSectionType.fromCodec("overlays", CODEC); + public static final MetadataSectionType TYPE = new MetadataSectionType<>("overlays", CODEC); + // Neo: alternative metadata section that will only be loaded on neoforged. Useful for making datapacks with special + // logic on different modloaders, or when running on neo vs in vanilla, without having to invert the main pack and overlays -+ public static final MetadataSectionType NEOFORGE_TYPE = MetadataSectionType.fromCodec("neoforge:overlays", CODEC); ++ public static final MetadataSectionType NEOFORGE_TYPE = new MetadataSectionType<>("neoforge:overlays", CODEC); private static DataResult validateOverlayDir(String p_296447_) { return !DIR_VALIDATOR.matcher(p_296447_).matches() diff --git a/patches/net/minecraft/server/packs/metadata/pack/PackMetadataSection.java.patch b/patches/net/minecraft/server/packs/metadata/pack/PackMetadataSection.java.patch index e34e6e1a5a..cb6dd83a17 100644 --- a/patches/net/minecraft/server/packs/metadata/pack/PackMetadataSection.java.patch +++ b/patches/net/minecraft/server/packs/metadata/pack/PackMetadataSection.java.patch @@ -3,7 +3,7 @@ @@ -19,4 +_,8 @@ .apply(p_337567_, PackMetadataSection::new) ); - public static final MetadataSectionType TYPE = MetadataSectionType.fromCodec("pack", CODEC); + public static final MetadataSectionType TYPE = new MetadataSectionType<>("pack", CODEC); + + public PackMetadataSection(Component description, int packVersion) { + this(description, packVersion, Optional.empty()); diff --git a/patches/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch b/patches/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch index 3745422f2c..90886b7c44 100644 --- a/patches/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch +++ b/patches/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch @@ -1,24 +1,36 @@ --- a/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java +++ b/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java -@@ -41,13 +_,15 @@ +@@ -43,10 +_,21 @@ protected Map prepare(ResourceManager p_10771_, ProfilerFiller p_10772_) { Map map = new HashMap<>(); -- scanDirectory(p_10771_, this.directory, this.ops, this.codec, map); +- scanDirectory(p_10771_, this.lister, this.ops, this.codec, map); + // Neo: add condition context -+ scanDirectory(p_10771_, this.directory, this.makeConditionalOps(), this.codec, map); ++ scanDirectory(p_10771_, this.lister, this.makeConditionalOps(this.ops), this.codec, map); return map; } ++ public static void scanDirectoryWithOptionalValues( ++ ResourceManager p_386974_, ++ ResourceKey> p_388878_, ++ DynamicOps p_388402_, ++ Codec> p_387608_, ++ Map> p_386495_ ++ ) { ++ scanDirectory(p_386974_, FileToIdConverter.registry(p_388878_), p_388402_, p_387608_, p_386495_); ++ } ++ public static void scanDirectory( - ResourceManager p_279308_, String p_279131_, DynamicOps p_371830_, Codec p_371493_, Map p_279404_ + ResourceManager p_386974_, + ResourceKey> p_388878_, +@@ -60,13 +_,16 @@ + public static void scanDirectory( + ResourceManager p_279308_, FileToIdConverter p_387906_, DynamicOps p_371830_, Codec p_371493_, Map p_279404_ ) { + var conditionalCodec = net.neoforged.neoforge.common.conditions.ConditionalOps.createConditionalCodec(p_371493_); - FileToIdConverter filetoidconverter = FileToIdConverter.json(p_279131_); - - for (Entry entry : filetoidconverter.listMatchingResources(p_279308_).entrySet()) { -@@ -55,8 +_,10 @@ - ResourceLocation resourcelocation1 = filetoidconverter.fileToId(resourcelocation); + for (Entry entry : p_387906_.listMatchingResources(p_279308_).entrySet()) { + ResourceLocation resourcelocation = entry.getKey(); + ResourceLocation resourcelocation1 = p_387906_.fileToId(resourcelocation); try (Reader reader = entry.getValue().openAsReader()) { - p_371493_.parse(p_371830_, JsonParser.parseReader(reader)).ifSuccess(p_371454_ -> { @@ -30,13 +42,13 @@ throw new IllegalStateException("Duplicate data file ignored with ID " + resourcelocation1); } }).ifError(p_371566_ -> LOGGER.error("Couldn't parse data file '{}' from '{}': {}", resourcelocation1, resourcelocation, p_371566_)); -@@ -64,5 +_,9 @@ +@@ -74,5 +_,9 @@ LOGGER.error("Couldn't parse data file '{}' from '{}'", resourcelocation1, resourcelocation, jsonparseexception); } } + } + + protected ResourceLocation getPreparedPath(ResourceLocation rl) { -+ return rl.withPath(this.directory + "/" + rl.getPath() + ".json"); ++ return this.lister.idToFile(rl); } } diff --git a/patches/net/minecraft/tags/ItemTags.java.patch b/patches/net/minecraft/tags/ItemTags.java.patch index 9dd688d2d9..4b22abdb66 100644 --- a/patches/net/minecraft/tags/ItemTags.java.patch +++ b/patches/net/minecraft/tags/ItemTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/ItemTags.java +++ b/net/minecraft/tags/ItemTags.java -@@ -183,4 +_,8 @@ +@@ -185,4 +_,8 @@ private static TagKey bind(String p_203855_) { return TagKey.create(Registries.ITEM, ResourceLocation.withDefaultNamespace(p_203855_)); } diff --git a/patches/net/minecraft/util/SpawnUtil.java.patch b/patches/net/minecraft/util/SpawnUtil.java.patch index 558cc70a2a..e39af19e21 100644 --- a/patches/net/minecraft/util/SpawnUtil.java.patch +++ b/patches/net/minecraft/util/SpawnUtil.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/util/SpawnUtil.java +++ b/net/minecraft/util/SpawnUtil.java -@@ -36,7 +_,7 @@ - && moveToPossibleSpawnPosition(p_216406_, p_216410_, blockpos$mutableblockpos, p_216411_)) { +@@ -47,7 +_,7 @@ + )) { T t = (T)p_216404_.create(p_216406_, null, blockpos$mutableblockpos, p_364255_, false, false); if (t != null) { - if (t.checkSpawnRules(p_216406_, p_364255_) && t.checkSpawnObstruction(p_216406_)) { + if (net.neoforged.neoforge.event.EventHooks.checkSpawnPosition(t, p_216406_, p_364255_)) { p_216406_.addFreshEntityWithPassengers(t); + t.playAmbientSound(); return Optional.of(t); - } diff --git a/patches/net/minecraft/util/context/ContextKeySet.java.patch b/patches/net/minecraft/util/context/ContextKeySet.java.patch new file mode 100644 index 0000000000..206d38b786 --- /dev/null +++ b/patches/net/minecraft/util/context/ContextKeySet.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/util/context/ContextKeySet.java ++++ b/net/minecraft/util/context/ContextKeySet.java +@@ -5,6 +_,9 @@ + import java.util.Set; + + public class ContextKeySet { ++ // Neo: Add EMPTY context set for convenience, since we disable the check for `required` keys in ContextMap.Builder. ++ public static final ContextKeySet EMPTY = new Builder().build(); ++ + private final Set> required; + private final Set> allowed; + diff --git a/patches/net/minecraft/util/context/ContextMap.java.patch b/patches/net/minecraft/util/context/ContextMap.java.patch index 86160aa256..2b800da6a3 100644 --- a/patches/net/minecraft/util/context/ContextMap.java.patch +++ b/patches/net/minecraft/util/context/ContextMap.java.patch @@ -1,5 +1,15 @@ --- a/net/minecraft/util/context/ContextMap.java +++ b/net/minecraft/util/context/ContextMap.java +@@ -9,6 +_,9 @@ + import org.jetbrains.annotations.Contract; + + public class ContextMap { ++ // Neo: Add EMPTY map for convenience. ++ public static final ContextMap EMPTY = new Builder().create(ContextKeySet.EMPTY); ++ + private final Map, Object> params; + + ContextMap(Map, Object> p_381157_) { @@ -73,7 +_,7 @@ public ContextMap create(ContextKeySet p_381168_) { diff --git a/patches/net/minecraft/util/datafix/DataFixers.java.patch b/patches/net/minecraft/util/datafix/DataFixers.java.patch index 5ab30c4c68..4baa96d57b 100644 --- a/patches/net/minecraft/util/datafix/DataFixers.java.patch +++ b/patches/net/minecraft/util/datafix/DataFixers.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/util/datafix/DataFixers.java +++ b/net/minecraft/util/datafix/DataFixers.java -@@ -1308,10 +_,35 @@ - Schema schema199 = p_14514_.addSchema(3800, SAME_NAMESPACED); +@@ -1314,10 +_,35 @@ + Schema schema198 = p_14514_.addSchema(3800, SAME_NAMESPACED); UnaryOperator unaryoperator2 = createRenamer(Map.of("minecraft:scute", "minecraft:turtle_scute")); - p_14514_.addFixer(ItemRenameFix.create(schema199, "Rename scute item to turtle_scute", unaryoperator2)); + p_14514_.addFixer(ItemRenameFix.create(schema198, "Rename scute item to turtle_scute", unaryoperator2)); + + // Neo: Remove step height attribute, which cannot be sanely updated + // Happens in 23w51a @@ -16,9 +16,9 @@ + ) + )); + - Schema schema200 = p_14514_.addSchema(3803, SAME_NAMESPACED); + Schema schema199 = p_14514_.addSchema(3803, SAME_NAMESPACED); p_14514_.addFixer( - new RenameEnchantmentsFix(schema200, "Rename sweeping enchant to sweeping_edge", Map.of("minecraft:sweeping", "minecraft:sweeping_edge")) + new RenameEnchantmentsFix(schema199, "Rename sweeping enchant to sweeping_edge", Map.of("minecraft:sweeping", "minecraft:sweeping_edge")) ); + + // Neo: rename neo attributes to new MC attributes @@ -33,11 +33,11 @@ + )) + )); + - Schema schema201 = p_14514_.addSchema(3807, V3807::new); - p_14514_.addFixer(new AddNewChoices(schema201, "Added Vault", References.BLOCK_ENTITY)); - Schema schema202 = p_14514_.addSchema(3807, 1, SAME_NAMESPACED); -@@ -1334,6 +_,18 @@ - schema209, "Rename jump strength attribute", createRenamer("minecraft:horse.jump_strength", "minecraft:generic.jump_strength") + Schema schema200 = p_14514_.addSchema(3807, V3807::new); + p_14514_.addFixer(new AddNewChoices(schema200, "Added Vault", References.BLOCK_ENTITY)); + Schema schema201 = p_14514_.addSchema(3807, 1, SAME_NAMESPACED); +@@ -1340,6 +_,18 @@ + schema208, "Rename jump strength attribute", createRenamer("minecraft:horse.jump_strength", "minecraft:generic.jump_strength") ) ); + @@ -52,6 +52,6 @@ + ) + )); + - Schema schema210 = p_14514_.addSchema(3816, V3816::new); - p_14514_.addFixer(new AddNewChoices(schema210, "Added Bogged", References.ENTITY)); - Schema schema211 = p_14514_.addSchema(3818, V3818::new); + Schema schema209 = p_14514_.addSchema(3816, V3816::new); + p_14514_.addFixer(new AddNewChoices(schema209, "Added Bogged", References.ENTITY)); + Schema schema210 = p_14514_.addSchema(3818, V3818::new); diff --git a/patches/net/minecraft/world/effect/PoisonMobEffect.java.patch b/patches/net/minecraft/world/effect/PoisonMobEffect.java.patch index d2c1139e5e..b85aced5a1 100644 --- a/patches/net/minecraft/world/effect/PoisonMobEffect.java.patch +++ b/patches/net/minecraft/world/effect/PoisonMobEffect.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/effect/PoisonMobEffect.java +++ b/net/minecraft/world/effect/PoisonMobEffect.java -@@ -11,7 +_,12 @@ +@@ -13,7 +_,12 @@ @Override public boolean applyEffectTick(ServerLevel p_376442_, LivingEntity p_296276_, int p_296233_) { if (p_296276_.getHealth() > 1.0F) { diff --git a/patches/net/minecraft/world/entity/Entity.java.patch b/patches/net/minecraft/world/entity/Entity.java.patch index 15f8303a24..35d70c49b2 100644 --- a/patches/net/minecraft/world/entity/Entity.java.patch +++ b/patches/net/minecraft/world/entity/Entity.java.patch @@ -39,7 +39,7 @@ } public boolean isColliding(BlockPos p_20040_, BlockState p_20041_) { -@@ -478,7 +_,7 @@ +@@ -482,7 +_,7 @@ if (this.isInLava()) { this.lavaHurt(); @@ -48,7 +48,7 @@ } this.checkBelowWorld(); -@@ -760,12 +_,12 @@ +@@ -772,12 +_,12 @@ this.setRemainingFireTicks(-this.getFireImmuneTicks()); } @@ -63,7 +63,7 @@ this.setRemainingFireTicks(-this.getFireImmuneTicks()); } } -@@ -845,9 +_,7 @@ +@@ -857,9 +_,7 @@ return blockpos; } else { BlockState blockstate = this.level().getBlockState(blockpos); @@ -74,7 +74,7 @@ ? blockpos.atY(Mth.floor(this.position.y - (double)p_216987_)) : blockpos; } -@@ -1129,19 +_,19 @@ +@@ -1141,19 +_,19 @@ return !blockstate.is(BlockTags.INSIDE_STEP_SOUND_BLOCKS) && !blockstate.is(BlockTags.COMBINATION_STEP_SOUND_BLOCKS) ? p_278049_ : blockpos; } @@ -100,7 +100,7 @@ this.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.15F, soundtype.getPitch()); } -@@ -1294,20 +_,23 @@ +@@ -1315,20 +_,23 @@ public void updateSwimming() { if (this.isSwimming()) { @@ -129,7 +129,7 @@ } void updateInWaterStateAndDoWaterCurrentPushing() { -@@ -1332,6 +_,7 @@ +@@ -1353,6 +_,7 @@ private void updateFluidOnEyes() { this.wasEyeInWater = this.isEyeInFluid(FluidTags.WATER); this.fluidOnEyes.clear(); @@ -137,7 +137,7 @@ double d0 = this.getEyeY(); if (this.getVehicle() instanceof AbstractBoat abstractboat && !abstractboat.isUnderWater() -@@ -1344,7 +_,7 @@ +@@ -1365,7 +_,7 @@ FluidState fluidstate = this.level().getFluidState(blockpos); double d1 = (double)((float)blockpos.getY() + fluidstate.getHeight(this.level(), blockpos)); if (d1 > d0) { @@ -146,7 +146,7 @@ } } -@@ -1389,12 +_,13 @@ +@@ -1410,12 +_,13 @@ } public boolean canSpawnSprintParticle() { @@ -161,7 +161,7 @@ if (blockstate.getRenderShape() != RenderShape.INVISIBLE) { Vec3 vec3 = this.getDeltaMovement(); BlockPos blockpos1 = this.blockPosition(); -@@ -1408,16 +_,19 @@ +@@ -1429,16 +_,19 @@ d1 = Mth.clamp(d1, (double)blockpos.getZ(), (double)blockpos.getZ() + 1.0); } @@ -183,7 +183,7 @@ } public void moveRelative(float p_19921_, Vec3 p_19922_) { -@@ -1796,6 +_,10 @@ +@@ -1817,6 +_,10 @@ p_20241_.put("Tags", listtag); } @@ -194,7 +194,7 @@ this.addAdditionalSaveData(p_20241_); if (this.isVehicle()) { ListTag listtag1 = new ListTag(); -@@ -1877,6 +_,8 @@ +@@ -1900,6 +_,8 @@ this.setGlowingTag(p_20259_.getBoolean("Glowing")); this.setTicksFrozen(p_20259_.getInt("TicksFrozen")); this.hasVisualFire = p_20259_.getBoolean("HasVisualFire"); @@ -203,7 +203,7 @@ if (p_20259_.contains("Tags", 9)) { this.tags.clear(); ListTag listtag3 = p_20259_.getList("Tags", 8); -@@ -1959,6 +_,8 @@ +@@ -1982,6 +_,8 @@ } else { ItemEntity itementity = new ItemEntity(p_376141_, this.getX(), this.getY() + (double)p_376881_, this.getZ(), p_376472_); itementity.setDefaultPickUpDelay(); @@ -212,7 +212,7 @@ p_376141_.addFreshEntity(itementity); return itementity; } -@@ -2026,7 +_,11 @@ +@@ -2054,7 +_,11 @@ public void rideTick() { this.setDeltaMovement(Vec3.ZERO); @@ -225,7 +225,7 @@ if (this.isPassenger()) { this.getVehicle().positionRider(this); } -@@ -2086,6 +_,7 @@ +@@ -2114,6 +_,7 @@ } } @@ -233,7 +233,7 @@ if (p_19967_ || this.canRide(p_19966_) && p_19966_.canAddPassenger(this)) { if (this.isPassenger()) { this.stopRiding(); -@@ -2117,6 +_,7 @@ +@@ -2145,6 +_,7 @@ public void removeVehicle() { if (this.vehicle != null) { Entity entity = this.vehicle; @@ -241,7 +241,7 @@ this.vehicle = null; entity.removePassenger(this); } -@@ -2166,6 +_,8 @@ +@@ -2194,6 +_,8 @@ return this.passengers.isEmpty(); } @@ -250,7 +250,7 @@ protected boolean couldAcceptPassenger() { return true; } -@@ -2354,7 +_,7 @@ +@@ -2382,7 +_,7 @@ } public boolean isVisuallyCrawling() { @@ -259,7 +259,7 @@ } public void setSwimming(boolean p_20283_) { -@@ -2467,7 +_,7 @@ +@@ -2495,7 +_,7 @@ this.igniteForSeconds(8.0F); } @@ -268,7 +268,7 @@ } public void onAboveBubbleCol(boolean p_20313_) { -@@ -2562,7 +_,7 @@ +@@ -2590,7 +_,7 @@ } protected Component getTypeName() { @@ -277,7 +277,7 @@ } public boolean is(Entity p_20356_) { -@@ -2617,10 +_,11 @@ +@@ -2645,10 +_,11 @@ } protected final boolean isInvulnerableToBase(DamageSource p_20122_) { @@ -290,7 +290,7 @@ } public boolean isInvulnerable() { -@@ -2645,6 +_,7 @@ +@@ -2673,6 +_,7 @@ @Nullable public Entity teleport(TeleportTransition p_379899_) { @@ -298,7 +298,7 @@ if (this.level() instanceof ServerLevel serverlevel && !this.isRemoved()) { ServerLevel serverlevel1 = p_379899_.newLevel(); boolean flag = serverlevel1.dimension() != serverlevel.dimension(); -@@ -2852,6 +_,7 @@ +@@ -2880,6 +_,7 @@ return this.stringUUID; } @@ -306,7 +306,7 @@ public boolean isPushedByFluid() { return true; } -@@ -2960,6 +_,8 @@ +@@ -2988,6 +_,8 @@ EntityDimensions entitydimensions = this.dimensions; Pose pose = this.getPose(); EntityDimensions entitydimensions1 = this.getDimensions(pose); @@ -315,7 +315,7 @@ this.dimensions = entitydimensions1; this.eyeHeight = entitydimensions1.eyeHeight(); this.reapplyPosition(); -@@ -3265,9 +_,17 @@ +@@ -3289,9 +_,17 @@ return Mth.lerp(p_352259_, this.yRotO, this.yRot); } @@ -334,7 +334,7 @@ } else { AABB aabb = this.getBoundingBox().deflate(0.001); int i = Mth.floor(aabb.minX); -@@ -3282,25 +_,36 @@ +@@ -3306,25 +_,36 @@ Vec3 vec3 = Vec3.ZERO; int k1 = 0; BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); @@ -378,7 +378,7 @@ } } } -@@ -3308,27 +_,30 @@ +@@ -3332,27 +_,30 @@ } } @@ -419,7 +419,7 @@ } } -@@ -3341,7 +_,10 @@ +@@ -3365,7 +_,10 @@ return !this.level().hasChunksAt(i, k, j, l); } @@ -430,7 +430,7 @@ return this.fluidHeight.getDouble(p_204037_); } -@@ -3478,6 +_,7 @@ +@@ -3502,6 +_,7 @@ this.levelCallback.onMove(); } @@ -438,7 +438,7 @@ } public void checkDespawn() { -@@ -3603,6 +_,128 @@ +@@ -3627,6 +_,128 @@ public boolean mayInteract(ServerLevel p_376870_, BlockPos p_146844_) { return true; diff --git a/patches/net/minecraft/world/entity/EntityType.java.patch b/patches/net/minecraft/world/entity/EntityType.java.patch index 4439873672..8f8b38efa5 100644 --- a/patches/net/minecraft/world/entity/EntityType.java.patch +++ b/patches/net/minecraft/world/entity/EntityType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/EntityType.java +++ b/net/minecraft/world/entity/EntityType.java -@@ -1088,6 +_,10 @@ +@@ -1070,6 +_,10 @@ private final float spawnDimensionsScale; private final FeatureFlagSet requiredFeatures; @@ -11,7 +11,7 @@ private static EntityType register(ResourceKey> p_368669_, EntityType.Builder p_368714_) { return Registry.register(BuiltInRegistries.ENTITY_TYPE, p_368669_, p_368714_.build(p_368669_)); } -@@ -1124,6 +_,28 @@ +@@ -1106,6 +_,28 @@ Optional> p_368696_, FeatureFlagSet p_273518_ ) { @@ -40,7 +40,7 @@ this.factory = p_273268_; this.category = p_272918_; this.canSpawnFarFromPlayer = p_272654_; -@@ -1138,6 +_,9 @@ +@@ -1120,6 +_,9 @@ this.descriptionId = p_368582_; this.lootTable = p_368696_; this.requiredFeatures = p_273518_; @@ -50,11 +50,10 @@ } @Nullable -@@ -1228,6 +_,15 @@ +@@ -1213,6 +_,13 @@ mob.yHeadRot = mob.getYRot(); mob.yBodyRot = mob.getYRot(); mob.finalizeSpawn(p_262637_, p_262637_.getCurrentDifficultyAt(mob.blockPosition()), p_360546_, null); -+ + if (mob.isSpawnCancelled()) { + // Neo: Discard mob, spawn was cancelled + mob.discard(); @@ -62,11 +61,10 @@ + // fixes llamas for wandering trader spawning if wandering trader was cancelled + return null; + } -+ - mob.playAmbientSound(); } -@@ -1410,14 +_,23 @@ + if (p_262629_ != null) { +@@ -1399,14 +_,23 @@ } public int clientTrackingRange() { @@ -90,8 +88,8 @@ return this != PLAYER && this != LLAMA_SPIT && this != WITHER -@@ -1469,6 +_,8 @@ - return (p_375561_, p_375562_) -> new ChestRaft(p_375561_, p_375562_, p_376648_); +@@ -1462,6 +_,8 @@ + return OP_ONLY_CUSTOM_DATA.contains(this); } + public Stream>> getTags() {return this.builtInRegistryHolder().tags();} @@ -99,7 +97,7 @@ public static class Builder { private final EntityType.EntityFactory factory; private final MobCategory category; -@@ -1488,6 +_,10 @@ +@@ -1481,6 +_,10 @@ ); private DependantName, String> descriptionId = p_367918_ -> Util.makeDescriptionId("entity", p_367918_.location()); @@ -110,7 +108,7 @@ private Builder(EntityType.EntityFactory p_20696_, MobCategory p_20697_) { this.factory = p_20696_; this.category = p_20697_; -@@ -1600,6 +_,21 @@ +@@ -1593,6 +_,21 @@ return this; } @@ -132,7 +130,7 @@ public EntityType build(ResourceKey> p_368626_) { if (this.serialize) { Util.fetchChoiceType(References.ENTITY_TREE, p_368626_.location().toString()); -@@ -1619,7 +_,10 @@ +@@ -1612,7 +_,10 @@ this.updateInterval, this.descriptionId.get(p_368626_), this.lootTable.get(p_368626_), diff --git a/patches/net/minecraft/world/entity/ExperienceOrb.java.patch b/patches/net/minecraft/world/entity/ExperienceOrb.java.patch index 9a5df1bf49..673882035f 100644 --- a/patches/net/minecraft/world/entity/ExperienceOrb.java.patch +++ b/patches/net/minecraft/world/entity/ExperienceOrb.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ExperienceOrb.java +++ b/net/minecraft/world/entity/ExperienceOrb.java -@@ -113,7 +_,8 @@ +@@ -114,7 +_,8 @@ this.applyEffectsFromBlocks(); float f = 0.98F; if (this.onGround()) { @@ -10,7 +10,7 @@ } this.setDeltaMovement(this.getDeltaMovement().multiply((double)f, 0.98, (double)f)); -@@ -134,7 +_,7 @@ +@@ -135,7 +_,7 @@ private void scanForEntities() { if (this.followingPlayer == null || this.followingPlayer.distanceToSqr(this) > 64.0) { @@ -19,7 +19,7 @@ } if (this.level() instanceof ServerLevel) { -@@ -232,6 +_,7 @@ +@@ -233,6 +_,7 @@ public void playerTouch(Player p_20792_) { if (p_20792_ instanceof ServerPlayer serverplayer) { if (p_20792_.takeXpDelay == 0) { @@ -27,7 +27,7 @@ p_20792_.takeXpDelay = 2; p_20792_.take(this, 1); int i = this.repairPlayerItems(serverplayer, this.value); -@@ -251,7 +_,7 @@ +@@ -252,7 +_,7 @@ Optional optional = EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, p_344821_, ItemStack::isDamaged); if (optional.isPresent()) { ItemStack itemstack = optional.get().itemStack(); diff --git a/patches/net/minecraft/world/entity/LivingEntity.java.patch b/patches/net/minecraft/world/entity/LivingEntity.java.patch index 982040cc46..2527407cae 100644 --- a/patches/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/net/minecraft/world/entity/LivingEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -137,7 +_,7 @@ +@@ -136,7 +_,7 @@ import net.minecraft.world.scores.Scoreboard; import org.slf4j.Logger; @@ -9,7 +9,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private static final String TAG_ACTIVE_EFFECTS = "active_effects"; private static final ResourceLocation SPEED_MODIFIER_POWDER_SNOW_ID = ResourceLocation.withDefaultNamespace("powder_snow"); -@@ -179,13 +_,18 @@ +@@ -178,13 +_,18 @@ public static final float EXTRA_RENDER_CULLING_SIZE_WITH_BIG_HAT = 0.5F; public static final float DEFAULT_BABY_SCALE = 0.5F; public static final String ATTRIBUTES_FIELD = "attributes"; @@ -30,7 +30,7 @@ }; private final AttributeMap attributes; private final CombatTracker combatTracker = new CombatTracker(this); -@@ -268,6 +_,14 @@ +@@ -266,6 +_,14 @@ EquipmentSlot.class ); protected float appliedScale = 1.0F; @@ -45,7 +45,7 @@ protected LivingEntity(EntityType p_20966_, Level p_20967_) { super(p_20966_, p_20967_); -@@ -334,7 +_,9 @@ +@@ -332,7 +_,9 @@ .add(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE) .add(Attributes.WATER_MOVEMENT_EFFICIENCY) .add(Attributes.MOVEMENT_EFFICIENCY) @@ -56,7 +56,7 @@ } @Override -@@ -362,7 +_,8 @@ +@@ -360,7 +_,8 @@ float f = (float)Mth.ceil((double)this.fallDistance - d7); double d4 = Math.min((double)(0.2F + f / 15.0F), 2.5); int i = (int)(150.0 * d4); @@ -66,7 +66,7 @@ } } -@@ -372,6 +_,7 @@ +@@ -370,6 +_,7 @@ } } @@ -74,7 +74,7 @@ public final boolean canBreatheUnderwater() { return this.getType().is(EntityTypeTags.CAN_BREATHE_UNDER_WATER); } -@@ -418,6 +_,9 @@ +@@ -416,6 +_,9 @@ } } @@ -258,22 +258,10 @@ } + p_376610_ = this.damageContainers.peek().getNewDamage(); //update local with container value - Entity entity = p_376460_.getEntity(); - if (entity != null) { - if (entity instanceof LivingEntity livingentity1 -@@ -1164,9 +_,9 @@ - if (entity instanceof Player player1) { - this.lastHurtByPlayerTime = 100; - this.lastHurtByPlayer = player1; -- } else if (entity instanceof Wolf wolf && wolf.isTame()) { -+ } else if (entity instanceof TamableAnimal tamableAnimal && tamableAnimal.isTame()) { - this.lastHurtByPlayerTime = 100; -- if (wolf.getOwner() instanceof Player player) { -+ if (tamableAnimal.getOwner() instanceof Player player) { - this.lastHurtByPlayer = player; - } else { - this.lastHurtByPlayer = null; -@@ -1237,6 +_,7 @@ + this.resolveMobResponsibleForDamage(p_376460_); + this.resolvePlayerResponsibleForDamage(p_376460_); + if (flag1) { +@@ -1218,6 +_,7 @@ CriteriaTriggers.PLAYER_HURT_ENTITY.trigger(serverplayer1, this, p_376460_, f, p_376610_, flag); } @@ -281,7 +269,19 @@ return flag2; } } -@@ -1259,7 +_,7 @@ +@@ -1238,9 +_,9 @@ + this.lastHurtByPlayer = player; + return player; + } else { +- if (entity instanceof Wolf wolf && wolf.isTame()) { ++ if (entity instanceof TamableAnimal tamableAnimal && tamableAnimal.isTame()) { + this.lastHurtByPlayerTime = 100; +- if (wolf.getOwner() instanceof Player player1) { ++ if (tamableAnimal.getOwner() instanceof Player player1) { + this.lastHurtByPlayer = player1; + } else { + this.lastHurtByPlayer = null; +@@ -1271,7 +_,7 @@ for (InteractionHand interactionhand : InteractionHand.values()) { ItemStack itemstack1 = this.getItemInHand(interactionhand); deathprotection = itemstack1.get(DataComponents.DEATH_PROTECTION); @@ -290,7 +290,7 @@ itemstack = itemstack1.copy(); itemstack1.shrink(1); break; -@@ -1309,7 +_,7 @@ +@@ -1321,7 +_,7 @@ } ItemStack itemstack = this.getItemBlockingWith(); @@ -299,7 +299,7 @@ Vec3 vec3 = p_21276_.getSourcePosition(); if (vec3 != null) { Vec3 vec31 = this.calculateViewVector(0.0F, this.getYHeadRot()); -@@ -1343,6 +_,7 @@ +@@ -1355,6 +_,7 @@ } public void die(DamageSource p_21014_) { @@ -307,7 +307,7 @@ if (!this.isRemoved() && !this.dead) { Entity entity = p_21014_.getEntity(); LivingEntity livingentity = this.getKillCredit(); -@@ -1378,7 +_,7 @@ +@@ -1390,7 +_,7 @@ if (this.level() instanceof ServerLevel serverlevel) { boolean flag = false; if (p_21269_ instanceof WitherBoss) { @@ -316,7 +316,7 @@ BlockPos blockpos = this.blockPosition(); BlockState blockstate = Blocks.WITHER_ROSE.defaultBlockState(); if (this.level().getBlockState(blockpos).isAir() && blockstate.canSurvive(this.level(), blockpos)) { -@@ -1396,6 +_,7 @@ +@@ -1408,6 +_,7 @@ } protected void dropAllDeathLoot(ServerLevel p_348524_, DamageSource p_21192_) { @@ -324,7 +324,7 @@ boolean flag = this.lastHurtByPlayerTime > 0; if (this.shouldDropLoot() && p_348524_.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { this.dropFromLootTable(p_348524_, p_21192_, flag); -@@ -1404,6 +_,10 @@ +@@ -1416,6 +_,10 @@ this.dropEquipment(p_348524_); this.dropExperience(p_348524_, p_21192_.getEntity()); @@ -335,7 +335,7 @@ } protected void dropEquipment(ServerLevel p_376330_) { -@@ -1415,7 +_,8 @@ +@@ -1427,7 +_,8 @@ this.isAlwaysExperienceDropper() || this.lastHurtByPlayerTime > 0 && this.shouldDropExperience() && p_376909_.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT) )) { @@ -345,7 +345,7 @@ } } -@@ -1496,6 +_,11 @@ +@@ -1508,6 +_,11 @@ } public void knockback(double p_147241_, double p_147242_, double p_147243_) { @@ -357,7 +357,7 @@ p_147241_ *= 1.0 - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE); if (!(p_147241_ <= 0.0)) { this.hasImpulse = true; -@@ -1569,15 +_,9 @@ +@@ -1585,15 +_,9 @@ } else { BlockPos blockpos = this.blockPosition(); BlockState blockstate = this.getInBlockState(); @@ -376,27 +376,7 @@ } } -@@ -1595,10 +_,18 @@ - return !this.isRemoved() && this.getHealth() > 0.0F; - } - -+ /** @deprecated Neo: use {@link #isLookingAtMe(LivingEntity, double, boolean, boolean, java.util.function.BiPredicate, DoubleSupplier...)} instead */ -+ @Deprecated - public boolean isLookingAtMe( - LivingEntity p_379420_, double p_379671_, boolean p_380253_, boolean p_380067_, Predicate p_380351_, DoubleSupplier... p_380073_ - ) { -- if (!p_380351_.test(p_379420_)) { -+ return isLookingAtMe(p_379420_, p_379671_, p_380253_, p_380067_, (observer, target) -> p_380351_.test(observer), p_380073_); -+ } -+ -+ public boolean isLookingAtMe( -+ LivingEntity p_379420_, double p_379671_, boolean p_380253_, boolean p_380067_, java.util.function.BiPredicate p_380351_, DoubleSupplier... p_380073_ -+ ) { -+ if (!p_380351_.test(p_379420_, this)) { - return false; - } else { - Vec3 vec3 = p_379420_.getViewVector(1.0F).normalize(); -@@ -1630,6 +_,11 @@ +@@ -1639,6 +_,11 @@ @Override public boolean causeFallDamage(float p_147187_, float p_147188_, DamageSource p_147189_) { @@ -408,7 +388,7 @@ boolean flag = super.causeFallDamage(p_147187_, p_147188_, p_147189_); int i = this.calculateFallDamage(p_147187_, p_147188_); if (i > 0) { -@@ -1657,9 +_,10 @@ +@@ -1666,9 +_,10 @@ int i = Mth.floor(this.getX()); int j = Mth.floor(this.getY() - 0.2F); int k = Mth.floor(this.getZ()); @@ -421,7 +401,7 @@ this.playSound(soundtype.getFallSound(), soundtype.getVolume() * 0.5F, soundtype.getPitch() * 0.75F); } } -@@ -1688,6 +_,8 @@ +@@ -1697,6 +_,8 @@ if (!(p_330394_ <= 0.0F)) { int i = (int)Math.max(1.0F, p_330394_ / 4.0F); @@ -430,7 +410,7 @@ for (EquipmentSlot equipmentslot : p_331314_) { ItemStack itemstack = this.getItemBySlot(equipmentslot); Equippable equippable = itemstack.get(DataComponents.EQUIPPABLE); -@@ -1721,6 +_,7 @@ +@@ -1730,6 +_,7 @@ p_21194_ = Math.max(f / 25.0F, 0.0F); float f2 = f1 - p_21194_; if (f2 > 0.0F && f2 < 3.4028235E37F) { @@ -438,7 +418,7 @@ if (this instanceof ServerPlayer) { ((ServerPlayer)this).awardStat(Stats.DAMAGE_RESISTED, Math.round(f2 * 10.0F)); } else if (p_21193_.getEntity() instanceof ServerPlayer) { -@@ -1743,6 +_,7 @@ +@@ -1752,6 +_,7 @@ if (f3 > 0.0F) { p_21194_ = CombatRules.getDamageAfterMagicAbsorb(p_21194_, f3); @@ -446,7 +426,7 @@ } return p_21194_; -@@ -1752,11 +_,14 @@ +@@ -1761,11 +_,14 @@ protected void actuallyHurt(ServerLevel p_376745_, DamageSource p_21240_, float p_21241_) { if (!this.isInvulnerableTo(p_376745_, p_21240_)) { @@ -466,7 +446,7 @@ if (f > 0.0F && f < 3.4028235E37F && p_21240_.getEntity() instanceof ServerPlayer serverplayer) { serverplayer.awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(f * 10.0F)); } -@@ -1764,9 +_,10 @@ +@@ -1773,9 +_,10 @@ if (f1 != 0.0F) { this.getCombatTracker().recordDamage(p_21240_, f1); this.setHealth(this.getHealth() - f1); @@ -478,7 +458,7 @@ } } -@@ -1820,6 +_,8 @@ +@@ -1829,6 +_,8 @@ } public void swing(InteractionHand p_21012_, boolean p_21013_) { @@ -487,7 +467,7 @@ if (!this.swinging || this.swingTime >= this.getCurrentSwingDuration() / 2 || this.swingTime < 0) { this.swingTime = -1; this.swinging = true; -@@ -1933,8 +_,10 @@ +@@ -1942,8 +_,10 @@ private void swapHandItems() { ItemStack itemstack = this.getItemBySlot(EquipmentSlot.OFFHAND); @@ -500,7 +480,7 @@ } @Override -@@ -2152,15 +_,18 @@ +@@ -2161,15 +_,18 @@ } this.hasImpulse = true; @@ -521,7 +501,7 @@ } protected float getWaterSlowDown() { -@@ -2196,7 +_,7 @@ +@@ -2205,7 +_,7 @@ private void travelInAir(Vec3 p_362457_) { BlockPos blockpos = this.getBlockPosBelowThatAffectsMyMovement(); @@ -530,7 +510,7 @@ float f1 = f * 0.91F; Vec3 vec3 = this.handleRelativeFrictionAndCalculateMovement(p_362457_, f); double d0 = vec3.y; -@@ -2219,11 +_,19 @@ +@@ -2228,11 +_,19 @@ } } @@ -551,7 +531,7 @@ float f = this.isSprinting() ? 0.9F : this.getWaterSlowDown(); float f1 = 0.02F; float f2 = (float)this.getAttributeValue(Attributes.WATER_MOVEMENT_EFFICIENCY); -@@ -2240,6 +_,7 @@ +@@ -2249,6 +_,7 @@ f = 0.96F; } @@ -559,7 +539,7 @@ this.moveRelative(f1, p_365480_); this.move(MoverType.SELF, this.getDeltaMovement()); Vec3 vec3 = this.getDeltaMovement(); -@@ -2389,7 +_,7 @@ +@@ -2398,7 +_,7 @@ double d0 = Mth.clamp(p_21298_.x, -0.15F, 0.15F); double d1 = Mth.clamp(p_21298_.z, -0.15F, 0.15F); double d2 = Math.max(p_21298_.y, -0.15F); @@ -568,7 +548,7 @@ d2 = 0.0; } -@@ -2574,6 +_,7 @@ +@@ -2583,6 +_,7 @@ }; ItemStack itemstack1 = this.getItemBySlot(equipmentslot); if (this.equipmentHasChanged(itemstack, itemstack1)) { @@ -576,7 +556,7 @@ if (map == null) { map = Maps.newEnumMap(EquipmentSlot.class); } -@@ -2733,6 +_,9 @@ +@@ -2742,6 +_,9 @@ profilerfiller.push("jump"); if (this.jumping && this.isAffectedByFluids()) { double d3; @@ -586,7 +566,7 @@ if (this.isInLava()) { d3 = this.getFluidHeight(FluidTags.LAVA); } else { -@@ -2743,15 +_,17 @@ +@@ -2752,15 +_,17 @@ double d4 = this.getFluidJumpThreshold(); if (!flag || this.onGround() && !(d3 > d4)) { if (!this.isInLava() || this.onGround() && !(d3 > d4)) { @@ -606,7 +586,7 @@ } } else { this.noJumpDelay = 0; -@@ -3104,8 +_,11 @@ +@@ -3113,8 +_,11 @@ private void updatingUsingItem() { if (this.isUsingItem()) { @@ -620,7 +600,7 @@ this.updateUsingItem(this.useItem); } else { this.stopUsingItem(); -@@ -3114,8 +_,11 @@ +@@ -3123,8 +_,11 @@ } protected void updateUsingItem(ItemStack p_147201_) { @@ -633,7 +613,7 @@ this.completeUsingItem(); } } -@@ -3143,8 +_,10 @@ +@@ -3152,8 +_,10 @@ public void startUsingItem(InteractionHand p_21159_) { ItemStack itemstack = this.getItemInHand(p_21159_); if (!itemstack.isEmpty() && !this.isUsingItem()) { @@ -645,7 +625,7 @@ if (!this.level().isClientSide) { this.setLivingEntityFlag(1, true); this.setLivingEntityFlag(2, p_21159_ == InteractionHand.OFF_HAND); -@@ -3207,7 +_,8 @@ +@@ -3216,7 +_,8 @@ this.releaseUsingItem(); } else { if (!this.useItem.isEmpty() && this.isUsingItem()) { @@ -655,7 +635,7 @@ if (itemstack != this.useItem) { this.setItemInHand(interactionhand, itemstack); } -@@ -3235,7 +_,11 @@ +@@ -3244,7 +_,11 @@ public void releaseUsingItem() { if (!this.useItem.isEmpty()) { @@ -667,7 +647,7 @@ if (this.useItem.useOnRelease()) { this.updatingUsingItem(); } -@@ -3245,6 +_,7 @@ +@@ -3254,6 +_,7 @@ } public void stopUsingItem() { @@ -675,7 +655,7 @@ if (!this.level().isClientSide) { boolean flag = this.isUsingItem(); this.setLivingEntityFlag(1, false); -@@ -3265,7 +_,7 @@ +@@ -3274,7 +_,7 @@ public ItemStack getItemBlockingWith() { if (this.isUsingItem() && !this.useItem.isEmpty()) { Item item = this.useItem.getItem(); @@ -684,7 +664,7 @@ return null; } else { return item.getUseDuration(this.useItem, this) - this.useItemRemaining < 5 ? null : this.useItem; -@@ -3410,8 +_,8 @@ +@@ -3419,8 +_,8 @@ } BlockState blockstate = this.level().getBlockState(p_21141_); @@ -695,11 +675,11 @@ } this.setPose(Pose.SLEEPING); -@@ -3426,15 +_,17 @@ +@@ -3435,15 +_,17 @@ } private boolean checkBedExists() { -- return this.getSleepingPos().map(p_381383_ -> this.level().getBlockState(p_381383_).getBlock() instanceof BedBlock).orElse(false); +- return this.getSleepingPos().map(p_390116_ -> this.level().getBlockState(p_390116_).getBlock() instanceof BedBlock).orElse(false); + // Neo: Overwrite the vanilla instanceof BedBlock check with isBed and fire the CanContinueSleepingEvent. + boolean hasBed = this.getSleepingPos().map(pos -> this.level().getBlockState(pos).isBed(this.level(), pos, this)).orElse(false); + return net.neoforged.neoforge.event.EventHooks.canEntityContinueSleeping(this, hasBed ? null : Player.BedSleepingProblem.NOT_POSSIBLE_HERE); @@ -716,7 +696,7 @@ Vec3 vec31 = BedBlock.findStandUpPosition(this.getType(), this.level(), p_261435_, direction, this.getYRot()).orElseGet(() -> { BlockPos blockpos = p_261435_.above(); return new Vec3((double)blockpos.getX() + 0.5, (double)blockpos.getY() + 0.1, (double)blockpos.getZ() + 0.5); -@@ -3455,7 +_,9 @@ +@@ -3464,7 +_,9 @@ @Nullable public Direction getBedOrientation() { BlockPos blockpos = this.getSleepingPos().orElse(null); @@ -727,7 +707,7 @@ } @Override -@@ -3464,7 +_,7 @@ +@@ -3473,7 +_,7 @@ } public ItemStack getProjectile(ItemStack p_21272_) { @@ -736,7 +716,7 @@ } private static byte entityEventForEquipmentBreak(EquipmentSlot p_21267_) { -@@ -3519,6 +_,8 @@ +@@ -3528,6 +_,8 @@ } public final EquipmentSlot getEquipmentSlotForItem(ItemStack p_147234_) { @@ -745,7 +725,7 @@ Equippable equippable = p_147234_.get(DataComponents.EQUIPPABLE); return equippable != null && this.canUseSlot(equippable.slot()) ? equippable.slot() : EquipmentSlot.MAINHAND; } -@@ -3604,7 +_,7 @@ +@@ -3613,7 +_,7 @@ } public boolean canDisableShield() { diff --git a/patches/net/minecraft/world/entity/Mob.java.patch b/patches/net/minecraft/world/entity/Mob.java.patch index 715ee233ce..4fc5a918fc 100644 --- a/patches/net/minecraft/world/entity/Mob.java.patch +++ b/patches/net/minecraft/world/entity/Mob.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -135,6 +_,11 @@ +@@ -131,6 +_,11 @@ private Leashable.LeashData leashData; private BlockPos restrictCenter = BlockPos.ZERO; private float restrictRadius = -1.0F; @@ -12,7 +12,7 @@ protected Mob(EntityType p_21368_, Level p_21369_) { super(p_21368_, p_21369_); -@@ -241,7 +_,10 @@ +@@ -237,7 +_,10 @@ } public void setTarget(@Nullable LivingEntity p_21544_) { @@ -24,7 +24,7 @@ } @Override -@@ -344,6 +_,12 @@ +@@ -340,6 +_,12 @@ if (!this.level().isClientSide && this.tickCount % 5 == 0) { this.updateControlFlags(); } @@ -37,7 +37,7 @@ } protected void updateControlFlags() { -@@ -423,6 +_,9 @@ +@@ -420,6 +_,9 @@ if (this.isNoAi()) { p_21484_.putBoolean("NoAI", this.isNoAi()); } @@ -47,9 +47,9 @@ } @Override -@@ -482,6 +_,14 @@ - } +@@ -486,6 +_,14 @@ + this.lootTableSeed = p_21450_.getLong("DeathLootTableSeed"); this.setNoAi(p_21450_.getBoolean("NoAI")); + + if (p_21450_.contains("neoforge:spawn_type")) { @@ -62,7 +62,7 @@ } @Override -@@ -534,7 +_,7 @@ +@@ -538,7 +_,7 @@ && this.canPickUpLoot() && this.isAlive() && !this.dead @@ -71,7 +71,7 @@ Vec3i vec3i = this.getPickupReach(); for (ItemEntity itementity : this.level() -@@ -666,6 +_,8 @@ +@@ -661,6 +_,8 @@ private double getApproximateAttributeWith(ItemStack p_371461_, Holder p_371421_, EquipmentSlot p_371891_) { double d0 = this.getAttributes().hasAttribute(p_371421_) ? this.getAttributeBaseValue(p_371421_) : 0.0; ItemAttributeModifiers itemattributemodifiers = p_371461_.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); @@ -80,7 +80,7 @@ return itemattributemodifiers.compute(d0, p_371891_); } -@@ -701,6 +_,7 @@ +@@ -703,6 +_,7 @@ @Override public void checkDespawn() { @@ -88,7 +88,7 @@ if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { this.discard(); } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { -@@ -1127,6 +_,11 @@ +@@ -1129,6 +_,11 @@ } } @@ -100,7 +100,7 @@ @Nullable public SpawnGroupData finalizeSpawn( ServerLevelAccessor p_21434_, DifficultyInstance p_21435_, EntitySpawnReason p_363352_, @Nullable SpawnGroupData p_21437_ -@@ -1140,6 +_,7 @@ +@@ -1142,6 +_,7 @@ } this.setLeftHanded(randomsource.nextFloat() < 0.05F); @@ -108,7 +108,7 @@ return p_21437_; } -@@ -1281,6 +_,7 @@ +@@ -1283,6 +_,7 @@ } else { p_371709_.type().convert(this, t, p_371709_); p_371266_.finalizeConversion(t); @@ -116,7 +116,7 @@ if (this.level() instanceof ServerLevel serverlevel) { serverlevel.addFreshEntity(t); } -@@ -1452,14 +_,24 @@ +@@ -1453,14 +_,24 @@ } @Override @@ -142,7 +142,7 @@ @VisibleForTesting public void removeFreeWill() { this.removeAllGoals(p_351790_ -> true); -@@ -1503,5 +_,40 @@ +@@ -1504,5 +_,40 @@ @VisibleForTesting public float[] getArmorDropChances() { return this.armorDropChances; diff --git a/patches/net/minecraft/world/entity/SpawnPlacements.java.patch b/patches/net/minecraft/world/entity/SpawnPlacements.java.patch index 4717f19fc6..97d3d28aa0 100644 --- a/patches/net/minecraft/world/entity/SpawnPlacements.java.patch +++ b/patches/net/minecraft/world/entity/SpawnPlacements.java.patch @@ -26,7 +26,7 @@ } static { -@@ -183,5 +_,16 @@ +@@ -182,5 +_,16 @@ @FunctionalInterface public interface SpawnPredicate { boolean test(EntityType p_217081_, ServerLevelAccessor p_217082_, EntitySpawnReason p_363558_, BlockPos p_217084_, RandomSource p_217085_); diff --git a/patches/net/minecraft/world/entity/TamableAnimal.java.patch b/patches/net/minecraft/world/entity/TamableAnimal.java.patch index f7af6e6974..a2b17b928a 100644 --- a/patches/net/minecraft/world/entity/TamableAnimal.java.patch +++ b/patches/net/minecraft/world/entity/TamableAnimal.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/TamableAnimal.java +++ b/net/minecraft/world/entity/TamableAnimal.java -@@ -221,13 +_,16 @@ +@@ -224,13 +_,16 @@ @Override public void die(DamageSource p_21809_) { diff --git a/patches/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java.patch b/patches/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java.patch index 26208739b5..2a3dd7d38f 100644 --- a/patches/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java.patch +++ b/patches/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java +++ b/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java -@@ -177,11 +_,12 @@ +@@ -176,11 +_,12 @@ .build(); public static AttributeSupplier getSupplier(EntityType p_22298_) { diff --git a/patches/net/minecraft/world/entity/animal/Bee.java.patch b/patches/net/minecraft/world/entity/animal/Bee.java.patch index 3e5e904026..bb949d825f 100644 --- a/patches/net/minecraft/world/entity/animal/Bee.java.patch +++ b/patches/net/minecraft/world/entity/animal/Bee.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Bee.java +++ b/net/minecraft/world/entity/animal/Bee.java -@@ -498,7 +_,7 @@ +@@ -501,7 +_,7 @@ if (this.hivePos == null) { return null; } else { @@ -9,7 +9,7 @@ } } -@@ -644,8 +_,18 @@ +@@ -664,8 +_,18 @@ } @Override diff --git a/patches/net/minecraft/world/entity/animal/Cat.java.patch b/patches/net/minecraft/world/entity/animal/Cat.java.patch index 45b5cd9505..26022339ce 100644 --- a/patches/net/minecraft/world/entity/animal/Cat.java.patch +++ b/patches/net/minecraft/world/entity/animal/Cat.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Cat.java +++ b/net/minecraft/world/entity/animal/Cat.java -@@ -373,9 +_,9 @@ +@@ -371,9 +_,9 @@ } } else if (this.isFood(itemstack) && this.getHealth() < this.getMaxHealth()) { if (!this.level().isClientSide()) { @@ -11,7 +11,7 @@ this.playEatingSound(); } -@@ -437,7 +_,7 @@ +@@ -435,7 +_,7 @@ } private void tryToTame(Player p_333858_) { diff --git a/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch b/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch index 373b37a15a..2e26e763a7 100644 --- a/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch +++ b/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/world/entity/animal/MushroomCow.java +++ b/net/minecraft/world/entity/animal/MushroomCow.java -@@ -166,11 +_,19 @@ +@@ -165,11 +_,19 @@ @Override public void shear(ServerLevel p_376375_, SoundSource p_28924_, ItemStack p_373092_) { p_376375_.playSound(null, this, SoundEvents.MOOSHROOM_SHEAR, p_28924_, 1.0F, 1.0F); + if (!net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.COW, (timer) -> {})) return; - this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), p_381482_ -> { -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381482_); + this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), p_390217_ -> { ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_390217_); p_376375_.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 1, 0.0, 0.0, 0.0, 0.0); - this.dropFromShearingLootTable(p_376375_, BuiltInLootTables.SHEAR_MOOSHROOM, p_373092_, (p_381483_, p_381484_) -> { - for (int i = 0; i < p_381484_.getCount(); i++) { -- p_381483_.addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), p_381484_.copyWithCount(1))); + this.dropFromShearingLootTable(p_376375_, BuiltInLootTables.SHEAR_MOOSHROOM, p_373092_, (p_390218_, p_390219_) -> { + for (int i = 0; i < p_390219_.getCount(); i++) { +- p_390218_.addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), p_390219_.copyWithCount(1))); + // Neo: Change from addFreshEntity to spawnAtLocation to ensure captureDrops can capture this, we also need to unset the default pickup delay from the item + // Vanilla uses this.getY(1.0) for the y-level, which is this.getY() + this.getBbHeight() * 1.0, so we pass the BB height as the Y-offset. -+ ItemEntity item = spawnAtLocation(p_381483_, p_381484_.copyWithCount(1), this.getBbHeight()); ++ ItemEntity item = spawnAtLocation(p_390218_, p_390219_.copyWithCount(1), this.getBbHeight()); + if (item != null) { + // addFreshEntity does not incur a pickup delay, while spawnAtLocation sets the default pickup delay. + item.setNoPickUpDelay(); diff --git a/patches/net/minecraft/world/entity/animal/Parrot.java.patch b/patches/net/minecraft/world/entity/animal/Parrot.java.patch index ba8eca84e8..ac16c7a64a 100644 --- a/patches/net/minecraft/world/entity/animal/Parrot.java.patch +++ b/patches/net/minecraft/world/entity/animal/Parrot.java.patch @@ -10,10 +10,10 @@ }; + /** @deprecated Neo: use the {@link net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps#PARROT_IMITATIONS data map} instead */ + @Deprecated - static final Map, SoundEvent> MOB_SOUND_MAP = Util.make(Maps.newHashMap(), p_379158_ -> { - p_379158_.put(EntityType.BLAZE, SoundEvents.PARROT_IMITATE_BLAZE); - p_379158_.put(EntityType.BOGGED, SoundEvents.PARROT_IMITATE_BOGGED); -@@ -261,7 +_,7 @@ + static final Map, SoundEvent> MOB_SOUND_MAP = Util.make(Maps.newHashMap(), p_389382_ -> { + p_389382_.put(EntityType.BLAZE, SoundEvents.PARROT_IMITATE_BLAZE); + p_389382_.put(EntityType.BOGGED, SoundEvents.PARROT_IMITATE_BOGGED); +@@ -259,7 +_,7 @@ } if (!this.level().isClientSide) { @@ -22,7 +22,7 @@ this.tame(p_29414_); this.level().broadcastEntityEvent(this, (byte)7); } else { -@@ -325,7 +_,10 @@ +@@ -323,7 +_,10 @@ public static SoundEvent getAmbient(Level p_218239_, RandomSource p_218240_) { if (p_218239_.getDifficulty() != Difficulty.PEACEFUL && p_218240_.nextInt(1000) == 0) { @@ -34,7 +34,7 @@ return getImitatedSound(list.get(p_218240_.nextInt(list.size()))); } else { return SoundEvents.PARROT_AMBIENT; -@@ -333,7 +_,9 @@ +@@ -331,7 +_,9 @@ } private static SoundEvent getImitatedSound(EntityType p_29409_) { diff --git a/patches/net/minecraft/world/entity/animal/Pig.java.patch b/patches/net/minecraft/world/entity/animal/Pig.java.patch index 35f07ef1d6..f1744c625a 100644 --- a/patches/net/minecraft/world/entity/animal/Pig.java.patch +++ b/patches/net/minecraft/world/entity/animal/Pig.java.patch @@ -6,13 +6,13 @@ public void thunderHit(ServerLevel p_29473_, LightningBolt p_29474_) { - if (p_29473_.getDifficulty() != Difficulty.PEACEFUL) { + if (p_29473_.getDifficulty() != Difficulty.PEACEFUL && net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.ZOMBIFIED_PIGLIN, (timer) -> {})) { - ZombifiedPiglin zombifiedpiglin = this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, false, true), p_381485_ -> { + ZombifiedPiglin zombifiedpiglin = this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, false, true), p_390220_ -> { if (this.getMainHandItem().isEmpty()) { - p_381485_.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD)); + p_390220_.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD)); } - p_381485_.setPersistenceRequired(); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381485_); + p_390220_.setPersistenceRequired(); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_390220_); }); if (zombifiedpiglin == null) { super.thunderHit(p_29473_, p_29474_); diff --git a/patches/net/minecraft/world/entity/animal/Sheep.java.patch b/patches/net/minecraft/world/entity/animal/Sheep.java.patch index e22cf4c2d2..0105181c13 100644 --- a/patches/net/minecraft/world/entity/animal/Sheep.java.patch +++ b/patches/net/minecraft/world/entity/animal/Sheep.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Sheep.java +++ b/net/minecraft/world/entity/animal/Sheep.java -@@ -156,7 +_,7 @@ +@@ -151,7 +_,7 @@ @Override public InteractionResult mobInteract(Player p_29853_, InteractionHand p_29854_) { ItemStack itemstack = p_29853_.getItemInHand(p_29854_); diff --git a/patches/net/minecraft/world/entity/animal/allay/Allay.java.patch b/patches/net/minecraft/world/entity/animal/allay/Allay.java.patch index f0ede9df6e..bc64513b73 100644 --- a/patches/net/minecraft/world/entity/animal/allay/Allay.java.patch +++ b/patches/net/minecraft/world/entity/animal/allay/Allay.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/allay/Allay.java +++ b/net/minecraft/world/entity/animal/allay/Allay.java -@@ -369,9 +_,9 @@ +@@ -375,9 +_,9 @@ public boolean wantsToPickUp(ServerLevel p_376111_, ItemStack p_218387_) { ItemStack itemstack = this.getItemInHand(InteractionHand.MAIN_HAND); return !itemstack.isEmpty() diff --git a/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch b/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch index 90a3bb4745..fd527c7159 100644 --- a/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch +++ b/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch @@ -6,8 +6,8 @@ private void ageUp() { + if (!net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.FROG, (timer) -> {})) return; if (this.level() instanceof ServerLevel serverlevel) { - this.convertTo(EntityType.FROG, ConversionParams.single(this, false, false), p_381493_ -> { -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381493_); - p_381493_.finalizeSpawn(serverlevel, this.level().getCurrentDifficultyAt(p_381493_.blockPosition()), EntitySpawnReason.CONVERSION, null); - p_381493_.setPersistenceRequired(); - p_381493_.fudgePositionAfterSizeChange(this.getDimensions(this.getPose())); + this.convertTo(EntityType.FROG, ConversionParams.single(this, false, false), p_390228_ -> { ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_390228_); + p_390228_.finalizeSpawn(serverlevel, this.level().getCurrentDifficultyAt(p_390228_.blockPosition()), EntitySpawnReason.CONVERSION, null); + p_390228_.setPersistenceRequired(); + p_390228_.fudgePositionAfterSizeChange(this.getDimensions(this.getPose())); diff --git a/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch b/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch index b807a36c3f..7e30268049 100644 --- a/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch +++ b/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch @@ -50,8 +50,8 @@ } if (this.dragonDeathTime == 1 && !this.isSilent()) { -@@ -549,7 +_,8 @@ - this.move(MoverType.SELF, new Vec3(0.0, 0.1F, 0.0)); +@@ -556,7 +_,8 @@ + if (this.dragonDeathTime == 200 && this.level() instanceof ServerLevel serverlevel1) { if (serverlevel1.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - ExperienceOrb.award(serverlevel1, this.position(), Mth.floor((float)i * 0.2F)); @@ -60,7 +60,7 @@ } if (this.dragonFight != null) { -@@ -860,8 +_,19 @@ +@@ -867,8 +_,19 @@ } @Override diff --git a/patches/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch b/patches/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch index 5e036c641e..6b23c70528 100644 --- a/patches/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch +++ b/patches/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -320,7 +_,7 @@ +@@ -319,7 +_,7 @@ if (this.destroyBlocksTick > 0) { this.destroyBlocksTick--; @@ -9,7 +9,7 @@ boolean flag = false; int l = Mth.floor(this.getBbWidth() / 2.0F + 1.0F); int i1 = Mth.floor(this.getBbHeight()); -@@ -329,7 +_,7 @@ +@@ -328,7 +_,7 @@ this.getBlockX() - l, this.getBlockY(), this.getBlockZ() - l, this.getBlockX() + l, this.getBlockY() + i1, this.getBlockZ() + l )) { BlockState blockstate = p_376675_.getBlockState(blockpos); @@ -18,7 +18,7 @@ flag = p_376675_.destroyBlock(blockpos, true, this) || flag; } } -@@ -348,6 +_,10 @@ +@@ -347,6 +_,10 @@ } } @@ -29,7 +29,7 @@ public static boolean canDestroy(BlockState p_31492_) { return !p_31492_.isAir() && !p_31492_.is(BlockTags.WITHER_IMMUNE); } -@@ -493,6 +_,7 @@ +@@ -492,6 +_,7 @@ @Override public void checkDespawn() { diff --git a/patches/net/minecraft/world/entity/decoration/HangingEntity.java.patch b/patches/net/minecraft/world/entity/decoration/HangingEntity.java.patch index 830741b8a3..ef8a61ff2b 100644 --- a/patches/net/minecraft/world/entity/decoration/HangingEntity.java.patch +++ b/patches/net/minecraft/world/entity/decoration/HangingEntity.java.patch @@ -4,8 +4,8 @@ if (!this.level().noCollision(this)) { return false; } else { -- boolean flag = BlockPos.betweenClosedStream(this.calculateSupportBox()).allMatch(p_381503_ -> { -+ boolean flag = BlockPos.betweenClosedStream(this.calculateSupportBox()).filter(pos -> !net.minecraft.world.level.block.Block.canSupportCenter(this.level(), pos, this.direction)).allMatch(p_381503_ -> { - BlockState blockstate = this.level().getBlockState(p_381503_); +- boolean flag = BlockPos.betweenClosedStream(this.calculateSupportBox()).allMatch(p_390238_ -> { ++ boolean flag = BlockPos.betweenClosedStream(this.calculateSupportBox()).filter(pos -> !net.minecraft.world.level.block.Block.canSupportCenter(this.level(), pos, this.direction)).allMatch(p_390238_ -> { + BlockState blockstate = this.level().getBlockState(p_390238_); return blockstate.isSolid() || DiodeBlock.isDiode(blockstate); }); diff --git a/patches/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch b/patches/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch index 02972fce45..2670ddf8d7 100644 --- a/patches/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch +++ b/patches/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java -@@ -161,7 +_,7 @@ +@@ -163,7 +_,7 @@ if (this.level() != null && !this.level().isClientSide) { this.goalSelector.removeGoal(this.meleeGoal); this.goalSelector.removeGoal(this.bowGoal); @@ -9,7 +9,7 @@ if (itemstack.is(Items.BOW)) { int i = this.getHardAttackInterval(); if (this.level().getDifficulty() != Difficulty.HARD) { -@@ -186,9 +_,11 @@ +@@ -188,9 +_,11 @@ @Override public void performRangedAttack(LivingEntity p_32141_, float p_32142_) { diff --git a/patches/net/minecraft/world/entity/monster/EnderMan.java.patch b/patches/net/minecraft/world/entity/monster/EnderMan.java.patch index 7ef7212218..f5c5fc13eb 100644 --- a/patches/net/minecraft/world/entity/monster/EnderMan.java.patch +++ b/patches/net/minecraft/world/entity/monster/EnderMan.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/EnderMan.java +++ b/net/minecraft/world/entity/monster/EnderMan.java -@@ -118,7 +_,6 @@ +@@ -117,7 +_,6 @@ @Override public void setTarget(@Nullable LivingEntity p_32537_) { @@ -8,7 +8,7 @@ AttributeInstance attributeinstance = this.getAttribute(Attributes.MOVEMENT_SPEED); if (p_32537_ == null) { this.targetChangeTime = 0; -@@ -132,6 +_,7 @@ +@@ -131,6 +_,7 @@ attributeinstance.addTransientModifier(SPEED_MODIFIER_ATTACKING); } } @@ -16,17 +16,20 @@ } @Override -@@ -213,7 +_,8 @@ +@@ -212,9 +_,10 @@ } boolean isBeingStaredBy(Player p_380267_) { -- return this.isLookingAtMe(p_380267_, 0.025, true, false, LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM, new DoubleSupplier[]{this::getEyeY}); -+ return this.isLookingAtMe(p_380267_, 0.025, true, false, LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET, new DoubleSupplier[]{this::getEyeY}) && +- return !LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM.test(p_380267_) ++ return !LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET.test(p_380267_, this) + ? false +- : this.isLookingAtMe(p_380267_, 0.025, true, false, new double[]{this.getEyeY()}); ++ : this.isLookingAtMe(p_380267_, 0.025, true, false, new double[]{this.getEyeY()}) && + !net.neoforged.neoforge.common.CommonHooks.shouldSuppressEnderManAnger(this, p_380267_); } @Override -@@ -291,8 +_,10 @@ +@@ -292,8 +_,10 @@ boolean flag = blockstate.blocksMotion(); boolean flag1 = blockstate.getFluidState().is(FluidTags.WATER); if (flag && !flag1) { @@ -38,7 +41,7 @@ if (flag2) { this.level().gameEvent(GameEvent.TELEPORT, vec3, GameEvent.Context.of(this)); if (!this.isSilent()) { -@@ -449,7 +_,7 @@ +@@ -450,7 +_,7 @@ if (this.enderman.getCarriedBlock() == null) { return false; } else { @@ -47,7 +50,7 @@ ? false : this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0; } -@@ -469,7 +_,7 @@ +@@ -470,7 +_,7 @@ BlockState blockstate2 = this.enderman.getCarriedBlock(); if (blockstate2 != null) { blockstate2 = Block.updateFromNeighbourShapes(blockstate2, this.enderman.level(), blockpos); @@ -56,7 +59,7 @@ level.setBlock(blockpos, blockstate2, 3); level.gameEvent(GameEvent.BLOCK_PLACE, blockpos, GameEvent.Context.of(this.enderman, blockstate2)); this.enderman.setCarriedBlock(null); -@@ -481,6 +_,7 @@ +@@ -482,6 +_,7 @@ return p_32562_.isAir() && !p_32563_.isAir() && !p_32563_.is(Blocks.BEDROCK) @@ -64,7 +67,7 @@ && p_32563_.isCollisionShapeFullBlock(p_32559_, p_32564_) && p_32561_.canSurvive(p_32559_, p_32560_) && p_32559_.getEntities(this.enderman, AABB.unitCubeFromLowerCorner(Vec3.atLowerCornerOf(p_32560_))).isEmpty(); -@@ -592,7 +_,7 @@ +@@ -593,7 +_,7 @@ if (this.enderman.getCarriedBlock() != null) { return false; } else { diff --git a/patches/net/minecraft/world/entity/monster/Pillager.java.patch b/patches/net/minecraft/world/entity/monster/Pillager.java.patch index ea74e23dd8..28cf44850e 100644 --- a/patches/net/minecraft/world/entity/monster/Pillager.java.patch +++ b/patches/net/minecraft/world/entity/monster/Pillager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Pillager.java +++ b/net/minecraft/world/entity/monster/Pillager.java -@@ -119,7 +_,7 @@ +@@ -127,7 +_,7 @@ public AbstractIllager.IllagerArmPose getArmPose() { if (this.isChargingCrossbow()) { return AbstractIllager.IllagerArmPose.CROSSBOW_CHARGE; diff --git a/patches/net/minecraft/world/entity/monster/Ravager.java.patch b/patches/net/minecraft/world/entity/monster/Ravager.java.patch index aabe0a1c02..5902929c19 100644 --- a/patches/net/minecraft/world/entity/monster/Ravager.java.patch +++ b/patches/net/minecraft/world/entity/monster/Ravager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Ravager.java +++ b/net/minecraft/world/entity/monster/Ravager.java -@@ -144,7 +_,7 @@ +@@ -141,7 +_,7 @@ if (this.level() instanceof ServerLevel serverlevel && this.horizontalCollision @@ -9,7 +9,7 @@ boolean flag = false; AABB aabb = this.getBoundingBox().inflate(0.2); -@@ -227,7 +_,7 @@ +@@ -224,7 +_,7 @@ private void roar() { if (this.isAlive()) { if (this.level() instanceof ServerLevel serverlevel) { diff --git a/patches/net/minecraft/world/entity/monster/Skeleton.java.patch b/patches/net/minecraft/world/entity/monster/Skeleton.java.patch index 2b3815fc32..10e7c45cf4 100644 --- a/patches/net/minecraft/world/entity/monster/Skeleton.java.patch +++ b/patches/net/minecraft/world/entity/monster/Skeleton.java.patch @@ -5,8 +5,8 @@ protected void doFreezeConversion() { + if (!net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.STRAY, (timer) -> this.conversionTime = timer)) return; - this.convertTo(EntityType.STRAY, ConversionParams.single(this, true, true), p_381508_ -> { -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381508_); + this.convertTo(EntityType.STRAY, ConversionParams.single(this, true, true), p_390244_ -> { ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_390244_); if (!this.isSilent()) { this.level().levelEvent(null, 1048, this.blockPosition(), 0); } diff --git a/patches/net/minecraft/world/entity/monster/Slime.java.patch b/patches/net/minecraft/world/entity/monster/Slime.java.patch index 7f975fbff1..de9d5d03d8 100644 --- a/patches/net/minecraft/world/entity/monster/Slime.java.patch +++ b/patches/net/minecraft/world/entity/monster/Slime.java.patch @@ -21,9 +21,9 @@ float f3 = ((float)(l / 2) - 0.5F) * f1; - this.convertTo( + Slime slime = this.convertTo( - this.getType(), new ConversionParams(ConversionType.SPLIT_ON_DEATH, false, false, playerteam), EntitySpawnReason.TRIGGERED, p_381514_ -> { - p_381514_.setSize(j, true); - p_381514_.moveTo(this.getX() + (double)f2, this.getY() + 0.5, this.getZ() + (double)f3, this.random.nextFloat() * 360.0F, 0.0F); + this.getType(), new ConversionParams(ConversionType.SPLIT_ON_DEATH, false, false, playerteam), EntitySpawnReason.TRIGGERED, p_390250_ -> { + p_390250_.setSize(j, true); + p_390250_.moveTo(this.getX() + (double)f2, this.getY() + 0.5, this.getZ() + (double)f3, this.random.nextFloat() * 360.0F, 0.0F); } ); + children.add(slime); // Neo: Record the slime until after event firing. diff --git a/patches/net/minecraft/world/entity/monster/Zombie.java.patch b/patches/net/minecraft/world/entity/monster/Zombie.java.patch index 08f332ee7f..f9f2b3d141 100644 --- a/patches/net/minecraft/world/entity/monster/Zombie.java.patch +++ b/patches/net/minecraft/world/entity/monster/Zombie.java.patch @@ -12,7 +12,7 @@ this.convertTo( p_34311_, ConversionParams.single(this, true, true), -- p_381517_ -> p_381517_.handleAttributes(p_381517_.level().getCurrentDifficultyAt(p_381517_.blockPosition()).getSpecialMultiplier()) +- p_390253_ -> p_390253_.handleAttributes(p_390253_.level().getCurrentDifficultyAt(p_390253_.blockPosition()).getSpecialMultiplier()) + p_381517_ -> { + p_381517_.handleAttributes(p_381517_.level().getCurrentDifficultyAt(p_381517_.blockPosition()).getSpecialMultiplier()); + net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381517_); diff --git a/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch b/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch index 8718946d79..c871e3d198 100644 --- a/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch +++ b/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/entity/monster/creaking/Creaking.java +++ b/net/minecraft/world/entity/monster/creaking/Creaking.java -@@ -230,7 +_,8 @@ - - return true; - } else { -- Predicate predicate = this.isActive() ? LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM : p_380174_ -> true; -+ // Neo: provide entity being looked at to disguise check -+ java.util.function.BiPredicate predicate = this.isActive() ? LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET : (p_380174_, target) -> true; - +@@ -503,7 +_,8 @@ for (Player player : list) { - if (!player.isCreative() + if (this.canAttack(player) && !this.isAlliedTo(player)) { + flag1 = true; +- if ((!flag || LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM.test(player)) ++ // Neo: provide entity being looked at to disguise check ++ if ((!flag || LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET.test(player, this)) + && this.isLookingAtMe( + player, + 0.5, diff --git a/patches/net/minecraft/world/entity/monster/piglin/Piglin.java.patch b/patches/net/minecraft/world/entity/monster/piglin/Piglin.java.patch index fc04171127..94c8351221 100644 --- a/patches/net/minecraft/world/entity/monster/piglin/Piglin.java.patch +++ b/patches/net/minecraft/world/entity/monster/piglin/Piglin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -355,7 +_,7 @@ +@@ -363,7 +_,7 @@ } else if (this.isChargingCrossbow()) { return PiglinArmPose.CROSSBOW_CHARGE; } else { @@ -9,7 +9,7 @@ } } -@@ -392,7 +_,7 @@ +@@ -400,7 +_,7 @@ } protected void holdInOffHand(ItemStack p_34786_) { @@ -18,7 +18,7 @@ this.setItemSlot(EquipmentSlot.OFFHAND, p_34786_); this.setGuaranteedDrop(EquipmentSlot.OFFHAND); } else { -@@ -402,7 +_,7 @@ +@@ -410,7 +_,7 @@ @Override public boolean wantsToPickUp(ServerLevel p_376232_, ItemStack p_34777_) { diff --git a/patches/net/minecraft/world/entity/npc/Villager.java.patch b/patches/net/minecraft/world/entity/npc/Villager.java.patch index 308d4a20d0..baae5ca954 100644 --- a/patches/net/minecraft/world/entity/npc/Villager.java.patch +++ b/patches/net/minecraft/world/entity/npc/Villager.java.patch @@ -27,10 +27,10 @@ - if (p_35409_.getDifficulty() != Difficulty.PEACEFUL) { + if (p_35409_.getDifficulty() != Difficulty.PEACEFUL && net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.WITCH, (timer) -> {})) { LOGGER.info("Villager {} was struck by lightning {}.", this, p_35410_); - Witch witch = this.convertTo(EntityType.WITCH, ConversionParams.single(this, false, false), p_381540_ -> { - p_381540_.finalizeSpawn(p_35409_, p_35409_.getCurrentDifficultyAt(p_381540_.blockPosition()), EntitySpawnReason.CONVERSION, null); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381540_); - p_381540_.setPersistenceRequired(); + Witch witch = this.convertTo(EntityType.WITCH, ConversionParams.single(this, false, false), p_390271_ -> { + p_390271_.finalizeSpawn(p_35409_, p_35409_.getCurrentDifficultyAt(p_390271_.blockPosition()), EntitySpawnReason.CONVERSION, null); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_390271_); + p_390271_.setPersistenceRequired(); this.releaseAllPois(); }); @@ -804,7 +_,10 @@ diff --git a/patches/net/minecraft/world/entity/player/Inventory.java.patch b/patches/net/minecraft/world/entity/player/Inventory.java.patch index 17c929ae65..d9fee6ddad 100644 --- a/patches/net/minecraft/world/entity/player/Inventory.java.patch +++ b/patches/net/minecraft/world/entity/player/Inventory.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/player/Inventory.java +++ b/net/minecraft/world/entity/player/Inventory.java -@@ -132,7 +_,7 @@ +@@ -126,7 +_,7 @@ for (int k = 0; k < 9; k++) { int l = (this.selected + k) % 9; @@ -9,7 +9,7 @@ return l; } } -@@ -204,11 +_,15 @@ +@@ -198,11 +_,15 @@ } public void tick() { @@ -26,7 +26,7 @@ } } } -@@ -258,6 +_,8 @@ +@@ -252,6 +_,8 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Adding item to inventory"); CrashReportCategory crashreportcategory = crashreport.addCategory("Item being added"); diff --git a/patches/net/minecraft/world/entity/player/Player.java.patch b/patches/net/minecraft/world/entity/player/Player.java.patch index a4bdc8c832..52a2dd2d7c 100644 --- a/patches/net/minecraft/world/entity/player/Player.java.patch +++ b/patches/net/minecraft/world/entity/player/Player.java.patch @@ -10,7 +10,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); public static final HumanoidArm DEFAULT_MAIN_HAND = HumanoidArm.RIGHT; public static final int DEFAULT_MODEL_CUSTOMIZATION = 0; -@@ -197,6 +_,10 @@ +@@ -200,6 +_,10 @@ public Entity currentExplosionCause; private boolean ignoreFallDamageFromCurrentImpulse; private int currentImpulseContextResetGraceTime; @@ -21,7 +21,7 @@ public Player(Level p_250508_, BlockPos p_250289_, float p_251702_, GameProfile p_252153_) { super(EntityType.PLAYER, p_250508_); -@@ -233,7 +_,8 @@ +@@ -236,7 +_,8 @@ .add(Attributes.SUBMERGED_MINING_SPEED) .add(Attributes.SNEAKING_SPEED) .add(Attributes.MINING_EFFICIENCY) @@ -31,15 +31,15 @@ } @Override -@@ -249,6 +_,7 @@ +@@ -252,6 +_,7 @@ @Override public void tick() { + net.neoforged.neoforge.event.EventHooks.firePlayerTickPre(this); this.noPhysics = this.isSpectator(); - if (this.isSpectator()) { + if (this.isSpectator() || this.isPassenger()) { this.setOnGround(false); -@@ -264,7 +_,7 @@ +@@ -267,7 +_,7 @@ this.sleepCounter = 100; } @@ -48,7 +48,7 @@ this.stopSleepInBed(false, true); } } else if (this.sleepCounter > 0) { -@@ -295,7 +_,11 @@ +@@ -298,7 +_,11 @@ } if (!this.isSleeping()) { @@ -61,7 +61,7 @@ } } -@@ -325,6 +_,7 @@ +@@ -328,6 +_,7 @@ if (this.currentImpulseContextResetGraceTime > 0) { this.currentImpulseContextResetGraceTime--; } @@ -69,7 +69,7 @@ } @Override -@@ -427,6 +_,10 @@ +@@ -430,6 +_,10 @@ } protected void updatePlayerPose() { @@ -80,7 +80,7 @@ if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.SWIMMING)) { Pose pose; if (this.isFallFlying()) { -@@ -654,6 +_,7 @@ +@@ -657,6 +_,7 @@ @Override public void die(DamageSource p_36152_) { @@ -88,7 +88,7 @@ super.die(p_36152_); this.reapplyPosition(); if (!this.isSpectator() && this.level() instanceof ServerLevel serverlevel) { -@@ -711,7 +_,7 @@ +@@ -714,7 +_,7 @@ @Nullable public ItemEntity drop(ItemStack p_36177_, boolean p_36178_) { @@ -97,7 +97,7 @@ } @Nullable -@@ -723,7 +_,15 @@ +@@ -726,7 +_,15 @@ return null; } @@ -113,7 +113,7 @@ float f = this.inventory.getDestroySpeed(p_36282_); if (f > 1.0F) { f += (float)this.getAttributeValue(Attributes.MINING_EFFICIENCY); -@@ -752,13 +_,19 @@ +@@ -755,13 +_,19 @@ f /= 5.0F; } @@ -133,7 +133,7 @@ @Override public void readAdditionalSaveData(CompoundTag p_36215_) { super.readAdditionalSaveData(p_36215_); -@@ -867,7 +_,8 @@ +@@ -870,7 +_,8 @@ return false; } else { this.removeEntitiesOnShoulder(); @@ -143,7 +143,7 @@ if (p_376451_.getDifficulty() == Difficulty.PEACEFUL) { p_376389_ = 0.0F; } -@@ -922,7 +_,7 @@ +@@ -925,7 +_,7 @@ @Override protected void hurtCurrentlyUsedShield(float p_36383_) { @@ -152,7 +152,7 @@ if (!this.level().isClientSide) { this.awardStat(Stats.ITEM_USED.get(this.useItem.getItem())); } -@@ -930,7 +_,13 @@ +@@ -933,7 +_,13 @@ if (p_36383_ >= 3.0F) { int i = 1 + Mth.floor(p_36383_); InteractionHand interactionhand = this.getUsedItemHand(); @@ -167,7 +167,7 @@ if (this.useItem.isEmpty()) { if (interactionhand == InteractionHand.MAIN_HAND) { this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); -@@ -948,11 +_,14 @@ +@@ -951,11 +_,14 @@ @Override protected void actuallyHurt(ServerLevel p_376500_, DamageSource p_36312_, float p_36313_) { if (!this.isInvulnerableTo(p_376500_, p_36312_)) { @@ -187,7 +187,7 @@ if (f > 0.0F && f < 3.4028235E37F) { this.awardStat(Stats.DAMAGE_ABSORBED, Math.round(f * 10.0F)); } -@@ -966,7 +_,9 @@ +@@ -969,7 +_,9 @@ } this.gameEvent(GameEvent.ENTITY_DAMAGE); @@ -197,7 +197,7 @@ } } -@@ -1010,6 +_,8 @@ +@@ -1013,6 +_,8 @@ return InteractionResult.PASS; } else { @@ -206,7 +206,7 @@ ItemStack itemstack = this.getItemInHand(p_36159_); ItemStack itemstack1 = itemstack.copy(); InteractionResult interactionresult = p_36158_.interact(this, p_36159_); -@@ -1018,6 +_,9 @@ +@@ -1021,6 +_,9 @@ itemstack.setCount(itemstack1.getCount()); } @@ -216,7 +216,7 @@ return interactionresult; } else { if (!itemstack.isEmpty() && p_36158_ instanceof LivingEntity) { -@@ -1029,6 +_,7 @@ +@@ -1032,6 +_,7 @@ if (interactionresult1.consumesAction()) { this.level().gameEvent(GameEvent.ENTITY_INTERACT, p_36158_.position(), GameEvent.Context.of(this)); if (itemstack.isEmpty() && !this.abilities.instabuild) { @@ -224,7 +224,7 @@ this.setItemInHand(p_36159_, ItemStack.EMPTY); } -@@ -1058,6 +_,7 @@ +@@ -1061,6 +_,7 @@ } @Override @@ -232,7 +232,7 @@ protected Vec3 maybeBackOffFromEdge(Vec3 p_36201_, MoverType p_36202_) { float f = this.maxUpStep(); if (!this.abilities.flying -@@ -1107,6 +_,7 @@ +@@ -1110,6 +_,7 @@ } } @@ -240,7 +240,7 @@ private boolean isAboveGround(float p_341626_) { return this.onGround() || this.fallDistance < p_341626_ && !this.canFallAtLeast(0.0, 0.0, p_341626_ - this.fallDistance); } -@@ -1128,6 +_,7 @@ +@@ -1131,6 +_,7 @@ } public void attack(Entity p_36347_) { @@ -248,7 +248,7 @@ if (p_36347_.isAttackable()) { if (!p_36347_.skipAttackInteraction(this)) { float f = this.isAutoSpinAttack() ? this.autoSpinAttackDmg : (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE); -@@ -1137,7 +_,6 @@ +@@ -1140,7 +_,6 @@ float f2 = this.getAttackStrengthScale(0.5F); f *= 0.2F + f2 * f2 * 0.8F; f1 *= f2; @@ -256,7 +256,7 @@ if (p_36347_.getType().is(EntityTypeTags.REDIRECTABLE_PROJECTILE) && p_36347_ instanceof Projectile projectile && projectile.deflect(ProjectileDeflection.AIM_DEFLECT, this, this, true)) { -@@ -1166,20 +_,31 @@ +@@ -1169,20 +_,31 @@ && !this.isPassenger() && p_36347_ instanceof LivingEntity && !this.isSprinting(); @@ -291,7 +291,7 @@ float f6 = 0.0F; if (p_36347_ instanceof LivingEntity livingentity) { f6 = livingentity.getHealth(); -@@ -1213,11 +_,12 @@ +@@ -1216,11 +_,12 @@ for (LivingEntity livingentity2 : this.level() .getEntitiesOfClass(LivingEntity.class, p_36347_.getBoundingBox().inflate(1.0, 0.25, 1.0))) { @@ -305,7 +305,7 @@ float f5 = this.getEnchantedDamage(livingentity2, f7, damagesource) * f2; livingentity2.knockback( 0.4F, -@@ -1264,11 +_,12 @@ +@@ -1267,11 +_,12 @@ this.setLastHurtMob(p_36347_); Entity entity = p_36347_; @@ -320,7 +320,7 @@ if (this.level() instanceof ServerLevel serverlevel1) { if (entity instanceof LivingEntity livingentity3) { flag5 = itemstack.hurtEnemy(livingentity3, this); -@@ -1283,6 +_,7 @@ +@@ -1286,6 +_,7 @@ } if (itemstack.isEmpty()) { @@ -328,7 +328,7 @@ if (itemstack == this.getMainHandItem()) { this.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); } else { -@@ -1307,6 +_,7 @@ +@@ -1310,6 +_,7 @@ .playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_NODAMAGE, this.getSoundSource(), 1.0F, 1.0F); } } @@ -336,7 +336,7 @@ } } } -@@ -1391,6 +_,7 @@ +@@ -1394,6 +_,7 @@ } public void stopSleepInBed(boolean p_36226_, boolean p_36227_) { @@ -344,7 +344,7 @@ super.stopSleeping(); if (this.level() instanceof ServerLevel && p_36227_) { ((ServerLevel)this.level()).updateSleepingPlayerList(); -@@ -1496,7 +_,8 @@ +@@ -1499,7 +_,8 @@ @Override public boolean causeFallDamage(float p_150093_, float p_150094_, DamageSource p_150095_) { @@ -354,7 +354,7 @@ return false; } else { if (p_150093_ >= 2.0F) { -@@ -1555,13 +_,13 @@ +@@ -1558,13 +_,13 @@ protected void playStepSound(BlockPos p_282121_, BlockState p_282194_) { if (this.isInWater()) { this.waterSwimSound(); @@ -370,7 +370,7 @@ } else { super.playStepSound(blockpos, blockstate); } -@@ -1592,6 +_,10 @@ +@@ -1595,6 +_,10 @@ } public void giveExperiencePoints(int p_36291_) { @@ -381,7 +381,7 @@ this.increaseScore(p_36291_); this.experienceProgress = this.experienceProgress + (float)p_36291_ / (float)this.getXpNeededForNextLevel(); this.totalExperience = Mth.clamp(this.totalExperience + p_36291_, 0, Integer.MAX_VALUE); -@@ -1619,7 +_,7 @@ +@@ -1622,7 +_,7 @@ } public void onEnchantmentPerformed(ItemStack p_36172_, int p_36173_) { @@ -390,7 +390,7 @@ if (this.experienceLevel < 0) { this.experienceLevel = 0; this.experienceProgress = 0.0F; -@@ -1630,6 +_,10 @@ +@@ -1633,6 +_,10 @@ } public void giveExperienceLevels(int p_36276_) { @@ -401,7 +401,7 @@ this.experienceLevel = IntMath.saturatedAdd(this.experienceLevel, p_36276_); if (this.experienceLevel < 0) { this.experienceLevel = 0; -@@ -1833,7 +_,11 @@ +@@ -1836,7 +_,11 @@ @Override public Component getDisplayName() { @@ -414,7 +414,7 @@ return this.decorateDisplayNameComponent(mutablecomponent); } -@@ -1997,21 +_,21 @@ +@@ -2000,21 +_,21 @@ if (!(p_36349_.getItem() instanceof ProjectileWeaponItem)) { return ItemStack.EMPTY; } else { @@ -441,7 +441,7 @@ } } } -@@ -2172,5 +_,41 @@ +@@ -2197,5 +_,41 @@ public Component getMessage() { return this.message; } diff --git a/patches/net/minecraft/world/entity/projectile/AbstractArrow.java.patch b/patches/net/minecraft/world/entity/projectile/AbstractArrow.java.patch index f84027025e..808cd25f46 100644 --- a/patches/net/minecraft/world/entity/projectile/AbstractArrow.java.patch +++ b/patches/net/minecraft/world/entity/projectile/AbstractArrow.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -189,7 +_,7 @@ +@@ -191,7 +_,7 @@ this.shakeTime--; } @@ -9,7 +9,7 @@ this.clearFire(); } -@@ -269,11 +_,15 @@ +@@ -275,11 +_,15 @@ if (entityhitresult == null) { if (this.isAlive() && p_371761_.getType() != HitResult.Type.MISS) { diff --git a/patches/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch b/patches/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch index e90d9725f3..c6ff3c513e 100644 --- a/patches/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch +++ b/patches/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java +++ b/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java -@@ -76,7 +_,8 @@ +@@ -72,7 +_,8 @@ if (this.level().isClientSide || (entity == null || !entity.isRemoved()) && this.level().hasChunkAt(this.blockPosition())) { HitResult hitresult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity, this.getClipType()); Vec3 vec3; @@ -10,7 +10,7 @@ vec3 = hitresult.getLocation(); } else { vec3 = this.position().add(this.getDeltaMovement()); -@@ -90,7 +_,7 @@ +@@ -86,7 +_,7 @@ this.igniteForSeconds(1.0F); } diff --git a/patches/net/minecraft/world/entity/projectile/Projectile.java.patch b/patches/net/minecraft/world/entity/projectile/Projectile.java.patch index b772c7043c..f381393b10 100644 --- a/patches/net/minecraft/world/entity/projectile/Projectile.java.patch +++ b/patches/net/minecraft/world/entity/projectile/Projectile.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/Projectile.java +++ b/net/minecraft/world/entity/projectile/Projectile.java -@@ -375,7 +_,7 @@ +@@ -364,7 +_,7 @@ Entity entity = this.getOwner(); return entity instanceof Player ? entity.mayInteract(p_376318_, p_150168_) diff --git a/patches/net/minecraft/world/flag/FeatureFlags.java.patch b/patches/net/minecraft/world/flag/FeatureFlags.java.patch index 5f5c94d3d9..0fb6d34232 100644 --- a/patches/net/minecraft/world/flag/FeatureFlags.java.patch +++ b/patches/net/minecraft/world/flag/FeatureFlags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/flag/FeatureFlags.java +++ b/net/minecraft/world/flag/FeatureFlags.java -@@ -37,6 +_,7 @@ +@@ -35,6 +_,7 @@ TRADE_REBALANCE = featureflagregistry$builder.createVanilla("trade_rebalance"); REDSTONE_EXPERIMENTS = featureflagregistry$builder.createVanilla("redstone_experiments"); MINECART_IMPROVEMENTS = featureflagregistry$builder.createVanilla("minecart_improvements"); diff --git a/patches/net/minecraft/world/inventory/ArmorSlot.java.patch b/patches/net/minecraft/world/inventory/ArmorSlot.java.patch index 1922b22e68..7683484078 100644 --- a/patches/net/minecraft/world/inventory/ArmorSlot.java.patch +++ b/patches/net/minecraft/world/inventory/ArmorSlot.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/ArmorSlot.java +++ b/net/minecraft/world/inventory/ArmorSlot.java -@@ -39,7 +_,7 @@ +@@ -38,7 +_,7 @@ @Override public boolean mayPlace(ItemStack p_345029_) { diff --git a/patches/net/minecraft/world/inventory/BrewingStandMenu.java.patch b/patches/net/minecraft/world/inventory/BrewingStandMenu.java.patch index f562eb3218..0a54b15446 100644 --- a/patches/net/minecraft/world/inventory/BrewingStandMenu.java.patch +++ b/patches/net/minecraft/world/inventory/BrewingStandMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/BrewingStandMenu.java +++ b/net/minecraft/world/inventory/BrewingStandMenu.java -@@ -42,9 +_,9 @@ +@@ -45,9 +_,9 @@ this.brewingStand = p_39095_; this.brewingStandData = p_39096_; PotionBrewing potionbrewing = p_39094_.player.level().potionBrewing(); @@ -13,7 +13,7 @@ this.ingredientSlot = this.addSlot(new BrewingStandMenu.IngredientsSlot(potionbrewing, p_39095_, 3, 79, 17)); this.addSlot(new BrewingStandMenu.FuelSlot(p_39095_, 4, 17, 17)); this.addDataSlots(p_39096_); -@@ -73,7 +_,7 @@ +@@ -76,7 +_,7 @@ if (!this.moveItemStackTo(itemstack1, 3, 4, false)) { return ItemStack.EMPTY; } @@ -22,7 +22,7 @@ if (!this.moveItemStackTo(itemstack1, 0, 3, false)) { return ItemStack.EMPTY; } -@@ -150,13 +_,20 @@ +@@ -158,13 +_,20 @@ } static class PotionSlot extends Slot { @@ -44,7 +44,7 @@ } @Override -@@ -168,14 +_,20 @@ +@@ -176,14 +_,20 @@ public void onTake(Player p_150499_, ItemStack p_150500_) { Optional> optional = p_150500_.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion(); if (optional.isPresent() && p_150499_ instanceof ServerPlayer serverplayer) { @@ -63,5 +63,5 @@ + public static boolean mayPlaceItem(PotionBrewing potionBrewing, ItemStack p_39134_) { + return potionBrewing.isInput(p_39134_) || p_39134_.is(Items.GLASS_BOTTLE); } - } - } + + @Override diff --git a/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch b/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch index a60216de04..8ee38753c8 100644 --- a/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch +++ b/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/net/minecraft/world/inventory/EnchantmentMenu.java -@@ -63,7 +_,7 @@ +@@ -62,7 +_,7 @@ this.addSlot(new Slot(this.enchantSlots, 1, 35, 47) { @Override public boolean mayPlace(ItemStack p_39517_) { @@ -9,7 +9,7 @@ } @Override -@@ -91,23 +_,24 @@ +@@ -90,23 +_,24 @@ if (!itemstack.isEmpty() && itemstack.isEnchantable()) { this.access.execute((p_344366_, p_344367_) -> { IdMap> idmap = p_344366_.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).asHolderIdMap(); @@ -37,7 +37,7 @@ } for (int l = 0; l < 3; l++) { -@@ -153,14 +_,10 @@ +@@ -152,14 +_,10 @@ List list = this.getEnchantmentList(p_347276_.registryAccess(), itemstack, p_39466_, this.costs[p_39466_]); if (!list.isEmpty()) { p_39465_.onEnchantmentPerformed(itemstack, i); @@ -56,7 +56,7 @@ itemstack1.consume(i, p_39465_); if (itemstack1.isEmpty()) { -@@ -239,7 +_,7 @@ +@@ -238,7 +_,7 @@ if (!this.moveItemStackTo(itemstack1, 2, 38, true)) { return ItemStack.EMPTY; } diff --git a/patches/net/minecraft/world/inventory/Slot.java.patch b/patches/net/minecraft/world/inventory/Slot.java.patch index 048dc6e960..7e6f116068 100644 --- a/patches/net/minecraft/world/inventory/Slot.java.patch +++ b/patches/net/minecraft/world/inventory/Slot.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/inventory/Slot.java +++ b/net/minecraft/world/inventory/Slot.java -@@ -81,7 +_,7 @@ +@@ -80,7 +_,7 @@ @Nullable - public Pair getNoItemIcon() { + public ResourceLocation getNoItemIcon() { - return null; -+ return backgroundPair; ++ return backgroundSprite; } public ItemStack remove(int p_40227_) { -@@ -94,6 +_,38 @@ +@@ -93,6 +_,37 @@ public boolean isActive() { return true; @@ -34,16 +34,15 @@ + return this.container == other.container; + } + -+ private Pair backgroundPair; ++ private ResourceLocation backgroundSprite; + /** + * Sets the background atlas and sprite location. + * -+ * @param atlas The atlas name + * @param sprite The sprite located on that atlas. + * @return this, to allow chaining. + */ -+ public Slot setBackground(ResourceLocation atlas, ResourceLocation sprite) { -+ this.backgroundPair = Pair.of(atlas, sprite); ++ public Slot setBackground(ResourceLocation sprite) { ++ this.backgroundSprite = sprite; + return this; } diff --git a/patches/net/minecraft/world/item/BundleItem.java.patch b/patches/net/minecraft/world/item/BundleItem.java.patch index ff5bc70598..9763a4877c 100644 --- a/patches/net/minecraft/world/item/BundleItem.java.patch +++ b/patches/net/minecraft/world/item/BundleItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/BundleItem.java +++ b/net/minecraft/world/item/BundleItem.java -@@ -61,7 +_,7 @@ +@@ -48,7 +_,7 @@ @Override public boolean overrideStackedOnOther(ItemStack p_150733_, Slot p_150734_, ClickAction p_150735_, Player p_150736_) { BundleContents bundlecontents = p_150733_.get(DataComponents.BUNDLE_CONTENTS); @@ -9,7 +9,7 @@ return false; } else { ItemStack itemstack = p_150734_.getItem(); -@@ -100,6 +_,7 @@ +@@ -87,6 +_,7 @@ public boolean overrideOtherStackedOnMe( ItemStack p_150742_, ItemStack p_150743_, Slot p_150744_, ClickAction p_150745_, Player p_150746_, SlotAccess p_150747_ ) { diff --git a/patches/net/minecraft/world/item/CrossbowItem.java.patch b/patches/net/minecraft/world/item/CrossbowItem.java.patch index 6cb5f7be7d..5ba2254704 100644 --- a/patches/net/minecraft/world/item/CrossbowItem.java.patch +++ b/patches/net/minecraft/world/item/CrossbowItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/CrossbowItem.java +++ b/net/minecraft/world/item/CrossbowItem.java -@@ -184,6 +_,7 @@ +@@ -185,6 +_,7 @@ Level p_40888_, LivingEntity p_40889_, InteractionHand p_40890_, ItemStack p_40891_, float p_40892_, float p_40893_, @Nullable LivingEntity p_331602_ ) { if (p_40888_ instanceof ServerLevel serverlevel) { diff --git a/patches/net/minecraft/world/item/DyeColor.java.patch b/patches/net/minecraft/world/item/DyeColor.java.patch index ff5a295142..9e4d126ebd 100644 --- a/patches/net/minecraft/world/item/DyeColor.java.patch +++ b/patches/net/minecraft/world/item/DyeColor.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/DyeColor.java +++ b/net/minecraft/world/item/DyeColor.java -@@ -43,6 +_,8 @@ +@@ -48,6 +_,8 @@ private final MapColor mapColor; private final int textureDiffuseColor; private final int fireworkColor; @@ -9,7 +9,7 @@ private final int textColor; private DyeColor(int p_41046_, String p_41047_, int p_41048_, MapColor p_285297_, int p_41050_, int p_41051_) { -@@ -50,6 +_,8 @@ +@@ -55,6 +_,8 @@ this.name = p_41047_; this.mapColor = p_285297_; this.textColor = p_41051_; @@ -18,7 +18,7 @@ this.textureDiffuseColor = ARGB.opaque(p_41048_); this.fireworkColor = p_41050_; } -@@ -102,5 +_,35 @@ +@@ -107,6 +_,36 @@ @Override public String getSerializedName() { return this.name; @@ -53,4 +53,5 @@ + + return null; } - } + + public static DyeColor getMixedColor(ServerLevel p_386897_, DyeColor p_388832_, DyeColor p_386710_) { diff --git a/patches/net/minecraft/world/item/Item.java.patch b/patches/net/minecraft/world/item/Item.java.patch index 85a8aab6d7..f4964bdec5 100644 --- a/patches/net/minecraft/world/item/Item.java.patch +++ b/patches/net/minecraft/world/item/Item.java.patch @@ -90,8 +90,8 @@ } public ItemStack getDefaultInstance() { -@@ -322,7 +_,7 @@ - return this.requiredFeatures; +@@ -326,7 +_,7 @@ + return false; } - public static class Properties { @@ -99,7 +99,7 @@ private static final DependantName BLOCK_DESCRIPTION_ID = p_371954_ -> Util.makeDescriptionId("block", p_371954_.location()); private static final DependantName ITEM_DESCRIPTION_ID = p_371511_ -> Util.makeDescriptionId("item", p_371511_.location()); private final DataComponentMap.Builder components = DataComponentMap.builder().addAll(DataComponents.COMMON_ITEM_COMPONENTS); -@@ -438,6 +_,7 @@ +@@ -437,6 +_,7 @@ } public Item.Properties component(DataComponentType p_330871_, T p_330323_) { @@ -107,7 +107,7 @@ this.components.set(p_330871_, p_330323_); return this; } -@@ -448,6 +_,10 @@ +@@ -447,6 +_,10 @@ DataComponentMap buildAndValidateComponents(Component p_371796_, ResourceLocation p_371450_) { DataComponentMap datacomponentmap = this.components.set(DataComponents.ITEM_NAME, p_371796_).set(DataComponents.ITEM_MODEL, p_371450_).build(); @@ -118,7 +118,7 @@ if (datacomponentmap.has(DataComponents.DAMAGE) && datacomponentmap.getOrDefault(DataComponents.MAX_STACK_SIZE, 1) > 1) { throw new IllegalStateException("Item cannot have both durability and be stackable"); } else { -@@ -484,6 +_,14 @@ +@@ -483,6 +_,14 @@ @Nullable MapItemSavedData mapData(MapId p_339670_); @@ -133,7 +133,7 @@ static Item.TooltipContext of(@Nullable final Level p_339599_) { return p_339599_ == null ? EMPTY : new Item.TooltipContext() { @Override -@@ -499,6 +_,11 @@ +@@ -498,6 +_,11 @@ @Override public MapItemSavedData mapData(MapId p_339628_) { return p_339599_.getMapData(p_339628_); diff --git a/patches/net/minecraft/world/item/ItemStack.java.patch b/patches/net/minecraft/world/item/ItemStack.java.patch index 6842e3538e..f826fb0dfc 100644 --- a/patches/net/minecraft/world/item/ItemStack.java.patch +++ b/patches/net/minecraft/world/item/ItemStack.java.patch @@ -6,21 +6,21 @@ -public final class ItemStack implements DataComponentHolder { +public final class ItemStack implements DataComponentHolder, net.neoforged.neoforge.common.extensions.IItemStackExtension, net.neoforged.neoforge.common.MutableDataComponentHolder { - public static final Codec CODEC = Codec.lazyInitialized( - () -> RecordCodecBuilder.create( - p_381569_ -> p_381569_.group( -@@ -233,6 +_,10 @@ - return !this.isEmpty() ? this.components.asPatch() : DataComponentPatch.EMPTY; + private static final List OP_NBT_WARNING = List.of( + Component.translatable("item.op_warning.line1").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), + Component.translatable("item.op_warning.line2").withStyle(ChatFormatting.RED), +@@ -242,6 +_,10 @@ + return !this.isEmpty() && this.components.hasNonDefault(p_389426_); } + public boolean isComponentsPatchEmpty() { -+ return !this.isEmpty() ? this.components.isPatchEmpty() : true; ++ return this.isEmpty() || this.components.isPatchEmpty(); + } + public ItemStack(ItemLike p_41599_) { this(p_41599_, 1); } -@@ -338,7 +_,7 @@ +@@ -347,7 +_,7 @@ } public boolean is(Holder p_220166_) { @@ -29,7 +29,7 @@ } public boolean is(HolderSet p_298683_) { -@@ -350,13 +_,27 @@ +@@ -359,13 +_,27 @@ } public InteractionResult useOn(UseOnContext p_41662_) { @@ -58,7 +58,7 @@ if (player != null && interactionresult instanceof InteractionResult.Success interactionresult$success && interactionresult$success.wasItemInteraction()) { -@@ -410,7 +_,8 @@ +@@ -419,7 +_,8 @@ if (this.isEmpty()) { throw new IllegalStateException("Cannot encode empty ItemStack"); } else { @@ -68,7 +68,7 @@ } } -@@ -418,7 +_,8 @@ +@@ -427,7 +_,8 @@ if (this.isEmpty()) { throw new IllegalStateException("Cannot encode empty ItemStack"); } else { @@ -78,7 +78,7 @@ } } -@@ -427,7 +_,7 @@ +@@ -436,7 +_,7 @@ } public int getMaxStackSize() { @@ -87,7 +87,7 @@ } public boolean isStackable() { -@@ -439,19 +_,19 @@ +@@ -448,19 +_,19 @@ } public boolean isDamaged() { @@ -111,7 +111,7 @@ } public boolean isBroken() { -@@ -463,6 +_,11 @@ +@@ -472,6 +_,11 @@ } public void hurtAndBreak(int p_220158_, ServerLevel p_346256_, @Nullable ServerPlayer p_220160_, Consumer p_348596_) { @@ -123,7 +123,7 @@ int i = this.processDurabilityChange(p_220158_, p_346256_, p_220160_); if (i != 0) { this.applyDamage(this.getDamageValue() + i, p_220160_, p_348596_); -@@ -470,6 +_,10 @@ +@@ -479,6 +_,10 @@ } private int processDurabilityChange(int p_361290_, ServerLevel p_361409_, @Nullable ServerPlayer p_364940_) { @@ -134,7 +134,7 @@ if (!this.isDamageableItem()) { return 0; } else if (p_364940_ != null && p_364940_.hasInfiniteMaterials()) { -@@ -480,8 +_,12 @@ +@@ -489,8 +_,12 @@ } private void applyDamage(int p_361754_, @Nullable ServerPlayer p_364853_, Consumer p_360895_) { @@ -149,7 +149,7 @@ } this.setDamageValue(p_361754_); -@@ -510,7 +_,7 @@ +@@ -519,7 +_,7 @@ this.hurtAndBreak( p_41623_, serverlevel, @@ -158,7 +158,7 @@ p_348383_ -> p_41624_.onEquippedItemBroken(p_348383_, p_319898_) ); } -@@ -785,7 +_,7 @@ +@@ -800,7 +_,7 @@ } public Component getStyledHoverName() { @@ -167,7 +167,7 @@ if (this.has(DataComponents.CUSTOM_NAME)) { mutablecomponent.withStyle(ChatFormatting.ITALIC); } -@@ -826,7 +_,9 @@ +@@ -842,7 +_,9 @@ this.addToTooltip(DataComponents.ENCHANTMENTS, p_339637_, consumer, p_41653_); this.addToTooltip(DataComponents.DYED_COLOR, p_339637_, consumer, p_41653_); this.addToTooltip(DataComponents.LORE, p_339637_, consumer, p_41653_); @@ -178,8 +178,8 @@ this.addToTooltip(DataComponents.UNBREAKABLE, p_339637_, consumer, p_41653_); this.addToTooltip(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, p_339637_, consumer, p_41653_); this.addToTooltip(DataComponents.SUSPICIOUS_STEW_EFFECTS, p_339637_, consumer, p_41653_); -@@ -860,10 +_,15 @@ - list.add(DISABLED_ITEM_TOOLTIP); +@@ -880,10 +_,15 @@ + list.addAll(OP_NBT_WARNING); } + net.neoforged.neoforge.event.EventHooks.onItemTooltip(this, p_41652_, list, p_41653_, p_339637_); @@ -194,7 +194,7 @@ private void addAttributeTooltips(Consumer p_330796_, @Nullable Player p_330530_) { ItemAttributeModifiers itemattributemodifiers = this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); if (itemattributemodifiers.showInTooltip()) { -@@ -973,6 +_,17 @@ +@@ -993,6 +_,17 @@ return !this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty(); } @@ -212,7 +212,7 @@ public ItemEnchantments getEnchantments() { return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); } -@@ -998,14 +_,26 @@ +@@ -1018,14 +_,26 @@ } public void forEachModifier(EquipmentSlotGroup p_348610_, BiConsumer, AttributeModifier> p_348516_) { @@ -239,7 +239,7 @@ EnchantmentHelper.forEachModifier(this, p_332001_, p_330882_); } -@@ -1017,7 +_,7 @@ +@@ -1037,7 +_,7 @@ MutableComponent mutablecomponent1 = ComponentUtils.wrapInSquareBrackets(mutablecomponent); if (!this.isEmpty()) { @@ -248,7 +248,7 @@ .withStyle(p_220170_ -> p_220170_.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackInfo(this)))); } -@@ -1085,6 +_,8 @@ +@@ -1105,6 +_,8 @@ this.getItem().onUseTick(p_41732_, p_41733_, this, p_41734_); } @@ -257,7 +257,7 @@ public void onDestroyed(ItemEntity p_150925_) { this.getItem().onDestroyed(p_150925_); } -@@ -1094,6 +_,7 @@ +@@ -1114,6 +_,7 @@ } public boolean canBeHurtBy(DamageSource p_335431_) { diff --git a/patches/net/minecraft/world/item/ItemUseAnimation.java.patch b/patches/net/minecraft/world/item/ItemUseAnimation.java.patch index bae3e76080..9e2141275f 100644 --- a/patches/net/minecraft/world/item/ItemUseAnimation.java.patch +++ b/patches/net/minecraft/world/item/ItemUseAnimation.java.patch @@ -12,7 +12,7 @@ NONE(0, "none"), EAT(1, "eat"), DRINK(2, "drink"), -@@ -38,5 +_,9 @@ +@@ -39,5 +_,9 @@ @Override public String getSerializedName() { return this.name; diff --git a/patches/net/minecraft/world/item/Items.java.patch b/patches/net/minecraft/world/item/Items.java.patch index 98327eb50c..9e6b1ca654 100644 --- a/patches/net/minecraft/world/item/Items.java.patch +++ b/patches/net/minecraft/world/item/Items.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/Items.java +++ b/net/minecraft/world/item/Items.java -@@ -2326,11 +_,19 @@ +@@ -2194,11 +_,19 @@ } public static Item registerBlock(Block p_252092_, Block... p_248886_) { diff --git a/patches/net/minecraft/world/item/SpawnEggItem.java.patch b/patches/net/minecraft/world/item/SpawnEggItem.java.patch index 5154845a82..2a8f26d433 100644 --- a/patches/net/minecraft/world/item/SpawnEggItem.java.patch +++ b/patches/net/minecraft/world/item/SpawnEggItem.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/item/SpawnEggItem.java +++ b/net/minecraft/world/item/SpawnEggItem.java -@@ -179,4 +_,45 @@ - } - } +@@ -190,4 +_,45 @@ + + return false; } + + public static final net.minecraft.core.dispenser.DispenseItemBehavior DEFAULT_DISPENSE_BEHAVIOR = new net.minecraft.core.dispenser.DefaultDispenseItemBehavior() { + @Override + protected ItemStack execute(net.minecraft.core.dispenser.BlockSource source, ItemStack egg) { + Direction direction = source.state().getValue(net.minecraft.world.level.block.DispenserBlock.FACING); -+ EntityType entitytype = ((SpawnEggItem)egg.getItem()).getType(egg); ++ EntityType entitytype = ((SpawnEggItem)egg.getItem()).getType(source.level().registryAccess(), egg); + + try { + entitytype.spawn( diff --git a/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch b/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch index f5c53ac620..a3e7318da7 100644 --- a/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch +++ b/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/alchemy/PotionContents.java +++ b/net/minecraft/world/item/alchemy/PotionContents.java -@@ -201,6 +_,10 @@ +@@ -197,6 +_,10 @@ p_331296_.accept(CommonComponents.EMPTY); p_331296_.accept(Component.translatable("potion.whenDrank").withStyle(ChatFormatting.DARK_PURPLE)); diff --git a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch index f80d5c47b2..d38b0c8667 100644 --- a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch +++ b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/item/crafting/Ingredient.java +++ b/net/minecraft/world/item/crafting/Ingredient.java -@@ -24,18 +_,20 @@ +@@ -23,16 +_,20 @@ import net.minecraft.world.level.ItemLike; - public final class Ingredient implements Predicate { + public final class Ingredient implements StackedContents.IngredientInfo>, Predicate { - public static final StreamCodec CONTENTS_STREAM_CODEC = ByteBufCodecs.holderSet(Registries.ITEM) - .map(Ingredient::new, p_360055_ -> p_360055_.values); - public static final StreamCodec> OPTIONAL_CONTENTS_STREAM_CODEC = ByteBufCodecs.holderSet(Registries.ITEM) @@ -20,14 +20,14 @@ - public static final Codec CODEC = ExtraCodecs.nonEmptyHolderSet(NON_AIR_HOLDER_SET_CODEC).xmap(Ingredient::new, p_360061_ -> p_360061_.values); + public static final Codec CODEC = net.neoforged.neoforge.common.crafting.IngredientCodecs.codec(ExtraCodecs.nonEmptyHolderSet(NON_AIR_HOLDER_SET_CODEC).xmap(Ingredient::new, p_360061_ -> p_360061_.values)); private final HolderSet values; - @Nullable - private List> items; -+ @Nullable ++ @org.jetbrains.annotations.Nullable + private net.neoforged.neoforge.common.crafting.ICustomIngredient customIngredient = null; ++ @org.jetbrains.annotations.Nullable ++ private List> customIngredientValues; private Ingredient(HolderSet p_365027_) { p_365027_.unwrap().ifRight(p_360057_ -> { -@@ -48,19 +_,31 @@ +@@ -45,12 +_,23 @@ this.values = p_365027_; } @@ -40,27 +40,36 @@ return p_362504_.map(p_360060_ -> p_360060_.test(p_363604_)).orElseGet(p_363604_::isEmpty); } - public List> items() { - if (this.items == null) { -- this.items = ImmutableList.copyOf(this.values); -+ if (this.customIngredient != null) { -+ this.items = this.customIngredient.items().toList(); -+ } else { -+ this.items = ImmutableList.copyOf(this.values); + @Deprecated + public Stream> items() { ++ if (this.customIngredient != null) { ++ if (this.customIngredientValues == null) { ++ this.customIngredientValues = this.customIngredient.items().toList(); + } - } ++ return this.customIngredientValues.stream(); ++ } + return this.values.stream(); + } - return this.items; +@@ -59,16 +_,67 @@ } public boolean test(ItemStack p_43914_) { + if (this.customIngredient != null) { + return this.customIngredient.test(p_43914_); + } - List> list = this.items(); + return p_43914_.is(this.values); + } - for (int i = 0; i < list.size(); i++) { -@@ -74,7 +_,49 @@ + public boolean acceptsItem(Holder p_389400_) { ++ if (this.customIngredient != null) { ++ if (this.customIngredientValues == null) { ++ this.customIngredientValues = this.customIngredient.items().toList(); ++ } ++ return this.customIngredientValues.contains(p_389400_); ++ } + return this.values.contains(p_389400_); + } @Override public boolean equals(Object p_301003_) { @@ -92,7 +101,7 @@ + */ + private HolderSet getValuesForSync() { + if (isCustom()) { -+ return HolderSet.direct(this.items()); ++ return HolderSet.direct(this.items().toList()); + } + return this.values; + } @@ -101,7 +110,7 @@ + return this.customIngredient == null || this.customIngredient.isSimple(); + } + -+ @Nullable ++ @org.jetbrains.annotations.Nullable + public net.neoforged.neoforge.common.crafting.ICustomIngredient getCustomIngredient() { + return this.customIngredient; + } @@ -111,7 +120,7 @@ } public static Ingredient of(ItemLike p_364285_) { -@@ -94,6 +_,9 @@ +@@ -88,6 +_,9 @@ } public SlotDisplay display() { diff --git a/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch b/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch index f33bac52e3..af19f7f2a6 100644 --- a/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch +++ b/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/item/crafting/RecipeManager.java +++ b/net/minecraft/world/item/crafting/RecipeManager.java -@@ -69,7 +_,7 @@ +@@ -71,7 +_,7 @@ protected RecipeMap prepare(ResourceManager p_379845_, ProfilerFiller p_380058_) { SortedMap> sortedmap = new TreeMap<>(); SimpleJsonResourceReloadListener.scanDirectory( -- p_379845_, Registries.elementsDirPath(Registries.RECIPE), this.registries.createSerializationContext(JsonOps.INSTANCE), Recipe.CODEC, sortedmap -+ p_379845_, Registries.elementsDirPath(Registries.RECIPE), new net.neoforged.neoforge.common.conditions.ConditionalOps<>(this.registries.createSerializationContext(JsonOps.INSTANCE), getContext()), Recipe.CODEC, sortedmap // Neo: add condition context +- p_379845_, RECIPE_LISTER, this.registries.createSerializationContext(JsonOps.INSTANCE), Recipe.CODEC, sortedmap ++ p_379845_, RECIPE_LISTER, new net.neoforged.neoforge.common.conditions.ConditionalOps<>(this.registries.createSerializationContext(JsonOps.INSTANCE), getContext()), Recipe.CODEC, sortedmap // Neo: add condition context ); List> list = new ArrayList<>(sortedmap.size()); sortedmap.forEach((p_379232_, p_379233_) -> { -@@ -258,6 +_,11 @@ +@@ -260,6 +_,11 @@ return p_380850_ -> p_380850_.getType() == p_381108_ && p_380850_ instanceof SingleItemRecipe singleitemrecipe ? Optional.of(singleitemrecipe.input()) : Optional.empty(); diff --git a/patches/net/minecraft/world/level/Level.java.patch b/patches/net/minecraft/world/level/Level.java.patch index 00df1925bc..e76860b35b 100644 --- a/patches/net/minecraft/world/level/Level.java.patch +++ b/patches/net/minecraft/world/level/Level.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -78,7 +_,7 @@ +@@ -79,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.Scoreboard; @@ -9,7 +9,7 @@ public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); public static final ResourceKey NETHER = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("the_nether")); -@@ -115,6 +_,11 @@ +@@ -116,6 +_,11 @@ private final RegistryAccess registryAccess; private final DamageSources damageSources; private long subTickCount; @@ -21,7 +21,7 @@ protected Level( WritableLevelData p_270739_, -@@ -215,11 +_,36 @@ +@@ -216,11 +_,36 @@ } else { LevelChunk levelchunk = this.getChunkAt(p_46605_); Block block = p_46606_.getBlock(); @@ -58,7 +58,7 @@ if (blockstate1 == p_46606_) { if (blockstate != blockstate1) { this.setBlocksDirty(p_46605_, blockstate, blockstate1); -@@ -246,9 +_,8 @@ +@@ -247,9 +_,8 @@ } this.onBlockStateChange(p_46605_, blockstate, blockstate1); @@ -69,7 +69,7 @@ } } } -@@ -300,6 +_,7 @@ +@@ -301,6 +_,7 @@ } public void updateNeighborsAt(BlockPos p_46673_, Block p_46674_) { @@ -77,7 +77,7 @@ } public void updateNeighborsAt(BlockPos p_365514_, Block p_364886_, @Nullable Orientation p_363337_) { -@@ -491,10 +_,26 @@ +@@ -500,10 +_,26 @@ (this.tickingBlockEntities ? this.pendingBlockEntityTickers : this.blockEntityTickers).add(p_151526_); } @@ -104,7 +104,7 @@ if (!this.pendingBlockEntityTickers.isEmpty()) { this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); this.pendingBlockEntityTickers.clear(); -@@ -518,12 +_,19 @@ +@@ -527,12 +_,19 @@ public void guardEntityTick(Consumer p_46654_, T p_46655_) { try { @@ -124,7 +124,7 @@ } } -@@ -673,6 +_,7 @@ +@@ -682,6 +_,7 @@ if (!this.isOutsideBuildHeight(p_46748_)) { this.getChunkAt(p_46748_).removeBlockEntity(p_46748_); } @@ -132,27 +132,19 @@ } public boolean isLoaded(BlockPos p_46750_) { -@@ -751,6 +_,7 @@ - list.add(p_151522_); - } - -+ if (false) - if (p_151522_ instanceof EnderDragon) { - for (EnderDragonPart enderdragonpart : ((EnderDragon)p_151522_).getSubEntities()) { - if (p_151522_ != p_46536_ && p_46538_.test(enderdragonpart)) { -@@ -759,6 +_,11 @@ - } +@@ -761,9 +_,9 @@ } }); -+ for (net.neoforged.neoforge.entity.PartEntity p : this.getPartEntities()) { -+ if (p != p_46536_ && p.getBoundingBox().intersects(p_46537_) && p_46538_.test(p)) { -+ list.add(p); -+ } -+ } - return list; - } -@@ -785,6 +_,8 @@ +- for (EnderDragonPart enderdragonpart : this.dragonParts()) { ++ for (net.neoforged.neoforge.entity.PartEntity enderdragonpart : this.dragonParts()) { + if (enderdragonpart != p_46536_ +- && enderdragonpart.parentMob != p_46536_ ++ && enderdragonpart.getParent() != p_46536_ + && p_46538_.test(enderdragonpart) + && p_46537_.intersects(enderdragonpart.getBoundingBox())) { + list.add(enderdragonpart); +@@ -796,6 +_,8 @@ } } @@ -161,11 +153,11 @@ if (p_261454_ instanceof EnderDragon enderdragon) { for (EnderDragonPart enderdragonpart : enderdragon.getSubEntities()) { T t = p_261885_.tryCast(enderdragonpart); -@@ -799,6 +_,15 @@ +@@ -810,12 +_,21 @@ return AbortableIterationConsumer.Continuation.CONTINUE; }); -+ for (net.neoforged.neoforge.entity.PartEntity p : this.getPartEntities()) { ++ for (net.neoforged.neoforge.entity.PartEntity p : this.dragonParts()) { + T t = p_261885_.tryCast(p); + if (t != null && t.getBoundingBox().intersects(p_262086_) && p_261688_.test(t)) { + p_262071_.add(t); @@ -177,7 +169,14 @@ } @Nullable -@@ -922,16 +_,15 @@ + public abstract Entity getEntity(int p_46492_); + +- public abstract Collection dragonParts(); ++ public abstract Collection> dragonParts(); + + public void blockEntityChanged(BlockPos p_151544_) { + if (this.hasChunkAt(p_151544_)) { +@@ -935,16 +_,15 @@ public abstract Scoreboard getScoreboard(); public void updateNeighbourForOutputSignal(BlockPos p_46718_, Block p_46719_) { @@ -198,7 +197,7 @@ this.neighborChanged(blockstate, blockpos, p_46719_, null, false); } } -@@ -1013,6 +_,18 @@ +@@ -1026,6 +_,18 @@ return this.biomeManager; } @@ -217,7 +216,7 @@ public final boolean isDebug() { return this.isDebug; } -@@ -1055,5 +_,38 @@ +@@ -1068,5 +_,38 @@ public String getSerializedName() { return this.id; } diff --git a/patches/net/minecraft/world/level/ServerExplosion.java.patch b/patches/net/minecraft/world/level/ServerExplosion.java.patch index 871697a696..d15e1e4a55 100644 --- a/patches/net/minecraft/world/level/ServerExplosion.java.patch +++ b/patches/net/minecraft/world/level/ServerExplosion.java.patch @@ -29,7 +29,7 @@ d3 *= d6; Vec3 vec3 = new Vec3(d1, d2, d3); + vec3 = net.neoforged.neoforge.event.EventHooks.getExplosionKnockback(this.level, this, entity, vec3, blocks); - entity.setDeltaMovement(entity.getDeltaMovement().add(vec3)); + entity.push(vec3); if (entity instanceof Player) { Player player = (Player)entity; @@ -246,7 +_,7 @@ diff --git a/patches/net/minecraft/world/level/biome/Biome.java.patch b/patches/net/minecraft/world/level/biome/Biome.java.patch index 54c553a09a..24e5ab6c1a 100644 --- a/patches/net/minecraft/world/level/biome/Biome.java.patch +++ b/patches/net/minecraft/world/level/biome/Biome.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/biome/Biome.java +++ b/net/minecraft/world/level/biome/Biome.java -@@ -35,8 +_,8 @@ +@@ -36,8 +_,8 @@ public final class Biome { public static final Codec DIRECT_CODEC = RecordCodecBuilder.create( p_220544_ -> p_220544_.group( @@ -11,7 +11,7 @@ BiomeGenerationSettings.CODEC.forGetter(p_220548_ -> p_220548_.generationSettings), MobSpawnSettings.CODEC.forGetter(p_220546_ -> p_220546_.mobSettings) ) -@@ -60,9 +_,11 @@ +@@ -61,9 +_,11 @@ ) public static final PerlinSimplexNoise BIOME_INFO_NOISE = new PerlinSimplexNoise(new WorldgenRandom(new LegacyRandomSource(2345L)), ImmutableList.of(0)); private static final int TEMPERATURE_CACHE_SIZE = 1024; @@ -23,7 +23,7 @@ private final BiomeSpecialEffects specialEffects; private final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> Util.make(() -> { Long2FloatLinkedOpenHashMap long2floatlinkedopenhashmap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { -@@ -79,6 +_,7 @@ +@@ -80,6 +_,7 @@ this.generationSettings = p_220532_; this.mobSettings = p_220533_; this.specialEffects = p_220531_; @@ -31,7 +31,7 @@ } public int getSkyColor() { -@@ -86,7 +_,7 @@ +@@ -87,7 +_,7 @@ } public MobSpawnSettings getMobSettings() { @@ -40,7 +40,7 @@ } public boolean hasPrecipitation() { -@@ -188,7 +_,7 @@ +@@ -189,7 +_,7 @@ } public BiomeGenerationSettings getGenerationSettings() { @@ -49,7 +49,7 @@ } public int getFogColor() { -@@ -411,5 +_,32 @@ +@@ -416,5 +_,32 @@ public String getSerializedName() { return this.name; } diff --git a/patches/net/minecraft/world/level/biome/BiomeSpecialEffects.java.patch b/patches/net/minecraft/world/level/biome/BiomeSpecialEffects.java.patch index 212f97fe12..b0904a498a 100644 --- a/patches/net/minecraft/world/level/biome/BiomeSpecialEffects.java.patch +++ b/patches/net/minecraft/world/level/biome/BiomeSpecialEffects.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/biome/BiomeSpecialEffects.java +++ b/net/minecraft/world/level/biome/BiomeSpecialEffects.java -@@ -212,7 +_,9 @@ +@@ -242,7 +_,9 @@ } } @@ -11,7 +11,7 @@ NONE("none") { @Override public int modifyColor(double p_48081_, double p_48082_, int p_48083_) { -@@ -234,12 +_,22 @@ +@@ -264,12 +_,22 @@ }; private final String name; @@ -35,7 +35,7 @@ } public String getName() { -@@ -249,6 +_,15 @@ +@@ -279,6 +_,15 @@ @Override public String getSerializedName() { return this.name; diff --git a/patches/net/minecraft/world/level/block/Block.java.patch b/patches/net/minecraft/world/level/block/Block.java.patch index 652a468069..651346f450 100644 --- a/patches/net/minecraft/world/level/block/Block.java.patch +++ b/patches/net/minecraft/world/level/block/Block.java.patch @@ -112,18 +112,7 @@ public float getExplosionResistance() { return this.explosionResistance; } -@@ -375,8 +_,10 @@ - - public void updateEntityMovementAfterFallOn(BlockGetter p_49821_, Entity p_49822_) { - p_49822_.setDeltaMovement(p_49822_.getDeltaMovement().multiply(1.0, 0.0, 1.0)); -+ p_49822_.setDeltaMovement(p_49822_.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D)); - } - -+ @Deprecated //Forge: Use more sensitive version - public ItemStack getCloneItemStack(LevelReader p_304395_, BlockPos p_49824_, BlockState p_49825_) { - return new ItemStack(this); - } -@@ -410,6 +_,7 @@ +@@ -406,6 +_,7 @@ public void handlePrecipitation(BlockState p_152450_, Level p_152451_, BlockPos p_152452_, Biome.Precipitation p_152453_) { } @@ -131,7 +120,7 @@ public boolean dropFromExplosion(Explosion p_49826_) { return true; } -@@ -475,6 +_,35 @@ +@@ -471,6 +_,35 @@ return this.stateDefinition.getPossibleStates().stream().collect(ImmutableMap.toImmutableMap(Function.identity(), p_152459_)); } diff --git a/patches/net/minecraft/world/level/block/Blocks.java.patch b/patches/net/minecraft/world/level/block/Blocks.java.patch index c9befa089f..f16c2db321 100644 --- a/patches/net/minecraft/world/level/block/Blocks.java.patch +++ b/patches/net/minecraft/world/level/block/Blocks.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/Blocks.java +++ b/net/minecraft/world/level/block/Blocks.java -@@ -690,7 +_,7 @@ +@@ -675,7 +_,7 @@ public static final Block RED_BED = registerBed("red_bed", DyeColor.RED); public static final Block BLACK_BED = registerBed("black_bed", DyeColor.BLACK); public static final Block POWERED_RAIL = register( @@ -9,7 +9,7 @@ ); public static final Block DETECTOR_RAIL = register( "detector_rail", DetectorRailBlock::new, BlockBehaviour.Properties.of().noCollission().strength(0.7F).sound(SoundType.METAL) -@@ -6919,7 +_,8 @@ +@@ -6935,7 +_,8 @@ static { for (Block block : BuiltInRegistries.BLOCK) { for (BlockState blockstate : block.getStateDefinition().getPossibleStates()) { diff --git a/patches/net/minecraft/world/level/block/CampfireBlock.java.patch b/patches/net/minecraft/world/level/block/CampfireBlock.java.patch index 927f77d8db..4db887cbad 100644 --- a/patches/net/minecraft/world/level/block/CampfireBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CampfireBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/CampfireBlock.java +++ b/net/minecraft/world/level/block/CampfireBlock.java -@@ -292,7 +_,7 @@ +@@ -287,7 +_,7 @@ return true; } diff --git a/patches/net/minecraft/world/level/block/ChestBlock.java.patch b/patches/net/minecraft/world/level/block/ChestBlock.java.patch index 47e4ad187d..05a8241fdc 100644 --- a/patches/net/minecraft/world/level/block/ChestBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ChestBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/ChestBlock.java +++ b/net/minecraft/world/level/block/ChestBlock.java -@@ -365,7 +_,8 @@ +@@ -360,7 +_,8 @@ @Override protected BlockState mirror(BlockState p_51549_, Mirror p_51550_) { diff --git a/patches/net/minecraft/world/level/block/ComposterBlock.java.patch b/patches/net/minecraft/world/level/block/ComposterBlock.java.patch index 5d1d96dda8..7824b8e764 100644 --- a/patches/net/minecraft/world/level/block/ComposterBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ComposterBlock.java.patch @@ -9,7 +9,7 @@ public static final Object2FloatMap COMPOSTABLES = new Object2FloatOpenHashMap<>(); private static final int AABB_SIDE_THICKNESS = 2; private static final VoxelShape OUTER_SHAPE = Shapes.block(); -@@ -231,6 +_,15 @@ +@@ -233,6 +_,15 @@ if (p_51978_.getValue(LEVEL) == 7) { p_51979_.scheduleTick(p_51980_, p_51978_.getBlock(), 20); } @@ -25,7 +25,7 @@ } @Override -@@ -238,7 +_,7 @@ +@@ -240,7 +_,7 @@ ItemStack p_316332_, BlockState p_316118_, Level p_316624_, BlockPos p_316660_, Player p_316715_, InteractionHand p_316472_, BlockHitResult p_316606_ ) { int i = p_316118_.getValue(LEVEL); @@ -34,7 +34,7 @@ if (i < 7 && !p_316624_.isClientSide) { BlockState blockstate = addItem(p_316715_, p_316118_, p_316624_, p_316660_, p_316332_); p_316624_.levelEvent(1500, p_316660_, p_316118_ != blockstate ? 1 : 0); -@@ -265,7 +_,7 @@ +@@ -267,7 +_,7 @@ public static BlockState insertItem(Entity p_270919_, BlockState p_270087_, ServerLevel p_270284_, ItemStack p_270253_, BlockPos p_270678_) { int i = p_270087_.getValue(LEVEL); @@ -43,7 +43,7 @@ BlockState blockstate = addItem(p_270919_, p_270087_, p_270284_, p_270678_, p_270253_); p_270253_.shrink(1); return blockstate; -@@ -296,7 +_,7 @@ +@@ -298,7 +_,7 @@ static BlockState addItem(@Nullable Entity p_270464_, BlockState p_270603_, LevelAccessor p_270151_, BlockPos p_270547_, ItemStack p_270354_) { int i = p_270603_.getValue(LEVEL); @@ -52,7 +52,7 @@ if ((i != 0 || !(f > 0.0F)) && !(p_270151_.getRandom().nextDouble() < (double)f)) { return p_270603_; } else { -@@ -396,7 +_,7 @@ +@@ -398,7 +_,7 @@ @Override public boolean canPlaceItemThroughFace(int p_52028_, ItemStack p_52029_, @Nullable Direction p_52030_) { @@ -61,7 +61,7 @@ } @Override -@@ -454,5 +_,11 @@ +@@ -456,5 +_,11 @@ ComposterBlock.empty(null, this.state, this.level, this.pos); this.changed = true; } diff --git a/patches/net/minecraft/world/level/block/FlowerPotBlock.java.patch b/patches/net/minecraft/world/level/block/FlowerPotBlock.java.patch index ce68c441bd..0dd734152f 100644 --- a/patches/net/minecraft/world/level/block/FlowerPotBlock.java.patch +++ b/patches/net/minecraft/world/level/block/FlowerPotBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/FlowerPotBlock.java +++ b/net/minecraft/world/level/block/FlowerPotBlock.java -@@ -35,6 +_,7 @@ +@@ -37,6 +_,7 @@ private static final Map POTTED_BY_CONTENT = Maps.newHashMap(); public static final float AABB_SIZE = 3.0F; protected static final VoxelShape SHAPE = Block.box(5.0, 0.0, 5.0, 11.0, 6.0, 11.0); @@ -8,7 +8,7 @@ private final Block potted; @Override -@@ -42,10 +_,31 @@ +@@ -44,10 +_,31 @@ return CODEC; } @@ -43,7 +43,7 @@ } @Override -@@ -58,7 +_,7 @@ +@@ -60,7 +_,7 @@ ItemStack p_316610_, BlockState p_316240_, Level p_316456_, BlockPos p_316502_, Player p_316491_, InteractionHand p_316444_, BlockHitResult p_316826_ ) { BlockState blockstate = (p_316610_.getItem() instanceof BlockItem blockitem @@ -52,7 +52,7 @@ : Blocks.AIR) .defaultBlockState(); if (blockstate.isAir()) { -@@ -84,7 +_,7 @@ +@@ -86,7 +_,7 @@ p_316338_.drop(itemstack, false); } @@ -61,7 +61,7 @@ p_316655_.gameEvent(p_316338_, GameEvent.BLOCK_CHANGE, p_316654_); return InteractionResult.SUCCESS; } -@@ -116,11 +_,44 @@ +@@ -118,12 +_,45 @@ } public Block getPotted() { @@ -106,4 +106,5 @@ + public Map> getFullPotsView() { + return java.util.Collections.unmodifiableMap(fullPots); } - } + + @Override diff --git a/patches/net/minecraft/world/level/block/SculkCatalystBlock.java.patch b/patches/net/minecraft/world/level/block/SculkCatalystBlock.java.patch index 6fb3c95fbd..a3a2a23c13 100644 --- a/patches/net/minecraft/world/level/block/SculkCatalystBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SculkCatalystBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SculkCatalystBlock.java +++ b/net/minecraft/world/level/block/SculkCatalystBlock.java -@@ -66,8 +_,14 @@ +@@ -61,8 +_,14 @@ @Override protected void spawnAfterBreak(BlockState p_222109_, ServerLevel p_222110_, BlockPos p_222111_, ItemStack p_222112_, boolean p_222113_) { super.spawnAfterBreak(p_222109_, p_222110_, p_222111_, p_222112_, p_222113_); diff --git a/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch b/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch index 5aee48d600..3a4f746903 100644 --- a/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SculkSensorBlock.java +++ b/net/minecraft/world/level/block/SculkSensorBlock.java -@@ -299,8 +_,13 @@ +@@ -294,8 +_,13 @@ @Override protected void spawnAfterBreak(BlockState p_222142_, ServerLevel p_222143_, BlockPos p_222144_, ItemStack p_222145_, boolean p_222146_) { super.spawnAfterBreak(p_222142_, p_222143_, p_222144_, p_222145_, p_222146_); diff --git a/patches/net/minecraft/world/level/block/SculkShriekerBlock.java.patch b/patches/net/minecraft/world/level/block/SculkShriekerBlock.java.patch index 646554aa30..39d5e849d8 100644 --- a/patches/net/minecraft/world/level/block/SculkShriekerBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SculkShriekerBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SculkShriekerBlock.java +++ b/net/minecraft/world/level/block/SculkShriekerBlock.java -@@ -149,9 +_,14 @@ +@@ -144,9 +_,14 @@ @Override protected void spawnAfterBreak(BlockState p_222192_, ServerLevel p_222193_, BlockPos p_222194_, ItemStack p_222195_, boolean p_222196_) { super.spawnAfterBreak(p_222192_, p_222193_, p_222194_, p_222195_, p_222196_); diff --git a/patches/net/minecraft/world/level/block/SoundType.java.patch b/patches/net/minecraft/world/level/block/SoundType.java.patch index 92c1ab63a3..f17836597f 100644 --- a/patches/net/minecraft/world/level/block/SoundType.java.patch +++ b/patches/net/minecraft/world/level/block/SoundType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SoundType.java +++ b/net/minecraft/world/level/block/SoundType.java -@@ -789,6 +_,7 @@ +@@ -801,6 +_,7 @@ private final SoundEvent hitSound; private final SoundEvent fallSound; diff --git a/patches/net/minecraft/world/level/block/SpongeBlock.java.patch b/patches/net/minecraft/world/level/block/SpongeBlock.java.patch index ac00ddee76..1d850fcce7 100644 --- a/patches/net/minecraft/world/level/block/SpongeBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SpongeBlock.java.patch @@ -14,6 +14,6 @@ FluidState fluidstate = p_56808_.getFluidState(p_294069_); - if (!fluidstate.is(FluidTags.WATER)) { + if (!spongeState.canBeHydrated(p_56808_, p_56809_, fluidstate, p_294069_)) { - return false; + return BlockPos.TraversalNodeStatus.SKIP; } else { if (blockstate.getBlock() instanceof BucketPickup bucketpickup diff --git a/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch index 03bd036ae7..0d5b214c7a 100644 --- a/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch @@ -1,30 +1,30 @@ --- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -54,6 +_,7 @@ +@@ -53,6 +_,7 @@ + public static final int NUM_DATA_VALUES = 4; public static final int BURN_TIME_STANDARD = 200; public static final int BURN_COOL_SPEED = 2; - public static final int UNKNOWN_LIT_DURATION = 0; + private final RecipeType recipeType; protected NonNullList items = NonNullList.withSize(3, ItemStack.EMPTY); - int litTime; - int litDuration = 0; -@@ -64,9 +_,14 @@ + int litTimeRemaining; + int litTotalTime; +@@ -63,9 +_,14 @@ public int get(int p_58431_) { switch (p_58431_) { case 0: -+ if (litDuration > Short.MAX_VALUE) { ++ if (litTotalTime > Short.MAX_VALUE) { + // Neo: preserve litTime / litDuration ratio on the client as data slots are synced as shorts. -+ return net.minecraft.util.Mth.floor(((double) litTime / litDuration) * Short.MAX_VALUE); ++ return net.minecraft.util.Mth.floor(((double) litTimeRemaining / litTotalTime) * Short.MAX_VALUE); + } + - return AbstractFurnaceBlockEntity.this.litTime; + return AbstractFurnaceBlockEntity.this.litTimeRemaining; case 1: -- return AbstractFurnaceBlockEntity.this.litDuration; -+ return Math.min(AbstractFurnaceBlockEntity.this.litDuration, Short.MAX_VALUE); +- return AbstractFurnaceBlockEntity.this.litTotalTime; ++ return Math.min(AbstractFurnaceBlockEntity.this.litTotalTime, Short.MAX_VALUE); case 2: - return AbstractFurnaceBlockEntity.this.cookingProgress; + return AbstractFurnaceBlockEntity.this.cookingTimer; case 3: -@@ -106,6 +_,7 @@ +@@ -105,6 +_,7 @@ ) { super(p_154991_, p_154992_, p_154993_); this.quickCheck = RecipeManager.createCheck((RecipeType)p_154994_); @@ -32,34 +32,38 @@ } private boolean isLit() { -@@ -117,9 +_,9 @@ +@@ -116,10 +_,10 @@ super.loadAdditional(p_155025_, p_323468_); this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); ContainerHelper.loadAllItems(p_155025_, this.items, p_323468_); -- this.litTime = p_155025_.getShort("BurnTime"); -- this.cookingProgress = p_155025_.getShort("CookTime"); -- this.cookingTotalTime = p_155025_.getShort("CookTimeTotal"); -+ this.litTime = p_155025_.getInt("BurnTime"); -+ this.cookingProgress = p_155025_.getInt("CookTime"); -+ this.cookingTotalTime = p_155025_.getInt("CookTimeTotal"); - this.litDuration = 0; +- this.cookingTimer = p_155025_.getShort("cooking_time_spent"); +- this.cookingTotalTime = p_155025_.getShort("cooking_total_time"); +- this.litTimeRemaining = p_155025_.getShort("lit_time_remaining"); +- this.litTotalTime = p_155025_.getShort("lit_total_time"); ++ this.cookingTimer = p_155025_.getInt("cooking_time_spent"); ++ this.cookingTotalTime = p_155025_.getInt("cooking_total_time"); ++ this.litTimeRemaining = p_155025_.getInt("lit_time_remaining"); ++ this.litTotalTime = p_155025_.getInt("lit_total_time"); CompoundTag compoundtag = p_155025_.getCompound("RecipesUsed"); -@@ -131,9 +_,9 @@ + for (String s : compoundtag.getAllKeys()) { +@@ -130,10 +_,10 @@ @Override protected void saveAdditional(CompoundTag p_187452_, HolderLookup.Provider p_323656_) { super.saveAdditional(p_187452_, p_323656_); -- p_187452_.putShort("BurnTime", (short)this.litTime); -- p_187452_.putShort("CookTime", (short)this.cookingProgress); -- p_187452_.putShort("CookTimeTotal", (short)this.cookingTotalTime); -+ p_187452_.putInt("BurnTime", this.litTime); -+ p_187452_.putInt("CookTime", this.cookingProgress); -+ p_187452_.putInt("CookTimeTotal", this.cookingTotalTime); +- p_187452_.putShort("cooking_time_spent", (short)this.cookingTimer); +- p_187452_.putShort("cooking_total_time", (short)this.cookingTotalTime); +- p_187452_.putShort("lit_time_remaining", (short)this.litTimeRemaining); +- p_187452_.putShort("lit_total_time", (short)this.litTotalTime); ++ p_187452_.putInt("cooking_time_spent", this.cookingTimer); ++ p_187452_.putInt("cooking_total_time", this.cookingTotalTime); ++ p_187452_.putInt("lit_time_remaining", this.litTimeRemaining); ++ p_187452_.putInt("lit_total_time", this.litTotalTime); ContainerHelper.saveAllItems(p_187452_, this.items, p_323656_); CompoundTag compoundtag = new CompoundTag(); this.recipesUsed.forEach((p_380898_, p_380899_) -> compoundtag.putInt(p_380898_.location().toString(), p_380899_)); -@@ -170,11 +_,15 @@ - p_155017_.litDuration = p_155017_.litTime; +@@ -166,11 +_,15 @@ + p_155017_.litTotalTime = p_155017_.litTimeRemaining; if (p_155017_.isLit()) { flag1 = true; + var remainder = itemstack.getCraftingRemainder(); @@ -75,7 +79,7 @@ } } } -@@ -227,9 +_,9 @@ +@@ -223,9 +_,9 @@ } else if (!ItemStack.isSameItemSameComponents(itemstack1, itemstack)) { return false; } else { @@ -87,7 +91,7 @@ } } } else { -@@ -251,7 +_,7 @@ +@@ -247,7 +_,7 @@ if (itemstack2.isEmpty()) { p_267073_.set(2, itemstack1.copy()); } else if (ItemStack.isSameItemSameComponents(itemstack2, itemstack1)) { @@ -96,7 +100,7 @@ } if (itemstack.is(Blocks.WET_SPONGE.asItem()) && !p_267073_.get(1).isEmpty() && p_267073_.get(1).is(Items.BUCKET)) { -@@ -266,7 +_,7 @@ +@@ -262,7 +_,7 @@ } protected int getBurnDuration(FuelValues p_363501_, ItemStack p_58343_) { @@ -105,7 +109,7 @@ } private static int getTotalCookTime(ServerLevel p_380169_, AbstractFurnaceBlockEntity p_222694_) { -@@ -329,7 +_,7 @@ +@@ -325,7 +_,7 @@ return true; } else { ItemStack itemstack = this.items.get(1); diff --git a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch index 16fb21f9f0..c2a70f7e4a 100644 --- a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -27,8 +_,9 @@ +@@ -26,8 +_,9 @@ import net.minecraft.world.level.block.state.BlockState; import org.slf4j.Logger; @@ -11,7 +11,7 @@ private final BlockEntityType type; @Nullable protected Level level; -@@ -36,6 +_,8 @@ +@@ -35,6 +_,8 @@ protected boolean remove; private BlockState blockState; private DataComponentMap components = DataComponentMap.EMPTY; @@ -20,7 +20,7 @@ public BlockEntity(BlockEntityType p_155228_, BlockPos p_155229_, BlockState p_155230_) { this.type = p_155228_; -@@ -51,7 +_,7 @@ +@@ -50,7 +_,7 @@ } public boolean isValidBlockState(BlockState p_353131_) { @@ -29,7 +29,7 @@ } public static BlockPos getPosFromTag(CompoundTag p_187473_) { -@@ -72,6 +_,8 @@ +@@ -71,6 +_,8 @@ } protected void loadAdditional(CompoundTag p_338466_, HolderLookup.Provider p_338445_) { @@ -38,7 +38,7 @@ } public final void loadWithComponents(CompoundTag p_338356_, HolderLookup.Provider p_338558_) { -@@ -87,6 +_,9 @@ +@@ -86,6 +_,9 @@ } protected void saveAdditional(CompoundTag p_187471_, HolderLookup.Provider p_323635_) { @@ -48,7 +48,7 @@ } public final CompoundTag saveWithFullMetadata(HolderLookup.Provider p_323767_) { -@@ -217,10 +_,14 @@ +@@ -208,10 +_,14 @@ public void setRemoved() { this.remove = true; @@ -63,7 +63,7 @@ } public boolean triggerEvent(int p_58889_, int p_58890_) { -@@ -247,6 +_,27 @@ +@@ -234,6 +_,27 @@ return this.type; } @@ -91,7 +91,7 @@ @Deprecated public void setBlockState(BlockState p_155251_) { this.validateBlockState(p_155251_); -@@ -326,5 +_,15 @@ +@@ -314,5 +_,15 @@ T get(DataComponentType p_338658_); T getOrDefault(DataComponentType p_338573_, T p_338734_); diff --git a/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch b/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch index 77f3f48d29..87245aa63a 100644 --- a/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/entity/BlockEntityType.java +++ b/net/minecraft/world/level/block/entity/BlockEntityType.java -@@ -229,6 +_,7 @@ - public static final BlockEntityType TRIAL_SPAWNER = register("trial_spawner", TrialSpawnerBlockEntity::new, Blocks.TRIAL_SPAWNER); +@@ -230,6 +_,7 @@ public static final BlockEntityType VAULT = register("vault", VaultBlockEntity::new, Blocks.VAULT); + private static final Set> OP_ONLY_CUSTOM_DATA = Set.of(COMMAND_BLOCK, LECTERN, SIGN, HANGING_SIGN, MOB_SPAWNER, TRIAL_SPAWNER); private final BlockEntityType.BlockEntitySupplier factory; + // Neo: This field will be modified by BlockEntityTypeAddBlocksEvent event. Please use the event to add to this field for vanilla or other mod's BlockEntityTypes. private final Set validBlocks; private final Holder.Reference> builtInRegistryHolder = BuiltInRegistries.BLOCK_ENTITY_TYPE.createIntrusiveHolder(this); -@@ -253,9 +_,24 @@ +@@ -254,9 +_,24 @@ this.validBlocks = p_155260_; } diff --git a/patches/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java.patch index d884906785..16cb1518aa 100644 --- a/patches/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +++ b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -@@ -231,7 +_,7 @@ +@@ -232,7 +_,7 @@ @Override public boolean canPlaceItemThroughFace(int p_59663_, ItemStack p_59664_, @Nullable Direction p_59665_) { diff --git a/patches/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch b/patches/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch index 54f0c94786..7e157d8a3b 100644 --- a/patches/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch +++ b/patches/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch @@ -22,7 +22,7 @@ mob.setPersistenceRequired(); spawndata.getEquipment().ifPresent(mob::equip); -@@ -413,5 +_,14 @@ +@@ -420,5 +_,14 @@ TrialSpawnerState getState(); void markUpdated(); diff --git a/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch b/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch index 9fdd0acefe..d1ee4eefd2 100644 --- a/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch +++ b/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch @@ -30,7 +30,7 @@ } } -@@ -389,6 +_,7 @@ +@@ -389,10 +_,13 @@ return this.isRandomlyTicking; } @@ -38,7 +38,13 @@ protected SoundType getSoundType(BlockState p_320941_) { return this.soundType; } -@@ -405,6 +_,10 @@ + ++ @Deprecated ++ /** @deprecated NeoForge: use {@link net.neoforged.neoforge.common.extensions.IBlockExtension#getCloneItemStack(BlockState, LevelReader, BlockPos, Player, boolean) player-sensitive version} */ + protected ItemStack getCloneItemStack(LevelReader p_382795_, BlockPos p_383120_, BlockState p_382830_, boolean p_388788_) { + return new ItemStack(this.asItem()); + } +@@ -409,6 +_,10 @@ return this.properties.destroyTime; } @@ -49,7 +55,7 @@ public abstract static class BlockStateBase extends StateHolder { private static final Direction[] DIRECTIONS = Direction.values(); private static final VoxelShape[] EMPTY_OCCLUSION_SHAPES = Util.make( -@@ -561,12 +_,14 @@ +@@ -565,12 +_,14 @@ return this.useShapeForLightOcclusion; } @@ -65,7 +71,7 @@ } public boolean ignitedByLava() { -@@ -579,9 +_,11 @@ +@@ -583,9 +_,11 @@ } public MapColor getMapColor(BlockGetter p_285002_, BlockPos p_285293_) { @@ -78,7 +84,7 @@ public BlockState rotate(Rotation p_60718_) { return this.getBlock().rotate(this.asState(), p_60718_); } -@@ -635,6 +_,8 @@ +@@ -639,6 +_,8 @@ } public PushReaction getPistonPushReaction() { @@ -87,7 +93,7 @@ return this.pushReaction; } -@@ -762,6 +_,9 @@ +@@ -766,6 +_,9 @@ } public InteractionResult useItemOn(ItemStack p_316374_, Level p_316651_, Player p_316623_, InteractionHand p_316469_, BlockHitResult p_316877_) { @@ -97,7 +103,7 @@ return this.getBlock().useItemOn(p_316374_, this.asState(), p_316651_, p_316877_.getBlockPos(), p_316623_, p_316469_, p_316877_); } -@@ -871,6 +_,7 @@ +@@ -875,6 +_,7 @@ return this.getBlock().getSeed(this.asState(), p_60727_); } @@ -105,7 +111,7 @@ public SoundType getSoundType() { return this.getBlock().getSoundType(this.asState()); } -@@ -996,7 +_,7 @@ +@@ -1004,7 +_,7 @@ BlockBehaviour.StateArgumentPredicate> isValidSpawn = (p_360193_, p_360194_, p_360195_, p_360196_) -> p_360193_.isFaceSturdy( p_360194_, p_360195_, Direction.UP ) diff --git a/patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch b/patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch index 7de81bd23b..303f56095a 100644 --- a/patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch +++ b/patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch @@ -9,7 +9,7 @@ public static final int NO_FILLED_SECTION = -1; private static final Logger LOGGER = LogUtils.getLogger(); private static final LongSet EMPTY_REFERENCE_SET = new LongOpenHashSet(); -@@ -324,10 +_,19 @@ +@@ -327,10 +_,19 @@ @Override public final void findBlockLightSources(BiConsumer p_285269_) { @@ -30,7 +30,7 @@ BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); for (int i = this.getMinSectionY(); i <= this.getMaxSectionY(); i++) { -@@ -339,8 +_,9 @@ +@@ -342,8 +_,9 @@ for (int k = 0; k < 16; k++) { for (int l = 0; l < 16; l++) { BlockState blockstate = levelchunksection.getBlockState(l, j, k); @@ -42,7 +42,7 @@ } } } -@@ -482,6 +_,74 @@ +@@ -485,6 +_,74 @@ public ChunkSkyLightSources getSkyLightSources() { return this.skyLightSources; } diff --git a/patches/net/minecraft/world/level/chunk/ChunkGenerator.java.patch b/patches/net/minecraft/world/level/chunk/ChunkGenerator.java.patch index 37936df20a..6aca891ac4 100644 --- a/patches/net/minecraft/world/level/chunk/ChunkGenerator.java.patch +++ b/patches/net/minecraft/world/level/chunk/ChunkGenerator.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/net/minecraft/world/level/chunk/ChunkGenerator.java -@@ -92,9 +_,14 @@ +@@ -93,9 +_,14 @@ public ChunkGenerator(BiomeSource p_255838_, Function, BiomeGenerationSettings> p_256216_) { this.biomeSource = p_255838_; this.generationSettingsGetter = p_256216_; diff --git a/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch b/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch index dfa6a02fdf..4a9a08cd9f 100644 --- a/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch +++ b/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -51,7 +_,7 @@ +@@ -52,7 +_,7 @@ import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; @@ -9,7 +9,7 @@ static final Logger LOGGER = LogUtils.getLogger(); private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { @Override -@@ -142,6 +_,7 @@ +@@ -146,6 +_,7 @@ this.setAllStarts(p_196851_.getAllStarts()); this.setAllReferences(p_196851_.getAllReferences()); @@ -17,7 +17,7 @@ for (Entry entry : p_196851_.getHeightmaps()) { if (ChunkStatus.FULL.heightmapsAfter().contains(entry.getKey())) { this.setHeightmap(entry.getKey(), entry.getValue().getRawData()); -@@ -279,7 +_,7 @@ +@@ -283,7 +_,7 @@ this.level.getChunkSource().onSectionEmptinessChanged(this.chunkPos.x, SectionPos.blockToSectionCoord(i), this.chunkPos.z, flag1); } @@ -26,7 +26,7 @@ ProfilerFiller profilerfiller = Profiler.get(); profilerfiller.push("updateSkyLightSources"); this.skyLightSources.update(this, j, i, l); -@@ -298,7 +_,7 @@ +@@ -302,7 +_,7 @@ if (!levelchunksection.getBlockState(j, k, l).is(block)) { return null; } else { @@ -35,7 +35,7 @@ p_62866_.onPlace(this.level, p_62865_, blockstate, p_62867_); } -@@ -353,6 +_,10 @@ +@@ -357,6 +_,10 @@ @Nullable public BlockEntity getBlockEntity(BlockPos p_62868_, LevelChunk.EntityCreationType p_62869_) { BlockEntity blockentity = this.blockEntities.get(p_62868_); @@ -46,7 +46,7 @@ if (blockentity == null) { CompoundTag compoundtag = this.pendingBlockEntities.remove(p_62868_); if (compoundtag != null) { -@@ -370,9 +_,6 @@ +@@ -374,9 +_,6 @@ this.addAndRegisterBlockEntity(blockentity); } } @@ -56,7 +56,7 @@ } return blockentity; -@@ -386,6 +_,7 @@ +@@ -390,6 +_,7 @@ } this.updateBlockEntityTicker(p_156391_); @@ -64,7 +64,7 @@ } } -@@ -429,6 +_,7 @@ +@@ -433,6 +_,7 @@ BlockEntity blockentity = this.blockEntities.put(blockpos.immutable(), p_156374_); if (blockentity != null && blockentity != p_156374_) { blockentity.setRemoved(); @@ -72,7 +72,7 @@ } } } -@@ -438,9 +_,14 @@ +@@ -442,9 +_,14 @@ public CompoundTag getBlockEntityNbtForSaving(BlockPos p_62932_, HolderLookup.Provider p_323699_) { BlockEntity blockentity = this.getBlockEntity(p_62932_); if (blockentity != null && !blockentity.isRemoved()) { @@ -87,7 +87,7 @@ } else { CompoundTag compoundtag = this.pendingBlockEntities.get(p_62932_); if (compoundtag != null) { -@@ -462,6 +_,7 @@ +@@ -466,6 +_,7 @@ } blockentity.setRemoved(); @@ -95,7 +95,7 @@ } } -@@ -522,7 +_,7 @@ +@@ -526,7 +_,7 @@ p_187974_.accept((p_338077_, p_338078_, p_338079_) -> { BlockEntity blockentity = this.getBlockEntity(p_338077_, LevelChunk.EntityCreationType.IMMEDIATE); if (blockentity != null && p_338079_ != null && blockentity.getType() == p_338078_) { @@ -104,7 +104,7 @@ } }); } -@@ -632,6 +_,7 @@ +@@ -636,6 +_,7 @@ } public void clearAllBlockEntities() { @@ -112,7 +112,7 @@ this.blockEntities.values().forEach(BlockEntity::setRemoved); this.blockEntities.clear(); this.tickersInLevel.values().forEach(p_187966_ -> p_187966_.rebind(NULL_TICKER)); -@@ -639,6 +_,7 @@ +@@ -643,6 +_,7 @@ } public void registerAllBlockEntitiesAfterLevelLoad() { @@ -120,7 +120,7 @@ this.blockEntities.values().forEach(p_187988_ -> { if (this.level instanceof ServerLevel serverlevel) { this.addGameEventListener(p_187988_, serverlevel); -@@ -690,6 +_,14 @@ +@@ -694,6 +_,14 @@ return new LevelChunk.BoundTickingBlockEntity<>(p_156376_, p_156377_); } @@ -135,7 +135,7 @@ class BoundTickingBlockEntity implements TickingBlockEntity { private final T blockEntity; private final BlockEntityTicker ticker; -@@ -707,6 +_,7 @@ +@@ -711,6 +_,7 @@ if (LevelChunk.this.isTicking(blockpos)) { try { ProfilerFiller profilerfiller = Profiler.get(); @@ -143,7 +143,7 @@ profilerfiller.push(this::getType); BlockState blockstate = LevelChunk.this.getBlockState(blockpos); if (this.blockEntity.getType().isValid(blockstate)) { -@@ -728,7 +_,15 @@ +@@ -732,7 +_,15 @@ CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking block entity"); CrashReportCategory crashreportcategory = crashreport.addCategory("Block entity being ticked"); this.blockEntity.fillCrashReportCategory(crashreportcategory); diff --git a/patches/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch b/patches/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch index a16cba61c5..79373d9e75 100644 --- a/patches/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch +++ b/patches/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -198,11 +_,22 @@ +@@ -199,11 +_,22 @@ } levelchunk.setFullStatus(generationchunkholder::getFullStatus); diff --git a/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch b/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch index 5eef3aff03..c8542d92f5 100644 --- a/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch +++ b/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/storage/SectionStorage.java +++ b/net/minecraft/world/level/chunk/storage/SectionStorage.java -@@ -302,6 +_,19 @@ +@@ -306,6 +_,19 @@ this.simpleRegionStorage.close(); } diff --git a/patches/net/minecraft/world/level/levelgen/structure/Structure.java.patch b/patches/net/minecraft/world/level/levelgen/structure/Structure.java.patch index 62c1626156..a658f2049a 100644 --- a/patches/net/minecraft/world/level/levelgen/structure/Structure.java.patch +++ b/patches/net/minecraft/world/level/levelgen/structure/Structure.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/structure/Structure.java +++ b/net/minecraft/world/level/levelgen/structure/Structure.java -@@ -42,10 +_,11 @@ +@@ -46,10 +_,11 @@ public abstract class Structure { public static final Codec DIRECT_CODEC = BuiltInRegistries.STRUCTURE_TYPE.byNameCodec().dispatch(Structure::type, StructureType::codec); public static final Codec> CODEC = RegistryFileCodec.create(Registries.STRUCTURE, DIRECT_CODEC); @@ -14,7 +14,7 @@ } public static MapCodec simpleCodec(Function p_226608_) { -@@ -54,6 +_,7 @@ +@@ -58,6 +_,7 @@ protected Structure(Structure.StructureSettings p_226558_) { this.settings = p_226558_; @@ -22,7 +22,7 @@ } public HolderSet biomes() { -@@ -196,6 +_,25 @@ +@@ -211,6 +_,25 @@ } public abstract StructureType type(); diff --git a/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch b/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch index 8dd492afb3..0158a9c570 100644 --- a/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch +++ b/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/DimensionDataStorage.java +++ b/net/minecraft/world/level/storage/DimensionDataStorage.java -@@ -69,7 +_,7 @@ +@@ -73,7 +_,7 @@ } @Nullable @@ -9,7 +9,7 @@ try { Path path = this.getDataFile(p_164870_); if (Files.exists(path)) { -@@ -88,7 +_,7 @@ +@@ -92,7 +_,7 @@ p_164857_.setDirty(); } @@ -18,7 +18,7 @@ CompoundTag compoundtag1; try ( InputStream inputstream = Files.newInputStream(this.getDataFile(p_78159_)); -@@ -103,9 +_,16 @@ +@@ -107,9 +_,16 @@ } } @@ -37,16 +37,16 @@ return compoundtag1; } -@@ -156,7 +_,11 @@ - private static CompletableFuture tryWriteAsync(Path p_364583_, CompoundTag p_363128_) { - return CompletableFuture.runAsync(() -> { - try { -- NbtIo.writeCompressed(p_363128_, p_364583_); -+ // Neo: ensure parent directories exist if the SavedData's path contains slashes -+ if (!Files.exists(p_364583_)) { -+ Files.createDirectories(p_364583_.getParent()); -+ } -+ net.neoforged.neoforge.common.IOUtilities.writeNbtCompressed(p_363128_, p_364583_); - } catch (IOException ioexception) { - LOGGER.error("Could not save data to {}", p_364583_.getFileName(), ioexception); - } +@@ -182,7 +_,11 @@ + + private static void tryWrite(Path p_390658_, CompoundTag p_390657_) { + try { +- NbtIo.writeCompressed(p_390657_, p_390658_); ++ // Neo: ensure parent directories exist if the SavedData's path contains slashes ++ if (!Files.exists(p_390658_)) { ++ Files.createDirectories(p_390658_.getParent()); ++ } ++ net.neoforged.neoforge.common.IOUtilities.writeNbtCompressed(p_390657_, p_390658_); + } catch (IOException ioexception) { + LOGGER.error("Could not save data to {}", p_390658_.getFileName(), ioexception); + } diff --git a/projects/base/build.gradle b/projects/base/build.gradle index 04cca6fe08..d0b0c18084 100644 --- a/projects/base/build.gradle +++ b/projects/base/build.gradle @@ -25,9 +25,14 @@ neoDev { server { server() } - // Generated files are in run/data/generated - data { - data() + // Generated files are in run/clientData/generated + clientData { + clientData() + programArgument "--all" + } + // Generated files are in run/serverData/generated + serverData { + serverData() programArgument "--all" } } diff --git a/projects/neoforge/build.gradle b/projects/neoforge/build.gradle index 9227a224e7..bc5638d3ed 100644 --- a/projects/neoforge/build.gradle +++ b/projects/neoforge/build.gradle @@ -151,7 +151,9 @@ neoDev { type = "gameTestServer" } data { - data() + // We perform client and server datagen in a single clientData run to avoid + // having to juggle two generated resources folders and two runs for no additional benefit. + clientData() programArguments.addAll '--mod', 'neoforge', '--flat', '--all', '--validate', '--existing', rootProject.file("src/main/resources").absolutePath, '--output', rootProject.file("src/generated/resources").absolutePath diff --git a/src/generated/resources/data/minecraft/loot_table/blocks/pale_oak_leaves.json b/src/generated/resources/data/minecraft/loot_table/blocks/pale_oak_leaves.json new file mode 100644 index 0000000000..ff55c72291 --- /dev/null +++ b/src/generated/resources/data/minecraft/loot_table/blocks/pale_oak_leaves.json @@ -0,0 +1,132 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:any_of", + "terms": [ + { + "ability": "shears_dig", + "condition": "neoforge:can_item_perform_ability" + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + } + ] + } + ], + "name": "minecraft:pale_oak_leaves" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "chances": [ + 0.05, + 0.0625, + 0.083333336, + 0.1 + ], + "condition": "minecraft:table_bonus", + "enchantment": "minecraft:fortune" + } + ], + "name": "minecraft:pale_oak_sapling" + } + ] + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:any_of", + "terms": [ + { + "ability": "shears_dig", + "condition": "neoforge:can_item_perform_ability" + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + } + ] + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "chances": [ + 0.02, + 0.022222223, + 0.025, + 0.033333335, + 0.1 + ], + "condition": "minecraft:table_bonus", + "enchantment": "minecraft:fortune" + } + ], + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 2.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + }, + { + "function": "minecraft:explosion_decay" + } + ], + "name": "minecraft:stick" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "minecraft:blocks/pale_oak_leaves" +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pale_oak_chest_boat.json b/src/generated/resources/data/minecraft/recipe/pale_oak_chest_boat.json new file mode 100644 index 0000000000..8339b115b1 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pale_oak_chest_boat.json @@ -0,0 +1,17 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "chest_boat", + "ingredients": [ + { + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" + }, + "minecraft:pale_oak_boat" + ], + "result": { + "count": 1, + "id": "minecraft:pale_oak_chest_boat" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pale_oak_fence.json b/src/generated/resources/data/minecraft/recipe/pale_oak_fence.json new file mode 100644 index 0000000000..c4a34ad537 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pale_oak_fence.json @@ -0,0 +1,17 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "wooden_fence", + "key": { + "#": "#c:rods/wooden", + "W": "minecraft:pale_oak_planks" + }, + "pattern": [ + "W#W", + "W#W" + ], + "result": { + "count": 3, + "id": "minecraft:pale_oak_fence" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pale_oak_fence_gate.json b/src/generated/resources/data/minecraft/recipe/pale_oak_fence_gate.json new file mode 100644 index 0000000000..b09f87fa2b --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pale_oak_fence_gate.json @@ -0,0 +1,17 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "group": "wooden_fence_gate", + "key": { + "#": "#c:rods/wooden", + "W": "minecraft:pale_oak_planks" + }, + "pattern": [ + "#W#", + "#W#" + ], + "result": { + "count": 1, + "id": "minecraft:pale_oak_fence_gate" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pale_oak_sign.json b/src/generated/resources/data/minecraft/recipe/pale_oak_sign.json new file mode 100644 index 0000000000..ac471218f3 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pale_oak_sign.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "wooden_sign", + "key": { + "#": "minecraft:pale_oak_planks", + "X": "#c:rods/wooden" + }, + "pattern": [ + "###", + "###", + " X " + ], + "result": { + "count": 3, + "id": "minecraft:pale_oak_sign" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/data_maps/entity_type/parrot_imitations.json b/src/generated/resources/data/neoforge/data_maps/entity_type/parrot_imitations.json index 513f03410d..8f1d1c0056 100644 --- a/src/generated/resources/data/neoforge/data_maps/entity_type/parrot_imitations.json +++ b/src/generated/resources/data/neoforge/data_maps/entity_type/parrot_imitations.json @@ -15,9 +15,6 @@ "minecraft:creaking": { "sound": "minecraft:entity.parrot.imitate.creaking" }, - "minecraft:creaking_transient": { - "sound": "minecraft:entity.parrot.imitate.creaking" - }, "minecraft:creeper": { "sound": "minecraft:entity.parrot.imitate.creeper" }, diff --git a/src/generated/resources/data/neoforge/data_maps/item/compostables.json b/src/generated/resources/data/neoforge/data_maps/item/compostables.json index 2b3bdff6a6..c0b3789290 100644 --- a/src/generated/resources/data/neoforge/data_maps/item/compostables.json +++ b/src/generated/resources/data/neoforge/data_maps/item/compostables.json @@ -70,6 +70,9 @@ "minecraft:cherry_sapling": { "chance": 0.3 }, + "minecraft:closed_eyeblossom": { + "chance": 0.65 + }, "minecraft:cocoa_beans": { "chance": 0.65 }, @@ -184,6 +187,9 @@ "minecraft:oak_sapling": { "chance": 0.3 }, + "minecraft:open_eyeblossom": { + "chance": 0.65 + }, "minecraft:orange_tulip": { "chance": 0.65 }, diff --git a/src/generated/resources/pack.mcmeta b/src/generated/resources/pack.mcmeta index f49d678e8d..607b7ff420 100644 --- a/src/generated/resources/pack.mcmeta +++ b/src/generated/resources/pack.mcmeta @@ -3,7 +3,7 @@ "description": { "translate": "pack.neoforge.description" }, - "pack_format": 57, + "pack_format": 61, "supported_formats": [ 0, 2147483647 diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index c7e42d8975..50750c45cb 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -17,16 +17,15 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.Stack; import java.util.UUID; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -38,7 +37,6 @@ import net.minecraft.client.MouseHandler; import net.minecraft.client.Options; import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.color.item.ItemColors; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.LerpingBossEvent; @@ -85,11 +83,12 @@ import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.model.AtlasSet; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.EquipmentClientInfo; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.sounds.MusicInfo; import net.minecraft.client.sounds.SoundEngine; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -104,7 +103,6 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ReloadableResourceManager; -import net.minecraft.sounds.Music; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.util.profiling.Profiler; @@ -118,7 +116,6 @@ import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.equipment.EquipmentModel; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; @@ -255,8 +252,8 @@ public static float getGuiFarPlane() { return 11_000F + depth; } - public static ResourceLocation getArmorTexture(ItemStack armor, EquipmentModel.LayerType type, EquipmentModel.Layer layer, ResourceLocation _default) { - ResourceLocation result = armor.getItem().getArmorTexture(armor, type, layer, _default); + public static ResourceLocation getArmorTexture(ItemStack armor, EquipmentClientInfo.LayerType type, EquipmentClientInfo.Layer layer, ResourceLocation _default) { + ResourceLocation result = IClientItemExtensions.of(armor).getArmorTexture(armor, type, layer, _default); return result != null ? result : _default; } @@ -303,11 +300,7 @@ public static void onBlockColorsInit(BlockColors blockColors) { ModLoader.postEvent(new RegisterColorHandlersEvent.Block(blockColors)); } - public static void onItemColorsInit(ItemColors itemColors, BlockColors blockColors) { - ModLoader.postEvent(new RegisterColorHandlersEvent.Item(itemColors, blockColors)); - } - - public static Model getArmorModel(ItemStack itemStack, EquipmentModel.LayerType layerType, Model _default) { + public static Model getArmorModel(ItemStack itemStack, EquipmentClientInfo.LayerType layerType, Model _default) { return IClientItemExtensions.of(itemStack).getGenericArmorModel(itemStack, layerType, _default); } @@ -395,7 +388,7 @@ public static SoundInstance playSound(SoundEngine manager, SoundInstance sound) } @Nullable - public static Music selectMusic(Music situational, @Nullable SoundInstance playing) { + public static MusicInfo selectMusic(MusicInfo situational, @Nullable SoundInstance playing) { SelectMusicEvent e = new SelectMusicEvent(situational, playing); NeoForge.EVENT_BUS.post(e); return e.getMusic(); @@ -452,7 +445,7 @@ public static FogParameters onFogRender(FogRenderer.FogMode mode, FogType type, return fogParameters; } - public static void onModifyBakingResult(Map models, Map stitchResults, ModelBakery modelBakery) { + public static void onModifyBakingResult(ModelBakery.BakingResult bakingResult, Map stitchResults, ModelBakery modelBakery) { Function textureGetter = material -> { AtlasSet.StitchResult stitchResult = stitchResults.get(material.atlasLocation()); TextureAtlasSprite sprite = stitchResult.getSprite(material.texture()); @@ -462,14 +455,14 @@ public static void onModifyBakingResult(Map m LOGGER.warn("Failed to retrieve texture '{}' from atlas '{}'", material.texture(), material.atlasLocation(), new Throwable()); return stitchResult.missing(); }; - ModLoader.postEvent(new ModelEvent.ModifyBakingResult(models, textureGetter, modelBakery)); + ModLoader.postEvent(new ModelEvent.ModifyBakingResult(bakingResult, textureGetter, modelBakery)); } - public static void onModelBake(ModelManager modelManager, Map models, ModelBakery modelBakery) { - ModLoader.postEvent(new ModelEvent.BakingCompleted(modelManager, Collections.unmodifiableMap(models), modelBakery)); + public static void onModelBake(ModelManager modelManager, ModelBakery.BakingResult bakingResult, ModelBakery modelBakery) { + ModLoader.postEvent(new ModelEvent.BakingCompleted(modelManager, bakingResult, modelBakery)); } - public static BakedModel handleCameraTransforms(PoseStack poseStack, BakedModel model, ItemDisplayContext cameraTransformType, boolean applyLeftHandTransform) { + public static BakedModel handleCameraTransforms(PoseStack poseStack, @Nullable BakedModel model, ItemDisplayContext cameraTransformType, boolean applyLeftHandTransform) { model = model.applyTransform(cameraTransformType, poseStack, applyLeftHandTransform); return model; } @@ -725,8 +718,8 @@ public static void onRegisterKeyMappings(Options options) { ModLoader.postEvent(new RegisterKeyMappingsEvent(options)); } - public static void onRegisterAdditionalModels(Set additionalModels) { - ModLoader.postEvent(new ModelEvent.RegisterAdditional(additionalModels)); + public static void onRegisterAdditionalModels(Consumer registrar) { + ModLoader.postEvent(new ModelEvent.RegisterAdditional(registrar)); } @Nullable diff --git a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java index f8526f30d3..f783a342f5 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java @@ -5,50 +5,75 @@ package net.neoforged.neoforge.client; +import java.util.Optional; +import net.minecraft.DetectedVersion; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BiomeColors; import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; +import net.minecraft.data.metadata.PackMetadataGenerator; +import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.ARGB; -import net.minecraft.world.item.SpawnEggItem; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.metadata.pack.PackMetadataSection; +import net.minecraft.util.InclusiveRange; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.material.FluidState; import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.config.ModConfigs; +import net.neoforged.neoforge.client.color.item.FluidContentsTint; import net.neoforged.neoforge.client.entity.animation.json.AnimationLoader; import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; import net.neoforged.neoforge.client.event.ModelEvent; import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; +import net.neoforged.neoforge.client.event.RegisterItemModelsEvent; import net.neoforged.neoforge.client.event.RegisterNamedRenderTypesEvent; import net.neoforged.neoforge.client.event.RegisterSpriteSourceTypesEvent; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent; import net.neoforged.neoforge.client.gui.ConfigurationScreen; import net.neoforged.neoforge.client.gui.IConfigScreenFactory; -import net.neoforged.neoforge.client.model.CompositeModel; -import net.neoforged.neoforge.client.model.DynamicFluidContainerModel; import net.neoforged.neoforge.client.model.EmptyModel; -import net.neoforged.neoforge.client.model.ItemLayerModel; -import net.neoforged.neoforge.client.model.SeparateTransformsModel; +import net.neoforged.neoforge.client.model.UnbakedCompositeModel; +import net.neoforged.neoforge.client.model.item.DynamicFluidContainerModel; import net.neoforged.neoforge.client.model.obj.ObjLoader; import net.neoforged.neoforge.client.textures.NamespacedDirectoryLister; import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForgeMod; +import net.neoforged.neoforge.common.data.internal.NeoForgeAdvancementProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeBiomeTagsProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeBlockTagsProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeDamageTypeTagsProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeDataMapsProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeEnchantmentTagsProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeEntityTypeTagsProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeFluidTagsProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeItemTagsProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeLanguageProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeLootTableProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeRecipeProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeRegistryOrderReportProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeSpriteSourceProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeStructureTagsProvider; +import net.neoforged.neoforge.common.data.internal.VanillaSoundDefinitionsProvider; import net.neoforged.neoforge.common.util.SelfTest; +import net.neoforged.neoforge.data.event.GatherDataEvent; import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal @Mod(value = "neoforge", dist = Dist.CLIENT) public class ClientNeoForgeMod { + private static ResourceLocation neoForgeId(String path) { + return ResourceLocation.fromNamespaceAndPath("neoforge", path); + } + public ClientNeoForgeMod(IEventBus modEventBus, ModContainer container) { SelfTest.initClient(); @@ -70,13 +95,39 @@ public ClientNeoForgeMod(IEventBus modEventBus, ModContainer container) { } @SubscribeEvent - static void onRegisterGeometryLoaders(ModelEvent.RegisterGeometryLoaders event) { - event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "empty"), EmptyModel.LOADER); - event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "obj"), ObjLoader.INSTANCE); - event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "fluid_container"), DynamicFluidContainerModel.Loader.INSTANCE); - event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "composite"), CompositeModel.Loader.INSTANCE); - event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "item_layers"), ItemLayerModel.Loader.INSTANCE); - event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "separate_transforms"), SeparateTransformsModel.Loader.INSTANCE); + static void onGatherData(GatherDataEvent.Client event) { + // We perform client and server datagen in a single clientData run to avoid + // having to juggle two generated resources folders and two runs for no additional benefit. + + event.createProvider(output -> new PackMetadataGenerator(output) + .add(PackMetadataSection.TYPE, new PackMetadataSection( + Component.translatable("pack.neoforge.description"), + DetectedVersion.BUILT_IN.getPackVersion(PackType.SERVER_DATA), + Optional.of(new InclusiveRange<>(0, Integer.MAX_VALUE))))); + + event.createProvider(NeoForgeAdvancementProvider::new); + event.createBlockAndItemTags(NeoForgeBlockTagsProvider::new, NeoForgeItemTagsProvider::new); + event.createProvider(NeoForgeEntityTypeTagsProvider::new); + event.createProvider(NeoForgeFluidTagsProvider::new); + event.createProvider(NeoForgeEnchantmentTagsProvider::new); + event.createProvider(NeoForgeRecipeProvider.Runner::new); + event.createProvider(NeoForgeLootTableProvider::new); + event.createProvider(NeoForgeBiomeTagsProvider::new); + event.createProvider(NeoForgeStructureTagsProvider::new); + event.createProvider(NeoForgeDamageTypeTagsProvider::new); + event.createProvider(NeoForgeRegistryOrderReportProvider::new); + event.createProvider(NeoForgeDataMapsProvider::new); + + event.createProvider(NeoForgeSpriteSourceProvider::new); + event.createProvider(VanillaSoundDefinitionsProvider::new); + event.createProvider(NeoForgeLanguageProvider::new); + } + + @SubscribeEvent + static void onRegisterModelLoaders(ModelEvent.RegisterLoaders event) { + event.register(neoForgeId("empty"), EmptyModel.LOADER); + event.register(neoForgeId("obj"), ObjLoader.INSTANCE); + event.register(neoForgeId("composite"), UnbakedCompositeModel.Loader.INSTANCE); } @SubscribeEvent @@ -165,12 +216,23 @@ public ResourceLocation getFlowingTexture() { }, milkType)); } - @SubscribeEvent(priority = EventPriority.LOWEST) - static void registerSpawnEggColors(RegisterColorHandlersEvent.Item event) { - SpawnEggItem.eggs().forEach(egg -> { - if (event.getItemColors().get(egg) == null) { - event.register((stack, layer) -> ARGB.opaque(egg.getColor(layer)), egg); - } - }); + @SubscribeEvent + static void registerItemTintSources(RegisterColorHandlersEvent.ItemTintSources event) { + event.register(neoForgeId("fluid_contents_tint"), FluidContentsTint.MAP_CODEC); + } + + @SubscribeEvent + static void registerItemModels(RegisterItemModelsEvent event) { + event.register(neoForgeId("fluid_container"), DynamicFluidContainerModel.Unbaked.MAP_CODEC); } + + // TODO 1.21.4 +// @SubscribeEvent(priority = EventPriority.LOWEST) +// static void registerSpawnEggColors(RegisterColorHandlersEvent.Item event) { +// SpawnEggItem.eggs().forEach(egg -> { +// if (event.getItemColors().get(egg) == null) { +// event.register((stack, layer) -> ARGB.opaque(egg.getColor(layer)), egg); +// } +// }); +// } } diff --git a/src/main/java/net/neoforged/neoforge/client/color/item/FluidContentsTint.java b/src/main/java/net/neoforged/neoforge/client/color/item/FluidContentsTint.java new file mode 100644 index 0000000000..db4842d04a --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/color/item/FluidContentsTint.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.color.item; + +import com.mojang.serialization.MapCodec; +import net.minecraft.client.color.item.ItemTintSource; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; +import net.neoforged.neoforge.client.model.item.DynamicFluidContainerModel; +import net.neoforged.neoforge.fluids.FluidUtil; +import org.jetbrains.annotations.Nullable; + +/** + * Returns the tint color of the fluid contained in the item stack. + * Notably, this is used internally by {@link DynamicFluidContainerModel}. + */ +public final class FluidContentsTint implements ItemTintSource { + public static final FluidContentsTint INSTANCE = new FluidContentsTint(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + private FluidContentsTint() {} + + @Override + public int calculate(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity) { + return FluidUtil.getFluidContained(stack) + .map(fluidStack -> IClientFluidTypeExtensions.of(fluidStack.getFluid()).getTintColor(fluidStack)) + .orElse(0xFFFFFFFF); + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/package-info.java b/src/main/java/net/neoforged/neoforge/client/color/item/package-info.java similarity index 86% rename from src/main/java/net/neoforged/neoforge/client/model/geometry/package-info.java rename to src/main/java/net/neoforged/neoforge/client/color/item/package-info.java index a553db4599..bceffd3ecd 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/package-info.java +++ b/src/main/java/net/neoforged/neoforge/client/color/item/package-info.java @@ -6,7 +6,7 @@ @FieldsAreNonnullByDefault @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -package net.neoforged.neoforge.client.model.geometry; +package net.neoforged.neoforge.client.color.item; import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.FieldsAreNonnullByDefault; diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java index 7d788419d2..4e959af379 100644 --- a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Map; import net.minecraft.client.animation.AnimationDefinition; +import net.minecraft.resources.FileToIdConverter; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; @@ -31,7 +32,7 @@ public final class AnimationLoader extends SimpleJsonResourceReloadListener strongHolderReferences = new ArrayList<>(); private AnimationLoader() { - super(AnimationParser.CODEC, "neoforge/animations/entity"); + super(AnimationParser.CODEC, FileToIdConverter.json("neoforge/animations/entity")); } /** diff --git a/src/main/java/net/neoforged/neoforge/client/event/ModelEvent.java b/src/main/java/net/neoforged/neoforge/client/event/ModelEvent.java index 650217ec9b..a3a234a883 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/ModelEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/ModelEvent.java @@ -6,21 +6,20 @@ package net.neoforged.neoforge.client.event; import com.google.common.base.Preconditions; +import java.util.Collections; import java.util.Map; -import java.util.Set; +import java.util.function.Consumer; import java.util.function.Function; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.resources.ResourceLocation; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; import net.neoforged.fml.event.IModBusEvent; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; +import net.neoforged.neoforge.client.model.UnbakedModelLoader; import org.jetbrains.annotations.ApiStatus; /** @@ -41,27 +40,27 @@ protected ModelEvent() {} * must therefore not be accessed in this event. *

* - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

+ *

This event is not {@linkplain ICancellableEvent cancellable}.

* *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static class ModifyBakingResult extends ModelEvent implements IModBusEvent { - private final Map models; + private final ModelBakery.BakingResult bakingResult; private final Function textureGetter; private final ModelBakery modelBakery; @ApiStatus.Internal - public ModifyBakingResult(Map models, Function textureGetter, ModelBakery modelBakery) { - this.models = models; + public ModifyBakingResult(ModelBakery.BakingResult bakingResult, Function textureGetter, ModelBakery modelBakery) { + this.bakingResult = bakingResult; this.textureGetter = textureGetter; this.modelBakery = modelBakery; } /** - * @return the modifiable registry map of models and their model names + * @return The result of the model baking */ - public Map getModels() { - return models; + public ModelBakery.BakingResult getBakingResult() { + return bakingResult; } /** @@ -89,19 +88,25 @@ public ModelBakery getModelBakery() { * The model registry given by this event is unmodifiable. To modify the model registry, use * {@link ModelEvent.ModifyBakingResult} instead. * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

+ *

This event is not {@linkplain ICancellableEvent cancellable}.

* *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static class BakingCompleted extends ModelEvent implements IModBusEvent { private final ModelManager modelManager; - private final Map models; + private final ModelBakery.BakingResult bakingResult; private final ModelBakery modelBakery; @ApiStatus.Internal - public BakingCompleted(ModelManager modelManager, Map models, ModelBakery modelBakery) { + public BakingCompleted(ModelManager modelManager, ModelBakery.BakingResult bakingResult, ModelBakery modelBakery) { this.modelManager = modelManager; - this.models = models; + this.bakingResult = new ModelBakery.BakingResult( + bakingResult.missingModel(), + Collections.unmodifiableMap(bakingResult.blockStateModels()), + bakingResult.missingItemModel(), + Collections.unmodifiableMap(bakingResult.itemStackModels()), + Collections.unmodifiableMap(bakingResult.itemProperties()), + Collections.unmodifiableMap(bakingResult.standaloneModels())); this.modelBakery = modelBakery; } @@ -113,10 +118,10 @@ public ModelManager getModelManager() { } /** - * @return an unmodifiable view of the registry map of models and their model names + * @return The result of the model baking */ - public Map getModels() { - return models; + public ModelBakery.BakingResult getBakingResult() { + return bakingResult; } /** @@ -128,58 +133,52 @@ public ModelBakery getModelBakery() { } /** - * Fired when the {@link net.minecraft.client.resources.model.ModelBakery} is notified of the resource manager reloading. - * Allows developers to register models to be loaded, along with their dependencies. Models registered through this - * event must use the {@link ModelResourceLocation#STANDALONE_VARIANT} variant. + * Fired when the {@link net.minecraft.client.resources.model.ModelDiscovery} is notified of dependency discovery of its top models. + * Allows developers to register models to be loaded, along with their dependencies. * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

+ *

This event is not {@linkplain ICancellableEvent cancellable}.

* *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static class RegisterAdditional extends ModelEvent implements IModBusEvent { - private final Set models; + private final Consumer registrar; @ApiStatus.Internal - public RegisterAdditional(Set models) { - this.models = models; + public RegisterAdditional(Consumer registrar) { + this.registrar = registrar; } /** * Registers a model to be loaded, along with its dependencies. - *

- * The {@link ModelResourceLocation} passed to this method must later be used to recover the loaded model. */ - public void register(ModelResourceLocation model) { - Preconditions.checkArgument( - model.getVariant().equals(ModelResourceLocation.STANDALONE_VARIANT), - "Side-loaded models must use the '" + ModelResourceLocation.STANDALONE_VARIANT + "' variant"); - models.add(model); + public void register(ResourceLocation model) { + registrar.accept(model); } } /** - * Allows users to register their own {@link IGeometryLoader geometry loaders} for use in block/item models. + * Allows users to register their own {@link UnbakedModelLoader unbaked model loaders} for use in block/item models. * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

+ *

This event is not {@linkplain ICancellableEvent cancellable}.

* *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ - public static class RegisterGeometryLoaders extends ModelEvent implements IModBusEvent { - private final Map> loaders; + public static class RegisterLoaders extends ModelEvent implements IModBusEvent { + private final Map> loaders; @ApiStatus.Internal - public RegisterGeometryLoaders(Map> loaders) { + public RegisterLoaders(Map> loaders) { this.loaders = loaders; } /** - * Registers a new geometry loader. - * + * Registers a new unbaked model loader. + * * @param key the ID of the loader - * @param loader the geometry loader to register + * @param loader the loader to register */ - public void register(ResourceLocation key, IGeometryLoader loader) { - Preconditions.checkArgument(!loaders.containsKey(key), "Geometry loader already registered: " + key); + public void register(ResourceLocation key, UnbakedModelLoader loader) { + Preconditions.checkArgument(!loaders.containsKey(key), "Unbaked model loader already registered: " + key); loaders.put(key, loader); } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterColorHandlersEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterColorHandlersEvent.java index b4210540d6..afa2873449 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RegisterColorHandlersEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterColorHandlersEvent.java @@ -6,13 +6,14 @@ package net.neoforged.neoforge.client.event; import com.google.common.collect.ImmutableList; +import com.mojang.serialization.MapCodec; import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.color.item.ItemColors; +import net.minecraft.client.color.item.ItemTintSource; import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; import net.minecraft.world.level.ColorResolver; -import net.minecraft.world.level.ItemLike; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; @@ -26,7 +27,8 @@ *

These events are fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @see RegisterColorHandlersEvent.Block - * @see RegisterColorHandlersEvent.Item + * @see RegisterColorHandlersEvent.ItemTintSources + * @see RegisterColorHandlersEvent.ColorResolvers */ public abstract class RegisterColorHandlersEvent extends Event implements IModBusEvent { @ApiStatus.Internal @@ -35,7 +37,7 @@ protected RegisterColorHandlersEvent() {} /** * Fired for registering block color handlers. * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

+ *

This event is not {@linkplain ICancellableEvent cancellable}.

* *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ @@ -68,67 +70,40 @@ public void register(BlockColor blockColor, net.minecraft.world.level.block.Bloc } /** - * Fired for registering item color handlers. - * - *

The block colors should only be used for referencing or delegating item colors to their respective block - * colors. Use {@link RegisterColorHandlersEvent.Block} for registering your block color handlers.

- * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

- * - *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

+ * Allows registration of custom {@link ColorResolver} implementations to be used with + * {@link net.minecraft.world.level.BlockAndTintGetter#getBlockTint(BlockPos, ColorResolver)}. */ - public static class Item extends RegisterColorHandlersEvent { - private final ItemColors itemColors; - private final BlockColors blockColors; + public static class ColorResolvers extends RegisterColorHandlersEvent { + private final ImmutableList.Builder builder; @ApiStatus.Internal - public Item(ItemColors itemColors, BlockColors blockColors) { - this.itemColors = itemColors; - this.blockColors = blockColors; - } - - /** - * {@return the item colors registry} - * - * @see ItemColors#register(ItemColor, ItemLike...) - */ - public ItemColors getItemColors() { - return itemColors; - } - - /** - * {@return the block colors registry} - * This should only be used for referencing or delegating item colors to their respective block colors. - */ - public BlockColors getBlockColors() { - return blockColors; + public ColorResolvers(ImmutableList.Builder builder) { + this.builder = builder; } - /** - * Registers a {@link ItemColor} instance for a set of blocks. - * - * @param itemColor The color provider - * @param items The items - */ - public void register(ItemColor itemColor, ItemLike... items) { - itemColors.register(itemColor, items); + public void register(ColorResolver resolver) { + this.builder.add(resolver); } } /** - * Allows registration of custom {@link ColorResolver} implementations to be used with - * {@link net.minecraft.world.level.BlockAndTintGetter#getBlockTint(BlockPos, ColorResolver)}. + * Fired for registering item color handlers. + *

+ * This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client} + * + * @see ItemTintSource + * @see ItemTintSources */ - public static class ColorResolvers extends RegisterColorHandlersEvent { - private final ImmutableList.Builder builder; + public static class ItemTintSources extends RegisterColorHandlersEvent { + private final ExtraCodecs.LateBoundIdMapper> idMapper; @ApiStatus.Internal - public ColorResolvers(ImmutableList.Builder builder) { - this.builder = builder; + public ItemTintSources(ExtraCodecs.LateBoundIdMapper> idMapper) { + this.idMapper = idMapper; } - public void register(ColorResolver resolver) { - this.builder.add(resolver); + public void register(ResourceLocation location, MapCodec source) { + this.idMapper.put(location, source); } } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterConditionalItemModelPropertyEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterConditionalItemModelPropertyEvent.java new file mode 100644 index 0000000000..8b76afe1e9 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterConditionalItemModelPropertyEvent.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import com.mojang.serialization.MapCodec; +import net.minecraft.client.renderer.item.properties.conditional.ConditionalItemModelProperty; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Event fired when special model renderers are registered. + *

+ * This event is fired during the model registration process for conditional item model properties. + * It is used to register property codecs which can be used to create custom conditional item model properties. + *

+ * This event is fired on the mod event bus. + */ +public class RegisterConditionalItemModelPropertyEvent extends Event implements IModBusEvent { + private final ExtraCodecs.LateBoundIdMapper> idMapper; + + @ApiStatus.Internal + public RegisterConditionalItemModelPropertyEvent(ExtraCodecs.LateBoundIdMapper> idMapper) { + this.idMapper = idMapper; + } + + public void register(ResourceLocation location, MapCodec source) { + this.idMapper.put(location, source); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterItemModelsEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterItemModelsEvent.java new file mode 100644 index 0000000000..0887e4b1c5 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterItemModelsEvent.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import com.mojang.serialization.MapCodec; +import net.minecraft.client.renderer.item.ItemModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Event fired when item models are registered. + *

+ * This event is fired during the model registration process for items. + * It is used to register custom item model codecs which can be used to create custom item models. + *

+ * This event is fired on the mod event bus. + */ +public class RegisterItemModelsEvent extends Event implements IModBusEvent { + private final ExtraCodecs.LateBoundIdMapper> idMapper; + + @ApiStatus.Internal + public RegisterItemModelsEvent(ExtraCodecs.LateBoundIdMapper> idMapper) { + this.idMapper = idMapper; + } + + public void register(ResourceLocation location, MapCodec source) { + this.idMapper.put(location, source); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterRangeSelectItemModelPropertyEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterRangeSelectItemModelPropertyEvent.java new file mode 100644 index 0000000000..28a7192685 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterRangeSelectItemModelPropertyEvent.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import com.mojang.serialization.MapCodec; +import net.minecraft.client.renderer.item.properties.numeric.RangeSelectItemModelProperty; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Event fired when special model renderers are registered. + *

+ * This event is fired during the model registration process for range select item model properties. + * It is used to register property codecs which can be used to create custom range select item model properties. + *

+ * This event is fired on the mod event bus. + */ +public class RegisterRangeSelectItemModelPropertyEvent extends Event implements IModBusEvent { + private final ExtraCodecs.LateBoundIdMapper> idMapper; + + @ApiStatus.Internal + public RegisterRangeSelectItemModelPropertyEvent(ExtraCodecs.LateBoundIdMapper> idMapper) { + this.idMapper = idMapper; + } + + public void register(ResourceLocation location, MapCodec source) { + this.idMapper.put(location, source); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterSelectItemModelPropertyEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterSelectItemModelPropertyEvent.java new file mode 100644 index 0000000000..2db147ea4a --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterSelectItemModelPropertyEvent.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import net.minecraft.client.renderer.item.properties.select.SelectItemModelProperty; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Event fired when item model property selectors are registered. + *

+ * This event is fired during the model registration process for item model property selectors. + * It is used to register custom selector types which can be used to create custom item model property selectors. + *

+ * This event is fired on the mod event bus. + */ +public class RegisterSelectItemModelPropertyEvent extends Event implements IModBusEvent { + private final ExtraCodecs.LateBoundIdMapper> idMapper; + + @ApiStatus.Internal + public RegisterSelectItemModelPropertyEvent(ExtraCodecs.LateBoundIdMapper> idMapper) { + this.idMapper = idMapper; + } + + public void register(ResourceLocation location, SelectItemModelProperty.Type source) { + this.idMapper.put(location, source); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterSpecialModelRendererEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterSpecialModelRendererEvent.java new file mode 100644 index 0000000000..b521657b64 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterSpecialModelRendererEvent.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import com.mojang.serialization.MapCodec; +import net.minecraft.client.renderer.special.SpecialModelRenderer; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Event fired when special model renderers are registered. + *

+ * This event is fired during the model registration process for special item model renderers. + * It is used to register custom special item model renderer codecs which can be used to create custom special item model renderers. + *

+ * This event is fired on the mod event bus. + */ +public class RegisterSpecialModelRendererEvent extends Event implements IModBusEvent { + private final ExtraCodecs.LateBoundIdMapper> idMapper; + + @ApiStatus.Internal + public RegisterSpecialModelRendererEvent(ExtraCodecs.LateBoundIdMapper> idMapper) { + this.idMapper = idMapper; + } + + public void register(ResourceLocation location, MapCodec source) { + this.idMapper.put(location, source); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderItemInFrameEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderItemInFrameEvent.java index 479758d4c0..5d1fdb416c 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderItemInFrameEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderItemInFrameEvent.java @@ -10,7 +10,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.ItemFrameRenderer; import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; -import net.minecraft.world.item.ItemStack; +import net.minecraft.client.renderer.item.ItemStackRenderState; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; @@ -30,7 +30,7 @@ * @see ItemFrameRenderer */ public class RenderItemInFrameEvent extends Event implements ICancellableEvent { - private final ItemStack itemStack; + private final ItemStackRenderState itemStack; private final ItemFrameRenderState frameRenderState; private final ItemFrameRenderer renderer; private final PoseStack poseStack; @@ -40,7 +40,7 @@ public class RenderItemInFrameEvent extends Event implements ICancellableEvent { @ApiStatus.Internal public RenderItemInFrameEvent(ItemFrameRenderState frameRenderState, ItemFrameRenderer renderItemFrame, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { - this.itemStack = frameRenderState.itemStack; + this.itemStack = frameRenderState.item; this.frameRenderState = frameRenderState; this.renderer = renderItemFrame; this.poseStack = poseStack; @@ -51,7 +51,7 @@ public RenderItemInFrameEvent(ItemFrameRenderState frameRenderState, ItemFrameRe /** * {@return the item stack being rendered} */ - public ItemStack getItemStack() { + public ItemStackRenderState getItemStackRenderState() { return itemStack; } diff --git a/src/main/java/net/neoforged/neoforge/client/event/SelectMusicEvent.java b/src/main/java/net/neoforged/neoforge/client/event/SelectMusicEvent.java index e0d20a712b..5a4004a76b 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/SelectMusicEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/SelectMusicEvent.java @@ -6,6 +6,7 @@ package net.neoforged.neoforge.client.event; import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.sounds.MusicInfo; import net.minecraft.sounds.Music; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; @@ -25,7 +26,7 @@ *
* Higher priorities would likely be better suited for biome-based or dimension-based musics, whereas lower priority is likely good for specific structures or situations.
*
- * This event is {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.
+ * This event is {@linkplain ICancellableEvent cancellable}.
* If the event is canceled, then whatever the latest music set was will be used as the music. *
* This event is fired on the {@linkplain NeoForge#EVENT_BUS main Forge event bus},
@@ -33,11 +34,11 @@ * */ public class SelectMusicEvent extends Event implements ICancellableEvent { - private @Nullable Music music; - private final Music originalMusic; + private @Nullable MusicInfo music; + private final MusicInfo originalMusic; private final @Nullable SoundInstance playingMusic; - public SelectMusicEvent(Music music, @Nullable SoundInstance playingMusic) { + public SelectMusicEvent(MusicInfo music, @Nullable SoundInstance playingMusic) { this.music = music; this.originalMusic = music; this.playingMusic = playingMusic; @@ -46,7 +47,7 @@ public SelectMusicEvent(Music music, @Nullable SoundInstance playingMusic) { /** * {@return the original situational music that was selected} */ - public Music getOriginalMusic() { + public MusicInfo getOriginalMusic() { return originalMusic; } @@ -62,7 +63,7 @@ public SoundInstance getPlayingMusic() { * {@return the Music to be played, or {@code null} if any playing music should be cancelled} */ @Nullable - public Music getMusic() { + public MusicInfo getMusic() { return music; } @@ -71,7 +72,7 @@ public Music getMusic() { * If this was {@code null} but on the next tick isn't, the music given will be immediately played.
*
*/ - public void setMusic(@Nullable Music newMusic) { + public void setMusic(@Nullable MusicInfo newMusic) { this.music = newMusic; } @@ -79,7 +80,7 @@ public void setMusic(@Nullable Music newMusic) { * Sets the music and then cancels the event so that other listeners will not be invoked.
* Note that listeners using {@link SubscribeEvent#receiveCanceled()} will still be able to override this, but by default they will not */ - public void overrideMusic(@Nullable Music newMusic) { + public void overrideMusic(@Nullable MusicInfo newMusic) { this.music = newMusic; this.setCanceled(true); } diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IBakedModelExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IBakedModelExtension.java index eee572c5e7..2567494587 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/IBakedModelExtension.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IBakedModelExtension.java @@ -11,6 +11,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.item.ItemModel; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; @@ -86,7 +87,7 @@ default ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, M } /** - * Gets an ordered list of {@link RenderType render types} to use when drawing this item. + * Gets the {@link RenderType render type} to use when drawing this item. * All render types using the {@link com.mojang.blaze3d.vertex.DefaultVertexFormat#NEW_ENTITY} format are supported. *

* This method will only be called on the models returned by {@link #getRenderPasses(ItemStack)}. @@ -95,18 +96,20 @@ default ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, M * * @see #getRenderPasses(ItemStack) */ - default List getRenderTypes(ItemStack itemStack) { - return List.of(RenderTypeHelper.getFallbackItemRenderType(itemStack, self())); + default RenderType getRenderType(ItemStack itemStack) { + return RenderTypeHelper.getFallbackItemRenderType(itemStack, self()); } /** * Gets an ordered list of baked models used to render this model as an item. - * Each of those models' render types will be queried via {@link #getRenderTypes(ItemStack)}. + * Each of those models' render type will be queried via {@link #getRenderType(ItemStack)}. *

* By default, returns the model itself. * - * @see #getRenderTypes(ItemStack) + * @see #getRenderType(ItemStack) + * @deprecated Please migrate to {@link ItemModel}s, or if this is not possible contact us at NeoForge. */ + @Deprecated(forRemoval = true, since = "1.21.4") default List getRenderPasses(ItemStack itemStack) { return List.of(self()); } diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IDimensionSpecialEffectsExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IDimensionSpecialEffectsExtension.java index 9268c20007..f6391f9357 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/IDimensionSpecialEffectsExtension.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IDimensionSpecialEffectsExtension.java @@ -8,7 +8,6 @@ import net.minecraft.client.Camera; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.DimensionSpecialEffects; -import net.minecraft.client.renderer.LightTexture; import org.joml.Matrix4f; /** @@ -42,7 +41,7 @@ default boolean renderSky(ClientLevel level, int ticks, float partialTick, Matri * * @return true to prevent vanilla snow and rain rendering */ - default boolean renderSnowAndRain(ClientLevel level, int ticks, float partialTick, LightTexture lightTexture, double camX, double camY, double camZ) { + default boolean renderSnowAndRain(ClientLevel level, int ticks, float partialTick, double camX, double camY, double camZ) { return false; } diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IModelBakerExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IModelBakerExtension.java index 90d84c3928..c0ed814b70 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/IModelBakerExtension.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IModelBakerExtension.java @@ -5,23 +5,40 @@ package net.neoforged.neoforge.client.extensions; -import java.util.function.Function; +import net.minecraft.client.renderer.block.model.TextureSlots; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; +/** + * An extension to {@link ModelBaker} that allows for custom model baking. + */ public interface IModelBakerExtension { - @Nullable - UnbakedModel getTopLevelModel(ModelResourceLocation location); + default ModelBaker self() { + return (ModelBaker) this; + } - BakedModel bake(ResourceLocation location, ModelState state, Function sprites); - - BakedModel bakeUncached(UnbakedModel model, ModelState state, Function sprites); + /** + * Gets the unbaked model for the given location. + * + * @param location The location of the model + * @return The unbaked model, or null if not found + */ + @Nullable + UnbakedModel getModel(ResourceLocation location); - Function getModelTextureGetter(); + /** + * Finds a sprite for the given slot name. + * + * @param slots The texture slots + * @param slotName The name of the slot + * @return The sprite, or a missing reference sprite if not found + */ + default TextureAtlasSprite findSprite(TextureSlots slots, String slotName) { + Material material = slots.getMaterial(slotName); + return material != null ? self().sprites().get(material) : self().sprites().reportMissingReference(slotName); + } } diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IUnbakedModelExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IUnbakedModelExtension.java new file mode 100644 index 0000000000..0d528dd671 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IUnbakedModelExtension.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.extensions; + +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.util.context.ContextKeySet; +import net.minecraft.util.context.ContextMap; +import net.neoforged.neoforge.client.model.ExtendedUnbakedModel; +import net.neoforged.neoforge.client.model.NeoForgeModelProperties; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +/** + * Extension type for the {@link UnbakedModel} interface. + */ +public interface IUnbakedModelExtension { + private UnbakedModel self() { + return (UnbakedModel) this; + } + + /** + * {@code bake} override with additional context. + * Consider inheriting from {@link ExtendedUnbakedModel} which overrides the vanilla {@code bake} method. + * + * @param additionalProperties additional properties provided by NeoForge or mods + */ + default BakedModel bake(TextureSlots textures, ModelBaker baker, ModelState modelState, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms itemTransforms, ContextMap additionalProperties) { + return self().bake(textures, baker, modelState, useAmbientOcclusion, usesBlockLight, itemTransforms); + } + + /** + * Appends additional properties for this model to the builder. + * + *

This method will already have been called on the parent models. + * It can modify the properties added by a parent model and/or add its own. + * This ensures that the properties are merged across the model parent-child chain. + * + *

The context map containing all the properties will be passed as the last parameter to + * {@link #bake(TextureSlots, ModelBaker, ModelState, boolean, boolean, ItemTransforms, ContextMap)}. + * + * @see NeoForgeModelProperties + */ + @ApiStatus.OverrideOnly + default void fillAdditionalProperties(ContextMap.Builder propertiesBuilder) {} + + /** + * Resolves additional properties by walking the model child-parent chain and calling {@link #fillAdditionalProperties(ContextMap.Builder)}. + */ + static ContextMap getTopAdditionalProperties(UnbakedModel topModel) { + var builder = new ContextMap.Builder(); + fillAdditionalProperties(topModel, builder); + return builder.create(ContextKeySet.EMPTY); + } + + private static void fillAdditionalProperties(@Nullable UnbakedModel model, ContextMap.Builder propertiesBuilder) { + if (model != null) { + fillAdditionalProperties(model.getParent(), propertiesBuilder); + model.fillAdditionalProperties(propertiesBuilder); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientFluidTypeExtensions.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientFluidTypeExtensions.java index d9df521cab..f53cfe257d 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientFluidTypeExtensions.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientFluidTypeExtensions.java @@ -13,6 +13,7 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.FogParameters; import net.minecraft.client.renderer.FogRenderer; +import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.ScreenEffectRenderer; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; @@ -150,10 +151,10 @@ default ResourceLocation getRenderOverlayTexture(Minecraft mc) { * @param mc the client instance * @param poseStack the transformations representing the current rendering position */ - default void renderOverlay(Minecraft mc, PoseStack poseStack) { + default void renderOverlay(Minecraft mc, PoseStack poseStack, MultiBufferSource buffers) { ResourceLocation texture = this.getRenderOverlayTexture(mc); if (texture != null) - ScreenEffectRenderer.renderFluid(mc, poseStack, texture); + ScreenEffectRenderer.renderFluid(mc, poseStack, buffers, texture); } /** diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java index 34018888a6..71032b91b4 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java @@ -6,14 +6,14 @@ package net.neoforged.neoforge.client.extensions.common; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.Model; import net.minecraft.client.player.LocalPlayer; -import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; import net.minecraft.client.renderer.entity.layers.EquipmentLayerRenderer; -import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.EquipmentClientInfo; +import net.minecraft.core.component.DataComponents; +import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.ItemTags; import net.minecraft.util.ARGB; import net.minecraft.world.InteractionHand; @@ -24,8 +24,6 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.DyedItemColor; -import net.minecraft.world.item.equipment.EquipmentModel; -import net.minecraft.world.level.block.state.BlockState; import net.neoforged.fml.LogicalSide; import net.neoforged.neoforge.client.IArmPoseTransformer; import org.jetbrains.annotations.Nullable; @@ -96,15 +94,15 @@ default boolean applyForgeHandTransform(PoseStack poseStack, LocalPlayer player, * @param layerType The slot the item is in * @param original The original armor model. Will have attributes set. * @return A HumanoidModel to be rendered. Relevant properties are to be copied over by the caller. - * @see #getGenericArmorModel(ItemStack, EquipmentModel.LayerType, Model) + * @see #getGenericArmorModel(ItemStack, EquipmentClientInfo.LayerType, Model) */ - default Model getHumanoidArmorModel(ItemStack itemStack, EquipmentModel.LayerType layerType, Model original) { + default Model getHumanoidArmorModel(ItemStack itemStack, EquipmentClientInfo.LayerType layerType, Model original) { return original; } /** * Queries the armor model for this item when it's equipped. Useful in place of - * {@link #getHumanoidArmorModel(ItemStack, EquipmentModel.LayerType, Model)} for wrapping the original + * {@link #getHumanoidArmorModel(ItemStack, EquipmentClientInfo.LayerType, Model)} for wrapping the original * model or returning anything non-standard. *

* If you override this method you are responsible for copying any properties you care about from the original model. @@ -113,9 +111,9 @@ default Model getHumanoidArmorModel(ItemStack itemStack, EquipmentModel.LayerTyp * @param layerType The slot the item is in * @param original The original armor model. Will have attributes set. * @return A Model to be rendered. Relevant properties must be copied over manually. - * @see #getHumanoidArmorModel(ItemStack, EquipmentModel.LayerType, Model) + * @see #getHumanoidArmorModel(ItemStack, EquipmentClientInfo.LayerType, Model) */ - default Model getGenericArmorModel(ItemStack itemStack, EquipmentModel.LayerType layerType, Model original) { + default Model getGenericArmorModel(ItemStack itemStack, EquipmentClientInfo.LayerType layerType, Model original) { Model replacement = getHumanoidArmorModel(itemStack, layerType, original); if (replacement != original) { // FIXME: equipment rendering deals with a plain Model now @@ -155,18 +153,6 @@ default void setupModelAnimations(LivingEntity livingEntity, ItemStack itemStack */ default void renderHelmetOverlay(ItemStack stack, Player player, int width, int height, float partialTick) {} - /** - * Queries this item's renderer. - *

- * Only used if {@link BakedModel#isCustomRenderer()} returns {@code true} or {@link BlockState#getRenderShape()} - * returns {@link net.minecraft.world.level.block.RenderShape#ENTITYBLOCK_ANIMATED}. - *

- * By default, returns vanilla's block entity renderer. - */ - default BlockEntityWithoutLevelRenderer getCustomRenderer() { - return Minecraft.getInstance().getItemRenderer().getBlockEntityRenderer(); - } - /** * {@return Whether the item should bob when rendered in the world as an entity} * @@ -201,13 +187,13 @@ default boolean shouldSpreadAsEntity(ItemStack stack) { * performance * @return a custom color for the layer, in ARGB format, or 0 to skip rendering */ - default int getArmorLayerTintColor(ItemStack stack, EquipmentModel.Layer layer, int layerIdx, int fallbackColor) { + default int getArmorLayerTintColor(ItemStack stack, EquipmentClientInfo.Layer layer, int layerIdx, int fallbackColor) { return EquipmentLayerRenderer.getColorForLayer(layer, fallbackColor); } /** * Called once per render pass of equipped armor items, regardless of the number of layers; the return value of this - * method is passed to {@link #getArmorLayerTintColor(ItemStack, EquipmentModel.Layer, int, int)} as + * method is passed to {@link #getArmorLayerTintColor(ItemStack, EquipmentClientInfo.Layer, int, int)} as * the {@code fallbackColor} parameter. *

* You can override this method for your custom armor item to provide an alternative default color for the item when @@ -220,6 +206,24 @@ default int getDefaultDyeColor(ItemStack stack) { return stack.is(ItemTags.DYEABLE) ? ARGB.opaque(DyedItemColor.getOrDefault(stack, 0)) : 0; } + /** + * Called by RenderBiped and RenderPlayer to determine the armor texture that + * should be used for the currently equipped item. This will be called on + * stacks with the {@link DataComponents#EQUIPPABLE} component. + * + * Returning null from this function will use the default value. + * + * @param stack ItemStack for the equipped armor + * @param type The layer type of the armor + * @param layer The armor layer + * @param _default The default texture determined by the equipment renderer + * @return Path of texture to bind, or null to use default + */ + @Nullable + default ResourceLocation getArmorTexture(ItemStack stack, EquipmentClientInfo.LayerType type, EquipmentClientInfo.Layer layer, ResourceLocation _default) { + return null; + } + enum FontContext { /** * Used to display the amount of items in the {@link ItemStack}. diff --git a/src/main/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java b/src/main/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java index becd2d4ca8..3ad5d25f70 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java @@ -11,6 +11,7 @@ import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig.Entry; import com.google.common.collect.ImmutableList; +import com.mojang.datafixers.util.Function4; import com.mojang.realmsclient.RealmsMainScreen; import com.mojang.serialization.Codec; import it.unimi.dsi.fastutil.booleans.BooleanConsumer; @@ -53,8 +54,6 @@ import net.minecraft.client.gui.screens.options.OptionsSubScreen; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.resources.language.I18n; -import net.minecraft.data.models.blockstates.PropertyDispatch.QuadFunction; -import net.minecraft.data.models.blockstates.PropertyDispatch.TriFunction; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -87,9 +86,9 @@ *

  • As an entry point for your custom configuration screen that handles fetching your configs, matching {@link Type} to the current game, enforcing level and game restarts, etc. *
  • As a ready-made system but extensible that works out of the box with all configs that use the {@link ModConfigSpec} system and don't do anything overly weird with it. * - * For the former one, use the 3-argument constructor {@link #ConfigurationScreen(ModContainer, Screen, TriFunction)} and return your own screen from the TriFunction. For the latter, + * For the former one, use the 3-argument constructor {@link #ConfigurationScreen(ModContainer, Screen, Function4)} and return your own screen from the Function4. For the latter, * use either the 2-argument constructor {@link #ConfigurationScreen(ModContainer, Screen)} if you don't need to extend the system, or the 3-argument one and return a subclass of - * {@link ConfigurationSectionScreen} from the TriFunction.

    + * {@link ConfigurationSectionScreen} from the Function4.

    * * In any case, register your configuration screen in your client mod class like this: * @@ -260,7 +259,7 @@ public void finish() { protected static final TranslationChecker translationChecker = new TranslationChecker(); protected final ModContainer mod; - private final QuadFunction sectionScreen; + private final Function4 sectionScreen; public RestartType needsRestart = RestartType.NONE; // If there is only one config type (and it can be edited, we show that instantly on the way "down" and want to close on the way "up". @@ -275,8 +274,7 @@ public ConfigurationScreen(final ModContainer mod, final Screen parent, Configur this(mod, parent, (a, b, c, d) -> new ConfigurationSectionScreen(a, b, c, d, filter)); } - @SuppressWarnings("resource") - public ConfigurationScreen(final ModContainer mod, final Screen parent, QuadFunction sectionScreen) { + public ConfigurationScreen(final ModContainer mod, final Screen parent, Function4 sectionScreen) { super(parent, Minecraft.getInstance().options, Component.translatable(translationChecker.check(mod.getModId() + ".configuration.title", LANG_PREFIX + "title"), mod.getModInfo().getDisplayName())); this.mod = mod; this.sectionScreen = sectionScreen; @@ -1389,6 +1387,16 @@ protected void checkButtons() { protected void updateWidgetNarration(final NarrationElementOutput pNarrationElementOutput) { // TODO I have no idea. Help? } + + @Override + protected int contentHeight() { + return 0; // TODO 1.21.4 no idea + } + + @Override + protected double scrollRate() { + return 4.0; // TODO 1.21.4 no idea + } } } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/LoadingErrorScreen.java b/src/main/java/net/neoforged/neoforge/client/gui/LoadingErrorScreen.java index 77cf132865..741c30259d 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/LoadingErrorScreen.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/LoadingErrorScreen.java @@ -115,7 +115,7 @@ public static class LoadingEntryList extends ObjectSelectionListof(null, new Size2i(0, 0)); diff --git a/src/main/java/net/neoforged/neoforge/client/gui/ScrollableExperimentsScreen.java b/src/main/java/net/neoforged/neoforge/client/gui/ScrollableExperimentsScreen.java index 8dd3f86409..fb3cbe2905 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/ScrollableExperimentsScreen.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/ScrollableExperimentsScreen.java @@ -81,7 +81,7 @@ protected void repositionElements() { if (this.selectionList != null && this.listLayout != null) { this.selectionList.setHeight(this.layout.getContentHeight() - this.listLayout.getY()); this.selectionList.setPosition(this.listLayout.getX(), this.listLayout.getY()); - this.selectionList.clampScrollAmount(); + this.selectionList.refreshScrollAmount(); } } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java b/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java index cd6626c322..831ac723f6 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java @@ -40,7 +40,7 @@ public ModListWidget(ModListScreen parent, int listWidth, int top, int bottom) { } @Override - protected int getScrollbarPosition() { + protected int scrollBarX() { return this.listWidth; } diff --git a/src/main/java/net/neoforged/neoforge/client/model/AbstractSimpleUnbakedModel.java b/src/main/java/net/neoforged/neoforge/client/model/AbstractSimpleUnbakedModel.java new file mode 100644 index 0000000000..a00f3502cc --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/model/AbstractSimpleUnbakedModel.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model; + +import net.minecraft.client.data.models.model.TextureSlot; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.SimpleBakedModel; +import net.minecraft.util.context.ContextMap; +import net.neoforged.neoforge.client.RenderTypeGroup; + +/** + * @deprecated Extend {@link ExtendedUnbakedModel} directly instead, and use {@link SimpleBakedModel.Builder} if appropriate. + */ +@Deprecated(forRemoval = true, since = "1.21.4") +public abstract class AbstractSimpleUnbakedModel implements ExtendedUnbakedModel { + @Override + public BakedModel bake(TextureSlots slots, + ModelBaker baker, + ModelState state, + boolean useAmbientOcclusion, + boolean usesBlockLight, + ItemTransforms transforms, + ContextMap additionalProperties) { + TextureAtlasSprite particle = baker.findSprite(slots, TextureSlot.PARTICLE.getId()); + var renderTypes = additionalProperties.getOrDefault(NeoForgeModelProperties.RENDER_TYPE, RenderTypeGroup.EMPTY); + + IModelBuilder builder = IModelBuilder.of(useAmbientOcclusion, usesBlockLight, isGui3d(), + transforms, particle, renderTypes); + + addQuads(builder, slots, baker, state, useAmbientOcclusion, usesBlockLight, transforms); + + return builder.build(); + } + + @Override + public void resolveDependencies(Resolver p_387087_) { + //Has no dependencies + } + + public abstract void addQuads( + IModelBuilder builder, + TextureSlots slots, + ModelBaker baker, + ModelState state, + boolean useAmbientOcclusion, + boolean usesBlockLight, + ItemTransforms transforms); + + protected boolean isGui3d() { + return true; + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/model/BakedModelWrapper.java b/src/main/java/net/neoforged/neoforge/client/model/BakedModelWrapper.java deleted file mode 100644 index 01417638b2..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/BakedModelWrapper.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model; - -import com.mojang.blaze3d.vertex.PoseStack; -import java.util.List; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.BakedOverrides; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemTransforms; -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.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.client.ChunkRenderTypeSet; -import net.neoforged.neoforge.client.model.data.ModelData; -import net.neoforged.neoforge.common.util.TriState; -import org.jetbrains.annotations.Nullable; - -/** - * Wrapper for {@link BakedModel} which delegates all operations to its parent. - *

    - * Useful for creating wrapper baked models which only override certain properties. - */ -public abstract class BakedModelWrapper implements BakedModel { - protected final T originalModel; - - public BakedModelWrapper(T originalModel) { - this.originalModel = originalModel; - } - - @Override - public List getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand) { - return originalModel.getQuads(state, side, rand); - } - - @Override - public boolean useAmbientOcclusion() { - return originalModel.useAmbientOcclusion(); - } - - @Override - public TriState useAmbientOcclusion(BlockState state, ModelData data, RenderType renderType) { - return originalModel.useAmbientOcclusion(state, data, renderType); - } - - @Override - public boolean isGui3d() { - return originalModel.isGui3d(); - } - - @Override - public boolean usesBlockLight() { - return originalModel.usesBlockLight(); - } - - @Override - public boolean isCustomRenderer() { - return originalModel.isCustomRenderer(); - } - - @Override - public TextureAtlasSprite getParticleIcon() { - return originalModel.getParticleIcon(); - } - - @Override - public ItemTransforms getTransforms() { - return originalModel.getTransforms(); - } - - @Override - public BakedOverrides overrides() { - return originalModel.overrides(); - } - - @Override - public BakedModel applyTransform(ItemDisplayContext cameraTransformType, PoseStack poseStack, boolean applyLeftHandTransform) { - return originalModel.applyTransform(cameraTransformType, poseStack, applyLeftHandTransform); - } - - @Override - public TextureAtlasSprite getParticleIcon(ModelData data) { - return originalModel.getParticleIcon(data); - } - - @Override - public List getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand, ModelData extraData, @Nullable RenderType renderType) { - return originalModel.getQuads(state, side, rand, extraData, renderType); - } - - @Override - public ModelData getModelData(BlockAndTintGetter level, BlockPos pos, BlockState state, ModelData modelData) { - return originalModel.getModelData(level, pos, state, modelData); - } - - @Override - public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, ModelData data) { - return originalModel.getRenderTypes(state, rand, data); - } - - @Override - public List getRenderTypes(ItemStack itemStack) { - return originalModel.getRenderTypes(itemStack); - } - - @Override - public List getRenderPasses(ItemStack itemStack) { - return originalModel.getRenderPasses(itemStack); - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/DelegateUnbakedModel.java b/src/main/java/net/neoforged/neoforge/client/model/DelegateUnbakedModel.java new file mode 100644 index 0000000000..1d61e20c54 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/model/DelegateUnbakedModel.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model; + +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.util.context.ContextMap; +import org.jetbrains.annotations.Nullable; + +public abstract class DelegateUnbakedModel implements ExtendedUnbakedModel { + protected final UnbakedModel wrapped; + + protected DelegateUnbakedModel(UnbakedModel wrapped) { + this.wrapped = wrapped; + } + + @Override + public BakedModel bake(TextureSlots textures, ModelBaker baker, ModelState modelState, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms itemTransforms, ContextMap additionalProperties) { + return this.wrapped.bake(textures, baker, modelState, useAmbientOcclusion, usesBlockLight, itemTransforms, additionalProperties); + } + + @Override + public void resolveDependencies(Resolver resolver) { + this.wrapped.resolveDependencies(resolver); + } + + @Nullable + @Override + public Boolean getAmbientOcclusion() { + return this.wrapped.getAmbientOcclusion(); + } + + @Nullable + @Override + public GuiLight getGuiLight() { + return this.wrapped.getGuiLight(); + } + + @Nullable + @Override + public ItemTransforms getTransforms() { + return this.wrapped.getTransforms(); + } + + @Override + public TextureSlots.Data getTextureSlots() { + return this.wrapped.getTextureSlots(); + } + + @Nullable + @Override + public UnbakedModel getParent() { + return this.wrapped.getParent(); + } + + @Override + public void fillAdditionalProperties(ContextMap.Builder propertiesBuilder) { + this.wrapped.fillAdditionalProperties(propertiesBuilder); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/model/DynamicFluidContainerModel.java b/src/main/java/net/neoforged/neoforge/client/model/DynamicFluidContainerModel.java deleted file mode 100644 index b15c779a95..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/DynamicFluidContainerModel.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model; - -import com.google.common.collect.Maps; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonObject; -import com.mojang.math.Transformation; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.BakedOverrides; -import net.minecraft.client.renderer.block.model.ItemOverride; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.BlockModelRotation; -import net.minecraft.client.resources.model.ItemModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelState; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.Fluids; -import net.neoforged.neoforge.client.ClientHooks; -import net.neoforged.neoforge.client.NeoForgeRenderTypes; -import net.neoforged.neoforge.client.RenderTypeGroup; -import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; -import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; -import net.neoforged.neoforge.client.model.geometry.StandaloneGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.UnbakedGeometryHelper; -import net.neoforged.neoforge.fluids.FluidUtil; -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -/** - * A dynamic fluid container model, capable of re-texturing itself at runtime to match the contained fluid. - *

    - * Composed of a base layer, a fluid layer (applied with a mask) and a cover layer (optionally applied with a mask). - * The entire model may optionally be flipped if the fluid is gaseous, and the fluid layer may glow if light-emitting. - *

    - * Fluid tinting requires registering a separate {@link ItemColor}. An implementation is provided in {@link Colors}. - * - * @see Colors - */ -public class DynamicFluidContainerModel implements IUnbakedGeometry { - // Depth offsets to prevent Z-fighting - private static final Transformation FLUID_TRANSFORM = new Transformation(new Vector3f(), new Quaternionf(), new Vector3f(1, 1, 1.002f), new Quaternionf()); - private static final Transformation COVER_TRANSFORM = new Transformation(new Vector3f(), new Quaternionf(), new Vector3f(1, 1, 1.004f), new Quaternionf()); - - private final Fluid fluid; - private final boolean flipGas; - private final boolean coverIsMask; - private final boolean applyFluidLuminosity; - - private DynamicFluidContainerModel(Fluid fluid, boolean flipGas, boolean coverIsMask, boolean applyFluidLuminosity) { - this.fluid = fluid; - this.flipGas = flipGas; - this.coverIsMask = coverIsMask; - this.applyFluidLuminosity = applyFluidLuminosity; - } - - public static RenderTypeGroup getLayerRenderTypes(boolean unlit) { - return new RenderTypeGroup(RenderType.translucent(), unlit ? NeoForgeRenderTypes.ITEM_UNSORTED_UNLIT_TRANSLUCENT.get() : NeoForgeRenderTypes.ITEM_UNSORTED_TRANSLUCENT.get()); - } - - /** - * Returns a new ModelDynBucket representing the given fluid, but with the same - * other properties (flipGas, tint, coverIsMask). - */ - public DynamicFluidContainerModel withFluid(Fluid newFluid) { - return new DynamicFluidContainerModel(newFluid, flipGas, coverIsMask, applyFluidLuminosity); - } - - @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { - Material particleLocation = context.hasMaterial("particle") ? context.getMaterial("particle") : null; - Material baseLocation = context.hasMaterial("base") ? context.getMaterial("base") : null; - Material fluidMaskLocation = context.hasMaterial("fluid") ? context.getMaterial("fluid") : null; - Material coverLocation = context.hasMaterial("cover") ? context.getMaterial("cover") : null; - - TextureAtlasSprite baseSprite = baseLocation != null ? spriteGetter.apply(baseLocation) : null; - TextureAtlasSprite fluidSprite = fluid != Fluids.EMPTY ? spriteGetter.apply(ClientHooks.getBlockMaterial(IClientFluidTypeExtensions.of(fluid).getStillTexture())) : null; - TextureAtlasSprite coverSprite = (coverLocation != null && (!coverIsMask || baseLocation != null)) ? spriteGetter.apply(coverLocation) : null; - - TextureAtlasSprite particleSprite = particleLocation != null ? spriteGetter.apply(particleLocation) : null; - - if (particleSprite == null) particleSprite = fluidSprite; - if (particleSprite == null) particleSprite = baseSprite; - if (particleSprite == null && !coverIsMask) particleSprite = coverSprite; - - // If the fluid is lighter than air, rotate 180deg to turn it upside down - if (flipGas && fluid != Fluids.EMPTY && fluid.getFluidType().isLighterThanAir()) { - modelState = new SimpleModelState( - modelState.getRotation().compose( - new Transformation(null, new Quaternionf(0, 0, 1, 0), null, null))); - } - - // We need to disable GUI 3D and block lighting for this to render properly - var itemContext = StandaloneGeometryBakingContext.builder(context).withGui3d(false).withUseBlockLight(false).build(ResourceLocation.fromNamespaceAndPath("neoforge", "dynamic_fluid_container")); - var modelBuilder = CompositeModel.Baked.builder(itemContext, particleSprite, context.getTransforms()); - - var normalRenderTypes = getLayerRenderTypes(false); - - if (baseLocation != null && baseSprite != null) { - // Base texture - var unbaked = UnbakedGeometryHelper.createUnbakedItemElements(0, baseSprite); - var quads = UnbakedGeometryHelper.bakeElements(unbaked, $ -> baseSprite, modelState); - modelBuilder.addQuads(normalRenderTypes, quads); - } - - if (fluidMaskLocation != null && fluidSprite != null) { - TextureAtlasSprite templateSprite = spriteGetter.apply(fluidMaskLocation); - if (templateSprite != null) { - // Fluid layer - var transformedState = new SimpleModelState(modelState.getRotation().compose(FLUID_TRANSFORM), modelState.isUvLocked()); - var unbaked = UnbakedGeometryHelper.createUnbakedItemMaskElements(1, templateSprite); // Use template as mask - var quads = UnbakedGeometryHelper.bakeElements(unbaked, $ -> fluidSprite, transformedState); // Bake with fluid texture - - var emissive = applyFluidLuminosity && fluid.getFluidType().getLightLevel() > 0; - var renderTypes = getLayerRenderTypes(emissive); - if (emissive) QuadTransformers.settingMaxEmissivity().processInPlace(quads); - - modelBuilder.addQuads(renderTypes, quads); - } - } - - if (coverSprite != null) { - var sprite = coverIsMask ? baseSprite : coverSprite; - if (sprite != null) { - // Cover/overlay - var transformedState = new SimpleModelState(modelState.getRotation().compose(COVER_TRANSFORM), modelState.isUvLocked()); - var unbaked = UnbakedGeometryHelper.createUnbakedItemMaskElements(2, coverSprite); // Use cover as mask - var quads = UnbakedGeometryHelper.bakeElements(unbaked, $ -> sprite, transformedState); // Bake with selected texture - modelBuilder.addQuads(normalRenderTypes, quads); - } - } - - modelBuilder.setParticle(particleSprite); - - BakedModel bakedModel = modelBuilder.build(); - var bakedOverrides = new ContainedFluidOverrideHandler(new BakedOverrides(baker, overrides, spriteGetter), bakedModel, baker, itemContext, this); - return new ItemModel.BakedModelWithOverrides(bakedModel, bakedOverrides); - } - - public static final class Loader implements IGeometryLoader { - public static final Loader INSTANCE = new Loader(); - - private Loader() {} - - @Override - public DynamicFluidContainerModel read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) { - if (!jsonObject.has("fluid")) - throw new RuntimeException("Bucket model requires 'fluid' value."); - - ResourceLocation fluidName = ResourceLocation.parse(jsonObject.get("fluid").getAsString()); - - Fluid fluid = BuiltInRegistries.FLUID.getValue(fluidName); - - boolean flip = GsonHelper.getAsBoolean(jsonObject, "flip_gas", false); - boolean coverIsMask = GsonHelper.getAsBoolean(jsonObject, "cover_is_mask", true); - boolean applyFluidLuminosity = GsonHelper.getAsBoolean(jsonObject, "apply_fluid_luminosity", true); - - // create new model with correct liquid - return new DynamicFluidContainerModel(fluid, flip, coverIsMask, applyFluidLuminosity); - } - } - - private static final class ContainedFluidOverrideHandler extends BakedOverrides { - private final Map cache = Maps.newHashMap(); // contains all the baked models since they'll never change - private final BakedOverrides nested; - private final BakedModel baseModel; - private final ModelBaker baker; - private final IGeometryBakingContext owner; - private final DynamicFluidContainerModel parent; - - private ContainedFluidOverrideHandler(BakedOverrides nested, BakedModel baseModel, ModelBaker baker, IGeometryBakingContext owner, DynamicFluidContainerModel parent) { - this.nested = nested; - this.baseModel = baseModel; - this.baker = baker; - this.owner = owner; - this.parent = parent; - } - - @Override - @Nullable - public BakedModel findOverride(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { - BakedModel overridden = nested.findOverride(stack, level, entity, seed); - if (overridden != null) return overridden; - - return FluidUtil.getFluidContained(stack) - .map(fluidStack -> { - Fluid fluid = fluidStack.getFluid(); - String name = BuiltInRegistries.FLUID.getKey(fluid).toString(); - - if (!cache.containsKey(name)) { - DynamicFluidContainerModel unbaked = this.parent.withFluid(fluid); - BakedModel bakedModel = unbaked.bake(owner, baker, Material::sprite, BlockModelRotation.X0_Y0, List.of()); - cache.put(name, bakedModel); - return bakedModel; - } - - return cache.get(name); - }) - // not a fluid item apparently - .orElse(baseModel); // empty bucket - } - } - - public static class Colors implements ItemColor { - @Override - public int getColor(ItemStack stack, int tintIndex) { - if (tintIndex != 1) return 0xFFFFFFFF; - return FluidUtil.getFluidContained(stack) - .map(fluidStack -> IClientFluidTypeExtensions.of(fluidStack.getFluid()).getTintColor(fluidStack)) - .orElse(0xFFFFFFFF); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/EmptyModel.java b/src/main/java/net/neoforged/neoforge/client/model/EmptyModel.java index f3e1084ed1..b512835250 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/EmptyModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/EmptyModel.java @@ -5,13 +5,17 @@ package net.neoforged.neoforge.client.model; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import java.lang.reflect.Type; import java.util.EnumMap; import java.util.List; import java.util.Map; -import java.util.function.Function; import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -20,34 +24,34 @@ import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; import net.minecraft.client.resources.model.SimpleBakedModel; +import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.core.Direction; import net.neoforged.neoforge.client.RenderTypeGroup; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; -import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; -import net.neoforged.neoforge.client.model.geometry.SimpleUnbakedGeometry; import net.neoforged.neoforge.client.textures.UnitTextureAtlasSprite; /** * A completely empty model with no quads or texture dependencies. *

    - * You can access it as a {@link BakedModel}, an {@link IUnbakedGeometry} or an {@link IGeometryLoader}. + * You can access it as a {@link BakedModel}. */ -public class EmptyModel extends SimpleUnbakedGeometry { +public class EmptyModel implements UnbakedModel, JsonDeserializer { public static final BakedModel BAKED = new Baked(); public static final EmptyModel INSTANCE = new EmptyModel(); - public static final IGeometryLoader LOADER = (json, ctx) -> INSTANCE; + public static final UnbakedModelLoader LOADER = (object, context) -> INSTANCE; private EmptyModel() {} @Override - protected void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuilder, ModelBaker baker, Function spriteGetter, ModelState modelTransform) { - // NO-OP + public BakedModel bake(TextureSlots p_386641_, ModelBaker p_250133_, ModelState p_119536_, boolean p_387129_, boolean p_388638_, ItemTransforms p_386911_) { + return BAKED; } @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { - return BAKED; + public void resolveDependencies(Resolver p_387087_) {} + + @Override + public EmptyModel deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + return INSTANCE; } private static class Baked extends SimpleBakedModel { diff --git a/src/main/java/net/neoforged/neoforge/client/model/ExtendedBlockModelDeserializer.java b/src/main/java/net/neoforged/neoforge/client/model/ExtendedBlockModelDeserializer.java deleted file mode 100644 index db0e19574d..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/ExtendedBlockModelDeserializer.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.mojang.math.Transformation; -import java.lang.reflect.Type; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import net.minecraft.client.renderer.block.model.BlockElement; -import net.minecraft.client.renderer.block.model.BlockElementFace; -import net.minecraft.client.renderer.block.model.BlockFaceUV; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverride; -import net.minecraft.client.renderer.block.model.ItemTransform; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.neoforged.neoforge.client.model.geometry.GeometryLoaderManager; -import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; -import net.neoforged.neoforge.common.util.TransformationHelper; -import org.jetbrains.annotations.Nullable; - -/** - * A version of {@link BlockModel.Deserializer} capable of deserializing models with custom loaders, as well as other - * changes introduced to the spec by Forge. - */ -public class ExtendedBlockModelDeserializer extends BlockModel.Deserializer { - public static final Gson INSTANCE = (new GsonBuilder()) - .registerTypeAdapter(BlockModel.class, new ExtendedBlockModelDeserializer()) - .registerTypeAdapter(BlockElement.class, new BlockElement.Deserializer()) - .registerTypeAdapter(BlockElementFace.class, new BlockElementFace.Deserializer()) - .registerTypeAdapter(BlockFaceUV.class, new BlockFaceUV.Deserializer()) - .registerTypeAdapter(ItemTransform.class, new ItemTransform.Deserializer()) - .registerTypeAdapter(ItemTransforms.class, new ItemTransforms.Deserializer()) - .registerTypeAdapter(ItemOverride.class, new ItemOverride.Deserializer()) - .registerTypeAdapter(Transformation.class, new TransformationHelper.Deserializer()) - .create(); - - @Override - public BlockModel deserialize(JsonElement element, Type targetType, JsonDeserializationContext deserializationContext) throws JsonParseException { - BlockModel model = super.deserialize(element, targetType, deserializationContext); - JsonObject jsonobject = element.getAsJsonObject(); - IUnbakedGeometry geometry = deserializeGeometry(deserializationContext, jsonobject); - - List elements = model.getElements(); - if (geometry != null) { - elements.clear(); - model.customData.setCustomGeometry(geometry); - } - - if (jsonobject.has("transform")) { - JsonElement transform = jsonobject.get("transform"); - model.customData.setRootTransform(deserializationContext.deserialize(transform, Transformation.class)); - } - - if (jsonobject.has("render_type")) { - var renderTypeHintName = GsonHelper.getAsString(jsonobject, "render_type"); - model.customData.setRenderTypeHint(ResourceLocation.parse(renderTypeHintName)); - } - - if (jsonobject.has("visibility")) { - JsonObject visibility = GsonHelper.getAsJsonObject(jsonobject, "visibility"); - for (Map.Entry part : visibility.entrySet()) { - model.customData.visibilityData.setVisibilityState(part.getKey(), part.getValue().getAsBoolean()); - } - } - - return model; - } - - @Nullable - public static IUnbakedGeometry deserializeGeometry(JsonDeserializationContext deserializationContext, JsonObject object) throws JsonParseException { - if (!object.has("loader")) - return null; - - ResourceLocation name; - boolean optional; - if (object.get("loader").isJsonObject()) { - JsonObject loaderObj = object.getAsJsonObject("loader"); - name = ResourceLocation.parse(GsonHelper.getAsString(loaderObj, "id")); - optional = GsonHelper.getAsBoolean(loaderObj, "optional", false); - } else { - name = ResourceLocation.parse(GsonHelper.getAsString(object, "loader")); - optional = false; - } - - var loader = GeometryLoaderManager.get(name); - if (loader == null) { - if (optional) { - return null; - } - throw new JsonParseException(String.format(Locale.ENGLISH, "Model loader '%s' not found. Registered loaders: %s", name, GeometryLoaderManager.getLoaderList())); - } - - return loader.read(object, deserializationContext); - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/ExtendedUnbakedModel.java b/src/main/java/net/neoforged/neoforge/client/model/ExtendedUnbakedModel.java new file mode 100644 index 0000000000..7c981e8f94 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/model/ExtendedUnbakedModel.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model; + +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.util.context.ContextMap; + +/** + * Base interface for unbaked models that wish to support the NeoForge-added {@code bake} method + * that receives {@linkplain #fillAdditionalProperties(ContextMap.Builder) additional properties}. + */ +public interface ExtendedUnbakedModel extends UnbakedModel { + @Deprecated + @Override + default BakedModel bake(TextureSlots textures, ModelBaker baker, ModelState modelState, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms itemTransforms) { + return bake(textures, baker, modelState, useAmbientOcclusion, usesBlockLight, itemTransforms, ContextMap.EMPTY); + } + + // Re-abstract the extended version + @Override + BakedModel bake(TextureSlots textures, ModelBaker baker, ModelState modelState, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms itemTransforms, ContextMap additionalProperties); +} diff --git a/src/main/java/net/neoforged/neoforge/client/model/IModelBuilder.java b/src/main/java/net/neoforged/neoforge/client/model/IModelBuilder.java index 51111b4d0b..a75207f330 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/IModelBuilder.java +++ b/src/main/java/net/neoforged/neoforge/client/model/IModelBuilder.java @@ -19,7 +19,10 @@ *

    * Provides a generic base implementation via {@link #of(boolean, boolean, boolean, ItemTransforms, TextureAtlasSprite, RenderTypeGroup)} * and a quad-collecting alternative via {@link #collecting(List)}. + * + * @deprecated Use {@link SimpleBakedModel.Builder} instead. */ +@Deprecated(forRemoval = true, since = "1.21.4") public interface IModelBuilder> { /** * Creates a new model builder that uses the provided attributes in the final baked model. @@ -38,10 +41,28 @@ static IModelBuilder collecting(List quads) { return new Collecting(quads); } + /** + * Adds a face to the model that will be culled based on the provided facing. + * + * @param facing The facing + * @param quad The quad + * @return This builder + */ T addCulledFace(Direction facing, BakedQuad quad); + /** + * Adds a face to the model that will not be culled. + * + * @param quad The quad + * @return This builder + */ T addUnculledFace(BakedQuad quad); + /** + * Builds the model from the collected faces. + * + * @return The baked model + */ BakedModel build(); class Simple implements IModelBuilder { diff --git a/src/main/java/net/neoforged/neoforge/client/model/ItemLayerModel.java b/src/main/java/net/neoforged/neoforge/client/model/ItemLayerModel.java deleted file mode 100644 index 005c98f626..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/ItemLayerModel.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model; - -import com.google.common.collect.ImmutableList; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.BakedOverrides; -import net.minecraft.client.renderer.block.model.ItemModelGenerator; -import net.minecraft.client.renderer.block.model.ItemOverride; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ItemModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelState; -import net.minecraft.resources.ResourceLocation; -import net.neoforged.neoforge.client.NeoForgeRenderTypes; -import net.neoforged.neoforge.client.RenderTypeGroup; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; -import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; -import net.neoforged.neoforge.client.model.geometry.UnbakedGeometryHelper; -import org.jetbrains.annotations.Nullable; - -/** - * Forge reimplementation of vanilla's {@link ItemModelGenerator}, i.e. builtin/generated models with some tweaks: - * - Represented as {@link IUnbakedGeometry} so it can be baked as usual instead of being special-cased - * - Not limited to an arbitrary number of layers (5) - * - Support for per-layer render types - */ -public class ItemLayerModel implements IUnbakedGeometry { - @Nullable - private ImmutableList textures; - private final Int2ObjectMap layerData; - private final Int2ObjectMap renderTypeNames; - - private ItemLayerModel(@Nullable ImmutableList textures, Int2ObjectMap layerData, Int2ObjectMap renderTypeNames) { - this.textures = textures; - this.layerData = layerData; - this.renderTypeNames = renderTypeNames; - } - - @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { - if (textures == null) { - ImmutableList.Builder builder = ImmutableList.builder(); - for (int i = 0; context.hasMaterial("layer" + i); i++) { - builder.add(context.getMaterial("layer" + i)); - } - textures = builder.build(); - } - - TextureAtlasSprite particle = spriteGetter.apply( - context.hasMaterial("particle") ? context.getMaterial("particle") : textures.get(0)); - var rootTransform = context.getRootTransform(); - if (!rootTransform.isIdentity()) - modelState = UnbakedGeometryHelper.composeRootTransformIntoModelState(modelState, rootTransform); - - var normalRenderTypes = new RenderTypeGroup(RenderType.translucent(), NeoForgeRenderTypes.ITEM_UNSORTED_TRANSLUCENT.get()); - CompositeModel.Baked.Builder builder = CompositeModel.Baked.builder(context, particle, context.getTransforms()); - for (int i = 0; i < textures.size(); i++) { - TextureAtlasSprite sprite = spriteGetter.apply(textures.get(i)); - var unbaked = UnbakedGeometryHelper.createUnbakedItemElements(i, sprite, this.layerData.get(i)); - var quads = UnbakedGeometryHelper.bakeElements(unbaked, $ -> sprite, modelState); - var renderTypeName = renderTypeNames.get(i); - var renderTypes = renderTypeName != null ? context.getRenderType(renderTypeName) : null; - builder.addQuads(renderTypes != null ? renderTypes : normalRenderTypes, quads); - } - - BakedModel baked = builder.build(); - if (!overrides.isEmpty()) { - baked = new ItemModel.BakedModelWithOverrides(baked, new BakedOverrides(baker, overrides, spriteGetter)); - } - return baked; - } - - public static final class Loader implements IGeometryLoader { - public static final Loader INSTANCE = new Loader(); - - @Override - public ItemLayerModel read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) { - var renderTypeNames = new Int2ObjectOpenHashMap(); - if (jsonObject.has("render_types")) { - var renderTypes = jsonObject.getAsJsonObject("render_types"); - for (Map.Entry entry : renderTypes.entrySet()) { - var renderType = ResourceLocation.parse(entry.getKey()); - for (var layer : entry.getValue().getAsJsonArray()) - if (renderTypeNames.put(layer.getAsInt(), renderType) != null) - throw new JsonParseException("Registered duplicate render type for layer " + layer); - } - } - - var emissiveLayers = new Int2ObjectArrayMap(); - if (jsonObject.has("neoforge_data")) { - JsonObject forgeData = jsonObject.get("neoforge_data").getAsJsonObject(); - readLayerData(forgeData, "layers", renderTypeNames, emissiveLayers, false); - } - return new ItemLayerModel(null, emissiveLayers, renderTypeNames); - } - - protected void readLayerData(JsonObject jsonObject, String name, Int2ObjectOpenHashMap renderTypeNames, Int2ObjectMap layerData, boolean logWarning) { - if (!jsonObject.has(name)) { - return; - } - var fullbrightLayers = jsonObject.getAsJsonObject(name); - for (var entry : fullbrightLayers.entrySet()) { - int layer = Integer.parseInt(entry.getKey()); - var data = ExtraFaceData.read(entry.getValue(), ExtraFaceData.DEFAULT); - layerData.put(layer, data); - } - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/NeoForgeModelProperties.java b/src/main/java/net/neoforged/neoforge/client/model/NeoForgeModelProperties.java new file mode 100644 index 0000000000..43dd5a89c8 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/model/NeoForgeModelProperties.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model; + +import com.mojang.math.Transformation; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.util.context.ContextKey; +import net.neoforged.neoforge.client.RenderTypeGroup; + +/** + * Properties that NeoForge adds for {@link BlockModel}s and {@link UnbakedModel}s. + */ +public final class NeoForgeModelProperties { + private NeoForgeModelProperties() {} + + /** + * Root transform. For block models, this can be specified under the {@code transform} JSON key. + */ + public static final ContextKey TRANSFORM = ContextKey.vanilla("transform"); + + /** + * Render type to use. For block models, this can be specified under the {@code render_type} JSON key. + */ + public static final ContextKey RENDER_TYPE = ContextKey.vanilla("render_type"); +} diff --git a/src/main/java/net/neoforged/neoforge/client/model/SeparateTransformsModel.java b/src/main/java/net/neoforged/neoforge/client/model/SeparateTransformsModel.java deleted file mode 100644 index 2db17ea34f..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/SeparateTransformsModel.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonObject; -import com.mojang.blaze3d.vertex.PoseStack; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.BakedOverrides; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverride; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ItemModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelState; -import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.core.Direction; -import net.minecraft.util.GsonHelper; -import net.minecraft.util.RandomSource; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.client.ChunkRenderTypeSet; -import net.neoforged.neoforge.client.model.data.ModelData; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; -import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; -import org.jetbrains.annotations.Nullable; - -/** - * A model composed of multiple sub-models which are picked based on the {@link ItemDisplayContext} being used. - */ -public class SeparateTransformsModel implements IUnbakedGeometry { - private final BlockModel baseModel; - private final ImmutableMap perspectives; - - public SeparateTransformsModel(BlockModel baseModel, ImmutableMap perspectives) { - this.baseModel = baseModel; - this.perspectives = perspectives; - } - - @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { - BakedModel baked = new Baked( - context.useAmbientOcclusion(), context.isGui3d(), context.useBlockLight(), - spriteGetter.apply(context.getMaterial("particle")), - baker.bakeUncached(baseModel, modelState, spriteGetter), - ImmutableMap.copyOf(Maps.transformValues(perspectives, value -> baker.bakeUncached(value, modelState, spriteGetter)))); - if (!overrides.isEmpty()) { - baked = new ItemModel.BakedModelWithOverrides(baked, new BakedOverrides(baker, overrides, spriteGetter)); - } - return baked; - } - - @Override - public void resolveDependencies(UnbakedModel.Resolver modelGetter, IGeometryBakingContext context) { - baseModel.resolveDependencies(modelGetter); - perspectives.values().forEach(model -> model.resolveDependencies(modelGetter)); - } - - public static class Baked implements IDynamicBakedModel { - private final boolean isAmbientOcclusion; - private final boolean isGui3d; - private final boolean isSideLit; - private final TextureAtlasSprite particle; - private final BakedModel baseModel; - private final ImmutableMap perspectives; - - public Baked(boolean isAmbientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, BakedModel baseModel, ImmutableMap perspectives) { - this.isAmbientOcclusion = isAmbientOcclusion; - this.isGui3d = isGui3d; - this.isSideLit = isSideLit; - this.particle = particle; - this.baseModel = baseModel; - this.perspectives = perspectives; - } - - @Override - public List getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand, ModelData data, @Nullable RenderType renderType) { - return baseModel.getQuads(state, side, rand, data, renderType); - } - - @Override - public boolean useAmbientOcclusion() { - return isAmbientOcclusion; - } - - @Override - public boolean isGui3d() { - return isGui3d; - } - - @Override - public boolean usesBlockLight() { - return isSideLit; - } - - @Override - public boolean isCustomRenderer() { - return false; - } - - @Override - public TextureAtlasSprite getParticleIcon() { - return particle; - } - - @Override - public ItemTransforms getTransforms() { - return ItemTransforms.NO_TRANSFORMS; - } - - @Override - public BakedModel applyTransform(ItemDisplayContext cameraTransformType, PoseStack poseStack, boolean applyLeftHandTransform) { - if (perspectives.containsKey(cameraTransformType)) { - BakedModel p = perspectives.get(cameraTransformType); - return p.applyTransform(cameraTransformType, poseStack, applyLeftHandTransform); - } - return baseModel.applyTransform(cameraTransformType, poseStack, applyLeftHandTransform); - } - - @Override - public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, ModelData data) { - return baseModel.getRenderTypes(state, rand, data); - } - } - - public static final class Loader implements IGeometryLoader { - public static final Loader INSTANCE = new Loader(); - - private Loader() {} - - @Override - public SeparateTransformsModel read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) { - BlockModel baseModel = deserializationContext.deserialize(GsonHelper.getAsJsonObject(jsonObject, "base"), BlockModel.class); - - JsonObject perspectiveData = GsonHelper.getAsJsonObject(jsonObject, "perspectives"); - - Map perspectives = new HashMap<>(); - for (ItemDisplayContext transform : ItemDisplayContext.values()) { - if (perspectiveData.has(transform.getSerializedName())) { - BlockModel perspectiveModel = deserializationContext.deserialize(GsonHelper.getAsJsonObject(perspectiveData, transform.getSerializedName()), BlockModel.class); - perspectives.put(transform, perspectiveModel); - } - } - - return new SeparateTransformsModel(baseModel, ImmutableMap.copyOf(perspectives)); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/CompositeModel.java b/src/main/java/net/neoforged/neoforge/client/model/UnbakedCompositeModel.java similarity index 74% rename from src/main/java/net/neoforged/neoforge/client/model/CompositeModel.java rename to src/main/java/net/neoforged/neoforge/client/model/UnbakedCompositeModel.java index efeacde773..b79dfa0c86 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/CompositeModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/UnbakedCompositeModel.java @@ -11,30 +11,29 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; +import com.mojang.math.Transformation; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; -import java.util.function.Function; +import net.minecraft.client.data.models.model.TextureSlot; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.BakedOverrides; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ItemModel; -import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; import net.minecraft.client.resources.model.UnbakedModel; 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.ItemStack; import net.minecraft.world.level.BlockAndTintGetter; @@ -43,44 +42,44 @@ import net.neoforged.neoforge.client.RenderTypeGroup; import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.client.model.data.ModelProperty; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; -import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; -import net.neoforged.neoforge.client.model.geometry.UnbakedGeometryHelper; import net.neoforged.neoforge.common.util.ConcatenatedListView; import org.jetbrains.annotations.Nullable; /** * A model composed of several named children. - *

    - * These respect component visibility as specified in {@link IGeometryBakingContext} and can additionally be provided - * with an item-specific render ordering, for multi-pass arrangements. */ -public class CompositeModel implements IUnbakedGeometry { - private final ImmutableMap children; +public class UnbakedCompositeModel implements UnbakedModel { + private final ImmutableMap children; private final ImmutableList itemPasses; + private final Transformation rootTransform; + private final Map partVisibility; - public CompositeModel(ImmutableMap children, ImmutableList itemPasses) { + public UnbakedCompositeModel(ImmutableMap children, ImmutableList itemPasses, Transformation rootTransform, Map partVisibility) { this.children = children; this.itemPasses = itemPasses; + this.rootTransform = rootTransform; + this.partVisibility = partVisibility; } @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { - Material particleLocation = context.getMaterial("particle"); - TextureAtlasSprite particle = spriteGetter.apply(particleLocation); + public BakedModel bake(TextureSlots slots, + ModelBaker baker, + ModelState state, + boolean useAmbientOcclusion, + boolean usesBlockLight, + ItemTransforms transforms) { + TextureAtlasSprite particle = baker.findSprite(slots, TextureSlot.PARTICLE.getId()); - var rootTransform = context.getRootTransform(); if (!rootTransform.isIdentity()) - modelState = UnbakedGeometryHelper.composeRootTransformIntoModelState(modelState, rootTransform); + state = UnbakedElementsHelper.composeRootTransformIntoModelState(state, rootTransform); var bakedPartsBuilder = ImmutableMap.builder(); for (var entry : children.entrySet()) { var name = entry.getKey(); - if (!context.isComponentVisible(name, true)) + if (!partVisibility.getOrDefault(name, true)) continue; var model = entry.getValue(); - bakedPartsBuilder.put(name, baker.bakeUncached(model, modelState, spriteGetter)); + bakedPartsBuilder.put(name, baker.bake(model, state)); } var bakedParts = bakedPartsBuilder.build(); @@ -92,36 +91,27 @@ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Functio itemPassesBuilder.add(model); } - BakedModel baked = new Baked(context.isGui3d(), context.useBlockLight(), context.useAmbientOcclusion(), particle, context.getTransforms(), bakedParts, itemPassesBuilder.build()); - if (!overrides.isEmpty()) { - baked = new ItemModel.BakedModelWithOverrides(baked, new BakedOverrides(baker, overrides, spriteGetter)); - } - return baked; - } - - @Override - public void resolveDependencies(UnbakedModel.Resolver modelGetter, IGeometryBakingContext context) { - children.values().forEach(child -> child.resolveDependencies(modelGetter)); + return new Baked(usesBlockLight, useAmbientOcclusion, particle, transforms, bakedParts, itemPassesBuilder.build()); } @Override - public Set getConfigurableComponentNames() { - return children.keySet(); + public void resolveDependencies(Resolver resolver) { + for (ResourceLocation path : children.values()) { + resolver.resolve(path); + } } public static class Baked implements IDynamicBakedModel { private final boolean isAmbientOcclusion; - private final boolean isGui3d; private final boolean isSideLit; private final TextureAtlasSprite particle; private final ItemTransforms transforms; private final ImmutableMap children; private final ImmutableList itemPasses; - public Baked(boolean isGui3d, boolean isSideLit, boolean isAmbientOcclusion, TextureAtlasSprite particle, ItemTransforms transforms, ImmutableMap children, ImmutableList itemPasses) { + public Baked(boolean isSideLit, boolean isAmbientOcclusion, TextureAtlasSprite particle, ItemTransforms transforms, ImmutableMap children, ImmutableList itemPasses) { this.children = children; this.isAmbientOcclusion = isAmbientOcclusion; - this.isGui3d = isGui3d; this.isSideLit = isSideLit; this.particle = particle; this.transforms = transforms; @@ -133,7 +123,7 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction List> quadLists = new ArrayList<>(); for (Map.Entry entry : children.entrySet()) { if (renderType == null || (state != null && entry.getValue().getRenderTypes(state, rand, data).contains(renderType))) { - quadLists.add(entry.getValue().getQuads(state, side, rand, CompositeModel.Data.resolve(data, entry.getKey()), renderType)); + quadLists.add(entry.getValue().getQuads(state, side, rand, Data.resolve(data, entry.getKey()), renderType)); } } return ConcatenatedListView.of(quadLists); @@ -154,7 +144,7 @@ public boolean useAmbientOcclusion() { @Override public boolean isGui3d() { - return isGui3d; + return true; } @Override @@ -162,11 +152,6 @@ public boolean usesBlockLight() { return isSideLit; } - @Override - public boolean isCustomRenderer() { - return false; - } - @Override public TextureAtlasSprite getParticleIcon() { return particle; @@ -181,7 +166,7 @@ public ItemTransforms getTransforms() { public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, ModelData data) { var sets = new ArrayList(); for (Map.Entry entry : children.entrySet()) - sets.add(entry.getValue().getRenderTypes(state, rand, CompositeModel.Data.resolve(data, entry.getKey()))); + sets.add(entry.getValue().getRenderTypes(state, rand, Data.resolve(data, entry.getKey()))); return ChunkRenderTypeSet.union(sets); } @@ -195,10 +180,6 @@ public BakedModel getPart(String name) { return children.get(name); } - public static Builder builder(IGeometryBakingContext owner, TextureAtlasSprite particle, ItemTransforms cameraTransforms) { - return builder(owner.useAmbientOcclusion(), owner.isGui3d(), owner.useBlockLight(), particle, cameraTransforms); - } - public static Builder builder(boolean isAmbientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemTransforms cameraTransforms) { return new Builder(isAmbientOcclusion, isGui3d, isSideLit, particle, cameraTransforms); } @@ -270,7 +251,7 @@ public BakedModel build() { childrenBuilder.put("model_" + (i++), model); itemPassesBuilder.add(model); } - return new Baked(isGui3d, isSideLit, isAmbientOcclusion, particle, transforms, childrenBuilder.build(), itemPassesBuilder.build()); + return new Baked(isSideLit, isAmbientOcclusion, particle, transforms, childrenBuilder.build(), itemPassesBuilder.build()); } } } @@ -325,16 +306,16 @@ public Data build() { } } - public static final class Loader implements IGeometryLoader { + public static final class Loader implements UnbakedModelLoader { public static final Loader INSTANCE = new Loader(); private Loader() {} @Override - public CompositeModel read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) { + public UnbakedCompositeModel read(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { List itemPasses = new ArrayList<>(); - ImmutableMap.Builder childrenBuilder = ImmutableMap.builder(); - readChildren(jsonObject, "children", deserializationContext, childrenBuilder, itemPasses); + ImmutableMap.Builder childrenBuilder = ImmutableMap.builder(); + readChildren(jsonObject, "children", childrenBuilder, itemPasses); var children = childrenBuilder.build(); if (children.isEmpty()) @@ -350,15 +331,34 @@ public CompositeModel read(JsonObject jsonObject, JsonDeserializationContext des } } - return new CompositeModel(children, ImmutableList.copyOf(itemPasses)); + final Map partVisibility; + if (jsonObject.has("visibility")) { + partVisibility = new HashMap<>(); + JsonObject visibility = jsonObject.getAsJsonObject("visibility"); + for (Map.Entry part : visibility.entrySet()) { + partVisibility.put(part.getKey(), part.getValue().getAsBoolean()); + } + } else { + partVisibility = Collections.emptyMap(); + } + + final Transformation transformation; + if (jsonObject.has("transform")) { + transformation = BlockModel.GSON.fromJson(jsonObject.get("transform"), Transformation.class); + } else { + transformation = Transformation.identity(); + } + + return new UnbakedCompositeModel(children, ImmutableList.copyOf(itemPasses), transformation, partVisibility); } - private void readChildren(JsonObject jsonObject, String name, JsonDeserializationContext deserializationContext, ImmutableMap.Builder children, List itemPasses) { + private void readChildren(JsonObject jsonObject, String name, ImmutableMap.Builder children, List itemPasses) { if (!jsonObject.has(name)) return; var childrenJsonObject = jsonObject.getAsJsonObject(name); for (Map.Entry entry : childrenJsonObject.entrySet()) { - children.put(entry.getKey(), deserializationContext.deserialize(entry.getValue(), BlockModel.class)); + ResourceLocation location = ResourceLocation.parse(entry.getValue().getAsString()); + children.put(entry.getKey(), location); itemPasses.add(entry.getKey()); // We can do this because GSON preserves ordering during deserialization } } diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/UnbakedGeometryHelper.java b/src/main/java/net/neoforged/neoforge/client/model/UnbakedElementsHelper.java similarity index 64% rename from src/main/java/net/neoforged/neoforge/client/model/geometry/UnbakedGeometryHelper.java rename to src/main/java/net/neoforged/neoforge/client/model/UnbakedElementsHelper.java index e790cef41c..5c5e67c538 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/UnbakedGeometryHelper.java +++ b/src/main/java/net/neoforged/neoforge/client/model/UnbakedElementsHelper.java @@ -1,86 +1,38 @@ /* - * Copyright (c) Forge Development LLC and contributors + * Copyright (c) NeoForged and contributors * SPDX-License-Identifier: LGPL-2.1-only */ -package net.neoforged.neoforge.client.model.geometry; +package net.neoforged.neoforge.client.model; import com.mojang.math.Transformation; import java.util.ArrayList; import java.util.BitSet; -import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import net.minecraft.Util; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BlockElement; import net.minecraft.client.renderer.block.model.BlockElementFace; import net.minecraft.client.renderer.block.model.BlockFaceUV; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.FaceBakery; import net.minecraft.client.renderer.block.model.ItemModelGenerator; -import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.client.renderer.texture.SpriteContents; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.SimpleBakedModel; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; import net.neoforged.neoforge.client.ClientHooks; -import net.neoforged.neoforge.client.model.ExtraFaceData; -import net.neoforged.neoforge.client.model.IModelBuilder; -import net.neoforged.neoforge.client.model.SimpleModelState; import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; -/** - * Helper for dealing with unbaked models and geometries. - */ -public class UnbakedGeometryHelper { - private static final ItemModelGenerator ITEM_MODEL_GENERATOR = new ItemModelGenerator(); - private static final FaceBakery FACE_BAKERY = new FaceBakery(); - - /** - * Explanation: - * This takes anything that looks like a valid resourcepack texture location, and tries to extract a resourcelocation out of it. - * 1. it will ignore anything up to and including an /assets/ folder, - * 2. it will take the next path component as a namespace, - * 3. it will match but skip the /textures/ part of the path, - * 4. it will take the rest of the path up to but excluding the .png extension as the resource path - * It's a best-effort situation, to allow model files exported by modelling software to be used without post-processing. - * Example: - * C:\Something\Or Other\src\main\resources\assets\mymodid\textures\item\my_thing.png - * ........................................--------_______----------_____________---- - * - * Result after replacing '\' to '/': mymodid:item/my_thing - */ - private static final Pattern FILESYSTEM_PATH_TO_RESLOC = Pattern.compile("(?:.*[\\\\/]assets[\\\\/](?[a-z_-]+)[\\\\/]textures[\\\\/])?(?[a-z_\\\\/-]+)\\.png"); - - /** - * Resolves a material that may have been defined with a filesystem path instead of a proper {@link ResourceLocation}. - *

    - * The target atlas will always be {@link TextureAtlas#LOCATION_BLOCKS}. - */ - public static Material resolveDirtyMaterial(@Nullable String tex, IGeometryBakingContext owner) { - if (tex == null) - return new Material(TextureAtlas.LOCATION_BLOCKS, MissingTextureAtlasSprite.getLocation()); - if (tex.startsWith("#")) - return owner.getMaterial(tex); - - // Attempt to convert a common (windows/linux/mac) filesystem path to a ResourceLocation. - // This makes no promises, if it doesn't work, too bad, fix your mtl file. - Matcher match = FILESYSTEM_PATH_TO_RESLOC.matcher(tex); - if (match.matches()) { - String namespace = match.group("namespace"); - String path = match.group("path").replace("\\", "/"); - tex = namespace != null ? namespace + ":" + path : path; - } +public final class UnbakedElementsHelper { + private UnbakedElementsHelper() {} - return new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.parse(tex)); - } + private static final ItemModelGenerator ITEM_MODEL_GENERATOR = new ItemModelGenerator(); /** * @see #createUnbakedItemElements(int, TextureAtlasSprite, ExtraFaceData) @@ -118,12 +70,13 @@ public static List createUnbakedItemMaskElements(int layerIndex, T * The {@link Direction#NORTH} and {@link Direction#SOUTH} faces take up only the pixels the texture uses. */ public static List createUnbakedItemMaskElements(int layerIndex, TextureAtlasSprite sprite, @Nullable ExtraFaceData faceData) { - var elements = createUnbakedItemElements(layerIndex, sprite, faceData); - elements.remove(0); // Remove north and south faces + List elements = createUnbakedItemElements(layerIndex, sprite, faceData); + elements.removeFirst(); // Remove north and south faces + float expand = -sprite.uvShrinkRatio(); SpriteContents spriteContents = sprite.contents(); int width = spriteContents.width(), height = spriteContents.height(); - var bits = new BitSet(width * height); + BitSet bits = new BitSet(width * height); // For every frame in the texture, mark all the opaque pixels (this is what vanilla does too) spriteContents.getUniqueFrames().forEach(frame -> { @@ -137,9 +90,8 @@ public static List createUnbakedItemMaskElements(int layerIndex, T for (int y = 0; y < height; y++) { int xStart = -1; for (int x = 0; x < width; x++) { - var opaque = bits.get(x + y * width); - if (opaque == (xStart == -1)) // (opaque && -1) || (!opaque && !-1) - { + boolean opaque = bits.get(x + y * width); + if (opaque == (xStart == -1)) { // (opaque && -1) || (!opaque && !-1) if (xStart == -1) { // We have found the start of a new segment, continue xStart = x; @@ -160,16 +112,31 @@ public static List createUnbakedItemMaskElements(int layerIndex, T bits.clear(i + j * width); // Create element - elements.add(new BlockElement( + BlockElement element = new BlockElement( new Vector3f(16 * xStart / (float) width, 16 - 16 * yEnd / (float) height, 7.5F), new Vector3f(16 * x / (float) width, 16 - 16 * y / (float) height, 8.5F), - Util.make(new HashMap<>(), map -> { - for (Direction direction : Direction.values()) - map.put(direction, new BlockElementFace(null, layerIndex, "layer" + layerIndex, new BlockFaceUV(null, 0))); - }), + Map.of( + Direction.NORTH, new BlockElementFace(null, layerIndex, "layer" + layerIndex, new BlockFaceUV(null, 0)), + Direction.SOUTH, new BlockElementFace(null, layerIndex, "layer" + layerIndex, new BlockFaceUV(null, 0))), null, true, - 0)); + 0); + // Expand coordinates to match the shrunk UVs of the front/back face on a standard generated model (done after to not affect the auto-generated UVs) + element.from.x = Mth.clamp(Mth.lerp(expand, element.from.x, 8F), 0F, 16F); + element.from.y = Mth.clamp(Mth.lerp(expand, element.from.y, 8F), 0F, 16F); + element.to.x = Mth.clamp(Mth.lerp(expand, element.to.x, 8F), 0F, 16F); + element.to.y = Mth.clamp(Mth.lerp(expand, element.to.y, 8F), 0F, 16F); + // Counteract sprite expansion to ensure pixel alignment + element.faces.forEach((dir, face) -> { + float[] uv = face.uv().uvs; + float centerU = (uv[0] + uv[0] + uv[2] + uv[2]) / 4.0F; + uv[0] = Mth.clamp(Mth.lerp(expand, uv[0], centerU), 0F, 16F); + uv[2] = Mth.clamp(Mth.lerp(expand, uv[2], centerU), 0F, 16F); + float centerV = (uv[1] + uv[1] + uv[3] + uv[3]) / 4.0F; + uv[1] = Mth.clamp(Mth.lerp(expand, uv[1], centerV), 0F, 16F); + uv[3] = Mth.clamp(Mth.lerp(expand, uv[3], centerV), 0F, 16F); + }); + elements.add(element); // Reset xStart xStart = -1; @@ -186,7 +153,7 @@ public static void bakeElements(IModelBuilder builder, List ele for (BlockElement element : elements) { element.faces.forEach((side, face) -> { var sprite = spriteGetter.apply(new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.parse(face.texture()))); - BakedQuad quad = BlockModel.bakeFace(element, face, sprite, side, modelState); + BakedQuad quad = SimpleBakedModel.bakeFace(element, face, sprite, side, modelState); if (face.cullForDirection() == null) builder.addUnculledFace(quad); else diff --git a/src/main/java/net/neoforged/neoforge/client/model/UnbakedModelLoader.java b/src/main/java/net/neoforged/neoforge/client/model/UnbakedModelLoader.java new file mode 100644 index 0000000000..0f518f18f8 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/model/UnbakedModelLoader.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.server.packs.resources.ResourceManagerReloadListener; +import net.neoforged.neoforge.client.event.ModelEvent; +import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; + +/** + * A loader for custom {@linkplain UnbakedModel unbaked models}. + *

    + * If you do any caching, you should implement {@link ResourceManagerReloadListener} and register it with + * {@link RegisterClientReloadListenersEvent}. + * + * @see ModelEvent.RegisterLoaders + * @see RegisterClientReloadListenersEvent + */ +public interface UnbakedModelLoader { + /** + * Reads an unbaked model from the passed JSON object. + * + *

    The {@link JsonDeserializationContext} argument can be used to deserialize types that the system already understands. + * For example, {@code deserializationContext.deserialize(, Transformation.class)} to parse a transformation, + * or {@code deserializationContext.deserialize(, UnbakedModel.class)} to parse a nested model. + * The set of supported types can be found in the declaration of {@link BlockModel#GSON}. + */ + T read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) throws JsonParseException; +} diff --git a/src/main/java/net/neoforged/neoforge/client/model/UnbakedModelParser.java b/src/main/java/net/neoforged/neoforge/client/model/UnbakedModelParser.java new file mode 100644 index 0000000000..37e26215c7 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/model/UnbakedModelParser.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model; + +import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import java.io.Reader; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.stream.Collectors; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.GsonHelper; +import net.neoforged.fml.ModLoader; +import net.neoforged.neoforge.client.event.ModelEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +public class UnbakedModelParser { + private static ImmutableMap> LOADERS; + + @Nullable + public static UnbakedModelLoader get(ResourceLocation name) { + return LOADERS.get(name); + } + + @ApiStatus.Internal + public static void init() { + var loaders = new HashMap>(); + ModLoader.postEventWrapContainerInModOrder(new ModelEvent.RegisterLoaders(loaders)); + LOADERS = ImmutableMap.copyOf(loaders); + } + + public static UnbakedModel parse(Reader reader) { + return GsonHelper.fromJson(BlockModel.GSON, reader, UnbakedModel.class); + } + + @ApiStatus.Internal + public static final class Deserializer implements JsonDeserializer { + @Override + public UnbakedModel deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + if (!jsonElement.isJsonObject()) { + throw new JsonParseException("Expected object, got " + jsonElement); + } else { + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + if (jsonObject.has("loader")) { + final ResourceLocation loader; + final boolean optional; + if (jsonObject.get("loader").isJsonObject()) { + JsonObject loaderObject = jsonObject.getAsJsonObject("loader"); + loader = ResourceLocation.parse(GsonHelper.getAsString(loaderObject, "id")); + optional = GsonHelper.getAsBoolean(loaderObject, "optional", false); + } else { + loader = ResourceLocation.parse(GsonHelper.getAsString(jsonObject, "loader")); + optional = false; + } + + var loaderInstance = UnbakedModelParser.get(loader); + if (loaderInstance != null) { + return loaderInstance.read(jsonObject, jsonDeserializationContext); + } + if (!optional) { + throw new JsonParseException("Unknown loader: " + loader + " (did you forget to register it?) Available loaders: " + LOADERS.keySet().stream().map(ResourceLocation::toString).collect(Collectors.joining(", "))); + } + } + + return jsonDeserializationContext.deserialize(jsonObject, BlockModel.class); + } + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/model/generators/CustomLoaderBuilder.java b/src/main/java/net/neoforged/neoforge/client/model/generators/CustomLoaderBuilder.java index a8717c551a..7e088ea4ef 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/generators/CustomLoaderBuilder.java +++ b/src/main/java/net/neoforged/neoforge/client/model/generators/CustomLoaderBuilder.java @@ -10,7 +10,6 @@ import java.util.LinkedHashMap; import java.util.Map; import net.minecraft.resources.ResourceLocation; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; import net.neoforged.neoforge.common.data.ExistingFileHelper; public abstract class CustomLoaderBuilder> { diff --git a/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java b/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java index 9afe777b8a..90d619fd9a 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java +++ b/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java @@ -25,9 +25,9 @@ import net.minecraft.client.renderer.block.model.BlockElementFace; import net.minecraft.client.renderer.block.model.BlockElementRotation; import net.minecraft.client.renderer.block.model.BlockFaceUV; -import net.minecraft.client.renderer.block.model.BlockModel.GuiLight; import net.minecraft.client.renderer.block.model.ItemTransform; import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; +import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; @@ -61,7 +61,8 @@ public class ModelBuilder> extends ModelFile { protected String renderType = null; protected boolean ambientOcclusion = true; - protected GuiLight guiLight = null; + + protected UnbakedModel.GuiLight guiLight = null; protected final List elements = new ArrayList<>(); @@ -185,7 +186,7 @@ public T ao(boolean ao) { return self(); } - public T guiLight(GuiLight light) { + public T guiLight(UnbakedModel.GuiLight light) { this.guiLight = light; return self(); } diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/BlockGeometryBakingContext.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/BlockGeometryBakingContext.java deleted file mode 100644 index 02c53783ae..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/BlockGeometryBakingContext.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.geometry; - -import com.mojang.math.Transformation; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverride; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelState; -import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; - -/** - * A {@linkplain IGeometryBakingContext geometry baking context} that is bound to a {@link BlockModel}. - *

    - * Users should not be instantiating this themselves. - */ -public class BlockGeometryBakingContext implements IGeometryBakingContext { - public final BlockModel owner; - public final VisibilityData visibilityData = new VisibilityData(); - @Nullable - private IUnbakedGeometry customGeometry; - @Nullable - private Transformation rootTransform; - @Nullable - private ResourceLocation renderTypeHint; - private boolean gui3d = true; - - @ApiStatus.Internal - public BlockGeometryBakingContext(BlockModel owner) { - this.owner = owner; - } - - @Override - public String getModelName() { - return owner.name; - } - - public boolean hasCustomGeometry() { - return getCustomGeometry() != null; - } - - @Nullable - public IUnbakedGeometry getCustomGeometry() { - return owner.parent != null && customGeometry == null ? owner.parent.customData.getCustomGeometry() : customGeometry; - } - - public void setCustomGeometry(IUnbakedGeometry geometry) { - this.customGeometry = geometry; - } - - @Override - public boolean isComponentVisible(String part, boolean fallback) { - return owner.parent != null && !visibilityData.hasCustomVisibility(part) ? owner.parent.customData.isComponentVisible(part, fallback) : visibilityData.isVisible(part, fallback); - } - - @Override - public boolean hasMaterial(String name) { - return owner.hasTexture(name); - } - - @Override - public Material getMaterial(String name) { - return owner.getMaterial(name); - } - - @Override - public boolean isGui3d() { - return gui3d; - } - - @Override - public boolean useBlockLight() { - return owner.getGuiLight().lightLikeBlock(); - } - - @Override - public boolean useAmbientOcclusion() { - return owner.hasAmbientOcclusion(); - } - - @Override - public ItemTransforms getTransforms() { - return owner.getTransforms(); - } - - @Override - public Transformation getRootTransform() { - if (rootTransform != null) - return rootTransform; - return owner.parent != null ? owner.parent.customData.getRootTransform() : Transformation.identity(); - } - - public void setRootTransform(Transformation rootTransform) { - this.rootTransform = rootTransform; - } - - @Nullable - @Override - public ResourceLocation getRenderTypeHint() { - if (renderTypeHint != null) - return renderTypeHint; - return owner.parent != null ? owner.parent.customData.getRenderTypeHint() : null; - } - - public void setRenderTypeHint(ResourceLocation renderTypeHint) { - this.renderTypeHint = renderTypeHint; - } - - public void setGui3d(boolean gui3d) { - this.gui3d = gui3d; - } - - public void copyFrom(BlockGeometryBakingContext other) { - this.customGeometry = other.customGeometry; - this.rootTransform = other.rootTransform; - this.visibilityData.copyFrom(other.visibilityData); - this.renderTypeHint = other.renderTypeHint; - this.gui3d = other.gui3d; - } - - public BakedModel bake(ModelBaker baker, Function bakedTextureGetter, ModelState modelTransform, List overrides) { - IUnbakedGeometry geometry = getCustomGeometry(); - if (geometry == null) - throw new IllegalStateException("Can not use custom baking without custom geometry"); - return geometry.bake(this, baker, bakedTextureGetter, modelTransform, overrides); - } - - public static class VisibilityData { - private final Map data = new HashMap<>(); - - public boolean hasCustomVisibility(String part) { - return data.containsKey(part); - } - - public boolean isVisible(String part, boolean fallback) { - return data.getOrDefault(part, fallback); - } - - public void setVisibilityState(String partName, boolean type) { - data.put(partName, type); - } - - public void copyFrom(VisibilityData visibilityData) { - data.clear(); - data.putAll(visibilityData.data); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/GeometryLoaderManager.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/GeometryLoaderManager.java deleted file mode 100644 index 1382c821c1..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/GeometryLoaderManager.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.geometry; - -import com.google.common.collect.ImmutableMap; -import java.util.HashMap; -import java.util.stream.Collectors; -import net.minecraft.resources.ResourceLocation; -import net.neoforged.fml.ModLoader; -import net.neoforged.neoforge.client.event.ModelEvent; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; - -/** - * Manager for {@linkplain IGeometryLoader geometry loaders}. - *

    - * Provides a lookup. - */ -public final class GeometryLoaderManager { - private static ImmutableMap> LOADERS; - private static String LOADER_LIST; - - /** - * Finds the {@link IGeometryLoader} for a given name, or null if not found. - */ - @Nullable - public static IGeometryLoader get(ResourceLocation name) { - return LOADERS.get(name); - } - - /** - * Retrieves a comma-separated list of all active loaders, for use in error messages. - */ - public static String getLoaderList() { - return LOADER_LIST; - } - - @ApiStatus.Internal - public static void init() { - var loaders = new HashMap>(); - var event = new ModelEvent.RegisterGeometryLoaders(loaders); - ModLoader.postEventWrapContainerInModOrder(event); - LOADERS = ImmutableMap.copyOf(loaders); - LOADER_LIST = loaders.keySet().stream().map(ResourceLocation::toString).collect(Collectors.joining(", ")); - } - - private GeometryLoaderManager() {} -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/IGeometryBakingContext.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/IGeometryBakingContext.java deleted file mode 100644 index 3b1950ceb1..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/IGeometryBakingContext.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.geometry; - -import com.mojang.math.Transformation; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.client.resources.model.Material; -import net.minecraft.resources.ResourceLocation; -import net.neoforged.neoforge.client.NamedRenderTypeManager; -import net.neoforged.neoforge.client.RenderTypeGroup; -import org.jetbrains.annotations.Nullable; - -/** - * The context in which a geometry is being baked, providing information such as lighting and - * {@linkplain ItemTransforms transforms}, and allowing the user to create {@linkplain Material materials} and query - * {@linkplain RenderTypeGroup render types}. - * - * @see StandaloneGeometryBakingContext - * @see BlockGeometryBakingContext - */ -public interface IGeometryBakingContext { - /** - * {@return the name of the model being baked for logging and caching purposes.} - */ - String getModelName(); - - /** - * Checks if a material is present in the model. - * - * @param name The name of the material - * @return true if the material is present, false otherwise - */ - boolean hasMaterial(String name); - - /** - * Resolves the final texture name, taking into account texture aliases and replacements. - * - * @param name The name of the material - * @return The material, or the missing texture if not found - */ - Material getMaterial(String name); - - /** - * {@return true if this model should render in 3D in a GUI, false otherwise} - */ - boolean isGui3d(); - - /** - * {@return true if block lighting should be used for this model, false otherwise} - */ - boolean useBlockLight(); - - /** - * {@return true if per-vertex ambient occlusion should be used for this model, false otherwise} - */ - boolean useAmbientOcclusion(); - - /** - * {@return the transforms for display in item form.} - */ - ItemTransforms getTransforms(); - - /** - * {@return the root transformation to be applied to all variants of this model, regardless of item transforms.} - */ - Transformation getRootTransform(); - - /** - * {@return a hint of the render type this model should use. Custom loaders may ignore this.} - */ - @Nullable - ResourceLocation getRenderTypeHint(); - - /** - * Queries the visibility of a component of this model. - * - * @param component The component for which to query visibility - * @param fallback The default visibility if an override isn't found - * @return The visibility of the component - */ - boolean isComponentVisible(String component, boolean fallback); - - /** - * {@return a {@link RenderTypeGroup} with the given name, or the empty group if not found.} - */ - default RenderTypeGroup getRenderType(ResourceLocation name) { - return NamedRenderTypeManager.get(name); - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/IGeometryLoader.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/IGeometryLoader.java deleted file mode 100644 index 67f2c7d090..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/IGeometryLoader.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.geometry; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import net.minecraft.server.packs.resources.ResourceManagerReloadListener; -import net.neoforged.neoforge.client.event.ModelEvent; -import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; - -/** - * A loader for custom {@linkplain IUnbakedGeometry model geometries}. - *

    - * If you do any caching, you should implement {@link ResourceManagerReloadListener} and register it with - * {@link RegisterClientReloadListenersEvent}. - * - * @see ModelEvent.RegisterGeometryLoaders - * @see RegisterClientReloadListenersEvent - */ -public interface IGeometryLoader> { - T read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) throws JsonParseException; -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/IUnbakedGeometry.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/IUnbakedGeometry.java deleted file mode 100644 index 79be568a61..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/IUnbakedGeometry.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.geometry; - -import java.util.List; -import java.util.Set; -import java.util.function.Function; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverride; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelState; -import net.minecraft.client.resources.model.UnbakedModel; - -/** - * General interface for any model that can be baked, superset of vanilla {@link UnbakedModel}. - *

    - * Instances of this class ar usually created via {@link IGeometryLoader}. - * - * @see IGeometryLoader - * @see IGeometryBakingContext - */ -public interface IUnbakedGeometry> { - BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides); - - /** - * Resolve parents of nested {@link BlockModel}s which are later used in - * {@link IUnbakedGeometry#bake(IGeometryBakingContext, ModelBaker, Function, ModelState, List)} - * via {@link BlockModel#resolveDependencies(UnbakedModel.Resolver)} - */ - default void resolveDependencies(UnbakedModel.Resolver modelGetter, IGeometryBakingContext context) {} - - /** - * {@return a set of all the components whose visibility may be configured via {@link IGeometryBakingContext}} - */ - default Set getConfigurableComponentNames() { - return Set.of(); - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/SimpleUnbakedGeometry.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/SimpleUnbakedGeometry.java deleted file mode 100644 index 1c8ea09699..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/SimpleUnbakedGeometry.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.geometry; - -import java.util.List; -import java.util.function.Function; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverride; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelState; -import net.neoforged.neoforge.client.RenderTypeGroup; -import net.neoforged.neoforge.client.model.IModelBuilder; - -/** - * Base class for implementations of {@link IUnbakedGeometry} which do not wish to handle model creation themselves, - * instead supplying {@linkplain BakedQuad baked quads} through a builder. - */ -public abstract class SimpleUnbakedGeometry> implements IUnbakedGeometry { - @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { - TextureAtlasSprite particle = spriteGetter.apply(context.getMaterial("particle")); - - var renderTypeHint = context.getRenderTypeHint(); - var renderTypes = renderTypeHint != null ? context.getRenderType(renderTypeHint) : RenderTypeGroup.EMPTY; - IModelBuilder builder = IModelBuilder.of(context.useAmbientOcclusion(), context.useBlockLight(), context.isGui3d(), - context.getTransforms(), particle, renderTypes); - - addQuads(context, builder, baker, spriteGetter, modelState); - - return builder.build(); - } - - protected abstract void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuilder, ModelBaker baker, Function spriteGetter, ModelState modelTransform); -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/StandaloneGeometryBakingContext.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/StandaloneGeometryBakingContext.java deleted file mode 100644 index f983b777bf..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/StandaloneGeometryBakingContext.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.geometry; - -import com.google.common.base.Predicates; -import com.mojang.math.Transformation; -import it.unimi.dsi.fastutil.objects.Object2BooleanMap; -import java.util.Map; -import java.util.function.BiPredicate; -import java.util.function.Function; -import java.util.function.Predicate; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureAtlas; -import net.minecraft.client.resources.model.Material; -import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.Nullable; - -/** - * A {@linkplain IGeometryBakingContext geometry baking context} that is not bound to block/item model loading. - */ -public class StandaloneGeometryBakingContext implements IGeometryBakingContext { - public static final ResourceLocation LOCATION = ResourceLocation.fromNamespaceAndPath("neoforge", "standalone"); - - public static final StandaloneGeometryBakingContext INSTANCE = create(LOCATION); - - public static StandaloneGeometryBakingContext create(ResourceLocation modelName) { - return builder().build(modelName); - } - - public static StandaloneGeometryBakingContext create(Map textures) { - return create(LOCATION, textures); - } - - public static StandaloneGeometryBakingContext create(ResourceLocation modelName, Map textures) { - return builder().withTextures(textures, MissingTextureAtlasSprite.getLocation()).build(modelName); - } - - private final ResourceLocation modelName; - private final Predicate materialCheck; - private final Function materialLookup; - private final boolean isGui3d; - private final boolean useBlockLight; - private final boolean useAmbientOcclusion; - private final ItemTransforms transforms; - private final Transformation rootTransform; - @Nullable - private final ResourceLocation renderTypeHint; - private final BiPredicate visibilityTest; - - private StandaloneGeometryBakingContext(ResourceLocation modelName, Predicate materialCheck, - Function materialLookup, boolean isGui3d, - boolean useBlockLight, boolean useAmbientOcclusion, - ItemTransforms transforms, Transformation rootTransform, - @Nullable ResourceLocation renderTypeHint, - BiPredicate visibilityTest) { - this.modelName = modelName; - this.materialCheck = materialCheck; - this.materialLookup = materialLookup; - this.isGui3d = isGui3d; - this.useBlockLight = useBlockLight; - this.useAmbientOcclusion = useAmbientOcclusion; - this.transforms = transforms; - this.rootTransform = rootTransform; - this.renderTypeHint = renderTypeHint; - this.visibilityTest = visibilityTest; - } - - @Override - public String getModelName() { - return modelName.toString(); - } - - @Override - public boolean hasMaterial(String name) { - return materialCheck.test(name); - } - - @Override - public Material getMaterial(String name) { - return materialLookup.apply(name); - } - - @Override - public boolean isGui3d() { - return isGui3d; - } - - @Override - public boolean useBlockLight() { - return useBlockLight; - } - - @Override - public boolean useAmbientOcclusion() { - return useAmbientOcclusion; - } - - @Override - public ItemTransforms getTransforms() { - return transforms; - } - - @Override - public Transformation getRootTransform() { - return rootTransform; - } - - @Nullable - @Override - public ResourceLocation getRenderTypeHint() { - return renderTypeHint; - } - - @Override - public boolean isComponentVisible(String component, boolean fallback) { - return visibilityTest.test(component, fallback); - } - - public static Builder builder() { - return new Builder(); - } - - public static Builder builder(IGeometryBakingContext parent) { - return new Builder(parent); - } - - public static final class Builder { - private static final Material NO_MATERIAL = new Material(TextureAtlas.LOCATION_BLOCKS, MissingTextureAtlasSprite.getLocation()); - private Predicate materialCheck = Predicates.alwaysFalse(); - private Function materialLookup = $ -> NO_MATERIAL; - private boolean isGui3d = true; - private boolean useBlockLight = true; - private boolean useAmbientOcclusion = true; - private ItemTransforms transforms = ItemTransforms.NO_TRANSFORMS; - private Transformation rootTransform = Transformation.identity(); - @Nullable - private ResourceLocation renderTypeHint; - private BiPredicate visibilityTest = (c, def) -> def; - - private Builder() {} - - private Builder(IGeometryBakingContext parent) { - this.materialCheck = parent::hasMaterial; - this.materialLookup = parent::getMaterial; - this.isGui3d = parent.isGui3d(); - this.useBlockLight = parent.useBlockLight(); - this.useAmbientOcclusion = parent.useAmbientOcclusion(); - this.transforms = parent.getTransforms(); - this.rootTransform = parent.getRootTransform(); - this.renderTypeHint = parent.getRenderTypeHint(); - this.visibilityTest = parent::isComponentVisible; - } - - public Builder withTextures(Map textures, ResourceLocation defaultTexture) { - return withTextures(TextureAtlas.LOCATION_BLOCKS, textures, defaultTexture); - } - - public Builder withTextures(ResourceLocation atlasLocation, Map textures, ResourceLocation defaultTexture) { - this.materialCheck = textures::containsKey; - this.materialLookup = name -> new Material(atlasLocation, textures.getOrDefault(name, defaultTexture)); - return this; - } - - public Builder withMaterials(Map materials, Material defaultMaterial) { - this.materialCheck = materials::containsKey; - this.materialLookup = name -> materials.getOrDefault(name, defaultMaterial); - return this; - } - - public Builder withGui3d(boolean isGui3d) { - this.isGui3d = isGui3d; - return this; - } - - public Builder withUseBlockLight(boolean useBlockLight) { - this.useBlockLight = useBlockLight; - return this; - } - - public Builder withUseAmbientOcclusion(boolean useAmbientOcclusion) { - this.useAmbientOcclusion = useAmbientOcclusion; - return this; - } - - public Builder withTransforms(ItemTransforms transforms) { - this.transforms = transforms; - return this; - } - - public Builder withRootTransform(Transformation rootTransform) { - this.rootTransform = rootTransform; - return this; - } - - public Builder withRenderTypeHint(ResourceLocation renderTypeHint) { - this.renderTypeHint = renderTypeHint; - return this; - } - - public Builder withVisibleComponents(Object2BooleanMap parts) { - this.visibilityTest = parts::getOrDefault; - return this; - } - - public StandaloneGeometryBakingContext build(ResourceLocation modelName) { - return new StandaloneGeometryBakingContext(modelName, materialCheck, materialLookup, isGui3d, useBlockLight, useAmbientOcclusion, transforms, rootTransform, renderTypeHint, visibilityTest); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/item/DynamicFluidContainerModel.java b/src/main/java/net/neoforged/neoforge/client/model/item/DynamicFluidContainerModel.java new file mode 100644 index 0000000000..d2f69a1d5b --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/model/item/DynamicFluidContainerModel.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model.item; + +import com.mojang.math.Transformation; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import net.minecraft.client.color.item.Constant; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.item.BlockModelWrapper; +import net.minecraft.client.renderer.item.ItemModel; +import net.minecraft.client.renderer.item.ItemModelResolver; +import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BlockModelRotation; +import net.minecraft.client.resources.model.Material; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.client.ClientHooks; +import net.neoforged.neoforge.client.NeoForgeRenderTypes; +import net.neoforged.neoforge.client.RenderTypeGroup; +import net.neoforged.neoforge.client.color.item.FluidContentsTint; +import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; +import net.neoforged.neoforge.client.model.QuadTransformers; +import net.neoforged.neoforge.client.model.SimpleModelState; +import net.neoforged.neoforge.client.model.UnbakedCompositeModel; +import net.neoforged.neoforge.client.model.UnbakedElementsHelper; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.FluidUtil; +import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +/** + * A dynamic fluid container model, capable of re-texturing itself at runtime to match the contained fluid. + *

    + * Composed of a base layer, a fluid layer (applied with a mask) and a cover layer (optionally applied with a mask). + * The entire model may optionally be flipped if the fluid is gaseous, and the fluid layer may glow if light-emitting. + */ +public class DynamicFluidContainerModel implements ItemModel { + // Depth offsets to prevent Z-fighting + private static final Transformation FLUID_TRANSFORM = new Transformation(new Vector3f(), new Quaternionf(), new Vector3f(1, 1, 1.002f), new Quaternionf()); + private static final Transformation COVER_TRANSFORM = new Transformation(new Vector3f(), new Quaternionf(), new Vector3f(1, 1, 1.004f), new Quaternionf()); + + private static RenderTypeGroup getLayerRenderTypes(boolean unlit) { + return new RenderTypeGroup(RenderType.translucent(), unlit ? NeoForgeRenderTypes.ITEM_UNSORTED_UNLIT_TRANSLUCENT.get() : NeoForgeRenderTypes.ITEM_UNSORTED_TRANSLUCENT.get()); + } + + private final Unbaked unbakedModel; + private final BakingContext bakingContext; + private final ItemTransforms itemTransforms; + private final Map cache = new IdentityHashMap<>(); // contains all the baked models since they'll never change + + private DynamicFluidContainerModel(Unbaked unbakedModel, BakingContext bakingContext) { + this.unbakedModel = unbakedModel; + this.bakingContext = bakingContext; + // Source ItemTransforms from the base item model + var baseItemModel = bakingContext.blockModelBaker().getModel(ResourceLocation.withDefaultNamespace("item/generated")); + if (baseItemModel == null) { + throw new IllegalStateException("Failed to access item/generated model"); + } + this.itemTransforms = baseItemModel.getTransforms(); + } + + private ItemModel bakeModelForFluid(Fluid fluid) { + var sprites = bakingContext.blockModelBaker().sprites(); + + Material particleLocation = unbakedModel.textures.particle.map(ClientHooks::getBlockMaterial).orElse(null); + Material baseLocation = unbakedModel.textures.base.map(ClientHooks::getBlockMaterial).orElse(null); + Material fluidMaskLocation = unbakedModel.textures.fluid.map(ClientHooks::getBlockMaterial).orElse(null); + Material coverLocation = unbakedModel.textures.cover.map(ClientHooks::getBlockMaterial).orElse(null); + + TextureAtlasSprite baseSprite = baseLocation != null ? sprites.get(baseLocation) : null; + TextureAtlasSprite fluidSprite = fluid != Fluids.EMPTY ? sprites.get(ClientHooks.getBlockMaterial(IClientFluidTypeExtensions.of(fluid).getStillTexture())) : null; + TextureAtlasSprite coverSprite = (coverLocation != null && (!unbakedModel.coverIsMask || baseLocation != null)) ? sprites.get(coverLocation) : null; + + TextureAtlasSprite particleSprite = particleLocation != null ? sprites.get(particleLocation) : null; + + if (particleSprite == null) particleSprite = fluidSprite; + if (particleSprite == null) particleSprite = baseSprite; + if (particleSprite == null && !unbakedModel.coverIsMask) particleSprite = coverSprite; + + // If the fluid is lighter than air, rotate 180deg to turn it upside down + ModelState state = BlockModelRotation.X0_Y0; + if (unbakedModel.flipGas && fluid != Fluids.EMPTY && fluid.getFluidType().isLighterThanAir()) { + state = new SimpleModelState( + state.getRotation().compose( + new Transformation(null, new Quaternionf(0, 0, 1, 0), null, null))); + } + + // We need to disable GUI 3D and block lighting for this to render properly + var modelBuilder = UnbakedCompositeModel.Baked.builder(true, false, false, particleSprite, itemTransforms); + + var normalRenderTypes = getLayerRenderTypes(false); + + if (baseLocation != null) { + // Base texture + var unbaked = UnbakedElementsHelper.createUnbakedItemElements(0, baseSprite); + var quads = UnbakedElementsHelper.bakeElements(unbaked, $ -> baseSprite, state); + modelBuilder.addQuads(normalRenderTypes, quads); + } + + if (fluidMaskLocation != null && fluidSprite != null) { + TextureAtlasSprite templateSprite = sprites.get(fluidMaskLocation); + // Fluid layer + var transformedState = new SimpleModelState(state.getRotation().compose(FLUID_TRANSFORM), state.isUvLocked()); + var unbaked = UnbakedElementsHelper.createUnbakedItemMaskElements(1, templateSprite); // Use template as mask + var quads = UnbakedElementsHelper.bakeElements(unbaked, $ -> fluidSprite, transformedState); // Bake with fluid texture + + var emissive = unbakedModel.applyFluidLuminosity && fluid.getFluidType().getLightLevel() > 0; + var renderTypes = getLayerRenderTypes(emissive); + if (emissive) QuadTransformers.settingMaxEmissivity().processInPlace(quads); + + modelBuilder.addQuads(renderTypes, quads); + } + + if (coverSprite != null) { + var sprite = unbakedModel.coverIsMask ? baseSprite : coverSprite; + // Cover/overlay + var transformedState = new SimpleModelState(state.getRotation().compose(COVER_TRANSFORM), state.isUvLocked()); + var unbaked = UnbakedElementsHelper.createUnbakedItemMaskElements(2, coverSprite); // Use cover as mask + var quads = UnbakedElementsHelper.bakeElements(unbaked, $ -> sprite, transformedState); // Bake with selected texture + modelBuilder.addQuads(normalRenderTypes, quads); + } + + modelBuilder.setParticle(particleSprite); + + return new BlockModelWrapper(modelBuilder.build(), List.of(new Constant(-1), FluidContentsTint.INSTANCE)); + } + + @Override + public void update(ItemStackRenderState renderState, ItemStack stack, ItemModelResolver modelResolver, ItemDisplayContext displayContext, @Nullable ClientLevel level, @Nullable LivingEntity entity, int p_387820_) { + var fluid = FluidUtil.getFluidContained(stack) + .map(FluidStack::getFluid) + // not a fluid item apparently + .orElse(unbakedModel.fluid); + + cache.computeIfAbsent(fluid, this::bakeModelForFluid) + .update(renderState, stack, modelResolver, displayContext, level, entity, p_387820_); + } + + public record Textures( + Optional particle, + Optional base, + Optional fluid, + Optional cover) { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance + .group( + ResourceLocation.CODEC.optionalFieldOf("particle").forGetter(Textures::particle), + ResourceLocation.CODEC.optionalFieldOf("base").forGetter(Textures::base), + ResourceLocation.CODEC.optionalFieldOf("fluid").forGetter(Textures::fluid), + ResourceLocation.CODEC.optionalFieldOf("cover").forGetter(Textures::cover)) + .apply(instance, Textures::new)) + .validate(textures -> { + if (textures.particle.isPresent() || textures.base.isPresent() || textures.fluid.isPresent() || textures.cover.isPresent()) { + return DataResult.success(textures); + } + return DataResult.error(() -> "Dynamic fluid container model requires at least one particle, base, fluid or cover texture."); + }); + } + + public record Unbaked(Textures textures, Fluid fluid, boolean flipGas, boolean coverIsMask, boolean applyFluidLuminosity) implements ItemModel.Unbaked { + + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec( + instance -> instance + .group( + Textures.CODEC.fieldOf("textures").forGetter(Unbaked::textures), + BuiltInRegistries.FLUID.byNameCodec().fieldOf("fluid").forGetter(Unbaked::fluid), + Codec.BOOL.optionalFieldOf("flip_gas", false).forGetter(Unbaked::flipGas), + Codec.BOOL.optionalFieldOf("cover_is_mask", true).forGetter(Unbaked::coverIsMask), + Codec.BOOL.optionalFieldOf("apply_fluid_luminosity", true).forGetter(Unbaked::applyFluidLuminosity)) + .apply(instance, Unbaked::new)); + @Override + public MapCodec type() { + return MAP_CODEC; + } + + @Override + public ItemModel bake(BakingContext bakingContext) { + return new DynamicFluidContainerModel(this, bakingContext); + } + + @Override + public void resolveDependencies(Resolver resolver) { + //No dependencies + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/model/renderable/package-info.java b/src/main/java/net/neoforged/neoforge/client/model/item/package-info.java similarity index 85% rename from src/main/java/net/neoforged/neoforge/client/model/renderable/package-info.java rename to src/main/java/net/neoforged/neoforge/client/model/item/package-info.java index c5923aab3d..87c7c56dae 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/renderable/package-info.java +++ b/src/main/java/net/neoforged/neoforge/client/model/item/package-info.java @@ -6,7 +6,7 @@ @FieldsAreNonnullByDefault @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -package net.neoforged.neoforge.client.model.renderable; +package net.neoforged.neoforge.client.model.item; import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.FieldsAreNonnullByDefault; diff --git a/src/main/java/net/neoforged/neoforge/client/model/obj/ObjLoader.java b/src/main/java/net/neoforged/neoforge/client/model/obj/ObjLoader.java index 65d2b939e7..0bf9931d93 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/obj/ObjLoader.java +++ b/src/main/java/net/neoforged/neoforge/client/model/obj/ObjLoader.java @@ -7,17 +7,21 @@ import com.google.common.collect.Maps; import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; +import com.mojang.math.Transformation; import java.io.FileNotFoundException; +import java.util.HashMap; import java.util.Map; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManagerReloadListener; import net.minecraft.util.GsonHelper; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; +import net.neoforged.neoforge.client.model.UnbakedModelLoader; /** * A loader for {@link ObjModel OBJ models}. @@ -25,7 +29,7 @@ * Allows the user to enable automatic face culling, toggle quad shading, flip UVs, render emissively and specify a * {@link ObjMaterialLibrary material library} override. */ -public class ObjLoader implements IGeometryLoader, ResourceManagerReloadListener { +public class ObjLoader implements UnbakedModelLoader, ResourceManagerReloadListener { public static ObjLoader INSTANCE = new ObjLoader(); private final Map modelCache = Maps.newConcurrentMap(); @@ -40,7 +44,7 @@ public void onResourceManagerReload(ResourceManager resourceManager) { } @Override - public ObjModel read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) { + public ObjModel read(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { if (!jsonObject.has("model")) throw new JsonParseException("OBJ Loader requires a 'model' key that points to a valid .OBJ model."); @@ -52,7 +56,21 @@ public ObjModel read(JsonObject jsonObject, JsonDeserializationContext deseriali boolean emissiveAmbient = GsonHelper.getAsBoolean(jsonObject, "emissive_ambient", true); String mtlOverride = GsonHelper.getAsString(jsonObject, "mtl_override", null); - return loadModel(new ObjModel.ModelSettings(ResourceLocation.parse(modelLocation), automaticCulling, shadeQuads, flipV, emissiveAmbient, mtlOverride)); + final Map partVisibility = new HashMap<>(); + if (jsonObject.has("visibility")) { + JsonObject visibility = GsonHelper.getAsJsonObject(jsonObject, "visibility"); + for (Map.Entry part : visibility.entrySet()) { + partVisibility.put(part.getKey(), part.getValue().getAsBoolean()); + } + } + + Transformation transformation = Transformation.identity(); + if (jsonObject.has("transform")) { + JsonElement transform = jsonObject.get("transform"); + transformation = BlockModel.GSON.fromJson(transform, Transformation.class); + } + + return loadModel(new ObjModel.ModelSettings(ResourceLocation.parse(modelLocation), automaticCulling, shadeQuads, flipV, emissiveAmbient, mtlOverride, partVisibility, transformation)); } public ObjModel loadModel(ObjModel.ModelSettings settings) { diff --git a/src/main/java/net/neoforged/neoforge/client/model/obj/ObjModel.java b/src/main/java/net/neoforged/neoforge/client/model/obj/ObjModel.java index 25404e5499..98625b04e1 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/obj/ObjModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/obj/ObjModel.java @@ -7,40 +7,33 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import com.mojang.math.Transformation; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; import joptsimple.internal.Strings; +import net.minecraft.client.data.models.model.TextureSlot; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.Material; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; -import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.client.resources.model.SimpleBakedModel; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; +import net.minecraft.util.context.ContextMap; import net.minecraft.world.phys.Vec2; -import net.neoforged.neoforge.client.model.IModelBuilder; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.SimpleUnbakedGeometry; -import net.neoforged.neoforge.client.model.geometry.UnbakedGeometryHelper; +import net.neoforged.neoforge.client.RenderTypeGroup; +import net.neoforged.neoforge.client.model.ExtendedUnbakedModel; +import net.neoforged.neoforge.client.model.NeoForgeModelProperties; import net.neoforged.neoforge.client.model.pipeline.QuadBakingVertexConsumer; -import net.neoforged.neoforge.client.model.renderable.CompositeRenderable; -import net.neoforged.neoforge.client.textures.UnitTextureAtlasSprite; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; @@ -52,7 +45,7 @@ * Supports positions, texture coordinates, normals and colors. The {@link ObjMaterialLibrary material library} * has support for numerous features, including support for {@link ResourceLocation} textures (non-standard). */ -public class ObjModel extends SimpleUnbakedGeometry { +public class ObjModel implements ExtendedUnbakedModel { private static final Vector4f COLOR_WHITE = new Vector4f(1, 1, 1, 1); private static final Vec2[] DEFAULT_COORDS = { new Vec2(0, 0), @@ -62,8 +55,6 @@ public class ObjModel extends SimpleUnbakedGeometry { }; private final Map parts = Maps.newLinkedHashMap(); - private final Set rootComponentNames = Collections.unmodifiableSet(parts.keySet()); - private Set allComponentNames; private final List positions = Lists.newArrayList(); private final List texCoords = Lists.newArrayList(); @@ -78,6 +69,8 @@ public class ObjModel extends SimpleUnbakedGeometry { public final String mtlOverride; public final ResourceLocation modelLocation; + public final Map partVisibility; + public final Transformation rootTransform; private ObjModel(ModelSettings settings) { this.modelLocation = settings.modelLocation; @@ -86,6 +79,8 @@ private ObjModel(ModelSettings settings) { this.flipV = settings.flipV; this.emissiveAmbient = settings.emissiveAmbient; this.mtlOverride = settings.mtlOverride; + this.partVisibility = settings.partVisibility; + this.rootTransform = settings.rootTransform; } public static ObjModel parse(ObjTokenizer tokenizer, ModelSettings settings) throws IOException { @@ -292,26 +287,6 @@ static Vector4f parseVector4(String[] line) { }; } - @Override - protected void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuilder, ModelBaker baker, Function spriteGetter, ModelState modelTransform) { - parts.values().stream().filter(part -> owner.isComponentVisible(part.name(), true)) - .forEach(part -> part.addQuads(owner, modelBuilder, baker, spriteGetter, modelTransform)); - } - - public Set getRootComponentNames() { - return rootComponentNames; - } - - @Override - public Set getConfigurableComponentNames() { - if (allComponentNames != null) - return allComponentNames; - var names = new HashSet(); - for (var group : parts.values()) - group.addNamesRecursively(names); - return allComponentNames = Collections.unmodifiableSet(names); - } - private Pair makeQuad(int[][] indices, int tintIndex, Vector4f colorTint, Vector4f ambientColor, TextureAtlasSprite texture, Transformation transform) { boolean needsNormalRecalculation = false; for (int[] ints : indices) { @@ -433,16 +408,22 @@ private Pair makeQuad(int[][] indices, int tintIndex, Vect return Pair.of(quadBaker.bakeQuad(), cull); } - public CompositeRenderable bakeRenderable(IGeometryBakingContext configuration) { - var builder = CompositeRenderable.builder(); + public boolean isComponentVisible(String part, boolean fallback) { + return partVisibility.getOrDefault(part, fallback); + } - for (var entry : parts.entrySet()) { - var name = entry.getKey(); - var part = entry.getValue(); - part.bake(builder.child(name), configuration); - } + @Override + public BakedModel bake(TextureSlots slots, ModelBaker baker, ModelState state, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms transforms, ContextMap additionalProperties) { + var builder = new SimpleBakedModel.Builder(useAmbientOcclusion, usesBlockLight, true, transforms); + builder.particle(baker.findSprite(slots, TextureSlot.PARTICLE.getId())); + parts.values().stream().filter(part -> isComponentVisible(part.name(), true)) + .forEach(part -> part.addQuads(builder, slots, baker, state, useAmbientOcclusion, usesBlockLight, transforms)); + return builder.build(additionalProperties.getOrDefault(NeoForgeModelProperties.RENDER_TYPE, RenderTypeGroup.EMPTY)); + } - return builder.get(); + @Override + public void resolveDependencies(Resolver resolver) { + // no dependencies } public class ModelObject { @@ -458,26 +439,12 @@ public String name() { return name; } - public void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuilder, ModelBaker baker, Function spriteGetter, ModelState modelTransform) { + public void addQuads(SimpleBakedModel.Builder builder, TextureSlots slots, ModelBaker baker, ModelState state, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms transforms) { for (ModelMesh mesh : meshes) { - mesh.addQuads(owner, modelBuilder, spriteGetter, modelTransform); + mesh.addQuads(builder, slots, baker, state, useAmbientOcclusion, usesBlockLight, transforms); } } - public void bake(CompositeRenderable.PartBuilder builder, IGeometryBakingContext configuration) { - for (ModelMesh mesh : this.meshes) { - mesh.bake(builder, configuration); - } - } - - public Collection getTextures(IGeometryBakingContext owner, Function modelGetter, Set> missingTextureErrors) { - return meshes.stream() - .flatMap(mesh -> mesh.mat != null - ? Stream.of(UnbakedGeometryHelper.resolveDirtyMaterial(mesh.mat.diffuseColorMap, owner)) - : Stream.of()) - .collect(Collectors.toSet()); - } - protected void addNamesRecursively(Set names) { names.add(name()); } @@ -491,31 +458,11 @@ public class ModelGroup extends ModelObject { } @Override - public void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuilder, ModelBaker baker, Function spriteGetter, ModelState modelTransform) { - super.addQuads(owner, modelBuilder, baker, spriteGetter, modelTransform); + public void addQuads(SimpleBakedModel.Builder builder, TextureSlots slots, ModelBaker baker, ModelState state, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms transforms) { + super.addQuads(builder, slots, baker, state, useAmbientOcclusion, usesBlockLight, transforms); - parts.values().stream().filter(part -> owner.isComponentVisible(part.name(), true)) - .forEach(part -> part.addQuads(owner, modelBuilder, baker, spriteGetter, modelTransform)); - } - - @Override - public void bake(CompositeRenderable.PartBuilder builder, IGeometryBakingContext configuration) { - super.bake(builder, configuration); - - for (var entry : parts.entrySet()) { - var name = entry.getKey(); - var part = entry.getValue(); - part.bake(builder.child(name), configuration); - } - } - - @Override - public Collection getTextures(IGeometryBakingContext owner, Function modelGetter, Set> missingTextureErrors) { - Set combined = Sets.newHashSet(); - combined.addAll(super.getTextures(owner, modelGetter, missingTextureErrors)); - for (ModelObject part : parts.values()) - combined.addAll(part.getTextures(owner, modelGetter, missingTextureErrors)); - return combined; + parts.values().stream().filter(part -> isComponentVisible("%s.%s".formatted(name(), part.name()), true)) + .forEach(part -> part.addQuads(builder, slots, baker, state, useAmbientOcclusion, usesBlockLight, transforms)); } @Override @@ -538,46 +485,27 @@ public ModelMesh(@Nullable ObjMaterialLibrary.Material currentMat, @Nullable Str this.smoothingGroup = currentSmoothingGroup; } - public void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuilder, Function spriteGetter, ModelState modelTransform) { + public void addQuads(SimpleBakedModel.Builder builder, TextureSlots slots, ModelBaker baker, ModelState state, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms transforms) { if (mat == null) return; - TextureAtlasSprite texture = spriteGetter.apply(UnbakedGeometryHelper.resolveDirtyMaterial(mat.diffuseColorMap, owner)); + TextureAtlasSprite texture = baker.findSprite(slots, mat.diffuseColorMap); int tintIndex = mat.diffuseTintIndex; Vector4f colorTint = mat.diffuseColor; - var rootTransform = owner.getRootTransform(); - var transform = rootTransform.isIdentity() ? modelTransform.getRotation() : modelTransform.getRotation().compose(rootTransform); + var rootTransform = ObjModel.this.rootTransform; + var transform = rootTransform.isIdentity() ? state.getRotation() : state.getRotation().compose(rootTransform); for (int[][] face : faces) { Pair quad = makeQuad(face, tintIndex, colorTint, mat.ambientColor, texture, transform); if (quad.getRight() == null) - modelBuilder.addUnculledFace(quad.getLeft()); + builder.addUnculledFace(quad.getLeft()); else - modelBuilder.addCulledFace(quad.getRight(), quad.getLeft()); - } - } - - public void bake(CompositeRenderable.PartBuilder builder, IGeometryBakingContext configuration) { - ObjMaterialLibrary.Material mat = this.mat; - if (mat == null) - return; - int tintIndex = mat.diffuseTintIndex; - Vector4f colorTint = mat.diffuseColor; - - final List quads = new ArrayList<>(); - - for (var face : this.faces) { - var pair = makeQuad(face, tintIndex, colorTint, mat.ambientColor, UnitTextureAtlasSprite.INSTANCE, Transformation.identity()); - quads.add(pair.getLeft()); + builder.addCulledFace(quad.getRight(), quad.getLeft()); } - - ResourceLocation textureLocation = UnbakedGeometryHelper.resolveDirtyMaterial(mat.diffuseColorMap, configuration).texture(); - ResourceLocation texturePath = ResourceLocation.fromNamespaceAndPath(textureLocation.getNamespace(), "textures/" + textureLocation.getPath() + ".png"); - - builder.addMesh(texturePath, quads); } } public record ModelSettings(ResourceLocation modelLocation, boolean automaticCulling, boolean shadeQuads, boolean flipV, - boolean emissiveAmbient, @Nullable String mtlOverride) {} + boolean emissiveAmbient, @Nullable String mtlOverride, + Map partVisibility, Transformation rootTransform) {} } diff --git a/src/main/java/net/neoforged/neoforge/client/model/renderable/BakedModelRenderable.java b/src/main/java/net/neoforged/neoforge/client/model/renderable/BakedModelRenderable.java deleted file mode 100644 index ec17ba246e..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/renderable/BakedModelRenderable.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.renderable; - -import com.mojang.blaze3d.vertex.PoseStack; -import java.util.Arrays; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.core.Direction; -import net.minecraft.util.RandomSource; -import net.minecraft.util.Unit; -import net.minecraft.world.inventory.InventoryMenu; -import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.client.event.ModelEvent; -import net.neoforged.neoforge.client.model.data.ModelData; -import org.jetbrains.annotations.Nullable; -import org.joml.Vector4f; - -/** - * {@linkplain IRenderable Renderable} wrapper for {@linkplain BakedModel baked models}. - *

    - * The context can provide the {@link BlockState}, faces to be rendered, a {@link RandomSource} and seed, - * a {@link ModelData} instance, and a {@link Vector4f tint}. - * - * @see Context - */ -public class BakedModelRenderable implements IRenderable { - /** - * Constructs a {@link BakedModelRenderable} from the given model location. - * The model is expected to have been baked ahead of time. - * - * @see ModelEvent.RegisterAdditional - */ - public static BakedModelRenderable of(ModelResourceLocation model) { - return of(Minecraft.getInstance().getModelManager().getModel(model)); - } - - /** - * Constructs a {@link BakedModelRenderable} from the given baked model. - */ - public static BakedModelRenderable of(BakedModel model) { - return new BakedModelRenderable(model); - } - - private final BakedModel model; - - private BakedModelRenderable(BakedModel model) { - this.model = model; - } - - @Override - public void render(PoseStack poseStack, MultiBufferSource bufferSource, ITextureRenderTypeLookup textureRenderTypeLookup, int lightmap, int overlay, float partialTick, Context context) { - var buffer = bufferSource.getBuffer(textureRenderTypeLookup.get(InventoryMenu.BLOCK_ATLAS)); - var tint = context.tint(); - var randomSource = context.randomSource(); - for (Direction direction : context.faces()) { - randomSource.setSeed(context.seed()); - // Given the lack of context, the requested render type has to be null to ensure the model renders all of its geometry - for (BakedQuad quad : model.getQuads(context.state(), direction, randomSource, context.data(), null)) - buffer.putBulkData(poseStack.last(), quad, tint.x(), tint.y(), tint.z(), tint.w(), lightmap, overlay, true); - } - } - - public IRenderable withContext(ModelData modelData) { - return withContext(new Context(modelData)); - } - - public IRenderable withModelDataContext() { - return (poseStack, bufferSource, textureRenderTypeLookup, lightmap, overlay, partialTick, context) -> render(poseStack, bufferSource, textureRenderTypeLookup, lightmap, overlay, partialTick, new Context(context)); - } - - public record Context(@Nullable BlockState state, Direction[] faces, RandomSource randomSource, long seed, ModelData data, Vector4f tint) { - - private static final Direction[] ALL_FACES_AND_NULL = Arrays.copyOf(Direction.values(), Direction.values().length + 1); - private static final Vector4f WHITE = new Vector4f(1, 1, 1, 1); - public Context(ModelData data) { - this(null, ALL_FACES_AND_NULL, RandomSource.create(), 42, data, WHITE); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/renderable/CompositeRenderable.java b/src/main/java/net/neoforged/neoforge/client/model/renderable/CompositeRenderable.java deleted file mode 100644 index d4fec4b841..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/renderable/CompositeRenderable.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.renderable; - -import com.google.common.collect.ImmutableMap; -import com.mojang.blaze3d.vertex.PoseStack; -import java.util.ArrayList; -import java.util.List; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix4f; - -/** - * A renderable object composed of a hierarchy of parts, each made up of a number of meshes. - *

    - * Each mesh renders a set of quads using a different texture. - * - * @see Builder - */ -public class CompositeRenderable implements IRenderable { - private final List components = new ArrayList<>(); - - private CompositeRenderable() {} - - @Override - public void render(PoseStack poseStack, MultiBufferSource bufferSource, ITextureRenderTypeLookup textureRenderTypeLookup, int lightmap, int overlay, float partialTick, Transforms context) { - for (var component : components) - component.render(poseStack, bufferSource, textureRenderTypeLookup, lightmap, overlay, context); - } - - public static Builder builder() { - return new Builder(); - } - - private static class Component { - private final String name; - private final List children = new ArrayList<>(); - private final List meshes = new ArrayList<>(); - - public Component(String name) { - this.name = name; - } - - public void render(PoseStack poseStack, MultiBufferSource bufferSource, ITextureRenderTypeLookup textureRenderTypeLookup, int lightmap, int overlay, Transforms context) { - Matrix4f matrix = context.getTransform(name); - if (matrix != null) { - poseStack.pushPose(); - poseStack.mulPose(matrix); - } - - for (var part : children) - part.render(poseStack, bufferSource, textureRenderTypeLookup, lightmap, overlay, context); - - for (var mesh : meshes) - mesh.render(poseStack, bufferSource, textureRenderTypeLookup, lightmap, overlay); - - if (matrix != null) - poseStack.popPose(); - } - } - - private static class Mesh { - private final ResourceLocation texture; - private final List quads = new ArrayList<>(); - - public Mesh(ResourceLocation texture) { - this.texture = texture; - } - - public void render(PoseStack poseStack, MultiBufferSource bufferSource, ITextureRenderTypeLookup textureRenderTypeLookup, int lightmap, int overlay) { - var consumer = bufferSource.getBuffer(textureRenderTypeLookup.get(texture)); - for (var quad : quads) { - consumer.putBulkData(poseStack.last(), quad, 1, 1, 1, 1, lightmap, overlay, true); - } - } - } - - public static class Builder { - private final CompositeRenderable renderable = new CompositeRenderable(); - - private Builder() {} - - public PartBuilder child(String name) { - var child = new Component(name); - renderable.components.add(child); - return new PartBuilder<>(this, child); - } - - public CompositeRenderable get() { - return renderable; - } - } - - public static class PartBuilder { - private final T parent; - private final Component component; - - private PartBuilder(T parent, Component component) { - this.parent = parent; - this.component = component; - } - - public PartBuilder> child(String name) { - var child = new Component(component.name + "/" + name); - this.component.children.add(child); - return new PartBuilder<>(this, child); - } - - public PartBuilder addMesh(ResourceLocation texture, List quads) { - var mesh = new Mesh(texture); - mesh.quads.addAll(quads); - component.meshes.add(mesh); - return this; - } - - public T end() { - return parent; - } - } - - /** - * A context value that provides {@link Matrix4f} transforms for certain parts of the model. - */ - public static class Transforms { - /** - * A default instance that has no transforms specified. - */ - public static final Transforms EMPTY = new Transforms(ImmutableMap.of()); - - /** - * Builds a MultipartTransforms object with the given mapping. - */ - public static Transforms of(ImmutableMap parts) { - return new Transforms(parts); - } - - private final ImmutableMap parts; - - private Transforms(ImmutableMap parts) { - this.parts = parts; - } - - @Nullable - public Matrix4f getTransform(String part) { - return parts.get(part); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/renderable/IRenderable.java b/src/main/java/net/neoforged/neoforge/client/model/renderable/IRenderable.java deleted file mode 100644 index 3a55eb3e46..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/renderable/IRenderable.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.renderable; - -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.util.Unit; - -/** - * A standard interface for things that can be rendered to a {@link MultiBufferSource}. - * - * @param The type of context object used by the rendering logic - */ -@FunctionalInterface -public interface IRenderable { - /** - * Draws the renderable by adding the geometry to the provided {@link MultiBufferSource} - * - * @param poseStack The pose stack - * @param bufferSource The buffer source where the vertex data should be output - * @param textureRenderTypeLookup A function that provides a RenderType for the given texture - * @param lightmap The lightmap coordinates representing the current lighting conditions. See {@link net.minecraft.client.renderer.LightTexture} - * @param overlay The overlay coordinates representing the current overlay status. See {@link net.minecraft.client.renderer.texture.OverlayTexture} - * @param partialTick The current time expressed in the fraction of a tick elapsed since the last client tick - * @param context The context used for rendering - */ - void render(PoseStack poseStack, MultiBufferSource bufferSource, ITextureRenderTypeLookup textureRenderTypeLookup, int lightmap, int overlay, float partialTick, T context); - - /** - * Wraps the current renderable along with a context. - * Useful for keeping a list of various renderables paired with their contexts. - * - * @param context The context used for rendering - * @return A renderable that accepts {@link Unit#INSTANCE} as context, but uses the provided {@code context} instead - */ - default IRenderable withContext(T context) { - return (poseStack, bufferSource, textureRenderTypeLookup, lightmap, overlay, partialTick, unused) -> this.render(poseStack, bufferSource, textureRenderTypeLookup, lightmap, overlay, partialTick, context); - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/renderable/ITextureRenderTypeLookup.java b/src/main/java/net/neoforged/neoforge/client/model/renderable/ITextureRenderTypeLookup.java deleted file mode 100644 index 8c05205fdd..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/renderable/ITextureRenderTypeLookup.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model.renderable; - -import net.minecraft.client.renderer.RenderType; -import net.minecraft.resources.ResourceLocation; - -/** - * A generic lookup for {@link RenderType} implementations that use the specified texture. - */ -@FunctionalInterface -public interface ITextureRenderTypeLookup { - RenderType get(ResourceLocation name); -} diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index d81c78914c..f99ab9d2d1 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -952,7 +952,7 @@ public static ItemStack getProjectile(LivingEntity entity, ItemStack projectileW * Used as the default implementation of {@link Item#getCreatorModId}. Call that method instead. */ @Nullable - public static String getDefaultCreatorModId(ItemStack itemStack) { + public static String getDefaultCreatorModId(HolderLookup.Provider registries, ItemStack itemStack) { Item item = itemStack.getItem(); ResourceLocation registryName = BuiltInRegistries.ITEM.getKey(item); String modId = registryName == null ? null : registryName.getNamespace(); @@ -974,7 +974,7 @@ public static String getDefaultCreatorModId(ItemStack itemStack) { return key.get().location().getNamespace(); } } else if (item instanceof SpawnEggItem spawnEggItem) { - Optional>> key = BuiltInRegistries.ENTITY_TYPE.getResourceKey(spawnEggItem.getType(itemStack)); + Optional>> key = BuiltInRegistries.ENTITY_TYPE.getResourceKey(spawnEggItem.getType(registries, itemStack)); if (key.isPresent()) { return key.get().location().getNamespace(); } diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index 0e22d8d00d..168192189a 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -11,7 +11,6 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.EnumSet; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.function.Function; @@ -27,16 +26,11 @@ import net.minecraft.core.RegistryCodecs; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.registries.Registries; -import net.minecraft.data.metadata.PackMetadataGenerator; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.packs.PackType; -import net.minecraft.server.packs.metadata.pack.PackMetadataSection; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; -import net.minecraft.util.InclusiveRange; import net.minecraft.world.damagesource.DamageSources; import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.effect.MobEffects; @@ -102,22 +96,6 @@ import net.neoforged.neoforge.common.crafting.DifferenceIngredient; import net.neoforged.neoforge.common.crafting.IngredientType; import net.neoforged.neoforge.common.crafting.IntersectionIngredient; -import net.neoforged.neoforge.common.data.internal.NeoForgeAdvancementProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeBiomeTagsProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeBlockTagsProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeDamageTypeTagsProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeDataMapsProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeEnchantmentTagsProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeEntityTypeTagsProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeFluidTagsProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeItemTagsProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeLanguageProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeLootTableProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeRecipeProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeRegistryOrderReportProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeSpriteSourceProvider; -import net.neoforged.neoforge.common.data.internal.NeoForgeStructureTagsProvider; -import net.neoforged.neoforge.common.data.internal.VanillaSoundDefinitionsProvider; import net.neoforged.neoforge.common.extensions.IPlayerExtension; import net.neoforged.neoforge.common.loot.AddTableLootModifier; import net.neoforged.neoforge.common.loot.CanItemPerformAbility; @@ -134,7 +112,6 @@ import net.neoforged.neoforge.common.world.NoneStructureModifier; import net.neoforged.neoforge.common.world.StructureModifier; import net.neoforged.neoforge.common.world.StructureModifiers; -import net.neoforged.neoforge.data.event.GatherDataEvent; import net.neoforged.neoforge.event.server.ServerStoppingEvent; import net.neoforged.neoforge.fluids.BaseFlowingFluid; import net.neoforged.neoforge.fluids.CauldronFluidContent; @@ -545,7 +522,6 @@ public NeoForgeMod(IEventBus modEventBus, Dist dist, ModContainer container) { event.dataPackRegistry(NeoForgeRegistries.Keys.STRUCTURE_MODIFIERS, StructureModifier.DIRECT_CODEC); }); modEventBus.addListener(this::preInit); - modEventBus.addListener(this::gatherData); modEventBus.addListener(this::loadComplete); modEventBus.addListener(this::registerFluids); modEventBus.addListener(this::registerLootData); @@ -614,34 +590,6 @@ public void serverStopping(ServerStoppingEvent evt) { }); } - public void gatherData(GatherDataEvent event) { - var includeServer = event.includeServer(); - var includeClient = event.includeClient(); - - event.createProvider(true, output -> new PackMetadataGenerator(output) - .add(PackMetadataSection.TYPE, new PackMetadataSection( - Component.translatable("pack.neoforge.description"), - DetectedVersion.BUILT_IN.getPackVersion(PackType.SERVER_DATA), - Optional.of(new InclusiveRange<>(0, Integer.MAX_VALUE))))); - - event.createProvider(includeServer, NeoForgeAdvancementProvider::new); - event.createBlockAndItemTags(NeoForgeBlockTagsProvider::new, NeoForgeItemTagsProvider::new); - event.createProvider(includeServer, NeoForgeEntityTypeTagsProvider::new); - event.createProvider(includeServer, NeoForgeFluidTagsProvider::new); - event.createProvider(includeServer, NeoForgeEnchantmentTagsProvider::new); - event.createProvider(includeServer, NeoForgeRecipeProvider.Runner::new); - event.createProvider(includeServer, NeoForgeLootTableProvider::new); - event.createProvider(includeServer, NeoForgeBiomeTagsProvider::new); - event.createProvider(includeServer, NeoForgeStructureTagsProvider::new); - event.createProvider(includeServer, NeoForgeDamageTypeTagsProvider::new); - event.createProvider(includeServer, NeoForgeRegistryOrderReportProvider::new); - event.createProvider(includeServer, NeoForgeDataMapsProvider::new); - - event.createProvider(includeClient, NeoForgeSpriteSourceProvider::new); - event.createProvider(includeClient, VanillaSoundDefinitionsProvider::new); - event.createProvider(includeClient, NeoForgeLanguageProvider::new); - } - // done in an event instead of deferred to only enable if a mod requests it public void registerFluids(RegisterEvent event) { if (enableMilkFluid) { diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/CompoundIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/CompoundIngredient.java index f703027003..ab4cf41c93 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/CompoundIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/CompoundIngredient.java @@ -37,7 +37,7 @@ public static Ingredient of(Ingredient... children) { @Override public Stream> items() { - return children.stream().flatMap(child -> child.items().stream()); + return children.stream().flatMap(Ingredient::items); } @Override diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/CustomDisplayIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/CustomDisplayIngredient.java index 2c88c2fa13..12ce024b1a 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/CustomDisplayIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/CustomDisplayIngredient.java @@ -37,7 +37,7 @@ public boolean test(ItemStack stack) { @Override public Stream> items() { - return base.items().stream(); + return base.items(); } @Override diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/DifferenceIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/DifferenceIngredient.java index 3ce8c7d3c5..8e7e3ec2ce 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/DifferenceIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/DifferenceIngredient.java @@ -25,7 +25,7 @@ public record DifferenceIngredient(Ingredient base, Ingredient subtracted) imple @Override public Stream> items() { - return base.items().stream().filter(i -> !subtracted.test(i.value().getDefaultInstance())); + return base.items().filter(i -> !subtracted.test(i.value().getDefaultInstance())); } @Override diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/IntersectionIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/IntersectionIngredient.java index b41dc85070..d726e710c7 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/IntersectionIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/IntersectionIngredient.java @@ -56,7 +56,7 @@ public boolean test(ItemStack stack) { @Override public Stream> items() { return children.stream() - .flatMap(child -> child.items().stream()) + .flatMap(child -> child.items()) .filter(i -> test(i.value().getDefaultInstance())); } diff --git a/src/main/java/net/neoforged/neoforge/common/data/GeneratingOverlayMetadataSection.java b/src/main/java/net/neoforged/neoforge/common/data/GeneratingOverlayMetadataSection.java index 431fdb4a1f..1b401583e0 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/GeneratingOverlayMetadataSection.java +++ b/src/main/java/net/neoforged/neoforge/common/data/GeneratingOverlayMetadataSection.java @@ -22,6 +22,6 @@ public record GeneratingOverlayMetadataSection(List TYPE = MetadataSectionType.fromCodec("overlays", CODEC); - public static final MetadataSectionType NEOFORGE_TYPE = MetadataSectionType.fromCodec("neoforge:overlays", CODEC); + public static final MetadataSectionType TYPE = new MetadataSectionType<>("overlays", CODEC); + public static final MetadataSectionType NEOFORGE_TYPE = new MetadataSectionType<>("neoforge:overlays", CODEC); } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java index f20dcdec2f..6640d90439 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java @@ -73,7 +73,6 @@ import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.pathfinder.PathType; import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; -import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.neoforged.fml.loading.FMLEnvironment; import net.neoforged.neoforge.capabilities.BlockCapabilityCache; @@ -324,14 +323,12 @@ default float getExplosionResistance(BlockState state, BlockGetter level, BlockP } /** - * * Called when A user uses the creative pick block button on this block * - * @param target The full target the player is looking at * @return A ItemStack to add to the player's inventory, empty itemstack if nothing should be added. */ - default ItemStack getCloneItemStack(BlockState state, HitResult target, LevelReader level, BlockPos pos, Player player) { - return self().getCloneItemStack(level, pos, state); + default ItemStack getCloneItemStack(LevelReader level, BlockPos pos, BlockState state, boolean includeData, Player player) { + return state.getCloneItemStack(level, pos, includeData); } /** diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockStateExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockStateExtension.java index ce05f6783f..8402500f21 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockStateExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockStateExtension.java @@ -39,7 +39,6 @@ import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.pathfinder.PathType; -import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.capabilities.BlockCapabilityCache; import net.neoforged.neoforge.common.ItemAbilities; @@ -223,11 +222,10 @@ default float getExplosionResistance(BlockGetter level, BlockPos pos, Explosion * * Called when A user uses the creative pick block button on this block * - * @param target The full target the player is looking at * @return A ItemStack to add to the player's inventory, empty itemstack if nothing should be added. */ - default ItemStack getCloneItemStack(HitResult target, LevelReader level, BlockPos pos, Player player) { - return self().getBlock().getCloneItemStack(self(), target, level, pos, player); + default ItemStack getCloneItemStack(BlockPos pos, LevelReader level, boolean includeData, Player player) { + return self().getBlock().getCloneItemStack(level, pos, self(), includeData, player); } /** diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java index 3b495ea523..ba45404353 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java @@ -20,11 +20,9 @@ import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.phys.HitResult; import net.neoforged.neoforge.attachment.AttachmentInternals; import net.neoforged.neoforge.attachment.AttachmentType; import net.neoforged.neoforge.common.SoundAction; @@ -89,17 +87,6 @@ default boolean shouldRiderSit() { return true; } - /** - * Called when a user uses the creative pick block button on this entity. - * - * @param target The full target the player is looking at - * @return A ItemStack to add to the player's inventory, null ItemStack if nothing should be added. - */ - @Nullable - default ItemStack getPickedResult(HitResult target) { - return self().getPickResult(); - } - /** * If a rider of this entity can interact with this entity. Should return true on the * ridden entity if so. diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java index ab5cc0f8e1..662f816944 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java @@ -13,13 +13,13 @@ import java.util.function.Consumer; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup.RegistryLookup; import net.minecraft.core.HolderSet; import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.ItemTags; import net.minecraft.util.Mth; @@ -48,7 +48,6 @@ import net.minecraft.world.item.enchantment.Enchantment.EnchantmentDefinition; import net.minecraft.world.item.enchantment.EnchantmentInstance; import net.minecraft.world.item.enchantment.ItemEnchantments; -import net.minecraft.world.item.equipment.EquipmentModel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.FuelValues; import net.minecraft.world.phys.AABB; @@ -296,24 +295,6 @@ default boolean isBookEnchantable(ItemStack stack, ItemStack book) { return true; } - /** - * Called by RenderBiped and RenderPlayer to determine the armor texture that - * should be used for the currently equipped item. This will be called on - * stacks with the {@link DataComponents#EQUIPPABLE} component. - * - * Returning null from this function will use the default value. - * - * @param stack ItemStack for the equipped armor - * @param type The layer type of the armor - * @param layer The armor layer - * @param _default The default texture determined by the equipment renderer - * @return Path of texture to bind, or null to use default - */ - @Nullable - default ResourceLocation getArmorTexture(ItemStack stack, EquipmentModel.LayerType type, EquipmentModel.Layer layer, ResourceLocation _default) { - return null; - } - /** * Called when a entity tries to play the 'swing' animation. * @@ -550,8 +531,8 @@ default boolean canContinueUsing(ItemStack oldStack, ItemStack newStack) { * associated mod and {@link net.minecraft.core.Registry#getKey(Object)} would return null. */ @Nullable - default String getCreatorModId(ItemStack itemStack) { - return CommonHooks.getDefaultCreatorModId(itemStack); + default String getCreatorModId(HolderLookup.Provider registries, ItemStack itemStack) { + return CommonHooks.getDefaultCreatorModId(registries, itemStack); } /** diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/ILevelExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/ILevelExtension.java index b85347746a..1b84f151de 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/ILevelExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/ILevelExtension.java @@ -5,8 +5,6 @@ package net.neoforged.neoforge.common.extensions; -import java.util.Collection; -import java.util.Collections; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; @@ -16,7 +14,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.capabilities.BlockCapability; import net.neoforged.neoforge.client.model.data.ModelDataManager; -import net.neoforged.neoforge.entity.PartEntity; import org.jetbrains.annotations.Nullable; public interface ILevelExtension { @@ -49,14 +46,6 @@ private Level self() { */ public double increaseMaxEntityRadius(double value); - /** - * All part entities in this world. Used when collecting entities in an AABB to fix parts being - * ignored whose parent entity is in a chunk that does not intersect with the AABB. - */ - public default Collection> getPartEntities() { - return Collections.emptyList(); - } - /** * Retrieves the model data manager for the given level. May be null on a server level. * diff --git a/src/main/java/net/neoforged/neoforge/common/loot/LootModifierManager.java b/src/main/java/net/neoforged/neoforge/common/loot/LootModifierManager.java index c7a060cf2e..f75bb6ea72 100644 --- a/src/main/java/net/neoforged/neoforge/common/loot/LootModifierManager.java +++ b/src/main/java/net/neoforged/neoforge/common/loot/LootModifierManager.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; import java.util.function.Function; +import net.minecraft.resources.FileToIdConverter; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; @@ -39,7 +40,7 @@ public class LootModifierManager extends SimpleJsonResourceReloadListener getAmbientAdditionsSound() { return this.ambientAdditionsSettings; } - public Optional getBackgroundMusic() { + public Optional> getBackgroundMusic() { return this.backgroundMusic; } } diff --git a/src/main/java/net/neoforged/neoforge/data/event/GatherDataEvent.java b/src/main/java/net/neoforged/neoforge/data/event/GatherDataEvent.java index af96f7a86c..f35bb1768a 100644 --- a/src/main/java/net/neoforged/neoforge/data/event/GatherDataEvent.java +++ b/src/main/java/net/neoforged/neoforge/data/event/GatherDataEvent.java @@ -25,13 +25,12 @@ import net.minecraft.data.tags.TagsProvider; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; -import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.Event; import net.neoforged.fml.ModContainer; import net.neoforged.fml.event.IModBusEvent; import net.neoforged.neoforge.common.data.ExistingFileHelper; -public class GatherDataEvent extends Event implements IModBusEvent { +public abstract class GatherDataEvent extends Event implements IModBusEvent { private final DataGenerator dataGenerator; private final DataGeneratorConfig config; private final ExistingFileHelper existingFileHelper; @@ -64,14 +63,6 @@ public CompletableFuture getLookupProvider() { return this.config.lookupProvider; } - public boolean includeServer() { - return this.config.server; - } - - public boolean includeClient() { - return this.config.client; - } - public boolean includeDev() { return this.config.dev; } @@ -84,13 +75,23 @@ public boolean validate() { return this.config.validate; } + public static class Server extends GatherDataEvent { + public Server(ModContainer mc, DataGenerator dataGenerator, DataGeneratorConfig dataGeneratorConfig, ExistingFileHelper existingFileHelper) { + super(mc, dataGenerator, dataGeneratorConfig, existingFileHelper); + } + } + + public static class Client extends GatherDataEvent { + public Client(ModContainer mc, DataGenerator dataGenerator, DataGeneratorConfig dataGeneratorConfig, ExistingFileHelper existingFileHelper) { + super(mc, dataGenerator, dataGeneratorConfig, existingFileHelper); + } + } + public static class DataGeneratorConfig { private final Set mods; private final Path path; private final Collection inputs; private final CompletableFuture lookupProvider; - private final boolean server; - private final boolean client; private final boolean dev; private final boolean reports; private final boolean validate; @@ -98,17 +99,18 @@ public static class DataGeneratorConfig { private final List generators = new ArrayList<>(); public DataGeneratorConfig(final Set mods, final Path path, final Collection inputs, final CompletableFuture lookupProvider, - final boolean server, final boolean client, final boolean dev, final boolean reports, final boolean validate, final boolean flat) { + final boolean dev, final boolean reports, final boolean validate, final boolean flat, final DataGenerator vanillaGenerator) { this.mods = mods; this.path = path; this.inputs = inputs; this.lookupProvider = lookupProvider; - this.server = server; - this.client = client; this.dev = dev; this.reports = reports; this.validate = validate; this.flat = flat; + if (mods.contains("minecraft") || mods.isEmpty()) { + this.generators.add(vanillaGenerator); + } } public Collection getInputs() { @@ -146,36 +148,29 @@ public void runAll() { } } - public boolean shouldRun(Dist dist) { - return switch (dist) { - case CLIENT -> includeClient(); - case DEDICATED_SERVER -> includeServer(); - }; - } - - public T addProvider(boolean run, T provider) { - return dataGenerator.addProvider(run, provider); + public T addProvider(T provider) { + return dataGenerator.addProvider(true, provider); } - public T createProvider(boolean run, DataProviderFromOutput builder) { - return addProvider(run, builder.create(dataGenerator.getPackOutput())); + public T createProvider(DataProviderFromOutput builder) { + return addProvider(builder.create(dataGenerator.getPackOutput())); } - public T createProvider(boolean run, DataProviderFromOutputFileHelper builder) { - return addProvider(run, builder.create(dataGenerator.getPackOutput(), existingFileHelper)); + public T createProvider(DataProviderFromOutputFileHelper builder) { + return addProvider(builder.create(dataGenerator.getPackOutput(), existingFileHelper)); } - public T createProvider(boolean run, DataProviderFromOutputLookup builder) { - return addProvider(run, builder.create(dataGenerator.getPackOutput(), config.lookupProvider)); + public T createProvider(DataProviderFromOutputLookup builder) { + return addProvider(builder.create(dataGenerator.getPackOutput(), config.lookupProvider)); } - public T createProvider(boolean run, DataProviderFromOutputLookupFileHelper builder) { - return addProvider(run, builder.create(dataGenerator.getPackOutput(), config.lookupProvider, existingFileHelper)); + public T createProvider(DataProviderFromOutputLookupFileHelper builder) { + return addProvider(builder.create(dataGenerator.getPackOutput(), config.lookupProvider, existingFileHelper)); } public void createBlockAndItemTags(DataProviderFromOutputLookupFileHelper> blockTagsProvider, ItemTagsProvider itemTagsProvider) { - var blockTags = createProvider(includeServer(), blockTagsProvider); - addProvider(includeServer(), itemTagsProvider.create(dataGenerator.getPackOutput(), config.lookupProvider, blockTags.contentsGetter(), existingFileHelper)); + var blockTags = createProvider(blockTagsProvider); + addProvider(itemTagsProvider.create(this.getGenerator().getPackOutput(), this.getLookupProvider(), blockTags.contentsGetter(), this.getExistingFileHelper())); } @FunctionalInterface @@ -198,6 +193,11 @@ public interface DataProviderFromOutputLookupFileHelper T create(PackOutput output, CompletableFuture lookupProvider, ExistingFileHelper existingFileHelper); } + @FunctionalInterface + public interface GatherDataEventGenerator { + GatherDataEvent create(final ModContainer mc, final DataGenerator dataGenerator, final DataGeneratorConfig dataGeneratorConfig, ExistingFileHelper existingFileHelper); + } + @FunctionalInterface public interface ItemTagsProvider { TagsProvider create(PackOutput output, CompletableFuture lookupProvider, CompletableFuture> contentsGetter, ExistingFileHelper existingFileHelper); diff --git a/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java b/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java index 687dc8dd71..faa52ca084 100644 --- a/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java +++ b/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java @@ -12,11 +12,10 @@ import java.util.concurrent.CompletableFuture; import net.minecraft.Util; import net.minecraft.core.HolderLookup; +import net.minecraft.data.DataGenerator; import net.minecraft.data.registries.VanillaRegistries; import net.minecraft.server.Bootstrap; import net.neoforged.fml.ModLoader; -import net.neoforged.neoforge.client.ClientHooks; -import net.neoforged.neoforge.client.entity.animation.json.AnimationTypeManager; import net.neoforged.neoforge.common.data.ExistingFileHelper; import net.neoforged.neoforge.data.event.GatherDataEvent; import net.neoforged.neoforge.internal.CommonModLoader; @@ -37,8 +36,9 @@ public static boolean isRunningDataGen() { @ApiStatus.Internal public static void begin(final Set mods, final Path path, final Collection inputs, Collection existingPacks, - Set existingMods, final boolean serverGenerators, final boolean clientGenerators, final boolean devToolGenerators, final boolean reportsGenerator, - final boolean structureValidator, final boolean flat, final String assetIndex, final File assetsDir) { + Set existingMods, final boolean devToolGenerators, final boolean reportsGenerator, + final boolean structureValidator, final boolean flat, final String assetIndex, final File assetsDir, Runnable setup, GatherDataEvent.GatherDataEventGenerator eventGenerator, + DataGenerator vanillaGenerator) { if (mods.contains("minecraft") && mods.size() == 1) return; LOGGER.info("Initializing Data Gatherer for mods {}", mods); @@ -48,18 +48,14 @@ public static void begin(final Set mods, final Path path, final Collecti // Modify components as the (modified) defaults may be required in datagen, i.e. stack size RegistrationEvents.modifyComponents(); CompletableFuture lookupProvider = CompletableFuture.supplyAsync(VanillaRegistries::createLookup, Util.backgroundExecutor()); - dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, lookupProvider, serverGenerators, - clientGenerators, devToolGenerators, reportsGenerator, structureValidator, flat); + dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, lookupProvider, devToolGenerators, reportsGenerator, structureValidator, flat, vanillaGenerator); if (!mods.contains("neoforge")) { // If we aren't generating data for forge, automatically add forge as an existing so mods can access forge's data existingMods.add("neoforge"); } - if (clientGenerators) { - ClientHooks.registerSpriteSourceTypes(); - AnimationTypeManager.init(); - } + setup.run(); existingFileHelper = new ExistingFileHelper(existingPacks, existingMods, structureValidator, assetIndex, assetsDir); - ModLoader.runEventGenerator(mc -> new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p -> dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()), + ModLoader.runEventGenerator(mc -> eventGenerator.create(mc, dataGeneratorConfig.makeGenerator(p -> dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()), dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig, existingFileHelper)); dataGeneratorConfig.runAll(); } diff --git a/src/main/java/net/neoforged/neoforge/resource/ContextAwareReloadListener.java b/src/main/java/net/neoforged/neoforge/resource/ContextAwareReloadListener.java index 34cf074faf..077dee9671 100644 --- a/src/main/java/net/neoforged/neoforge/resource/ContextAwareReloadListener.java +++ b/src/main/java/net/neoforged/neoforge/resource/ContextAwareReloadListener.java @@ -6,9 +6,11 @@ package net.neoforged.neoforge.resource; import com.google.gson.JsonElement; +import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; import net.minecraft.core.HolderLookup; import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.RegistryOps; import net.minecraft.server.packs.resources.PreparableReloadListener; import net.minecraft.server.packs.resources.SimplePreparableReloadListener; import net.neoforged.neoforge.common.conditions.ConditionalOps; @@ -54,4 +56,14 @@ protected final HolderLookup.Provider getRegistryLookup() { protected final ConditionalOps makeConditionalOps() { return new ConditionalOps<>(getRegistryLookup().createSerializationContext(JsonOps.INSTANCE), getContext()); } + + protected final ConditionalOps makeConditionalOps(DynamicOps ops) { + if (ops instanceof ConditionalOps conditionalOps) { + return conditionalOps; + } + if (ops instanceof RegistryOps registryOps) { + return new ConditionalOps<>(registryOps, getContext()); + } + return makeConditionalOps(); + } } diff --git a/src/main/java/net/neoforged/neoforge/resource/EmptyPackResources.java b/src/main/java/net/neoforged/neoforge/resource/EmptyPackResources.java index f349038cb9..3ccaf5aa35 100644 --- a/src/main/java/net/neoforged/neoforge/resource/EmptyPackResources.java +++ b/src/main/java/net/neoforged/neoforge/resource/EmptyPackResources.java @@ -13,7 +13,7 @@ import net.minecraft.server.packs.PackLocationInfo; import net.minecraft.server.packs.PackResources; import net.minecraft.server.packs.PackType; -import net.minecraft.server.packs.metadata.MetadataSectionSerializer; +import net.minecraft.server.packs.metadata.MetadataSectionType; import net.minecraft.server.packs.metadata.pack.PackMetadataSection; import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.resources.IoSupplier; @@ -27,11 +27,10 @@ public EmptyPackResources(PackLocationInfo packId, PackMetadataSection packMeta) this.packMeta = packMeta; } - @SuppressWarnings("unchecked") @Nullable @Override - public T getMetadataSection(MetadataSectionSerializer deserializer) { - return deserializer.getMetadataSectionName().equals("pack") ? (T) this.packMeta : null; + public T getMetadataSection(MetadataSectionType type) { + return PackMetadataSection.TYPE.equals(type) ? (T) this.packMeta : null; } @Override diff --git a/src/main/java/net/neoforged/neoforge/resource/ResourcePackLoader.java b/src/main/java/net/neoforged/neoforge/resource/ResourcePackLoader.java index 049aae13ca..3e85ad9ab4 100644 --- a/src/main/java/net/neoforged/neoforge/resource/ResourcePackLoader.java +++ b/src/main/java/net/neoforged/neoforge/resource/ResourcePackLoader.java @@ -141,7 +141,7 @@ private static void packFinder(Map modResource packAcceptor.accept(makePack(packType, hiddenPacks)); } - public static final MetadataSectionType OPTIONAL_FORMAT = MetadataSectionType.fromCodec("pack", RecordCodecBuilder.create( + public static final MetadataSectionType OPTIONAL_FORMAT = new MetadataSectionType<>("pack", RecordCodecBuilder.create( in -> in.group( ComponentSerialization.CODEC.optionalFieldOf("description", Component.empty()).forGetter(PackMetadataSection::description), Codec.INT.optionalFieldOf("pack_format", -1).forGetter(PackMetadataSection::packFormat), diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 9f04978b10..9a143aea76 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -70,9 +70,6 @@ public net.minecraft.client.renderer.RenderStateShard$TransparencyStateShard public net.minecraft.client.renderer.RenderStateShard$WriteMaskStateShard #endgroup default net.minecraft.client.renderer.chunk.RenderChunk wrapped -protected net.minecraft.client.renderer.block.model.BakedOverrides ()V -public net.minecraft.client.renderer.block.model.BakedOverrides$BakedOverride -public net.minecraft.client.renderer.block.model.BakedOverrides$BakedOverride ([Lnet/minecraft/client/renderer/block/model/BakedOverrides$PropertyMatcher;Lnet/minecraft/client/resources/model/BakedModel;)V public net.minecraft.client.renderer.block.model.BlockElement uvsByFace(Lnet/minecraft/core/Direction;)[F # uvsByFace public net.minecraft.client.renderer.block.model.BlockElement$Deserializer public net.minecraft.client.renderer.block.model.BlockElement$Deserializer ()V # constructor @@ -80,13 +77,8 @@ public net.minecraft.client.renderer.block.model.BlockElementFace$Deserializer public net.minecraft.client.renderer.block.model.BlockElementFace$Deserializer ()V # constructor public net.minecraft.client.renderer.block.model.BlockFaceUV$Deserializer public net.minecraft.client.renderer.block.model.BlockFaceUV$Deserializer ()V # constructor -public net.minecraft.client.renderer.block.model.BlockModel textureMap # textureMap -public net.minecraft.client.renderer.block.model.BlockModel parent # parent -public net.minecraft.client.renderer.block.model.BlockModel hasAmbientOcclusion # hasAmbientOcclusion -public net.minecraft.client.renderer.block.model.BlockModel bakeFace(Lnet/minecraft/client/renderer/block/model/BlockElement;Lnet/minecraft/client/renderer/block/model/BlockElementFace;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;Lnet/minecraft/core/Direction;Lnet/minecraft/client/resources/model/ModelState;)Lnet/minecraft/client/renderer/block/model/BakedQuad; # bakeFace +public net.minecraft.client.renderer.block.model.BlockModel GSON public net.minecraft.client.renderer.block.model.ItemModelGenerator processFrames(ILjava/lang/String;Lnet/minecraft/client/renderer/texture/SpriteContents;)Ljava/util/List; # processFrames -public net.minecraft.client.renderer.block.model.ItemOverride$Deserializer -public net.minecraft.client.renderer.block.model.ItemOverride$Deserializer ()V # constructor public net.minecraft.client.renderer.block.model.ItemTransform$Deserializer public net.minecraft.client.renderer.block.model.ItemTransform$Deserializer ()V # constructor public net.minecraft.client.renderer.block.model.ItemTransform$Deserializer DEFAULT_ROTATION # DEFAULT_ROTATION @@ -97,10 +89,9 @@ public net.minecraft.client.renderer.block.model.ItemTransforms$Deserializer (Lnet/minecraft/client/resources/model/BakedModel;Ljava/util/List;)V public net.minecraft.client.renderer.texture.SpriteContents byMipLevel # byMipLevel default net.minecraft.client.renderer.texture.SpriteContents animatedTexture # animatedTexture public net.minecraft.client.renderer.texture.atlas.sources.PalettedPermutations (Ljava/util/List;Lnet/minecraft/resources/ResourceLocation;Ljava/util/Map;)V # constructor @@ -112,7 +103,8 @@ public net.minecraft.client.renderer.texture.atlas.sources.Unstitcher$RegionInst public net.minecraft.client.renderer.texture.atlas.sources.Unstitcher$RegionInstance (Lnet/minecraft/client/renderer/texture/atlas/sources/LazyLoadedImage;Lnet/minecraft/client/renderer/texture/atlas/sources/Unstitcher$Region;DD)V # constructor public net.minecraft.client.resources.ClientPackSource createVanillaPackSource(Ljava/nio/file/Path;)Lnet/minecraft/server/packs/VanillaPackResources; # createVanillaPackSource protected net.minecraft.client.resources.TextureAtlasHolder textureAtlas # textureAtlas -public net.minecraft.client.resources.model.ItemModel$BakedModelWithOverrides +public net.minecraft.client.resources.model.ModelBakery$ModelBakerImpl getModel(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/resources/model/UnbakedModel; +public net.minecraft.client.resources.model.SimpleBakedModel bakeFace(Lnet/minecraft/client/renderer/block/model/BlockElement;Lnet/minecraft/client/renderer/block/model/BlockElementFace;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;Lnet/minecraft/core/Direction;Lnet/minecraft/client/resources/model/ModelState;)Lnet/minecraft/client/renderer/block/model/BakedQuad; public net.minecraft.client.resources.model.SimpleBakedModel$Builder (ZZZLnet/minecraft/client/renderer/block/model/ItemTransforms;)V public net.minecraft.client.sounds.SoundEngine soundManager # soundManager public net.minecraft.commands.CommandSourceStack source # source @@ -123,9 +115,6 @@ protected net.minecraft.core.IdMapper nextId # nextId protected net.minecraft.core.IdMapper tToId # tToId - internal map protected net.minecraft.core.IdMapper idToT # idToT - internal index list public net.minecraft.core.particles.SimpleParticleType (Z)V # constructor -public net.minecraft.data.models.ItemModelGenerators GENERATED_TRIM_MODELS -public net.minecraft.data.models.ItemModelGenerators$TrimModelData -public net.minecraft.data.models.ItemModelGenerators$TrimModelData (Ljava/lang/String;FLjava/util/Map;)V protected net.minecraft.data.loot.BlockLootSubProvider createSilkTouchOnlyTable(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/level/storage/loot/LootTable$Builder; # createSilkTouchOnlyTable protected net.minecraft.data.loot.BlockLootSubProvider createPotFlowerItemTable(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/level/storage/loot/LootTable$Builder; # createPotFlowerItemTable protected net.minecraft.data.loot.BlockLootSubProvider createSelfDropDispatchTable(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/storage/loot/predicates/LootItemCondition$Builder;Lnet/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer$Builder;)Lnet/minecraft/world/level/storage/loot/LootTable$Builder; # createSelfDropDispatchTable @@ -446,7 +435,7 @@ public com.mojang.blaze3d.vertex.VertexFormatElement$Usage$SetupState # Below you will find particle constructor ATs protected net.minecraft.client.particle.AttackSweepParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor protected net.minecraft.client.particle.BlockMarker (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/block/state/BlockState;)V # constructor -protected net.minecraft.client.particle.BreakingItemParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/world/item/ItemStack;)V # constructor +protected net.minecraft.client.particle.BreakingItemParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/renderer/item/ItemStackRenderState;)V # constructor protected net.minecraft.client.particle.BubbleColumnUpParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor protected net.minecraft.client.particle.BubbleParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor protected net.minecraft.client.particle.BubblePopParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor @@ -505,4 +494,4 @@ public net.minecraft.world.item.enchantment.Enchantment blockHitContext(Lnet/min public net.minecraft.world.item.enchantment.Enchantment applyEffects(Ljava/util/List;Lnet/minecraft/world/level/storage/loot/LootContext;Ljava/util/function/Consumer;)V # Made public for mc logo render in mods list public net.minecraft.client.gui.components.LogoRenderer LOGO_TEXTURE_WIDTH -public net.minecraft.client.gui.components.LogoRenderer LOGO_TEXTURE_HEIGHT \ No newline at end of file +public net.minecraft.client.gui.components.LogoRenderer LOGO_TEXTURE_HEIGHT diff --git a/testframework/src/main/java/net/neoforged/testframework/client/AbstractTestScreen.java b/testframework/src/main/java/net/neoforged/testframework/client/AbstractTestScreen.java index d2fc91efe3..1dbbc80b6c 100644 --- a/testframework/src/main/java/net/neoforged/testframework/client/AbstractTestScreen.java +++ b/testframework/src/main/java/net/neoforged/testframework/client/AbstractTestScreen.java @@ -73,12 +73,12 @@ public void resetRows(String search) { } @Override - protected boolean isValidMouseClick(int button) { + protected boolean isValidClickButton(int button) { return button == GLFW.GLFW_MOUSE_BUTTON_LEFT || button == GLFW.GLFW_MOUSE_BUTTON_RIGHT || button == GLFW.GLFW_MOUSE_BUTTON_MIDDLE; } @Override - protected int getScrollbarPosition() { + protected int scrollBarX() { return this.width / 2 + 144; } diff --git a/testframework/src/main/java/net/neoforged/testframework/condition/TestEnabledIngredient.java b/testframework/src/main/java/net/neoforged/testframework/condition/TestEnabledIngredient.java index 7cd6675258..ce331c6ce6 100644 --- a/testframework/src/main/java/net/neoforged/testframework/condition/TestEnabledIngredient.java +++ b/testframework/src/main/java/net/neoforged/testframework/condition/TestEnabledIngredient.java @@ -36,7 +36,7 @@ public boolean test(ItemStack stack) { @Override public Stream> items() { - return base.items().stream(); + return base.items(); } @Override diff --git a/testframework/src/main/java/net/neoforged/testframework/gametest/ExtendedGameTestHelper.java b/testframework/src/main/java/net/neoforged/testframework/gametest/ExtendedGameTestHelper.java index 3dce9e062c..7d0a259726 100644 --- a/testframework/src/main/java/net/neoforged/testframework/gametest/ExtendedGameTestHelper.java +++ b/testframework/src/main/java/net/neoforged/testframework/gametest/ExtendedGameTestHelper.java @@ -142,6 +142,7 @@ protected void keepConnectionAlive() {} serverplayer.setYRot(180); serverplayer.connection.chunkSender.sendNextChunks(serverplayer); serverplayer.connection.chunkSender.onChunkBatchReceivedByClient(64f); + serverplayer.setClientLoaded(true); return serverplayer; } @@ -163,7 +164,7 @@ public boolean isLocalPlayer() { } @Override - protected int getPermissionLevel() { + public int getPermissionLevel() { return commandLevel; } }; diff --git a/testframework/src/main/java/net/neoforged/testframework/impl/reg/RegistrationHelperImpl.java b/testframework/src/main/java/net/neoforged/testframework/impl/reg/RegistrationHelperImpl.java index bf9743250c..d357f6dcd6 100644 --- a/testframework/src/main/java/net/neoforged/testframework/impl/reg/RegistrationHelperImpl.java +++ b/testframework/src/main/java/net/neoforged/testframework/impl/reg/RegistrationHelperImpl.java @@ -108,8 +108,10 @@ protected void start() { } private final String modId; - private final ListMultimap, Consumer> providers = Multimaps.newListMultimap(new IdentityHashMap<>(), ArrayList::new); - private final List> directProviders = new ArrayList<>(); + private final ListMultimap, Consumer> clientProviders = Multimaps.newListMultimap(new IdentityHashMap<>(), ArrayList::new); + private final ListMultimap, Consumer> serverProviders = Multimaps.newListMultimap(new IdentityHashMap<>(), ArrayList::new); + private final List> directClientProviders = new ArrayList<>(); + private final List> directServerProviders = new ArrayList<>(); private final Map>, DeferredRegister> registrars = new ConcurrentHashMap<>(); @Override @@ -199,13 +201,23 @@ public String registerSubpack(String name) { } @Override - public void provider(Class type, Consumer consumer) { - providers.put(type, consumer); + public void serverProvider(Class type, Consumer consumer) { + serverProviders.put(type, consumer); } @Override - public void addProvider(Function provider) { - directProviders.add(provider); + public void clientProvider(Class type, Consumer consumer) { + clientProviders.put(type, consumer); + } + + @Override + public void addClientProvider(Function provider) { + directClientProviders.add(provider); + } + + @Override + public void addServerProvider(Function provider) { + directServerProviders.add(provider); } private IEventBus bus; @@ -214,7 +226,8 @@ public void addProvider(Function provider) { public void register(IEventBus bus, ModContainer container) { this.bus = bus; this.owner = container; - bus.addListener(this::gather); + bus.addListener(this::gatherServer); + bus.addListener(this::gatherClient); listeners.forEach(bus::addListener); registrars.values().forEach(r -> r.register(bus)); } @@ -226,7 +239,15 @@ public Consumer> eventListeners() { return bus == null ? listeners::add : bus::addListener; } - private void gather(final GatherDataEvent event) { + private void gatherServer(final GatherDataEvent.Server event) { + gather(event, serverProviders, directServerProviders); + } + + private void gatherClient(final GatherDataEvent.Client event) { + gather(event, clientProviders, directClientProviders); + } + + private void gather(final T event, ListMultimap, Consumer> providers, List> directProviders) { providers.asMap().forEach((cls, cons) -> event.getGenerator().addProvider(true, PROVIDERS.get(cls).create( event.getGenerator().getPackOutput(), event.getLookupProvider(), event.getGenerator(), event.getExistingFileHelper(), modId, (List) cons))); diff --git a/testframework/src/main/java/net/neoforged/testframework/registration/DeferredBlockBuilder.java b/testframework/src/main/java/net/neoforged/testframework/registration/DeferredBlockBuilder.java index 1de427adae..9595db892b 100644 --- a/testframework/src/main/java/net/neoforged/testframework/registration/DeferredBlockBuilder.java +++ b/testframework/src/main/java/net/neoforged/testframework/registration/DeferredBlockBuilder.java @@ -5,11 +5,17 @@ package net.neoforged.testframework.registration; +import com.mojang.serialization.MapCodec; +import java.util.Objects; import java.util.function.Consumer; +import net.minecraft.client.color.item.ItemTintSource; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.neoforged.fml.loading.FMLLoader; import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; @@ -17,6 +23,7 @@ import net.neoforged.neoforge.client.model.generators.BlockStateProvider; import net.neoforged.neoforge.common.data.LanguageProvider; import net.neoforged.neoforge.registries.DeferredBlock; +import org.jetbrains.annotations.Nullable; public class DeferredBlockBuilder extends DeferredBlock { private final RegistrationHelper helper; @@ -41,7 +48,7 @@ public DeferredBlockBuilder withBlockItem(Item.Properties properties, Consume } public DeferredBlockBuilder withLang(String name) { - helper.provider(LanguageProvider.class, prov -> prov.add(value(), name)); + helper.clientProvider(LanguageProvider.class, prov -> prov.add(value(), name)); return this; } @@ -49,7 +56,7 @@ public DeferredBlockBuilder withLang(String name) { private boolean hasColor = false; public DeferredBlockBuilder withDefaultWhiteModel() { - helper.provider(BlockStateProvider.class, prov -> { + helper.clientProvider(BlockStateProvider.class, prov -> { final BlockModelBuilder model; if (hasColor) { model = prov.models().getBuilder(key.location().getPath()) @@ -81,11 +88,57 @@ public DeferredBlockBuilder withColor(int color) { } private void colorInternal(int color) { + //Capture the color into a local tint source, which has a unit mapcodec for serialization + final ConstantItemTintSourceBuilder source = new ConstantItemTintSourceBuilder(color); + helper.eventListeners().accept((final RegisterColorHandlersEvent.Block event) -> event.register((p_92567_, p_92568_, p_92569_, p_92570_) -> color, value())); - helper.eventListeners().accept((final RegisterColorHandlersEvent.Item event) -> { + helper.eventListeners().accept((final RegisterColorHandlersEvent.ItemTintSources event) -> { if (hasItem) { - event.register((stack, index) -> color, value()); + event.register(key.location(), source.type()); } }); } + + private static final class ConstantItemTintSourceBuilder implements ItemTintSource { + public final MapCodec codec = MapCodec.unit(this); + + private final int color; + + private ConstantItemTintSourceBuilder(int color) { + this.color = color; + } + + @Override + public int calculate(ItemStack p_388652_, @Nullable ClientLevel p_390356_, @Nullable LivingEntity p_390510_) { + return color; + } + + @Override + public MapCodec type() { + return codec; + } + + public int color() { + return color; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (ConstantItemTintSourceBuilder) obj; + return this.color == that.color; + } + + @Override + public int hashCode() { + return Objects.hash(color); + } + + @Override + public String toString() { + return "ConstantItemTintSourceBuilder[" + + "color=" + color + ']'; + } + } } diff --git a/testframework/src/main/java/net/neoforged/testframework/registration/DeferredEntityTypeBuilder.java b/testframework/src/main/java/net/neoforged/testframework/registration/DeferredEntityTypeBuilder.java index 8434dd0a65..cd1b4569df 100644 --- a/testframework/src/main/java/net/neoforged/testframework/registration/DeferredEntityTypeBuilder.java +++ b/testframework/src/main/java/net/neoforged/testframework/registration/DeferredEntityTypeBuilder.java @@ -40,7 +40,7 @@ public DeferredEntityTypeBuilder withAttributes(Supplier withLang(String name) { - helper.provider(LanguageProvider.class, prov -> prov.add(value(), name)); + helper.clientProvider(LanguageProvider.class, prov -> prov.add(value(), name)); return this; } } diff --git a/testframework/src/main/java/net/neoforged/testframework/registration/DeferredItemBuilder.java b/testframework/src/main/java/net/neoforged/testframework/registration/DeferredItemBuilder.java index 34f267a4d1..4065c74bb7 100644 --- a/testframework/src/main/java/net/neoforged/testframework/registration/DeferredItemBuilder.java +++ b/testframework/src/main/java/net/neoforged/testframework/registration/DeferredItemBuilder.java @@ -24,7 +24,7 @@ protected DeferredItemBuilder(ResourceKey key, RegistrationHelper registra } public DeferredItemBuilder withLang(String name) { - registrationHelper.provider(LanguageProvider.class, prov -> prov.add(value(), name)); + registrationHelper.clientProvider(LanguageProvider.class, prov -> prov.add(value(), name)); return this; } @@ -38,7 +38,7 @@ public DeferredItemBuilder tab(ResourceKey tab) { } public DeferredItemBuilder withModel(Consumer modelConsumer) { - registrationHelper.provider(ItemModelProvider.class, prov -> modelConsumer.accept(prov.getBuilder(key.location().toString()))); + registrationHelper.clientProvider(ItemModelProvider.class, prov -> modelConsumer.accept(prov.getBuilder(key.location().toString()))); return this; } } diff --git a/testframework/src/main/java/net/neoforged/testframework/registration/RegistrationHelper.java b/testframework/src/main/java/net/neoforged/testframework/registration/RegistrationHelper.java index 7a35f06dc2..77c23b8d95 100644 --- a/testframework/src/main/java/net/neoforged/testframework/registration/RegistrationHelper.java +++ b/testframework/src/main/java/net/neoforged/testframework/registration/RegistrationHelper.java @@ -59,9 +59,13 @@ public interface RegistrationHelper { String registerSubpack(String name); - void addProvider(Function provider); + void addClientProvider(Function provider); - void provider(Class type, Consumer consumer); + void addServerProvider(Function provider); + + void serverProvider(Class type, Consumer consumer); + + void clientProvider(Class type, Consumer consumer); Consumer> eventListeners(); diff --git a/tests/build.gradle b/tests/build.gradle index 37ea199d5b..6243371418 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -75,7 +75,7 @@ neoDev { type = "gameTestServer" } data { - data() + clientData() programArguments.addAll '--flat', '--all', '--validate', '--mod', 'data_gen_test', diff --git a/tests/src/generated/resources/pack.mcmeta b/tests/src/generated/resources/pack.mcmeta index 7454aa99dd..9620710f1d 100644 --- a/tests/src/generated/resources/pack.mcmeta +++ b/tests/src/generated/resources/pack.mcmeta @@ -49,7 +49,7 @@ }, "pack": { "description": "NeoForge tests resource pack", - "pack_format": 42, + "pack_format": 46, "supported_formats": [ 0, 2147483647 diff --git a/tests/src/junit/java/net/neoforged/neoforge/unittest/CustomFeatureFlagsTest.java b/tests/src/junit/java/net/neoforged/neoforge/unittest/CustomFeatureFlagsTest.java index 317312afe5..a89e9b44bd 100644 --- a/tests/src/junit/java/net/neoforged/neoforge/unittest/CustomFeatureFlagsTest.java +++ b/tests/src/junit/java/net/neoforged/neoforge/unittest/CustomFeatureFlagsTest.java @@ -80,8 +80,8 @@ void testFlagSetEquals() { @Order(5) void testFlagSetEqualsVanilla() { FeatureFlagSet flagSetOne = FeatureFlagSet.of(FeatureFlags.VANILLA); - FeatureFlagSet flagSetTwo = FeatureFlagSet.of(FeatureFlags.WINTER_DROP); - FeatureFlagSet flagSetThree = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.WINTER_DROP); + FeatureFlagSet flagSetTwo = FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS); + FeatureFlagSet flagSetThree = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.MINECART_IMPROVEMENTS); FeatureFlagSet flagSetFour = FeatureFlagSet.of(FeatureFlags.VANILLA); assertThat(flagSetOne).isNotEqualTo(flagSetTwo); @@ -113,8 +113,8 @@ void testFlagSetIsSubsetOf() { @Test @Order(7) void testFlagSetIsSubsetOfVanilla() { - FeatureFlagSet flagSetOne = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.WINTER_DROP, FeatureFlags.TRADE_REBALANCE); - FeatureFlagSet flagSetTwo = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.WINTER_DROP); + FeatureFlagSet flagSetOne = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.MINECART_IMPROVEMENTS, FeatureFlags.TRADE_REBALANCE); + FeatureFlagSet flagSetTwo = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.MINECART_IMPROVEMENTS); assertThat(flagSetTwo.isSubsetOf(flagSetOne)).isTrue(); assertThat(flagSetOne.isSubsetOf(flagSetTwo)).isFalse(); } @@ -141,9 +141,9 @@ void testFlagSetIntersects() { @Test @Order(9) void testFlagSetIntersectsVanilla() { - FeatureFlagSet flagSetOne = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.WINTER_DROP); + FeatureFlagSet flagSetOne = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.MINECART_IMPROVEMENTS); FeatureFlagSet flagSetTwo = FeatureFlagSet.of(FeatureFlags.VANILLA); - FeatureFlagSet flagSetThree = FeatureFlagSet.of(FeatureFlags.WINTER_DROP); + FeatureFlagSet flagSetThree = FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS); assertThat(flagSetOne.intersects(flagSetTwo)).isTrue(); assertThat(flagSetOne.intersects(flagSetThree)).isTrue(); assertThat(flagSetTwo.intersects(flagSetThree)).isFalse(); @@ -171,8 +171,8 @@ void testFlagSetJoin() { @Order(11) void testFlagSetJoinVanilla() { FeatureFlagSet flagSetOne = FeatureFlagSet.of(FeatureFlags.VANILLA); - FeatureFlagSet flagSetTwo = FeatureFlagSet.of(FeatureFlags.WINTER_DROP); - FeatureFlagSet flagSetThree = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.WINTER_DROP); + FeatureFlagSet flagSetTwo = FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS); + FeatureFlagSet flagSetThree = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.MINECART_IMPROVEMENTS); assertThat(flagSetOne.join(flagSetTwo)).isEqualTo(flagSetThree); } @@ -198,9 +198,9 @@ void testFlagSetSubtract() { @Test @Order(13) void testFlagSetSubtractVanilla() { - FeatureFlagSet flagSetOne = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.WINTER_DROP); + FeatureFlagSet flagSetOne = FeatureFlagSet.of(FeatureFlags.VANILLA, FeatureFlags.MINECART_IMPROVEMENTS); FeatureFlagSet flagSetTwo = FeatureFlagSet.of(FeatureFlags.VANILLA); - FeatureFlagSet flagSetThree = FeatureFlagSet.of(FeatureFlags.WINTER_DROP); + FeatureFlagSet flagSetThree = FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS); assertThat(flagSetOne.subtract(flagSetTwo)).isEqualTo(flagSetThree); } diff --git a/tests/src/junit/java/net/neoforged/neoforge/unittest/IngredientTests.java b/tests/src/junit/java/net/neoforged/neoforge/unittest/IngredientTests.java index 164ab1a686..b2424d96bc 100644 --- a/tests/src/junit/java/net/neoforged/neoforge/unittest/IngredientTests.java +++ b/tests/src/junit/java/net/neoforged/neoforge/unittest/IngredientTests.java @@ -32,7 +32,7 @@ @ExtendWith(EphemeralTestServerProvider.class) public class IngredientTests { private static List ingredientItemsAsStacks(Ingredient ingredient) { - return ingredient.items().stream().map(i -> i.value().getDefaultInstance()).toList(); + return ingredient.items().map(i -> i.value().getDefaultInstance()).toList(); } @ParameterizedTest @@ -59,7 +59,7 @@ void testIntersectionIngredient(MinecraftServer server) { final var second = Ingredient.of(Items.BIRCH_LOG, Items.SPRUCE_LOG, Items.DISPENSER); final var ingredient = IntersectionIngredient.of(Ingredient.of(server.registryAccess().lookupOrThrow(Registries.ITEM).getOrThrow(ItemTags.LOGS)), second); - Assertions.assertThat(ingredient.items().stream().map(Holder::value).distinct()) + Assertions.assertThat(ingredient.items().map(Holder::value).distinct()) .containsExactlyInAnyOrder(Items.BIRCH_LOG, Items.SPRUCE_LOG); } diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java index e4b71b535f..fde67adaf8 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java @@ -27,7 +27,7 @@ static void testConditionalRecipe(DynamicTest test, RegistrationHelper reg) { // name pointing to recipe which should never be enabled var recipeName = ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath(reg.modId(), "always_disabled_recipe")); - reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { return new RecipeProvider(registries, output) { diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/block/BlockTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/block/BlockTests.java index 9050b2126b..12fa397f0e 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/block/BlockTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/block/BlockTests.java @@ -81,7 +81,7 @@ static void decoratedPotBreaking(final DynamicTest test) { static void woodlessFenceGate(final DynamicTest test, final RegistrationHelper reg) { final var gate = reg.blocks().registerBlock("gate", props -> new FenceGateBlock(props, SoundEvents.BARREL_OPEN, SoundEvents.CHEST_CLOSE), BlockBehaviour.Properties.ofFullCopy(Blocks.ACACIA_FENCE_GATE)) .withLang("Woodless Fence Gate").withBlockItem(); - reg.provider(BlockStateProvider.class, prov -> prov.fenceGateBlock(gate.get(), ResourceLocation.withDefaultNamespace("block/iron_block"))); + reg.clientProvider(BlockStateProvider.class, prov -> prov.fenceGateBlock(gate.get(), ResourceLocation.withDefaultNamespace("block/iron_block"))); test.onGameTest(helper -> helper.startSequence(() -> helper.makeTickingMockServerPlayerInCorner(GameType.SURVIVAL)) .thenExecute(() -> helper.setBlock(1, 1, 1, gate.get().defaultBlockState().setValue(FenceGateBlock.OPEN, true))) diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java index 88e0f2d82b..3eed63a3e8 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java @@ -17,9 +17,7 @@ import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.core.SectionPos; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.context.ContextKey; @@ -129,12 +127,10 @@ static void renderPlayerEvent(final DynamicTest test) { test.whenEnabled(listeners -> { var item = Items.IRON_BLOCK; var itemStack = item.getDefaultInstance(); - var modelId = ModelResourceLocation.inventory(BuiltInRegistries.ITEM.getKey(item)); listeners.forge().addListener((final RenderPlayerEvent.Post event) -> { event.getPoseStack().pushPose(); event.getPoseStack().translate(0, 2, 0); - var model = Minecraft.getInstance().getModelManager().getModel(modelId); - Minecraft.getInstance().getItemRenderer().render(itemStack, ItemDisplayContext.GROUND, false, event.getPoseStack(), event.getMultiBufferSource(), event.getPackedLight(), OverlayTexture.NO_OVERLAY, model); + Minecraft.getInstance().getItemRenderer().renderStatic(itemStack, ItemDisplayContext.GROUND, event.getPackedLight(), OverlayTexture.NO_OVERLAY, event.getPoseStack(), event.getMultiBufferSource(), Minecraft.getInstance().level, 0); event.getPoseStack().popPose(); }); test.requestConfirmation(Minecraft.getInstance().player, Component.literal("Is an iron block rendered above you in third-person?")); diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java index bf1bfcb49c..b89c9e5394 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java @@ -56,7 +56,7 @@ static void keyMappingTest(final DynamicTest test) { final KeyMapping stickKey = new KeyMapping("stick_key", InputConstants.KEY_BACKSLASH, KeyMapping.CATEGORY_MISC); final KeyMapping rockKey = new KeyMapping("rock_key", InputConstants.KEY_BACKSLASH, KeyMapping.CATEGORY_MISC); - test.registrationHelper().provider(LanguageProvider.class, lang -> { + test.registrationHelper().clientProvider(LanguageProvider.class, lang -> { lang.add(stickKey.getName(), "Stick key"); lang.add(rockKey.getName(), "Rock key"); }); diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java index c64cfde25a..216d5de6c6 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java @@ -70,7 +70,7 @@ public class IngredientTests { @EmptyTemplate @TestHolder(description = "Tests if BlockTagIngredient works") static void blockTagIngredient(final DynamicTest test, final RegistrationHelper reg) { - reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { return new RecipeProvider(registries, output) { @@ -111,7 +111,7 @@ public String getName() { @EmptyTemplate @TestHolder(description = "Tests if partial NBT ingredients match the correct stacks") static void partialNBTIngredient(final DynamicTest test, final RegistrationHelper reg) { - reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { return new RecipeProvider(registries, output) { @@ -167,7 +167,7 @@ public String getName() { @EmptyTemplate @TestHolder(description = "Tests if strict NBT ingredients match the correct stacks") static void strictNBTIngredient(final DynamicTest test, final RegistrationHelper reg) { - reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { return new RecipeProvider(registries, output) { @@ -377,7 +377,7 @@ private void ensureValid(ResourceKey> p_379745_) { @EmptyTemplate @TestHolder(description = "Tests if sized ingredients serialize and deserialize correctly") static void testSizedIngredient(final DynamicTest test, final RegistrationHelper reg) { - reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { return new RecipeProvider(registries, output) { diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/damagesource/DamageTypeTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/damagesource/DamageTypeTests.java index 6800316600..c8ac07a90d 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/damagesource/DamageTypeTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/damagesource/DamageTypeTests.java @@ -96,7 +96,7 @@ public boolean onLeftClickEntity(ItemStack stack, Player player, Entity entity) bootstrap.register(TEST_DMG_TYPE, new DamageType("test_mod", scaling, 0.0f, effects, msgType)); }); - reg.addProvider(event -> new DatapackBuiltinEntriesProvider( + reg.addClientProvider(event -> new DatapackBuiltinEntriesProvider( event.getGenerator().getPackOutput(), event.getLookupProvider(), registrySetBuilder, diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java index 10419da329..090309ffca 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/data/CustomFeatureFlagsTests.java @@ -110,7 +110,7 @@ static void testFlagCondition(DynamicTest test, RegistrationHelper reg) { var modId = reg.modId(); var enabledRecipeName = ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath(modId, "diamonds_from_dirt")); - reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { class Provider extends RecipeProvider implements IConditionBuilder { diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java index 4506dfaa09..08b3960e77 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java @@ -86,7 +86,7 @@ static void dataMapMerger(final DynamicTest test, final RegistrationHelper reg) final String subpackName = reg.registerSubpack("second_layer"); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(someData) @@ -104,7 +104,7 @@ public String getName() { } }); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(subpackName), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(subpackName), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(someData) @@ -166,7 +166,7 @@ public Optional> remove(Map value, R final String subpackName = reg.registerSubpack("second_layer"); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(someData) @@ -186,7 +186,7 @@ public String getName() { } }); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(subpackName), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(subpackName), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(someData) @@ -230,7 +230,7 @@ static void dataMapTest(final DynamicTest test, final RegistrationHelper reg) { test.framework().modEventBus().addListener((final RegisterDataMapTypesEvent event) -> event.register(someData)); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(someData) @@ -283,7 +283,7 @@ record ExperienceGrant(int amount) { Registries.DAMAGE_TYPE, ExperienceGrant.CODEC) .build()); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(xpGrant) @@ -315,7 +315,7 @@ static void reloadableRegDataMaps(final DynamicTest test, final RegistrationHelp Registries.LOOT_TABLE, MobEffectInstance.CODEC) .build()); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(effectGrant) @@ -344,7 +344,7 @@ protected void gather(HolderLookup.Provider provider) { @EmptyTemplate @TestHolder(description = "Tests if custom compostables work") static void compostablesMapTest(final DynamicTest test, final RegistrationHelper reg) { - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(NeoForgeDataMaps.COMPOSTABLES) @@ -367,7 +367,7 @@ static void dataMapUpdateEventTest(final DynamicTest test, final RegistrationHel ResourceLocation.fromNamespaceAndPath(reg.modId(), "weight"), Registries.ITEM, Codec.INT) .build()); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(dataMap) @@ -413,7 +413,7 @@ static void oxidizablesAndWaxablesMapTest(final DynamicTest test, final Registra Holder lightlyOxidizedWaxedIron = reg.blocks().registerBlock("lightly_oxidized_waxed_iron", Block::new, BlockBehaviour.Properties.of()); - reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + reg.addClientProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override protected void gather(HolderLookup.Provider provider) { builder(NeoForgeDataMaps.OXIDIZABLES) diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/data/registries/DatapackEntryTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/data/registries/DatapackEntryTests.java index 9824ffda4b..3d11736872 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/data/registries/DatapackEntryTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/data/registries/DatapackEntryTests.java @@ -41,7 +41,7 @@ static void conditionalDatapackEntries(final DynamicTest test, final Registratio bootstrap.register(REGULAR_DAMAGE_TYPE, new DamageType("inFire", 0.1f, DamageEffects.BURNING)); }); - reg.addProvider(event -> new DatapackBuiltinEntriesProvider( + reg.addClientProvider(event -> new DatapackBuiltinEntriesProvider( event.getGenerator().getPackOutput(), event.getLookupProvider(), builder, diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/entity/player/AdvancementTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/entity/player/AdvancementTests.java index 56bf999fdc..b17af6164c 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/entity/player/AdvancementTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/entity/player/AdvancementTests.java @@ -92,7 +92,7 @@ static void customPredicateTest(final DynamicTest test, final RegistrationHelper reg.registrar(Registries.ITEM_SUB_PREDICATE_TYPE) .register("custom_name", () -> type); - reg.addProvider(event -> new AdvancementProvider( + reg.addClientProvider(event -> new AdvancementProvider( event.getGenerator().getPackOutput(), event.getLookupProvider(), event.getExistingFileHelper(), diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/fluid/ClientFluidTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/fluid/ClientFluidTests.java index cc40433fce..d20ad28557 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/fluid/ClientFluidTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/fluid/ClientFluidTests.java @@ -50,7 +50,7 @@ public boolean shouldHideAdjacentFluidFace(BlockState state, Direction selfFace, @TestHolder(description = "Tests if blocks can prevent neighboring fluids from rendering against them") static void testWaterGlassFaceRemoval(final DynamicTest test, final RegistrationHelper reg) { final var glass = reg.blocks().registerBlock("water_glass", WaterGlassBlock::new, BlockBehaviour.Properties.ofFullCopy(Blocks.GLASS)).withLang("Water Glass").withBlockItem(); - reg.provider(BlockStateProvider.class, prov -> prov.simpleBlock(glass.get(), prov.models() + reg.clientProvider(BlockStateProvider.class, prov -> prov.simpleBlock(glass.get(), prov.models() .cubeAll("water_glass", ResourceLocation.withDefaultNamespace("block/glass")) .renderType("cutout"))); final var waterPosition = new BlockPos(1, 1, 2); diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemTests.java index 3ff8d51fc8..08d076e486 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemTests.java @@ -45,7 +45,7 @@ import net.minecraft.world.item.equipment.ArmorMaterial; import net.minecraft.world.item.equipment.ArmorMaterials; import net.minecraft.world.item.equipment.ArmorType; -import net.minecraft.world.item.equipment.EquipmentModels; +import net.minecraft.world.item.equipment.EquipmentAssets; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.DispenserBlock; @@ -122,7 +122,7 @@ static void forgeSpawnEggTest(final DynamicTest test, final RegistrationHelper r .withRenderer(() -> PigRenderer::new) .withLang("Test Pig spawn egg"); - final var egg = reg.items().registerItem("test_spawn_egg", props -> new SpawnEggItem(testEntity.get(), 0x0000FF, 0xFF0000, props) { + final var egg = reg.items().registerItem("test_spawn_egg", props -> new SpawnEggItem(testEntity.get(), props) { @Override public InteractionResult useOn(UseOnContext ctx) { final var result = super.useOn(ctx); @@ -210,7 +210,7 @@ public boolean canWalkOnPowderedSnow(ItemStack stack, LivingEntity wearer) { map.put(ArmorType.CHESTPLATE, 3); map.put(ArmorType.HELMET, 1); map.put(ArmorType.BODY, 3); - }), 15, SoundEvents.AMBIENT_CAVE, 0.0F, 0.0F, Tags.Items.BARRELS, EquipmentModels.LEATHER); + }), 15, SoundEvents.AMBIENT_CAVE, 0.0F, 0.0F, Tags.Items.BARRELS, EquipmentAssets.LEATHER); @TestHolder(description = "Tests that registries can correctly handle named holder set references.") static void toolItem(final DynamicTest test, final RegistrationHelper reg) { diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/loot/GlobalLootModifiersTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/loot/GlobalLootModifiersTest.java index 23eb25dd51..c24349eeb3 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/loot/GlobalLootModifiersTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/loot/GlobalLootModifiersTest.java @@ -247,7 +247,7 @@ static void smeltingModifierTest(final DynamicTest test) { .build(SMELT.location()))); var subpack = HELPER.registerSubpack("smelt_glms"); - HELPER.addProvider(event -> new GlobalLootModifierProvider(event.getGenerator().getPackOutput(subpack), CompletableFuture.supplyAsync(() -> registrySetBuilder.build(RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)), Util.backgroundExecutor()), HELPER.modId()) { + HELPER.addClientProvider(event -> new GlobalLootModifierProvider(event.getGenerator().getPackOutput(subpack), CompletableFuture.supplyAsync(() -> registrySetBuilder.build(RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)), Util.backgroundExecutor()), HELPER.modId()) { @Override protected void start() { add("smelting", new SmeltingEnchantmentModifier( @@ -266,7 +266,7 @@ public String getName() { return super.getName() + " - smelting modifier"; } }); - HELPER.addProvider(event -> new DatapackBuiltinEntriesProvider(event.getGenerator().getPackOutput(), event.getLookupProvider(), + HELPER.addClientProvider(event -> new DatapackBuiltinEntriesProvider(event.getGenerator().getPackOutput(), event.getLookupProvider(), registrySetBuilder, Set.of(HELPER.modId()))); test.onGameTest(helper -> helper.startSequence(() -> helper.makeTickingMockServerPlayerInCorner(GameType.SURVIVAL).preventItemPickup()) @@ -297,7 +297,7 @@ public String getName() { @TestHolder(description = "Tests if a GLM replacing loot table values works, by replacing seeds with wheat when harvesting wheat") static void wheatSeedReplacerTest(final DynamicTest test) { var subpack = HELPER.registerSubpack("wheat_seed_glms"); - HELPER.addProvider(event -> new GlobalLootModifierProvider(event.getGenerator().getPackOutput(subpack), event.getLookupProvider(), HELPER.modId()) { + HELPER.addClientProvider(event -> new GlobalLootModifierProvider(event.getGenerator().getPackOutput(subpack), event.getLookupProvider(), HELPER.modId()) { @Override protected void start() { this.add("wheat_harvest", new WheatSeedsConverterModifier( @@ -335,7 +335,7 @@ public String getName() { @EmptyTemplate @TestHolder(description = "Tests if dungeon loot modifiers work, by rolling the simple_dungeon loot table") static void dungeonLootTest(final DynamicTest test) { - HELPER.provider(GlobalLootModifierProvider.class, prov -> prov.add("dungeon_loot", new DungeonLootEnhancerModifier( + HELPER.clientProvider(GlobalLootModifierProvider.class, prov -> prov.add("dungeon_loot", new DungeonLootEnhancerModifier( new LootItemCondition[] { LootTableIdCondition.builder(ResourceLocation.withDefaultNamespace("chests/simple_dungeon")).build(), new TestEnabledLootCondition(test) diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java index fce7b70d4a..a9fddd9cd3 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java @@ -46,7 +46,7 @@ public class LootPoolTest { @EmptyTemplate @TestHolder(description = "Tests if loading loot pools with custom names works") public static void testPoolLoading(DynamicTest test, RegistrationHelper reg) { - reg.addProvider(event -> new LootTableProvider( + reg.addClientProvider(event -> new LootTableProvider( event.getGenerator().getPackOutput(), Set.of(), List.of( @@ -78,7 +78,7 @@ public static void testPoolLoading(DynamicTest test, RegistrationHelper reg) { static void pinkConcreteLootTableCanceled(final DynamicTest test, final RegistrationHelper reg) { ResourceKey lootTableToUse = TEST_LOOT_TABLE_2; - reg.addProvider(event -> new LootTableProvider( + reg.addClientProvider(event -> new LootTableProvider( event.getGenerator().getPackOutput(), Set.of(), List.of( @@ -117,7 +117,7 @@ static void pinkConcreteLootTableCanceled(final DynamicTest test, final Registra static void orangeConcreteLootTableReplaced(final DynamicTest test, final RegistrationHelper reg) { ResourceKey lootTableToUse = TEST_LOOT_TABLE_3; - reg.addProvider(event -> new LootTableProvider( + reg.addClientProvider(event -> new LootTableProvider( event.getGenerator().getPackOutput(), Set.of(), List.of( @@ -158,7 +158,7 @@ static void orangeConcreteLootTableReplaced(final DynamicTest test, final Regist static void yellowConcreteLootTableAppended(final DynamicTest test, final RegistrationHelper reg) { ResourceKey lootTableToUse = TEST_LOOT_TABLE_4; - reg.addProvider(event -> new LootTableProvider( + reg.addClientProvider(event -> new LootTableProvider( event.getGenerator().getPackOutput(), Set.of(), List.of( diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/registry/BiomeModifierSyncTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/registry/BiomeModifierSyncTest.java index 02068930b5..985468cb0c 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/registry/BiomeModifierSyncTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/registry/BiomeModifierSyncTest.java @@ -73,7 +73,7 @@ static void init(final TestFramework framework) { @WithListener(Listener.class) static void biomeModifierSync(final DynamicTest test) { ResourceKey modifyTaigaModifier = ResourceKey.create(NeoForgeRegistries.Keys.BIOME_MODIFIERS, ResourceLocation.fromNamespaceAndPath(HELPER.modId(), "modify_taiga")); - HELPER.addProvider(event -> new DatapackBuiltinEntriesProvider( + HELPER.addClientProvider(event -> new DatapackBuiltinEntriesProvider( event.getGenerator().getPackOutput(), event.getLookupProvider(), new RegistrySetBuilder().add(NeoForgeRegistries.Keys.BIOME_MODIFIERS, context -> { diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/resources/ModDatapackTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/resources/ModDatapackTest.java index deb783a8d7..ccd65e4e6a 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/resources/ModDatapackTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/resources/ModDatapackTest.java @@ -31,7 +31,7 @@ public class ModDatapackTest { static void modDatapack(final DynamicTest test) { final ResourceLocation testAdvancement = ResourceLocation.fromNamespaceAndPath(test.createModId(), "recipes/misc/test_advancement"); - test.registrationHelper().addProvider(event -> { + test.registrationHelper().addClientProvider(event -> { List generators = List.of((registries, saver, existingFileHelper) -> Advancement.Builder.recipeAdvancement() .parent(RecipeBuilder.ROOT_RECIPE_ADVANCEMENT) .addCriterion("has_scute", CriteriaTriggers.INVENTORY_CHANGED.createCriterion( diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java index a5d5f1041f..43723c7ca5 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java @@ -42,10 +42,10 @@ import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.AdvancementType; import net.minecraft.advancements.critereon.InventoryChangeTrigger; -import net.minecraft.client.renderer.block.model.BlockModel.GuiLight; import net.minecraft.client.renderer.block.model.ItemTransform; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.block.model.Variant; +import net.minecraft.client.resources.model.UnbakedModel.GuiLight; import net.minecraft.core.Direction; import net.minecraft.core.Holder; import net.minecraft.core.HolderGetter; @@ -152,7 +152,7 @@ public class DataGeneratorTest { .add(Registries.LEVEL_STEM, DataGeneratorTest::levelStem); @SubscribeEvent - public static void gatherData(GatherDataEvent event) { + public static void gatherData(GatherDataEvent.Client event) { GSON = new GsonBuilder() .registerTypeAdapter(Variant.class, new Variant.Deserializer()) .registerTypeAdapter(ItemTransforms.class, new ItemTransforms.Deserializer()) @@ -174,18 +174,18 @@ public static void gatherData(GatherDataEvent event) { Component.literal("NeoForge tests resource pack"), DetectedVersion.BUILT_IN.getPackVersion(PackType.CLIENT_RESOURCES), Optional.of(new InclusiveRange<>(0, Integer.MAX_VALUE))))); - gen.addProvider(event.includeClient(), new Lang(packOutput)); + gen.addProvider(true, new Lang(packOutput)); // Let blockstate provider see generated item models by passing its existing file helper ItemModelProvider itemModels = new ItemModels(packOutput, event.getExistingFileHelper()); - gen.addProvider(event.includeClient(), itemModels); - gen.addProvider(event.includeClient(), new BlockStates(packOutput, itemModels.existingFileHelper)); - gen.addProvider(event.includeClient(), new SoundDefinitions(packOutput, event.getExistingFileHelper())); - gen.addProvider(event.includeClient(), new ParticleDescriptions(packOutput, event.getExistingFileHelper())); - - gen.addProvider(event.includeServer(), new Recipes.Runner(packOutput, lookupProvider)); - gen.addProvider(event.includeServer(), new Tags(packOutput, lookupProvider, event.getExistingFileHelper())); - gen.addProvider(event.includeServer(), new AdvancementProvider(packOutput, lookupProvider, event.getExistingFileHelper(), List.of(new Advancements()))); - gen.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(packOutput, lookupProvider, BUILDER, Set.of(MODID))); + gen.addProvider(true, itemModels); + gen.addProvider(true, new BlockStates(packOutput, itemModels.existingFileHelper)); + gen.addProvider(true, new SoundDefinitions(packOutput, event.getExistingFileHelper())); + gen.addProvider(true, new ParticleDescriptions(packOutput, event.getExistingFileHelper())); + + gen.addProvider(true, new Recipes.Runner(packOutput, lookupProvider)); + gen.addProvider(true, new Tags(packOutput, lookupProvider, event.getExistingFileHelper())); + gen.addProvider(true, new AdvancementProvider(packOutput, lookupProvider, event.getExistingFileHelper(), List.of(new Advancements()))); + gen.addProvider(true, new DatapackBuiltinEntriesProvider(packOutput, lookupProvider, BUILDER, Set.of(MODID))); } public static void levelStem(BootstrapContext context) { diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/DeferredRegistryTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/DeferredRegistryTest.java index 1976621c13..a81a3650af 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/DeferredRegistryTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/DeferredRegistryTest.java @@ -94,10 +94,10 @@ public void serverStarted(ServerStartedEvent event) { //PLACED_FEATURE.get(); } - public void gatherData(GatherDataEvent event) { + public void gatherData(GatherDataEvent.Client event) { DataGenerator gen = event.getGenerator(); - gen.addProvider(event.includeClient(), new BlockStateProvider(gen.getPackOutput(), MODID, event.getExistingFileHelper()) { + gen.addProvider(true, new BlockStateProvider(gen.getPackOutput(), MODID, event.getExistingFileHelper()) { @Override protected void registerStatesAndModels() { simpleBlockWithItem(BLOCK.get(), models().cubeAll(BLOCK.getId().getPath(), mcLoc("block/furnace_top"))); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/RemoveTagDatagenTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/RemoveTagDatagenTest.java index 7ac89d1be1..9ef0b8f795 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/RemoveTagDatagenTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/RemoveTagDatagenTest.java @@ -32,7 +32,7 @@ public RemoveTagDatagenTest(IEventBus modBus) { modBus.addListener(this::onGatherData); } - private void onGatherData(GatherDataEvent event) { + private void onGatherData(GatherDataEvent.Client event) { DataGenerator generator = event.getGenerator(); ExistingFileHelper helper = event.getExistingFileHelper(); @@ -50,9 +50,9 @@ protected void addTags(HolderLookup.Provider provider) { } }; - generator.addProvider(event.includeServer(), blocks); + generator.addProvider(true, blocks); - generator.addProvider(event.includeServer(), new ItemTagsProvider(generator.getPackOutput(), event.getLookupProvider(), blocks.contentsGetter(), MODID, helper) { + generator.addProvider(true, new ItemTagsProvider(generator.getPackOutput(), event.getLookupProvider(), blocks.contentsGetter(), MODID, helper) { @Override protected void addTags(HolderLookup.Provider provider) { // This is for testing if it is functional, remove spruce_planks from planks, which makes us unable to craft beds with them. diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/block/FullPotsAccessorDemo.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/block/FullPotsAccessorDemo.java index 4014e2b0b7..9ea4f3778d 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/block/FullPotsAccessorDemo.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/block/FullPotsAccessorDemo.java @@ -7,18 +7,17 @@ import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import java.util.ArrayList; import java.util.List; -import java.util.function.Function; import java.util.stream.Collectors; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverride; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.Material; +import net.minecraft.client.resources.model.DelegateBakedModel; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; import net.minecraft.client.resources.model.UnbakedModel; @@ -32,6 +31,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.stats.Stats; import net.minecraft.util.RandomSource; +import net.minecraft.util.context.ContextMap; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; @@ -60,12 +60,10 @@ import net.neoforged.fml.common.Mod; import net.neoforged.neoforge.client.ChunkRenderTypeSet; import net.neoforged.neoforge.client.event.ModelEvent; -import net.neoforged.neoforge.client.model.BakedModelWrapper; +import net.neoforged.neoforge.client.model.DelegateUnbakedModel; +import net.neoforged.neoforge.client.model.UnbakedModelLoader; import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.client.model.data.ModelProperty; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; -import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; import net.neoforged.neoforge.common.util.ConcatenatedListView; import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; import net.neoforged.neoforge.registries.DeferredBlock; @@ -226,31 +224,30 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider holderLooku @EventBusSubscriber(modid = MOD_ID, value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD) private static class ClientHandler { @SubscribeEvent - public static void registerLoader(final ModelEvent.RegisterGeometryLoaders event) { + public static void registerLoader(final ModelEvent.RegisterLoaders event) { event.register(ResourceLocation.fromNamespaceAndPath(MOD_ID, "diorite_pot"), new DioritePotGeometryLoader()); } - private static class DioritePotGeometryLoader implements IGeometryLoader { + private static class DioritePotGeometryLoader implements UnbakedModelLoader { @Override - public DioritePotModelGeometry read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) { + public DioritePotModelGeometry read(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { JsonObject wrappedModel = jsonObject.getAsJsonObject("model"); - return new DioritePotModelGeometry(deserializationContext.deserialize(wrappedModel, BlockModel.class)); + return new DioritePotModelGeometry(jsonDeserializationContext.deserialize(wrappedModel, UnbakedModel.class)); } } - private record DioritePotModelGeometry(UnbakedModel wrappedModel) implements IUnbakedGeometry { - @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { - return new DioritePotModel(wrappedModel.bake(baker, spriteGetter, modelState)); + private static final class DioritePotModelGeometry extends DelegateUnbakedModel { + private DioritePotModelGeometry(UnbakedModel wrappedModel) { + super(wrappedModel); } @Override - public void resolveDependencies(UnbakedModel.Resolver modelGetter, IGeometryBakingContext context) { - wrappedModel.resolveDependencies(modelGetter); + public BakedModel bake(TextureSlots p_386641_, ModelBaker p_250133_, ModelState p_119536_, boolean p_387129_, boolean p_388638_, ItemTransforms p_386911_, ContextMap additionalProperties) { + return new DioritePotModel(wrapped.bake(p_386641_, p_250133_, p_119536_, p_387129_, p_388638_, p_386911_, additionalProperties)); } } - private static class DioritePotModel extends BakedModelWrapper { + private static class DioritePotModel extends DelegateBakedModel { private static final ChunkRenderTypeSet CUTOUT = ChunkRenderTypeSet.of(RenderType.cutout()); private static final ResourceLocation POT_TEXTURE = ResourceLocation.fromNamespaceAndPath("minecraft", "block/flower_pot"); private static final ResourceLocation DIRT_TEXTURE = ResourceLocation.fromNamespaceAndPath("minecraft", "block/dirt"); @@ -262,7 +259,7 @@ public DioritePotModel(BakedModel wrappedModel) { @Override public List getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand, ModelData extraData, @Nullable RenderType renderType) { List> quads = new ArrayList<>(); - quads.add(originalModel.getQuads(state, side, rand, extraData, renderType)); + quads.add(parent.getQuads(state, side, rand, extraData, renderType)); Block plant = extraData.get(DioriteFlowerPotBlockEntity.PLANT_PROPERTY); if (plant != null && plant != Blocks.AIR) { diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/block/ScaffoldingTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/block/ScaffoldingTest.java index bc95052150..a5fe858ab8 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/block/ScaffoldingTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/block/ScaffoldingTest.java @@ -46,9 +46,9 @@ public ScaffoldingTest(IEventBus modBus) { modBus.addListener(this::gatherData); } - private void gatherData(final GatherDataEvent event) { + private void gatherData(final GatherDataEvent.Client event) { DataGenerator gen = event.getGenerator(); - gen.addProvider(event.includeClient(), new ScaffoldingBlockState(gen.getPackOutput(), MODID, event.getExistingFileHelper())); + event.addProvider(new ScaffoldingBlockState(gen.getPackOutput(), MODID, event.getExistingFileHelper())); } static class ScaffoldingBlockState extends BlockStateProvider { diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomArmorModelTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomArmorModelTest.java index a5cac68259..cc3a1486d2 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomArmorModelTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomArmorModelTest.java @@ -10,6 +10,7 @@ import net.minecraft.client.model.Model; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.state.HumanoidRenderState; +import net.minecraft.client.resources.model.EquipmentClientInfo; import net.minecraft.core.component.DataComponents; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ArmorItem; @@ -17,10 +18,8 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.DyedItemColor; -import net.minecraft.world.item.equipment.ArmorMaterial; import net.minecraft.world.item.equipment.ArmorMaterials; import net.minecraft.world.item.equipment.ArmorType; -import net.minecraft.world.item.equipment.EquipmentModel; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLEnvironment; @@ -44,8 +43,8 @@ public class CustomArmorModelTest { ArmorType.LEGGINGS, props.stacksTo(1).component(DataComponents.DYED_COLOR, new DyedItemColor(0xFF0000, false)))); // demonstrates the properties are copied from the vanilla model - private static final DeferredItem ENDERMAN_CHESTPLATE = ITEMS.registerItem("enderman_chestplate", props -> new EndermanArmorItem(ArmorMaterials.GOLD, ArmorType.CHESTPLATE, props.stacksTo(1))); - private static final DeferredItem ENDERMAN_BOOTS = ITEMS.registerItem("enderman_boots", props -> new EndermanArmorItem(ArmorMaterials.GOLD, ArmorType.BOOTS, props.stacksTo(1))); + private static final DeferredItem ENDERMAN_CHESTPLATE = ITEMS.registerItem("enderman_chestplate", props -> new ArmorItem(ArmorMaterials.GOLD, ArmorType.CHESTPLATE, props.stacksTo(1))); + private static final DeferredItem ENDERMAN_BOOTS = ITEMS.registerItem("enderman_boots", props -> new ArmorItem(ArmorMaterials.GOLD, ArmorType.BOOTS, props.stacksTo(1))); public CustomArmorModelTest(IEventBus modBus) { ITEMS.register(modBus); @@ -64,29 +63,22 @@ private void addCreative(BuildCreativeModeTabContentsEvent event) { } } - private static class EndermanArmorItem extends ArmorItem { - private static final ResourceLocation ARMOR_TEXTURE = ResourceLocation.withDefaultNamespace("textures/entity/enderman/enderman.png"); - - public EndermanArmorItem(ArmorMaterial material, ArmorType slot, Properties props) { - super(material, slot, props); - } - - @Nullable - @Override - public ResourceLocation getArmorTexture(ItemStack stack, EquipmentModel.LayerType type, EquipmentModel.Layer layer, ResourceLocation _default) { - return ARMOR_TEXTURE; - } - } - private static final class ClientEvents { + private static final ResourceLocation ARMOR_TEXTURE = ResourceLocation.withDefaultNamespace("textures/entity/enderman/enderman.png"); private static final Lazy> ENDERMAN = Lazy.of(() -> new HumanoidModel<>(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.ENDERMAN))); private static void onRegisterClientExtensions(RegisterClientExtensionsEvent event) { event.registerItem(new IClientItemExtensions() { @Override - public HumanoidModel getHumanoidArmorModel(ItemStack itemStack, EquipmentModel.LayerType armorSlot, Model _default) { + public HumanoidModel getHumanoidArmorModel(ItemStack itemStack, EquipmentClientInfo.LayerType armorSlot, Model _default) { return ENDERMAN.get(); } + + @Nullable + @Override + public ResourceLocation getArmorTexture(ItemStack stack, EquipmentClientInfo.LayerType type, EquipmentClientInfo.Layer layer, ResourceLocation _default) { + return ARMOR_TEXTURE; + } }, ENDERMAN_BOOTS.get(), ENDERMAN_CHESTPLATE.get()); } } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomPresetEditorTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomPresetEditorTest.java index b5701b006a..10edb82823 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomPresetEditorTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomPresetEditorTest.java @@ -51,7 +51,7 @@ public class CustomPresetEditorTest { @EventBusSubscriber(modid = MODID, bus = EventBusSubscriber.Bus.MOD) public static class CommonModEvents { @SubscribeEvent - public static void onGatherData(GatherDataEvent event) { + public static void onGatherData(GatherDataEvent.Client event) { DataGenerator gen = event.getGenerator(); PackOutput packOutput = gen.getPackOutput(); CompletableFuture lookupProvider = event.getLookupProvider(); @@ -59,7 +59,7 @@ public static void onGatherData(GatherDataEvent event) { RegistrySetBuilder registrySetBuilder = new RegistrySetBuilder() .add(Registries.WORLD_PRESET, context -> context.register(WORLD_PRESET_KEY, makeWorldPreset(context))); - gen.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(packOutput, lookupProvider, registrySetBuilder, Set.of(MODID)) { + gen.addProvider(true, new DatapackBuiltinEntriesProvider(packOutput, lookupProvider, registrySetBuilder, Set.of(MODID)) { @Override public String getName() { return MODID + ":" + super.getName(); // dataproviders must have unique names diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/CustomItemDisplayContextTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/CustomItemDisplayContextTest.java index c281cc6ee4..2a2e2e98cd 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/CustomItemDisplayContextTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/CustomItemDisplayContextTest.java @@ -5,6 +5,8 @@ package net.neoforged.neoforge.oldtest.client.model; +import static net.minecraft.client.data.models.model.ModelLocationUtils.getModelLocation; + import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.serialization.MapCodec; import net.minecraft.client.Minecraft; @@ -18,7 +20,6 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.DataGenerator; import net.minecraft.data.PackOutput; -import net.minecraft.data.models.model.ModelLocationUtils; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; import net.minecraft.network.protocol.Packet; @@ -100,9 +101,7 @@ public void render(ItemHangerBlockEntity blocken, float partialTicks, PoseStack ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); - var model = itemRenderer.getModel(blocken.heldItem, blocken.getLevel(), null, 0); - - itemRenderer.render(blocken.heldItem, HANGING, false, poseStack, bufferSource, packedLight, overlayCoord, model); + itemRenderer.renderStatic(blocken.heldItem, HANGING, packedLight, overlayCoord, poseStack, bufferSource, blocken.getLevel(), 0); poseStack.popPose(); } @@ -130,12 +129,12 @@ private void addCreative(BuildCreativeModeTabContentsEvent event) { event.accept(ITEM_HANGER_ITEM); } - public void gatherData(GatherDataEvent event) { + public void gatherData(GatherDataEvent.Client event) { DataGenerator gen = event.getGenerator(); final PackOutput output = gen.getPackOutput(); - gen.addProvider(event.includeClient(), new ItemModels(output, event.getExistingFileHelper())); - gen.addProvider(event.includeClient(), new BlockStateModels(output, event.getExistingFileHelper())); + gen.addProvider(true, new ItemModels(output, event.getExistingFileHelper())); + gen.addProvider(true, new BlockStateModels(output, event.getExistingFileHelper())); } public static class BlockStateModels extends BlockStateProvider { @@ -147,7 +146,7 @@ public BlockStateModels(PackOutput output, ExistingFileHelper exFileHelper) { protected void registerStatesAndModels() { { Block block = ITEM_HANGER_BLOCK.get(); - horizontalBlock(block, models().getExistingFile(ModelLocationUtils.getModelLocation(block))); + horizontalBlock(block, models().getExistingFile(getModelLocation(block))); } } } @@ -210,7 +209,7 @@ public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { @Deprecated @Override public RenderShape getRenderShape(BlockState state) { - return RenderShape.ENTITYBLOCK_ANIMATED; + return RenderShape.MODEL; } } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/MegaModelTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/MegaModelTest.java index e864f03a17..54fc9d6a20 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/MegaModelTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/MegaModelTest.java @@ -11,6 +11,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.DelegateBakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -39,7 +40,6 @@ import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; import net.neoforged.neoforge.client.event.ModelEvent; -import net.neoforged.neoforge.client.model.BakedModelWrapper; import net.neoforged.neoforge.client.model.QuadTransformers; import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.client.model.data.ModelProperty; @@ -98,7 +98,7 @@ public static class ClientEvents { @SubscribeEvent public static void onModelBakingCompleted(ModelEvent.ModifyBakingResult event) { var name = new ModelResourceLocation(ResourceLocation.fromNamespaceAndPath(MOD_ID, REG_NAME), ""); - event.getModels().computeIfPresent(name, (n, m) -> new TransformingModelWrapper(m)); + event.getBakingResult().blockStateModels().computeIfPresent(name, (n, m) -> new TransformingModelWrapper(m)); } } @@ -147,7 +147,7 @@ private record TestData(Transformation transform) { public static final ModelProperty PROPERTY = new ModelProperty<>(); } - private static class TransformingModelWrapper extends BakedModelWrapper { + private static class TransformingModelWrapper extends DelegateBakedModel { public TransformingModelWrapper(BakedModel originalModel) { super(originalModel); } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/NewModelLoaderTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/NewModelLoaderTest.java index db7b863456..199266704f 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/NewModelLoaderTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/NewModelLoaderTest.java @@ -7,16 +7,22 @@ import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import java.util.Arrays; -import java.util.function.Function; +import net.minecraft.client.data.models.model.TextureSlot; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.SimpleBakedModel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.data.DataGenerator; import net.minecraft.data.PackOutput; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.context.ContextMap; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.BlockItem; @@ -35,8 +41,11 @@ import net.minecraft.world.phys.shapes.VoxelShape; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.client.RenderTypeGroup; import net.neoforged.neoforge.client.event.ModelEvent; -import net.neoforged.neoforge.client.model.IModelBuilder; +import net.neoforged.neoforge.client.model.ExtendedUnbakedModel; +import net.neoforged.neoforge.client.model.NeoForgeModelProperties; +import net.neoforged.neoforge.client.model.UnbakedModelLoader; import net.neoforged.neoforge.client.model.generators.BlockModelBuilder; import net.neoforged.neoforge.client.model.generators.BlockStateProvider; import net.neoforged.neoforge.client.model.generators.ConfiguredModel; @@ -44,9 +53,6 @@ import net.neoforged.neoforge.client.model.generators.loaders.ItemLayerModelBuilder; import net.neoforged.neoforge.client.model.generators.loaders.ObjModelBuilder; import net.neoforged.neoforge.client.model.generators.loaders.SeparateTransformsModelBuilder; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; -import net.neoforged.neoforge.client.model.geometry.SimpleUnbakedGeometry; import net.neoforged.neoforge.client.model.pipeline.QuadBakingVertexConsumer; import net.neoforged.neoforge.common.data.ExistingFileHelper; import net.neoforged.neoforge.data.event.GatherDataEvent; @@ -119,21 +125,21 @@ private void addCreative(BuildCreativeModeTabContentsEvent event) { } } - public void modelRegistry(ModelEvent.RegisterGeometryLoaders event) { + public void modelRegistry(ModelEvent.RegisterLoaders event) { event.register(ResourceLocation.fromNamespaceAndPath(MODID, "custom_loader"), new TestLoader()); } - static class TestLoader implements IGeometryLoader { + static class TestLoader implements UnbakedModelLoader { @Override - public TestModel read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) { + public TestModel read(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { return new TestModel(); } } - static class TestModel extends SimpleUnbakedGeometry { + static class TestModel implements ExtendedUnbakedModel { @Override - protected void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuilder, ModelBaker baker, Function spriteGetter, ModelState modelTransform) { - TextureAtlasSprite texture = spriteGetter.apply(owner.getMaterial("particle")); + public BakedModel bake(TextureSlots textures, ModelBaker baker, ModelState modelState, boolean useAmbientOcclusion, boolean usesBlockLight, ItemTransforms itemTransforms, ContextMap additionalProperties) { + TextureAtlasSprite texture = baker.findSprite(textures, TextureSlot.PARTICLE.getId()); var quadBaker = new QuadBakingVertexConsumer(); @@ -145,18 +151,26 @@ protected void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuil quadBaker.addVertex(1, 0, 0.5f).setColor(255, 255, 255, 255).setUv(texture.getU(16), texture.getV(16)).setOverlay(0).setNormal(0, 0, 0); quadBaker.addVertex(1, 1, 0.5f).setColor(255, 255, 255, 255).setUv(texture.getU(16), texture.getV(0)).setOverlay(0).setNormal(0, 0, 0); - modelBuilder.addUnculledFace(quadBaker.bakeQuad()); + return new SimpleBakedModel.Builder(useAmbientOcclusion, usesBlockLight, true, itemTransforms) + .particle(texture) + .addUnculledFace(quadBaker.bakeQuad()) + .build(additionalProperties.getOrDefault(NeoForgeModelProperties.RENDER_TYPE, RenderTypeGroup.EMPTY)); + } + + @Override + public void resolveDependencies(Resolver p_387087_) { + // No dependencies } } - private void datagen(GatherDataEvent event) { + private void datagen(GatherDataEvent.Client event) { DataGenerator gen = event.getGenerator(); final PackOutput output = gen.getPackOutput(); // Let blockstate provider see generated item models by passing its existing file helper ItemModelProvider itemModels = new ItemModels(output, event.getExistingFileHelper()); - gen.addProvider(event.includeClient(), itemModels); - gen.addProvider(event.includeClient(), new BlockStates(output, itemModels.existingFileHelper)); + gen.addProvider(true, itemModels); + gen.addProvider(true, new BlockStates(output, itemModels.existingFileHelper)); } public static class ItemModels extends ItemModelProvider { diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/TRSRTransformerTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/TRSRTransformerTest.java index f30a5f7cc6..aed6f66b18 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/TRSRTransformerTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/TRSRTransformerTest.java @@ -7,9 +7,10 @@ import com.mojang.math.Transformation; import java.util.List; +import java.util.Map; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.BakedOverrides; import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; @@ -61,9 +62,10 @@ private void addCreative(BuildCreativeModeTabContentsEvent event) { } public void onModelBake(ModelEvent.ModifyBakingResult e) { - for (ModelResourceLocation id : e.getModels().keySet()) { + Map models = e.getBakingResult().blockStateModels(); + for (ModelResourceLocation id : models.keySet()) { if (MODID.equals(id.id().getNamespace()) && "test".equals(id.id().getPath())) { - e.getModels().put(id, new MyBakedModel(e.getModels().get(id))); + models.put(id, new MyBakedModel(models.get(id))); } } } @@ -101,19 +103,14 @@ public boolean usesBlockLight() { return base.usesBlockLight(); } - @Override - public boolean isCustomRenderer() { - return base.isCustomRenderer(); - } - @Override public TextureAtlasSprite getParticleIcon() { return base.getParticleIcon(); } @Override - public BakedOverrides overrides() { - return base.overrides(); + public ItemTransforms getTransforms() { + return base.getTransforms(); } } } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/CustomParticleTypeTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/CustomParticleTypeTest.java index 6e6a8e1183..7a1de85be4 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/CustomParticleTypeTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/CustomParticleTypeTest.java @@ -5,13 +5,12 @@ package net.neoforged.neoforge.oldtest.client.rendering; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.Tesselator; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.particle.ParticleRenderType; import net.minecraft.client.particle.TerrainParticle; -import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.Blocks; import net.neoforged.api.distmarker.Dist; @@ -29,30 +28,8 @@ public CustomParticleTypeTest() {} @EventBusSubscriber(modid = CustomParticleTypeTest.MOD_ID, bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT) public static class ClientEvents { - private static final ParticleRenderType CUSTOM_TYPE = new ParticleRenderType() { - @Override - public BufferBuilder begin(Tesselator tesselator, TextureManager texMgr) { - Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer(); - return ParticleRenderType.TERRAIN_SHEET.begin(tesselator, texMgr); - } - - @Override - public String toString() { - return "CUSTOM_TYPE"; - } - }; - private static final ParticleRenderType CUSTOM_TYPE_TWO = new ParticleRenderType() { - @Override - public BufferBuilder begin(Tesselator tesselator, TextureManager texMgr) { - Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer(); - return ParticleRenderType.TERRAIN_SHEET.begin(tesselator, texMgr); - } - - @Override - public String toString() { - return "CUSTOM_TYPE_TWO"; - } - }; + private static final ParticleRenderType CUSTOM_TYPE = new ParticleRenderType("CUSTOM_TYPE", RenderType.translucentParticle(TextureAtlas.LOCATION_BLOCKS)); + private static final ParticleRenderType CUSTOM_TYPE_TWO = new ParticleRenderType("CUSTOM_TYPE_TWO", RenderType.translucentParticle(TextureAtlas.LOCATION_BLOCKS)); private static class CustomParticle extends TerrainParticle { public CustomParticle(ClientLevel level, double x, double y, double z) { diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/RenderableTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/RenderableTest.java deleted file mode 100644 index 3e5e7f34a9..0000000000 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/RenderableTest.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.oldtest.client.rendering; - -import com.google.common.collect.ImmutableMap; -import com.mojang.blaze3d.vertex.PoseStack; -import java.util.Map; -import net.minecraft.client.DeltaTracker; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.server.packs.resources.SimplePreparableReloadListener; -import net.minecraft.util.profiling.Profiler; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.world.phys.Vec3; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.common.Mod; -import net.neoforged.fml.loading.FMLEnvironment; -import net.neoforged.neoforge.client.NeoForgeRenderTypes; -import net.neoforged.neoforge.client.event.ModelEvent; -import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; -import net.neoforged.neoforge.client.event.RenderLevelStageEvent; -import net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage; -import net.neoforged.neoforge.client.model.data.ModelData; -import net.neoforged.neoforge.client.model.geometry.StandaloneGeometryBakingContext; -import net.neoforged.neoforge.client.model.obj.ObjLoader; -import net.neoforged.neoforge.client.model.obj.ObjModel; -import net.neoforged.neoforge.client.model.renderable.BakedModelRenderable; -import net.neoforged.neoforge.client.model.renderable.CompositeRenderable; -import net.neoforged.neoforge.client.model.renderable.IRenderable; -import net.neoforged.neoforge.common.NeoForge; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.joml.Matrix4f; - -/** - * This mod is testing the use of {@link RenderLevelStageEvent} and is a modifaction of a pre-existing test mod that used the old - * RenderLevelLastEvent. To restore the old behavior, set {@link #USE_LEVEL_RENDERER_STAGE} to false. - * - * When you enter a world, there should be 6 sugar gliders rendering at (0, 120, 0) that test the various stages in {@link RenderLevelStageEvent}. - * From left to right (with the sugar gliders facing you) they represent {@link Stage#AFTER_SKY}, {@link Stage#AFTER_SOLID_BLOCKS}, - * {@link Stage#AFTER_TRANSLUCENT_BLOCKS}, {@link Stage#AFTER_TRIPWIRE_BLOCKS}, {@link Stage#AFTER_PARTICLES}, and {@link Stage#AFTER_WEATHER}. - * Due to how weather modifies the projection matrix, it's sugar glider will be positioned weirdly. Below each sugar gliders is a render of - * blue stained glass to test translucency with fabulous graphics. {@link Stage#AFTER_PARTICLES} will render the stained glass using - * {@link NeoForgeRenderTypes#TRANSLUCENT_ON_PARTICLES_TARGET}. - */ -@Mod(RenderableTest.MODID) -public class RenderableTest { - public static final String MODID = "renderable_test"; - private static final Logger LOGGER = LogManager.getLogger(); - - public static final boolean ENABLED = false; // Renders at (0, 120, 0) - - public RenderableTest(IEventBus modEventBus) { - if (ENABLED) { - if (FMLEnvironment.dist.isClient()) { - Client.init(modEventBus); - } - } - } - - private static class Client { - private static ModelResourceLocation MODEL_LOC = ModelResourceLocation.standalone( - ResourceLocation.fromNamespaceAndPath("minecraft", "block/blue_stained_glass")); - - private static IRenderable renderable; - private static IRenderable bakedRenderable; - - public static void init(IEventBus modBus) { - var forgeBus = NeoForge.EVENT_BUS; - modBus.addListener(Client::registerModels); - modBus.addListener(Client::registerReloadListeners); - modBus.addListener(Client::registerStage); - forgeBus.addListener(Client::renderStage); - } - - private static void registerModels(ModelEvent.RegisterAdditional event) { - event.register(MODEL_LOC); - } - - public static void registerReloadListeners(RegisterClientReloadListenersEvent event) { - event.registerReloadListener(new SimplePreparableReloadListener() { - @Override - protected ObjModel prepare(ResourceManager resourceManager, ProfilerFiller profilerFiller) { - var settings = new ObjModel.ModelSettings( - ResourceLocation.fromNamespaceAndPath("new_model_loader_test", "models/item/sugar_glider.obj"), - false, - true, - true, - false, - null); - return ObjLoader.INSTANCE.loadModel(settings); - } - - @Override - protected void apply(ObjModel model, ResourceManager resourceManager, ProfilerFiller profilerFiller) { - var config = StandaloneGeometryBakingContext.create(Map.of( - "#qr", ResourceLocation.fromNamespaceAndPath("minecraft", "block/quartz_block_top"))); - renderable = model.bakeRenderable(config); - } - }); - } - - public static void registerStage(RenderLevelStageEvent.RegisterStageEvent event) { - var stage = event.register(ResourceLocation.fromNamespaceAndPath(MODID, "test_stage"), null); - LOGGER.info("Registered RenderLevelStageEvent.Stage: {}", stage); - } - - private static void renderStage(RenderLevelStageEvent event) { - int xOffset = -1; - var stage = event.getStage(); - if (stage == Stage.AFTER_SKY) - xOffset = 0; - else if (stage == Stage.AFTER_SOLID_BLOCKS) - xOffset = 1; - else if (stage == Stage.AFTER_TRANSLUCENT_BLOCKS) - xOffset = 2; - else if (stage == Stage.AFTER_TRIPWIRE_BLOCKS) - xOffset = 3; - else if (stage == Stage.AFTER_PARTICLES) - xOffset = 4; - else if (stage == Stage.AFTER_WEATHER) - xOffset = 5; - - Vec3 cam = event.getCamera().getPosition(); - if (xOffset > -1) { - PoseStack poseStack = event.getPoseStack(); - render(stage, poseStack, event.getRenderTick(), event.getPartialTick(), cam.x, cam.y, cam.z, xOffset); - } - } - - private static void render(Stage stage, PoseStack poseStack, int renderTick, DeltaTracker deltaTracker, double camX, double camY, double camZ, int xOffset) { - double x = camX, y = camY, z = camZ; - if (!BlockPos.containing(0, y, 0).closerThan(BlockPos.containing(x, y, z), 100)) - return; - - var profiler = Profiler.get(); - profiler.push("renderable_test"); - if (bakedRenderable == null) { - bakedRenderable = BakedModelRenderable.of(MODEL_LOC).withModelDataContext(); - } - - var bufferSource = Minecraft.getInstance().renderBuffers().bufferSource(); - - float partialTick = deltaTracker.getGameTimeDeltaPartialTick(false); - double time = renderTick + partialTick; - - var map = ImmutableMap.builder(); - - var left = new Matrix4f(); - left.rotation((float) Math.sin(time * 0.4) * 0.1f, 0, 0, 1); - map.put("object_1", left); - - var right = new Matrix4f(); - right.rotation(-(float) Math.sin(time * 0.4) * 0.1f, 0, 0, 1); - map.put("object_9", right); - - var transforms = CompositeRenderable.Transforms.of(map.build()); - - poseStack.pushPose(); - poseStack.translate(0 - x + xOffset, 120 - y, 0 - z); - renderable.render(poseStack, bufferSource, RenderType::entitySolid, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, partialTick, transforms); - - poseStack.translate(0, -1, 0); - bakedRenderable.render(poseStack, bufferSource, texture -> getRenderType(stage, texture), LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, partialTick, ModelData.EMPTY); - poseStack.popPose(); - - bufferSource.endBatch(); - profiler.pop(); - } - - private static RenderType getRenderType(Stage stage, ResourceLocation texture) { - if (stage == Stage.AFTER_PARTICLES) - return NeoForgeRenderTypes.TRANSLUCENT_ON_PARTICLES_TARGET.get(); - return RenderType.entityTranslucent(texture); - } - } -} diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/item/CustomElytraTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/item/CustomElytraTest.java index 1b487ba11d..db79755c77 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/item/CustomElytraTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/item/CustomElytraTest.java @@ -6,11 +6,14 @@ package net.neoforged.neoforge.oldtest.item; import net.minecraft.core.component.DataComponents; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.item.Item; +import net.minecraft.world.item.equipment.EquipmentAsset; +import net.minecraft.world.item.equipment.EquipmentAssets; import net.minecraft.world.item.equipment.Equippable; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; @@ -21,11 +24,12 @@ @Mod(CustomElytraTest.MOD_ID) public class CustomElytraTest { public static final String MOD_ID = "custom_elytra_test"; + private static final ResourceKey TEST_ELYTRA_ASSET = ResourceKey.create(EquipmentAssets.ROOT_ID, ResourceLocation.fromNamespaceAndPath(MOD_ID, "test_elytra")); private static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MOD_ID); private static final DeferredItem TEST_ELYTRA = ITEMS.registerItem( "test_elytra", props -> new Item(props.durability(100) .component(DataComponents.EQUIPPABLE, Equippable.builder(EquipmentSlot.CHEST) - .setModel(ResourceLocation.fromNamespaceAndPath(MOD_ID, "test_elytra")) + .setAsset(TEST_ELYTRA_ASSET) .setEquipSound(SoundEvents.ARMOR_EQUIP_ELYTRA) .setDamageOnHurt(false) .build()))); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/item/RangedMobsUseModdedWeaponsTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/item/RangedMobsUseModdedWeaponsTest.java index a20a22f2ed..aeafcaaa62 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/item/RangedMobsUseModdedWeaponsTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/item/RangedMobsUseModdedWeaponsTest.java @@ -5,18 +5,12 @@ package net.neoforged.neoforge.oldtest.item; -import net.minecraft.client.renderer.item.ItemProperties; -import net.minecraft.core.component.DataComponents; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.BowItem; import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.item.CrossbowItem; import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.component.ChargedProjectiles; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; -import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; import net.neoforged.neoforge.registries.DeferredItem; import net.neoforged.neoforge.registries.DeferredRegister; @@ -39,7 +33,6 @@ public class RangedMobsUseModdedWeaponsTest { public RangedMobsUseModdedWeaponsTest(IEventBus modEventBus) { if (ENABLE) { ITEMS.register(modEventBus); - modEventBus.addListener(this::onClientSetup); modEventBus.addListener(this::addCreative); } } @@ -50,38 +43,4 @@ private void addCreative(BuildCreativeModeTabContentsEvent event) { event.accept(MODDED_CROSSBOW); } } - - private void onClientSetup(FMLClientSetupEvent event) { - RangedWeaponModeLProperties.initBowModelProperties(); - RangedWeaponModeLProperties.initCrossbowModelProperties(); - } - - private static class RangedWeaponModeLProperties { - static void initBowModelProperties() { - ItemProperties.register(MODDED_BOW.get(), ResourceLocation.withDefaultNamespace("pull"), (itemStack, clientWorld, livingEntity, seed) -> { - if (livingEntity == null) { - return 0.0F; - } else { - return livingEntity.getUseItem() != itemStack ? 0.0F : (float) (itemStack.getUseDuration(livingEntity) - livingEntity.getUseItemRemainingTicks()) / 20.0F; - } - }); - ItemProperties.register(MODDED_BOW.get(), ResourceLocation.withDefaultNamespace("pulling"), (itemStack, clientWorld, livingEntity, seed) -> livingEntity != null && livingEntity.isUsingItem() && livingEntity.getUseItem() == itemStack ? 1.0F : 0.0F); - } - - static void initCrossbowModelProperties() { - ItemProperties.register(MODDED_CROSSBOW.get(), ResourceLocation.withDefaultNamespace("pull"), (itemStack, clientWorld, livingEntity, seed) -> { - if (livingEntity == null) { - return 0.0F; - } else { - return CrossbowItem.isCharged(itemStack) ? 0.0F : (float) (itemStack.getUseDuration(livingEntity) - livingEntity.getUseItemRemainingTicks()) / (float) CrossbowItem.getChargeDuration(itemStack, livingEntity); - } - }); - ItemProperties.register(MODDED_CROSSBOW.get(), ResourceLocation.withDefaultNamespace("pulling"), (itemStack, clientWorld, livingEntity, seed) -> livingEntity != null && livingEntity.isUsingItem() && livingEntity.getUseItem() == itemStack && !CrossbowItem.isCharged(itemStack) ? 1.0F : 0.0F); - ItemProperties.register(MODDED_CROSSBOW.get(), ResourceLocation.withDefaultNamespace("charged"), (itemStack, clientWorld, livingEntity, seed) -> livingEntity != null && CrossbowItem.isCharged(itemStack) ? 1.0F : 0.0F); - ItemProperties.register(MODDED_CROSSBOW.get(), ResourceLocation.withDefaultNamespace("firework"), (itemStack, clientWorld, livingEntity, seed) -> { - ChargedProjectiles chargedprojectiles = itemStack.get(DataComponents.CHARGED_PROJECTILES); - return chargedprojectiles != null && chargedprojectiles.contains(Items.FIREWORK_ROCKET) ? 1.0F : 0.0F; - }); - } - } } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/misc/DataPackRegistriesTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/misc/DataPackRegistriesTest.java index 6e27bf2a21..f120f78030 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/misc/DataPackRegistriesTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/misc/DataPackRegistriesTest.java @@ -81,7 +81,7 @@ public DataPackRegistriesTest(IEventBus modBus) { } } - private void onGatherData(final GatherDataEvent event) { + private void onGatherData(final GatherDataEvent.Client event) { // Example of how to datagen datapack registry objects. // Objects to be datagenerated must be registered (e.g. via DeferredRegister above). // This outputs to data/data_pack_registries_test/data_pack_registries_test/unsyncable/datagen_test.json @@ -95,7 +95,7 @@ private void onGatherData(final GatherDataEvent event) { final String pathString = String.join("/", PackType.SERVER_DATA.getDirectory(), id.getNamespace(), registryId.getNamespace(), registryId.getPath(), id.getPath() + ".json"); final Path path = outputFolder.resolve(pathString); - generator.addProvider(event.includeServer(), new DataProvider() { + generator.addProvider(true, new DataProvider() { @Override public CompletableFuture run(final CachedOutput cache) { return providerCompletableFuture.thenCompose(provider -> { diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/world/BiomeModifierTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/world/BiomeModifierTest.java index a6a6b19699..1b5aeb7395 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/world/BiomeModifierTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/world/BiomeModifierTest.java @@ -125,8 +125,8 @@ public BiomeModifierTest(IEventBus modBus) { modBus.addListener(this::onGatherData); } - private void onGatherData(GatherDataEvent event) { - event.getGenerator().addProvider(event.includeServer(), (DataProvider.Factory) output -> new BiomeModifiers(output, event.getLookupProvider())); + private void onGatherData(GatherDataEvent.Client event) { + event.getGenerator().addProvider(true, (DataProvider.Factory) output -> new BiomeModifiers(output, event.getLookupProvider())); } private static class BiomeModifiers extends DatapackBuiltinEntriesProvider { diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/world/LoginPacketSplitTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/world/LoginPacketSplitTest.java index 45235579bd..e4d88fbc1b 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/world/LoginPacketSplitTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/world/LoginPacketSplitTest.java @@ -43,7 +43,7 @@ import net.minecraft.server.packs.PackResources; import net.minecraft.server.packs.PackSelectionConfig; import net.minecraft.server.packs.PackType; -import net.minecraft.server.packs.metadata.MetadataSectionSerializer; +import net.minecraft.server.packs.metadata.MetadataSectionType; import net.minecraft.server.packs.repository.BuiltInPackSource; import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackSource; @@ -210,12 +210,14 @@ public Set getNamespaces(PackType type) { @Nullable @Override - public T getMetadataSection(MetadataSectionSerializer section) throws IOException { + public T getMetadataSection(MetadataSectionType section) throws IOException { final JsonObject json = GsonHelper.parse(new String(root.get("pack.mcmeta").get())); - if (!json.has(section.getMetadataSectionName())) { + if (!json.has(section.name())) { return null; } else { - return section.fromJson(GsonHelper.getAsJsonObject(json, section.getMetadataSectionName())); + return section.codec().parse(JsonOps.INSTANCE, json.get(section.name())) + .result() + .orElse(null); } } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/world/StructureModifierTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/world/StructureModifierTest.java index 36f3494f6e..4608334011 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/world/StructureModifierTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/world/StructureModifierTest.java @@ -61,7 +61,7 @@ public StructureModifierTest(IEventBus modBus) { modBus.addListener(this::onGatherData); } - private void onGatherData(GatherDataEvent event) { + private void onGatherData(GatherDataEvent.Client event) { /* TODO: During the update to 1.19.3 data providers got partially turned into async executions. Creating a registry ops requires this. // Example of how to datagen datapack registry objects. diff --git a/tests/src/main/resources/assets/custom_fluid_container_test/items/custom_fluid_container.json b/tests/src/main/resources/assets/custom_fluid_container_test/items/custom_fluid_container.json new file mode 100644 index 0000000000..1e8e2a0398 --- /dev/null +++ b/tests/src/main/resources/assets/custom_fluid_container_test/items/custom_fluid_container.json @@ -0,0 +1,10 @@ +{ + "model": { + "type": "neoforge:fluid_container", + "fluid": "minecraft:empty", + "textures": { + "base": "item/bucket", + "fluid": "neoforge:item/mask/bucket_fluid_drip" + } + } +} diff --git a/tests/src/main/resources/assets/custom_fluid_container_test/models/item/custom_fluid_container.json b/tests/src/main/resources/assets/custom_fluid_container_test/models/item/custom_fluid_container.json deleted file mode 100644 index 0376391827..0000000000 --- a/tests/src/main/resources/assets/custom_fluid_container_test/models/item/custom_fluid_container.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "parent": "neoforge:item/default", - "loader": "neoforge:fluid_container", - "fluid": "minecraft:empty", - "cover_is_mask": true, - "textures": { - "base": "item/bucket", - "fluid": "neoforge:item/mask/bucket_fluid_drip", - "cover": "neoforge:item/mask/bucket_fluid_cover_drip" - } -} From 731d2264dea1afbc2f6397ebe2fcee5932275308 Mon Sep 17 00:00:00 2001 From: shartte Date: Tue, 3 Dec 2024 20:28:05 +0100 Subject: [PATCH 18/27] Fix JSON type of "spec" field in installer profile JSON (#1723) (#1727) --- .../neoforged/neodev/installer/CreateInstallerProfile.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateInstallerProfile.java b/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateInstallerProfile.java index 3b745f744a..c9da8c83ec 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateInstallerProfile.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateInstallerProfile.java @@ -178,7 +178,7 @@ public void createInstallerProfile() throws IOException { )))); var profile = new InstallerProfile( - "1", + 1, "NeoForge", "neoforge-%s".formatted(getNeoForgeVersion().get()), icon, @@ -203,7 +203,7 @@ public void createInstallerProfile() throws IOException { } record InstallerProfile( - String spec, + int spec, String profile, String version, String icon, From d6085a989a15332e054a0f87e51dfc1bc309a46a Mon Sep 17 00:00:00 2001 From: shartte Date: Wed, 4 Dec 2024 00:02:40 +0100 Subject: [PATCH 19/27] Make self-test more robust against ticking multiple times (#1729) --- .../neoforged/neoforge/common/util/SelfTest.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/common/util/SelfTest.java b/src/main/java/net/neoforged/neoforge/common/util/SelfTest.java index 734294cdf0..e669653751 100644 --- a/src/main/java/net/neoforged/neoforge/common/util/SelfTest.java +++ b/src/main/java/net/neoforged/neoforge/common/util/SelfTest.java @@ -39,8 +39,10 @@ public static void initClient() { if (Minecraft.getInstance().getOverlay() instanceof LoadingOverlay) { return; } - writeSelfTestReport(clientSelfTestDestination); - Minecraft.getInstance().stop(); + if (Minecraft.getInstance().isRunning()) { + writeSelfTestReport(clientSelfTestDestination); + Minecraft.getInstance().stop(); + } }); } } @@ -53,8 +55,10 @@ public static void initCommon() { System.exit(1); } NeoForge.EVENT_BUS.addListener((ServerTickEvent.Pre e) -> { - writeSelfTestReport(serverSelfTestDestination); - e.getServer().halt(false); + if (e.getServer().isRunning()) { + writeSelfTestReport(serverSelfTestDestination); + e.getServer().halt(false); + } }); } } @@ -66,11 +70,10 @@ public static void initCommon() { private static void writeSelfTestReport(String path) { try { Files.createFile(Paths.get(path)); + LOGGER.info("Wrote self-test report to '{}'", path); } catch (IOException e) { LOGGER.error("Failed to write self-test to '{}'", path, e); System.exit(1); } - - LOGGER.info("Write self-test report to '{}'", path); } } From 48244999bedb1589b0e973b2029191a52549d32c Mon Sep 17 00:00:00 2001 From: IMS Date: Wed, 4 Dec 2024 08:24:33 -0800 Subject: [PATCH 20/27] Fix incorrect ParticleEngine render patch (#1728) --- .../net/minecraft/client/renderer/LevelRenderer.java.patch | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch index 8bb0f0e49c..3150741277 100644 --- a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch @@ -81,10 +81,12 @@ FramePass framepass = p_363357_.addPass("particles"); if (this.targets.particles != null) { this.targets.particles = framepass.readsAndWrites(this.targets.particles); -@@ -679,6 +_,7 @@ +@@ -678,7 +_,8 @@ + resourcehandle1.get().copyDepthFrom(resourcehandle.get()); } - this.minecraft.particleEngine.render(p_365299_, p_364282_, this.renderBuffers.bufferSource()); +- this.minecraft.particleEngine.render(p_365299_, p_364282_, this.renderBuffers.bufferSource()); ++ this.minecraft.particleEngine.render(p_365299_, p_364282_, this.renderBuffers.bufferSource(), frustum, resourcehandle1 == null ? type -> type.translucent() : type -> true); // Neo: only render translucent particles here in Fast/Fancy + net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_PARTICLES, this, null, modelViewMatrix, projectionMatrix, this.ticks, p_365299_, getFrustum()); }); } From 371fc84b7a37f12304a1752b24e23f84ba678a6a Mon Sep 17 00:00:00 2001 From: Matyrobbrt <65940752+Matyrobbrt@users.noreply.github.com> Date: Wed, 4 Dec 2024 22:22:58 +0200 Subject: [PATCH 21/27] Patch `Ingredient#isEmpty` for custom ingredients (#1735) --- .../world/item/crafting/Ingredient.java.patch | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch index d38b0c8667..a7604a0a1f 100644 --- a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch +++ b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch @@ -27,7 +27,7 @@ private Ingredient(HolderSet p_365027_) { p_365027_.unwrap().ifRight(p_360057_ -> { -@@ -45,12 +_,23 @@ +@@ -45,30 +_,96 @@ this.values = p_365027_; } @@ -43,15 +43,16 @@ @Deprecated public Stream> items() { + if (this.customIngredient != null) { -+ if (this.customIngredientValues == null) { -+ this.customIngredientValues = this.customIngredient.items().toList(); -+ } -+ return this.customIngredientValues.stream(); ++ return updateCustomIngredientValues().stream(); + } return this.values.stream(); } -@@ -59,16 +_,67 @@ + public boolean isEmpty() { ++ if (this.customIngredient != null) { ++ return updateCustomIngredientValues().isEmpty(); ++ } + return this.values.size() == 0; } public boolean test(ItemStack p_43914_) { @@ -63,10 +64,7 @@ public boolean acceptsItem(Holder p_389400_) { + if (this.customIngredient != null) { -+ if (this.customIngredientValues == null) { -+ this.customIngredientValues = this.customIngredient.items().toList(); -+ } -+ return this.customIngredientValues.contains(p_389400_); ++ return updateCustomIngredientValues().contains(p_389400_); + } return this.values.contains(p_389400_); } @@ -117,6 +115,13 @@ + + public boolean isCustom() { + return this.customIngredient != null; ++ } ++ ++ private List> updateCustomIngredientValues() { ++ if (this.customIngredientValues == null) { ++ this.customIngredientValues = this.customIngredient.items().toList(); ++ } ++ return this.customIngredientValues; } public static Ingredient of(ItemLike p_364285_) { From 220ce160beab0e5eb52451ca707f4c0fe4960348 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Wed, 4 Dec 2024 20:26:38 +0000 Subject: [PATCH 22/27] Allow running client commands from chat components (#554) --- .../client/multiplayer/ClientPacketListener.java.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch index dab1a825b8..e7245ea6e2 100644 --- a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch @@ -143,6 +143,15 @@ SignableCommand signablecommand = SignableCommand.of(this.parseCommand(p_250092_)); if (signablecommand.arguments().isEmpty()) { this.send(new ServerboundChatCommandPacket(p_250092_)); +@@ -2565,6 +_,8 @@ + } + + public boolean sendUnsignedCommand(String p_251509_) { ++ // Neo: Dispatch client commands for text component click actions. ++ if (net.neoforged.neoforge.client.ClientCommandHandler.runCommand(p_251509_)) return true; + if (!SignableCommand.hasSignableArguments(this.parseCommand(p_251509_))) { + this.send(new ServerboundChatCommandPacket(p_251509_)); + return true; @@ -2640,6 +_,10 @@ public Scoreboard scoreboard() { From c4c7d94ca702a57031647542523d314ba7d0cfb4 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 4 Dec 2024 21:46:39 -0500 Subject: [PATCH 23/27] Skip GL state manipulation in ItemDecoratorHandler when there are no decorators (#1737) --- .../net/neoforged/neoforge/client/ItemDecoratorHandler.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/net/neoforged/neoforge/client/ItemDecoratorHandler.java b/src/main/java/net/neoforged/neoforge/client/ItemDecoratorHandler.java index 5be3ae2574..33fe41b1e9 100644 --- a/src/main/java/net/neoforged/neoforge/client/ItemDecoratorHandler.java +++ b/src/main/java/net/neoforged/neoforge/client/ItemDecoratorHandler.java @@ -50,6 +50,10 @@ public static ItemDecoratorHandler of(ItemStack stack) { } public void render(GuiGraphics guiGraphics, Font font, ItemStack stack, int xOffset, int yOffset) { + if (itemDecorators.isEmpty()) { + return; + } + RenderSystem.backupGlState(stateBackup); resetRenderState(); From 7df0d3591129cca20a980eb64df563ed76604ec2 Mon Sep 17 00:00:00 2001 From: Matyrobbrt <65940752+Matyrobbrt@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:01:00 +0200 Subject: [PATCH 24/27] Do not attempt to format mod description contents (#1739) Fixes #1561 --- .../java/net/neoforged/neoforge/client/gui/ModListScreen.java | 2 +- tests/src/main/resources/META-INF/neoforge.mods.toml | 2 +- tests/src/main/resources/assets/neotests/lang/fr_fr.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java b/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java index 12797e7beb..e269ca3c46 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java @@ -426,7 +426,7 @@ public void upload() { lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.updateavailable", vercheck.url() == null ? "" : vercheck.url()).replace("\r\n", "\n")); lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.license", selectedMod.getOwningFile().getLicense()).replace("\r\n", "\n")); lines.add(null); - lines.add(FMLTranslations.parseMessageWithFallback("fml.menu.mods.info.description." + selectedMod.getModId(), selectedMod::getDescription)); + lines.add(FMLTranslations.getPattern("fml.menu.mods.info.description." + selectedMod.getModId(), selectedMod::getDescription)); /* Removed because people bitched that this information was misleading. lines.add(null); diff --git a/tests/src/main/resources/META-INF/neoforge.mods.toml b/tests/src/main/resources/META-INF/neoforge.mods.toml index 54ccb00e57..481bcfb8c2 100644 --- a/tests/src/main/resources/META-INF/neoforge.mods.toml +++ b/tests/src/main/resources/META-INF/neoforge.mods.toml @@ -7,7 +7,7 @@ license="LGPL v2.1" [[mods]] modId="neotests" - description="NeoForge tests. Change the language to fr_fr and the description should change too." + description="NeoForge's tests. Change the language to fr_fr and the description should change too." enumExtensions="META-INF/enumextensions.json" [[mods]] modId="configui" diff --git a/tests/src/main/resources/assets/neotests/lang/fr_fr.json b/tests/src/main/resources/assets/neotests/lang/fr_fr.json index 02c2309d89..b659ab125e 100644 --- a/tests/src/main/resources/assets/neotests/lang/fr_fr.json +++ b/tests/src/main/resources/assets/neotests/lang/fr_fr.json @@ -1,3 +1,3 @@ { - "fml.menu.mods.info.description.neotests": "Le mod de test de NeoForge oh la la !" + "fml.menu.mods.info.description.neotests": "Le mod de test de NeoForge oh la la ! J'aime le français !" } From adc897458b0656a54fdebfaf92b9c33d0fa412a1 Mon Sep 17 00:00:00 2001 From: Matyrobbrt <65940752+Matyrobbrt@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:34:49 +0200 Subject: [PATCH 25/27] Implement synced registry check in holder stream codec (#974) --- .../network/codec/ByteBufCodecs.java.patch | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/patches/net/minecraft/network/codec/ByteBufCodecs.java.patch b/patches/net/minecraft/network/codec/ByteBufCodecs.java.patch index ac8e4a2731..0ae4bbce31 100644 --- a/patches/net/minecraft/network/codec/ByteBufCodecs.java.patch +++ b/patches/net/minecraft/network/codec/ByteBufCodecs.java.patch @@ -1,19 +1,37 @@ --- a/net/minecraft/network/codec/ByteBufCodecs.java +++ b/net/minecraft/network/codec/ByteBufCodecs.java -@@ -487,7 +_,11 @@ +@@ -487,7 +_,7 @@ ) { return new StreamCodec() { private IdMap getRegistryOrThrow(RegistryFriendlyByteBuf p_362297_) { - return p_320353_.apply(p_362297_.registryAccess().lookupOrThrow(p_319942_)); -+ var registry = p_362297_.registryAccess().lookupOrThrow(p_319942_); -+ if (net.neoforged.neoforge.registries.RegistryManager.isNonSyncedBuiltInRegistry(registry)) { -+ throw new IllegalStateException("Cannot use ID syncing for non-synced built-in registry: " + registry.key()); -+ } -+ return p_320353_.apply(registry); ++ return p_320353_.apply(getSyncableRegistryOrThrow(p_362297_, p_319942_)); } public R decode(RegistryFriendlyByteBuf p_340887_) { -@@ -544,8 +_,25 @@ +@@ -517,7 +_,7 @@ + private static final int DIRECT_HOLDER_ID = 0; + + private IdMap> getRegistryOrThrow(RegistryFriendlyByteBuf p_376392_) { +- return p_376392_.registryAccess().lookupOrThrow(p_320391_).asHolderIdMap(); ++ return getSyncableRegistryOrThrow(p_376392_, p_320391_).asHolderIdMap(); + } + + public Holder decode(RegistryFriendlyByteBuf p_363509_) { +@@ -539,13 +_,38 @@ + }; + } + ++ private static Registry getSyncableRegistryOrThrow(RegistryFriendlyByteBuf buffer, ResourceKey> registryKey) { ++ var registry = buffer.registryAccess().lookupOrThrow(registryKey); ++ if (net.neoforged.neoforge.registries.RegistryManager.isNonSyncedBuiltInRegistry(registry)) { ++ throw new io.netty.handler.codec.CodecException("Cannot use ID syncing for non-synced built-in registry: " + registry.key()); ++ } ++ return registry; ++ } ++ + static StreamCodec> holderSet(final ResourceKey> p_332137_) { + return new StreamCodec>() { private static final int NAMED_SET = -1; private final StreamCodec> holderCodec = ByteBufCodecs.holderRegistry(p_332137_); From e59a37f023e4d0c929426bbfd9ef103da09b89b8 Mon Sep 17 00:00:00 2001 From: Matyrobbrt <65940752+Matyrobbrt@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:47:35 +0200 Subject: [PATCH 26/27] Fix statistics for vehicles not working (#1744) --- .../network/ServerGamePacketListenerImpl.java.patch | 8 ++++++++ src/main/resources/META-INF/accesstransformer.cfg | 1 + 2 files changed, 9 insertions(+) diff --git a/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 8575501ec9..21867c9a0e 100644 --- a/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -12,6 +12,14 @@ this.send(ClientboundMoveVehiclePacket.fromEntity(entity)); return; } +@@ -455,6 +_,7 @@ + entity.setOnGroundWithMovement(p_9876_.onGround(), vec3); + entity.doCheckFallDamage(vec3.x, vec3.y, vec3.z, p_9876_.onGround()); + this.player.checkMovementStatistics(vec3.x, vec3.y, vec3.z); ++ this.player.checkRidingStatistics(vec3.x, vec3.y, vec3.z); // Neo: check riding stats too as vanilla checks them in rideTick based on the assumption that Entity#rideTick will move the entity, which we break + this.clientVehicleIsFloating = d11 >= -0.03125 + && !flag1 + && !this.server.isFlightAllowed() @@ -467,6 +_,23 @@ } } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 9a143aea76..1f3cdb8df4 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -161,6 +161,7 @@ public net.minecraft.server.MinecraftServer$ReloadableResources (Lnet/mine public net.minecraft.server.level.ChunkMap getVisibleChunkIfPresent(J)Lnet/minecraft/server/level/ChunkHolder; public net.minecraft.server.level.ServerChunkCache level # level public net.minecraft.server.level.ServerLevel getEntities()Lnet/minecraft/world/level/entity/LevelEntityGetter; # getEntities +public net.minecraft.server.level.ServerPlayer checkRidingStatistics(DDD)V # checkRidingStatistics public net.minecraft.server.level.ServerPlayer$RespawnPosAngle public net.minecraft.server.level.ServerPlayer$RespawnPosAngle (Lnet/minecraft/world/phys/Vec3;F)V public net.minecraft.server.packs.FilePackResources (Lnet/minecraft/server/packs/PackLocationInfo;Lnet/minecraft/server/packs/FilePackResources$SharedZipFileAccess;Ljava/lang/String;)V # constructor From 00f3f80ef94a08d867d9cdd5107c35777712050f Mon Sep 17 00:00:00 2001 From: Matyrobbrt <65940752+Matyrobbrt@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:22:16 +0200 Subject: [PATCH 27/27] Add task to generate ats (#1719) --- .github/workflows/check-local-changes.yml | 4 +- buildSrc/build.gradle | 2 + .../neodev/ApplyAccessTransformer.java | 25 +- .../neodev/GenerateAccessTransformers.java | 179 +++++++++ .../net/neoforged/neodev/NeoDevPlugin.java | 51 ++- .../neodev/utils/SerializablePredicate.java | 10 + .../neodev/utils/structure/ClassInfo.java | 27 ++ .../structure/ClassStructureVisitor.java | 83 ++++ .../neodev/utils/structure/FieldInfo.java | 10 + .../neodev/utils/structure/MethodInfo.java | 10 + projects/neoforge/build.gradle | 61 +++ settings.gradle | 1 + .../resources/META-INF/accesstransformer.cfg | 206 +--------- .../META-INF/accesstransformergenerated.cfg | 380 ++++++++++++++++++ .../resources/META-INF/neoforge.mods.toml | 5 + 15 files changed, 823 insertions(+), 231 deletions(-) create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/GenerateAccessTransformers.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/utils/SerializablePredicate.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/utils/structure/ClassInfo.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/utils/structure/ClassStructureVisitor.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/utils/structure/FieldInfo.java create mode 100644 buildSrc/src/main/java/net/neoforged/neodev/utils/structure/MethodInfo.java create mode 100644 src/main/resources/META-INF/accesstransformergenerated.cfg diff --git a/.github/workflows/check-local-changes.yml b/.github/workflows/check-local-changes.yml index 0609d67e89..3af8b101d0 100644 --- a/.github/workflows/check-local-changes.yml +++ b/.github/workflows/check-local-changes.yml @@ -40,8 +40,8 @@ jobs: - name: Gen package infos run: ./gradlew generatePackageInfos - - name: Gen patches - run: ./gradlew :neoforge:genPatches + - name: Gen patches and ATs + run: ./gradlew :neoforge:genPatches :neoforge:generateAccessTransformers - name: Run datagen with Gradle run: ./gradlew :neoforge:runData :tests:runData diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 6d0ce4c5af..7c272aa20a 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -23,4 +23,6 @@ dependencies { implementation "com.google.code.gson:gson:${gradle.parent.ext.gson_version}" implementation "io.codechicken:DiffPatch:${gradle.parent.ext.diffpatch_version}" + + implementation "org.ow2.asm:asm:${gradle.parent.ext.asm_version}" } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/ApplyAccessTransformer.java b/buildSrc/src/main/java/net/neoforged/neodev/ApplyAccessTransformer.java index 7131cc8fdd..2456766cef 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/ApplyAccessTransformer.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/ApplyAccessTransformer.java @@ -7,6 +7,7 @@ import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.JavaExec; import org.gradle.api.tasks.OutputFile; @@ -17,6 +18,8 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; /** * Runs JavaSourceTransformer to apply @@ -28,8 +31,8 @@ abstract class ApplyAccessTransformer extends JavaExec { @InputFile public abstract RegularFileProperty getInputJar(); - @InputFile - public abstract RegularFileProperty getAccessTransformer(); + @InputFiles + public abstract ConfigurableFileCollection getAccessTransformers(); @Input public abstract Property getValidate(); @@ -59,13 +62,23 @@ public void exec() { throw new UncheckedIOException("Failed to write libraries for JST.", exception); } - args( + var args = new ArrayList<>(Arrays.asList( "--enable-accesstransformers", - "--access-transformer", getAccessTransformer().getAsFile().get().getAbsolutePath(), "--access-transformer-validation", getValidate().get() ? "error" : "log", - "--libraries-list", getLibrariesFile().getAsFile().get().getAbsolutePath(), + "--libraries-list", getLibrariesFile().getAsFile().get().getAbsolutePath() + )); + + for (var file : getAccessTransformers().getFiles()) { + args.addAll(Arrays.asList( + "--access-transformer", file.getAbsolutePath() + )); + } + + args.addAll(Arrays.asList( getInputJar().getAsFile().get().getAbsolutePath(), - getOutputJar().getAsFile().get().getAbsolutePath()); + getOutputJar().getAsFile().get().getAbsolutePath())); + + args(args); super.exec(); } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/GenerateAccessTransformers.java b/buildSrc/src/main/java/net/neoforged/neodev/GenerateAccessTransformers.java new file mode 100644 index 0000000000..0158087e5a --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/GenerateAccessTransformers.java @@ -0,0 +1,179 @@ +package net.neoforged.neodev; + +import net.neoforged.neodev.utils.FileUtils; +import net.neoforged.neodev.utils.SerializablePredicate; +import net.neoforged.neodev.utils.structure.ClassInfo; +import net.neoforged.neodev.utils.structure.ClassStructureVisitor; +import net.neoforged.neodev.utils.structure.FieldInfo; +import net.neoforged.neodev.utils.structure.MethodInfo; +import org.gradle.api.DefaultTask; +import org.gradle.api.Named; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.ListProperty; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.TaskAction; +import org.objectweb.asm.Opcodes; + +import javax.annotation.Nullable; +import java.io.IOException; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * This task is used to generate access transformers based on a set of rules defined in the buildscript. + */ +public abstract class GenerateAccessTransformers extends DefaultTask { + public static final Modifier PUBLIC = new Modifier("public", false, Opcodes.ACC_PUBLIC); + public static final Modifier PROTECTED = new Modifier("protected", false, Opcodes.ACC_PUBLIC, Opcodes.ACC_PROTECTED); + + @InputFile + public abstract RegularFileProperty getInput(); + + @OutputFile + public abstract RegularFileProperty getAccessTransformer(); + + @Input + public abstract ListProperty getGroups(); + + @TaskAction + public void exec() throws IOException { + // First we collect all classes + var targets = ClassStructureVisitor.readJar(getInput().getAsFile().get()); + + var groupList = getGroups().get(); + + List[] groups = new List[groupList.size()]; + for (int i = 0; i < groupList.size(); i++) { + groups[i] = new ArrayList<>(); + } + + // Now we check each class against each group and see if the group wants to handle it + for (ClassInfo value : targets.values()) { + for (int i = 0; i < groupList.size(); i++) { + var group = groupList.get(i); + if (group.classMatch.test(value)) { + var lastInner = value.name().lastIndexOf("$"); + // Skip anonymous classes + if (lastInner >= 0 && Character.isDigit(value.name().charAt(lastInner + 1))) { + continue; + } + + // fieldMatch is non-null only for field ATs + if (group.fieldMatch != null) { + for (var field : value.fields()) { + if (group.fieldMatch.test(field) && !group.modifier.test(field.access())) { + groups[i].add(group.modifier.name + " " + value.name().replace('/', '.') + " " + field.name()); + } + } + } + // methodMatch is non-null only for group ATs + else if (group.methodMatch != null) { + for (var method : value.methods()) { + if (group.methodMatch.test(method) && !group.modifier.test(method.access())) { + groups[i].add(group.modifier.name + " " + value.name().replace('/', '.') + " " + method.name() + method.descriptor()); + } + } + } + // If there's neither a field nor a method predicate, this is a class AT + else if (!group.modifier.test(value.access().intValue())) { + groups[i].add(group.modifier.name + " " + value.name().replace('/', '.')); + + // If we AT a record we must ensure that its constructors have the same AT + if (value.hasSuperclass("java/lang/Record")) { + for (MethodInfo method : value.methods()) { + if (method.name().equals("")) { + groups[i].add(group.modifier.name + " " + value.name().replace('/', '.') + " " + method.name() + method.descriptor()); + } + } + } + } + } + } + } + + // Dump the ATs + var text = new StringBuilder(); + + text.append("# This file is generated based on the rules defined in the buildscript. DO NOT modify it manually.\n# Add more rules in the buildscript and then run the generateAccessTransformers task to update this file.\n\n"); + + for (int i = 0; i < groups.length; i++) { + // Check if the group found no targets. If it didn't, there's probably an error in the test and it should be reported + if (groups[i].isEmpty()) { + throw new IllegalStateException("Generated AT group '" + groupList.get(i).name + "' found no entries!"); + } + text.append("# ").append(groupList.get(i).name).append('\n'); + text.append(groups[i].stream().sorted().collect(Collectors.joining("\n"))); + text.append('\n'); + + if (i < groups.length - 1) text.append('\n'); + } + + var outFile = getAccessTransformer().getAsFile().get().toPath(); + if (!Files.exists(outFile.getParent())) { + Files.createDirectories(outFile.getParent()); + } + + FileUtils.writeStringSafe(outFile, text.toString(), StandardCharsets.UTF_8); + } + + public void classGroup(String name, Modifier modifier, SerializablePredicate match) { + getGroups().add(new AtGroup(name, modifier, match, null, null)); + } + + public void methodGroup(String name, Modifier modifier, SerializablePredicate targetTest, SerializablePredicate methodTest) { + getGroups().add(new AtGroup(name, modifier, targetTest, methodTest, null)); + } + + public void fieldGroup(String name, Modifier modifier, SerializablePredicate targetTest, SerializablePredicate fieldTest) { + getGroups().add(new AtGroup(name, modifier, targetTest, null, fieldTest)); + } + + public SerializablePredicate named(String name) { + return target -> target.getName().equals(name); + } + + public SerializablePredicate classesWithSuperclass(String superClass) { + return target -> target.hasSuperclass(superClass); + } + + public SerializablePredicate innerClassesOf(String parent) { + var parentFullName = parent + "$"; + return target -> target.name().startsWith(parentFullName); + } + + public SerializablePredicate methodsReturning(String type) { + var endMatch = ")L" + type + ";"; + return methodInfo -> methodInfo.descriptor().endsWith(endMatch); + } + + public SerializablePredicate fieldsOfType(SerializablePredicate type) { + return value -> type.test(value.type()); + } + + public SerializablePredicate matchAny() { + return value -> true; + } + + public record AtGroup(String name, Modifier modifier, SerializablePredicate classMatch, + @Nullable SerializablePredicate methodMatch, @Nullable SerializablePredicate fieldMatch) implements Serializable { + } + + public record Modifier(String name, boolean isFinal, int... validOpcodes) implements Serializable { + public boolean test(int value) { + if (isFinal && (value & Opcodes.ACC_FINAL) == 0) return false; + + for (int validOpcode : validOpcodes) { + if ((value & validOpcode) != 0) { + return true; + } + } + return false; + } + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java index d38f91f46b..0a5afa2539 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java @@ -70,14 +70,42 @@ public void apply(Project project) { // Task must run on sync to have MC resources available for IDEA nondelegated builds. NeoDevFacade.runTaskOnProjectSync(project, createSourceArtifacts); + // Obtain clean binary artifacts, needed to be able to generate ATs + var createCleanArtifacts = tasks.register("createCleanArtifacts", CreateCleanArtifacts.class, task -> { + task.setGroup(INTERNAL_GROUP); + task.setDescription("This task retrieves various files for the Minecraft version without applying NeoForge patches to them"); + var cleanArtifactsDir = neoDevBuildDir.map(dir -> dir.dir("artifacts/clean")); + task.getRawClientJar().set(cleanArtifactsDir.map(dir -> dir.file("raw-client.jar"))); + task.getCleanClientJar().set(cleanArtifactsDir.map(dir -> dir.file("client.jar"))); + task.getRawServerJar().set(cleanArtifactsDir.map(dir -> dir.file("raw-server.jar"))); + task.getCleanServerJar().set(cleanArtifactsDir.map(dir -> dir.file("server.jar"))); + task.getCleanJoinedJar().set(cleanArtifactsDir.map(dir -> dir.file("joined.jar"))); + task.getMergedMappings().set(cleanArtifactsDir.map(dir -> dir.file("merged-mappings.txt"))); + task.getNeoFormArtifact().set(mcAndNeoFormVersion.map(version -> "net.neoforged:neoform:" + version + "@zip")); + }); + + var genAts = project.getRootProject().file("src/main/resources/META-INF/accesstransformergenerated.cfg"); + + var genAtsTask = tasks.register("generateAccessTransformers", GenerateAccessTransformers.class, task -> { + task.setGroup(GROUP); + task.setDescription("Generate access transformers based on a set of rules defined in the buildscript"); + task.getInput().set(createCleanArtifacts.flatMap(CreateCleanArtifacts::getCleanJoinedJar)); + task.getAccessTransformer().set(genAts); + }); + // 2. Apply AT to the source jar from 1. - var atFile = project.getRootProject().file("src/main/resources/META-INF/accesstransformer.cfg"); + var atFiles = List.of( + project.getRootProject().file("src/main/resources/META-INF/accesstransformer.cfg"), + genAts + ); var applyAt = configureAccessTransformer( project, configurations, createSourceArtifacts, neoDevBuildDir, - atFile); + atFiles); + + applyAt.configure(task -> task.mustRunAfter(genAtsTask)); // 3. Apply patches to the source jar from 2. var patchesFolder = project.getRootProject().file("patches"); @@ -212,19 +240,6 @@ public void apply(Project project) { jarJarTask.configure(task -> task.setGroup(INTERNAL_GROUP)); universalJar.configure(task -> task.from(jarJarTask)); - var createCleanArtifacts = tasks.register("createCleanArtifacts", CreateCleanArtifacts.class, task -> { - task.setGroup(INTERNAL_GROUP); - task.setDescription("This task retrieves various files for the Minecraft version without applying NeoForge patches to them"); - var cleanArtifactsDir = neoDevBuildDir.map(dir -> dir.dir("artifacts/clean")); - task.getRawClientJar().set(cleanArtifactsDir.map(dir -> dir.file("raw-client.jar"))); - task.getCleanClientJar().set(cleanArtifactsDir.map(dir -> dir.file("client.jar"))); - task.getRawServerJar().set(cleanArtifactsDir.map(dir -> dir.file("raw-server.jar"))); - task.getCleanServerJar().set(cleanArtifactsDir.map(dir -> dir.file("server.jar"))); - task.getCleanJoinedJar().set(cleanArtifactsDir.map(dir -> dir.file("joined.jar"))); - task.getMergedMappings().set(cleanArtifactsDir.map(dir -> dir.file("merged-mappings.txt"))); - task.getNeoFormArtifact().set(mcAndNeoFormVersion.map(version -> "net.neoforged:neoform:" + version + "@zip")); - }); - var binaryPatchOutputs = configureBinaryPatchCreation( project, configurations, @@ -390,7 +405,7 @@ public void apply(Project project) { task.from(writeUserDevConfig.flatMap(CreateUserDevConfig::getUserDevConfig), spec -> { spec.rename(s -> "config.json"); }); - task.from(atFile, spec -> { + task.from(atFiles, spec -> { spec.into("ats/"); }); task.from(binaryPatchOutputs.binaryPatchesForMerged(), spec -> { @@ -434,7 +449,7 @@ private static TaskProvider configureAccessTransformer( NeoDevConfigurations configurations, TaskProvider createSourceArtifacts, Provider neoDevBuildDir, - File atFile) { + List atFiles) { // Pass -PvalidateAccessTransformers to validate ATs. var validateAts = project.getProviders().gradleProperty("validateAccessTransformers").map(p -> true).orElse(false); @@ -442,7 +457,7 @@ private static TaskProvider configureAccessTransformer( task.setGroup(INTERNAL_GROUP); task.classpath(configurations.getExecutableTool(Tools.JST)); task.getInputJar().set(createSourceArtifacts.flatMap(CreateMinecraftArtifacts::getSourcesArtifact)); - task.getAccessTransformer().set(atFile); + task.getAccessTransformers().from(atFiles); task.getValidate().set(validateAts); task.getOutputJar().set(neoDevBuildDir.map(dir -> dir.file("artifacts/access-transformed-sources.jar"))); task.getLibraries().from(configurations.neoFormClasspath); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/utils/SerializablePredicate.java b/buildSrc/src/main/java/net/neoforged/neodev/utils/SerializablePredicate.java new file mode 100644 index 0000000000..9a42b1669e --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/utils/SerializablePredicate.java @@ -0,0 +1,10 @@ +package net.neoforged.neodev.utils; + +import java.io.Serializable; +import java.util.function.Predicate; + +@FunctionalInterface +public interface SerializablePredicate extends Serializable, Predicate { + @Override + boolean test(T value); +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/ClassInfo.java b/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/ClassInfo.java new file mode 100644 index 0000000000..a9a4102f12 --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/ClassInfo.java @@ -0,0 +1,27 @@ +package net.neoforged.neodev.utils.structure; + +import org.apache.commons.lang3.mutable.MutableInt; +import org.gradle.api.Named; + +import java.util.List; + +public record ClassInfo(String name, MutableInt access, List parents, List methods, + List fields) implements Named { + public void addMethod(String name, String desc, int access) { + this.methods.add(new MethodInfo(name, desc, access)); + } + + public boolean hasSuperclass(String name) { + for (ClassInfo parent : parents) { + if (parent.hasSuperclass(name)) { + return true; + } + } + return this.name.equals(name); + } + + @Override + public String getName() { + return name; + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/ClassStructureVisitor.java b/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/ClassStructureVisitor.java new file mode 100644 index 0000000000..ae6f99ef5b --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/ClassStructureVisitor.java @@ -0,0 +1,83 @@ +package net.neoforged.neodev.utils.structure; + +import org.apache.commons.lang3.mutable.MutableInt; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.zip.ZipFile; + +public final class ClassStructureVisitor extends ClassVisitor { + private final Map classes; + ClassInfo current; + + private ClassStructureVisitor(Map classes) { + super(Opcodes.ASM9); + this.classes = classes; + } + + public static Map readJar(File file) throws IOException { + var map = new HashMap(); + var visitor = new ClassStructureVisitor(map); + try (var zip = new ZipFile(file)) { + var entries = zip.entries(); + while (entries.hasMoreElements()) { + var next = entries.nextElement(); + if (next.isDirectory() || !next.getName().endsWith(".class")) continue; + + try (var in = zip.getInputStream(next)) { + var reader = new ClassReader(in); + reader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + } + } + } + return map; + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + current = getClass(name); + current.access().setValue(access); + if (superName != null) { + current.parents().add(getClass(superName)); + } + for (String iface : interfaces) { + current.parents().add(getClass(iface)); + } + } + + @Override + public void visitInnerClass(String name, String outerName, String innerName, int access) { + if (name.equals(current.name())) { + current.access().setValue(access); + } + } + + @Override + public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { + current.fields().add(new FieldInfo(name, getClass(Type.getType(descriptor).getInternalName()), access)); + return null; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + current.addMethod(name, descriptor, access); + return null; + } + + private ClassInfo getClass(String name) { + var existing = classes.get(name); + if (existing != null) return existing; + existing = new ClassInfo(name, new MutableInt(0), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); + classes.put(name, existing); + return existing; + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/FieldInfo.java b/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/FieldInfo.java new file mode 100644 index 0000000000..378c634a8e --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/FieldInfo.java @@ -0,0 +1,10 @@ +package net.neoforged.neodev.utils.structure; + +import org.gradle.api.Named; + +public record FieldInfo(String name, ClassInfo type, int access) implements Named { + @Override + public String getName() { + return name; + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/MethodInfo.java b/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/MethodInfo.java new file mode 100644 index 0000000000..8ec02e3678 --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/utils/structure/MethodInfo.java @@ -0,0 +1,10 @@ +package net.neoforged.neodev.utils.structure; + +import org.gradle.api.Named; + +public record MethodInfo(String name, String descriptor, int access) implements Named { + @Override + public String getName() { + return name; + } +} diff --git a/projects/neoforge/build.gradle b/projects/neoforge/build.gradle index bc5638d3ed..6fb662a162 100644 --- a/projects/neoforge/build.gradle +++ b/projects/neoforge/build.gradle @@ -161,6 +161,67 @@ neoDev { } } +generateAccessTransformers { + // Make all state shards public + classGroup( + 'render state shard classes', PUBLIC, + innerClassesOf('net/minecraft/client/renderer/RenderStateShard') + ) + // Make all state shard fields public + fieldGroup( + 'render state shards', PUBLIC, + named('net/minecraft/client/renderer/RenderStateShard'), + fieldsOfType(classesWithSuperclass('net/minecraft/client/renderer/RenderStateShard')) + ) + + // Make all block constructors public so they can be used by mods + methodGroup( + 'block constructors', PUBLIC, + classesWithSuperclass('net/minecraft/world/level/block/Block'), + named('') + ) + // Make all particle constructors public so they can be used by mods + methodGroup( + 'particle constructors', PUBLIC, + classesWithSuperclass('net/minecraft/client/particle/Particle'), + named('') + ) + + // Make all criteria methods in the recipe provider protected so mods can use them + methodGroup( + 'recipe criteria', PROTECTED, + named('net/minecraft/data/recipes/RecipeProvider'), + methodsReturning('net/minecraft/advancements/Criterion') + ) + + // getStepSound is package-private and abstract, so mods couldn't otherwise extend from AbstractSkeleton + methodGroup( + 'skeleton step sound', PROTECTED, + classesWithSuperclass('net/minecraft/world/entity/monster/AbstractSkeleton'), + named('getStepSound') + ) + + // Make all noise generator setting factories public so mods can use them for custom dimensions + methodGroup( + 'noise generator', PUBLIC, + named('net/minecraft/world/level/levelgen/NoiseGeneratorSettings'), + methodsReturning('net/minecraft/world/level/levelgen/NoiseGeneratorSettings') + ) + + fieldGroup( + 'biome effects builder', PROTECTED, + named('net/minecraft/world/level/biome/BiomeSpecialEffects$Builder'), + matchAny() + ) + + // Make all creative tab ids accessible + fieldGroup( + 'creative tabs', PUBLIC, + named('net/minecraft/world/item/CreativeModeTabs'), + fieldsOfType(named('net/minecraft/resources/ResourceKey')) + ) +} + tasks.withType(Javadoc.class).configureEach { options.tags = [ 'apiNote:a:API Note:', diff --git a/settings.gradle b/settings.gradle index aff93fdd4c..8ebcc3b576 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,6 +15,7 @@ plugins { gradle.ext.moddevgradle_plugin_version = moddevgradle_plugin_version gradle.ext.gson_version = gson_version gradle.ext.diffpatch_version = diffpatch_version +gradle.ext.asm_version = asm_version dependencyResolutionManagement { repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 1f3cdb8df4..0497cdda0e 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -1,3 +1,4 @@ +# Note: This file is for manually added ATs. When AT entries can be programmatically generated based on fixed rules you may define those rules in the build.gradle file public net.minecraft.advancements.CriteriaTriggers register(Ljava/lang/String;Lnet/minecraft/advancements/CriterionTrigger;)Lnet/minecraft/advancements/CriterionTrigger; # register default net.minecraft.client.KeyMapping isDown # isDown public-f net.minecraft.client.Options keyMappings # keyMappings @@ -47,27 +48,9 @@ public net.minecraft.client.renderer.RenderType create(Ljava/lang/String;Lcom/mo public net.minecraft.client.renderer.RenderType create(Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;Lcom/mojang/blaze3d/vertex/VertexFormat$Mode;IZZLnet/minecraft/client/renderer/RenderType$CompositeState;)Lnet/minecraft/client/renderer/RenderType$CompositeRenderType; # create public net.minecraft.client.renderer.RenderType$OutlineProperty public net.minecraft.client.renderer.RenderType$CompositeState -public net.minecraft.client.renderer.RenderStateShard * protected-f net.minecraft.client.renderer.RenderStateShard$TextureStateShard blur # blur protected-f net.minecraft.client.renderer.RenderStateShard$TextureStateShard mipmap # mipmap public net.minecraft.client.renderer.RenderStateShard setupGlintTexturing(F)V -public net.minecraft.client.renderer.RenderStateShard$BooleanStateShard -public net.minecraft.client.renderer.RenderStateShard$ColorLogicStateShard -public net.minecraft.client.renderer.RenderStateShard$CullStateShard -public net.minecraft.client.renderer.RenderStateShard$DepthTestStateShard -public net.minecraft.client.renderer.RenderStateShard$EmptyTextureStateShard -public net.minecraft.client.renderer.RenderStateShard$LayeringStateShard -public net.minecraft.client.renderer.RenderStateShard$LightmapStateShard -public net.minecraft.client.renderer.RenderStateShard$LineStateShard -public net.minecraft.client.renderer.RenderStateShard$MultiTextureStateShard -public net.minecraft.client.renderer.RenderStateShard$OffsetTexturingStateShard -public net.minecraft.client.renderer.RenderStateShard$OutputStateShard -public net.minecraft.client.renderer.RenderStateShard$OverlayStateShard -public net.minecraft.client.renderer.RenderStateShard$ShaderStateShard -public net.minecraft.client.renderer.RenderStateShard$TextureStateShard -public net.minecraft.client.renderer.RenderStateShard$TexturingStateShard -public net.minecraft.client.renderer.RenderStateShard$TransparencyStateShard -public net.minecraft.client.renderer.RenderStateShard$WriteMaskStateShard #endgroup default net.minecraft.client.renderer.chunk.RenderChunk wrapped public net.minecraft.client.renderer.block.model.BlockElement uvsByFace(Lnet/minecraft/core/Direction;)[F # uvsByFace @@ -118,9 +101,6 @@ public net.minecraft.core.particles.SimpleParticleType (Z)V # constructor protected net.minecraft.data.loot.BlockLootSubProvider createSilkTouchOnlyTable(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/level/storage/loot/LootTable$Builder; # createSilkTouchOnlyTable protected net.minecraft.data.loot.BlockLootSubProvider createPotFlowerItemTable(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/level/storage/loot/LootTable$Builder; # createPotFlowerItemTable protected net.minecraft.data.loot.BlockLootSubProvider createSelfDropDispatchTable(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/storage/loot/predicates/LootItemCondition$Builder;Lnet/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer$Builder;)Lnet/minecraft/world/level/storage/loot/LootTable$Builder; # createSelfDropDispatchTable -protected net.minecraft.data.recipes.RecipeProvider insideOf(Lnet/minecraft/world/level/block/Block;)Lnet/minecraft/advancements/Criterion; # insideOf -protected net.minecraft.data.recipes.RecipeProvider inventoryTrigger([Lnet/minecraft/advancements/critereon/ItemPredicate;)Lnet/minecraft/advancements/Criterion; # inventoryTrigger -protected net.minecraft.data.recipes.RecipeProvider has(Lnet/minecraft/advancements/critereon/MinMaxBounds$Ints;Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/advancements/Criterion; # has protected net.minecraft.data.recipes.RecipeProvider getBaseBlock(Lnet/minecraft/data/BlockFamily;Lnet/minecraft/data/BlockFamily$Variant;)Lnet/minecraft/world/level/block/Block; # getBaseBlock protected net.minecraft.data.recipes.RecipeProvider buttonBuilder(Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/RecipeBuilder; # buttonBuilder protected net.minecraft.data.recipes.RecipeProvider fenceBuilder(Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/RecipeBuilder; # fenceBuilder @@ -134,7 +114,6 @@ protected net.minecraft.data.recipes.RecipeProvider polishedBuilder(Lnet/minecra protected net.minecraft.data.recipes.RecipeProvider pressurePlateBuilder(Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/RecipeBuilder; # pressurePlateBuilder protected net.minecraft.data.recipes.RecipeProvider nineBlockStorageRecipes(Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V # nineBlockStorageRecipes protected net.minecraft.data.recipes.RecipeProvider simpleCookingRecipe(Ljava/lang/String;Lnet/minecraft/world/item/crafting/RecipeSerializer;Lnet/minecraft/world/item/crafting/AbstractCookingRecipe$Factory;ILnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/level/ItemLike;F)V # simpleCookingRecipe -protected net.minecraft.data.recipes.RecipeProvider inventoryTrigger([Lnet/minecraft/advancements/critereon/ItemPredicate$Builder;)Lnet/minecraft/advancements/Criterion; # inventoryTrigger public net.minecraft.data.recipes.RecipeProvider$Runner protected net.minecraft.data.recipes.packs.VanillaRecipeProvider (Lnet/minecraft/core/HolderLookup$Provider;Lnet/minecraft/data/recipes/RecipeOutput;)V public net.minecraft.data.recipes.packs.VanillaRecipeProvider COAL_SMELTABLES # COAL_SMELTABLES @@ -196,10 +175,6 @@ public net.minecraft.world.entity.Mob goalSelector # goalSelector public net.minecraft.world.entity.Mob targetSelector # targetSelector public net.minecraft.world.entity.ai.sensing.SensorType (Ljava/util/function/Supplier;)V # constructor protected net.minecraft.world.entity.item.PrimedTnt explode()V # explode - make it easier to extend TNTEntity with custom explosion logic -protected net.minecraft.world.entity.monster.AbstractSkeleton getStepSound()Lnet/minecraft/sounds/SoundEvent; # getStepSound - make AbstractSkeletonEntity implementable -protected net.minecraft.world.entity.monster.Skeleton getStepSound()Lnet/minecraft/sounds/SoundEvent; # getStepSound - make AbstractSkeletonEntity implementable -protected net.minecraft.world.entity.monster.Stray getStepSound()Lnet/minecraft/sounds/SoundEvent; # getStepSound - make AbstractSkeletonEntity implementable -protected net.minecraft.world.entity.monster.WitherSkeleton getStepSound()Lnet/minecraft/sounds/SoundEvent; # getStepSound - make AbstractSkeletonEntity implementable public net.minecraft.world.entity.npc.VillagerType (Ljava/lang/String;)V # constructor public net.minecraft.world.entity.player.Player closeContainer()V # closeContainer protected net.minecraft.world.entity.projectile.Projectile (Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/Level;)V # constructor @@ -211,20 +186,6 @@ public net.minecraft.world.inventory.AnvilMenu repairItemCountCost # repairItemC public net.minecraft.world.inventory.MenuType (Lnet/minecraft/world/inventory/MenuType$MenuSupplier;Lnet/minecraft/world/flag/FeatureFlagSet;)V # constructor public net.minecraft.world.inventory.MenuType$MenuSupplier public net.minecraft.world.item.CreativeModeTab$TabVisibility -public net.minecraft.world.item.CreativeModeTabs COLORED_BLOCKS # COLORED_BLOCKS -public net.minecraft.world.item.CreativeModeTabs SPAWN_EGGS # SPAWN_EGGS -public net.minecraft.world.item.CreativeModeTabs SEARCH # SEARCH -public net.minecraft.world.item.CreativeModeTabs NATURAL_BLOCKS # NATURAL_BLOCKS -public net.minecraft.world.item.CreativeModeTabs BUILDING_BLOCKS # BUILDING_BLOCKS -public net.minecraft.world.item.CreativeModeTabs FUNCTIONAL_BLOCKS # FUNCTIONAL_BLOCKS -public net.minecraft.world.item.CreativeModeTabs COMBAT # COMBAT -public net.minecraft.world.item.CreativeModeTabs OP_BLOCKS # OP_BLOCKS -public net.minecraft.world.item.CreativeModeTabs FOOD_AND_DRINKS # FOOD_AND_DRINKS -public net.minecraft.world.item.CreativeModeTabs TOOLS_AND_UTILITIES # TOOLS_AND_UTILITIES -public net.minecraft.world.item.CreativeModeTabs HOTBAR # HOTBAR -public net.minecraft.world.item.CreativeModeTabs INGREDIENTS # INGREDIENTS -public net.minecraft.world.item.CreativeModeTabs REDSTONE_BLOCKS # REDSTONE_BLOCKS -public net.minecraft.world.item.CreativeModeTabs INVENTORY # INVENTORY #group public net.minecraft.world.item.Item public net.minecraft.world.item.DiggerItem (Lnet/minecraft/world/item/ToolMaterial;Lnet/minecraft/tags/TagKey;FFLnet/minecraft/world/item/Item$Properties;)V #endgroup @@ -252,124 +213,9 @@ public net.minecraft.world.level.biome.BiomeGenerationSettings (Lnet/minec protected net.minecraft.world.level.biome.BiomeGenerationSettings$PlainBuilder features # features protected net.minecraft.world.level.biome.BiomeGenerationSettings$PlainBuilder carvers # carvers protected net.minecraft.world.level.biome.BiomeGenerationSettings$PlainBuilder addFeatureStepsUpTo(I)V # addFeatureStepsUpTo -#group protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder * -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder fogColor # fogColor -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder waterColor # waterColor -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder waterFogColor # waterFogColor -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder skyColor # skyColor -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder foliageColorOverride # foliageColorOverride -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder grassColorOverride # grassColorOverride -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder grassColorModifier # grassColorModifier -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder ambientParticle # ambientParticle -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder ambientLoopSoundEvent # ambientLoopSoundEvent -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder ambientMoodSettings # ambientMoodSettings -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder ambientAdditionsSettings # ambientAdditionsSettings -protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder backgroundMusic # backgroundMusic -#endgroup protected net.minecraft.world.level.biome.MobSpawnSettings$Builder spawners # spawners protected net.minecraft.world.level.biome.MobSpawnSettings$Builder mobSpawnCosts # mobSpawnCosts protected net.minecraft.world.level.biome.MobSpawnSettings$Builder creatureGenerationProbability # creatureGenerationProbability -#group public net.minecraft.world.level.block.Block -public net.minecraft.world.level.block.AttachedStemBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.AzaleaBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.BarrierBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.BaseCoralFanBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.BaseCoralPlantBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.BaseCoralPlantTypeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.BaseCoralWallFanBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.BigDripleafBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.BigDripleafStemBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.BlastFurnaceBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.ButtonBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;ILnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CactusBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CakeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CandleCakeBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CartographyTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CarvedPumpkinBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.ChestBlock (Ljava/util/function/Supplier;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.ChorusFlowerBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.ChorusPlantBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CoralFanBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CoralPlantBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CoralWallFanBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CraftingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.CropBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.DeadBushBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.DecoratedPotBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.DirtPathBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.DispenserBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.DoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.EnchantingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.EndGatewayBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.EndPortalBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.EndRodBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.EnderChestBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.FarmBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.FletchingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.FungusBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.FurnaceBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.GrindstoneBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.HalfTransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.HangingRootsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.IronBarsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.JigsawBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.JukeboxBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.KelpBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.KelpPlantBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.LadderBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.LecternBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.LeverBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.LiquidBlock (Lnet/minecraft/world/level/material/FlowingFluid;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.LoomBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.MangroveRootsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.NetherWartBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.NyliumBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.PinkPetalsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.PipeBlock (FLnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.PlayerHeadBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.PlayerWallHeadBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.PoweredRailBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.PressurePlateBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.PumpkinBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.RailBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.RedstoneTorchBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.RedstoneWallTorchBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.RepeaterBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.RodBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.RootsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SaplingBlock (Lnet/minecraft/world/level/block/grower/TreeGrower;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.ScaffoldingBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SeaPickleBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SeagrassBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SkullBlock (Lnet/minecraft/world/level/block/SkullBlock$Type;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SmithingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SmokerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SnowLayerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SnowyDirtBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SpawnerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SpongeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.StairBlock (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.StemBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.StructureBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.StructureVoidBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.SugarCaneBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.TallGrassBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.TorchBlock (Lnet/minecraft/core/particles/SimpleParticleType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.TransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.TrapDoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WallSkullBlock (Lnet/minecraft/world/level/block/SkullBlock$Type;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WallTorchBlock (Lnet/minecraft/core/particles/SimpleParticleType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WaterlilyBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WaterloggedTransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WeatheringCopperDoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WeatheringCopperGrateBlock (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WeatheringCopperTrapDoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WeightedPressurePlateBlock (ILnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WetSpongeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WitherSkullBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WitherWallSkullBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -public net.minecraft.world.level.block.WoolCarpetBlock (Lnet/minecraft/world/item/DyeColor;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V # constructor -#endgroup public net.minecraft.world.level.block.Block popExperience(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;I)V # popExperience public net.minecraft.world.level.block.Blocks always(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; # always public net.minecraft.world.level.block.Blocks never(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; # never @@ -411,13 +257,6 @@ private-f net.minecraft.world.level.levelgen.DebugLevelSource GRID_WIDTH # GRID_ private-f net.minecraft.world.level.levelgen.DebugLevelSource GRID_HEIGHT # GRID_HEIGHT public-f net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator protected net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator iterateNoiseColumn(Lnet/minecraft/world/level/LevelHeightAccessor;Lnet/minecraft/world/level/levelgen/RandomState;IILorg/apache/commons/lang3/mutable/MutableObject;Ljava/util/function/Predicate;)Ljava/util/OptionalInt; # iterateNoiseColumn -#group public net.minecraft.world.level.levelgen.NoiseGeneratorSettings *() -public net.minecraft.world.level.levelgen.NoiseGeneratorSettings caves(Lnet/minecraft/data/worldgen/BootstrapContext;)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; # caves -public net.minecraft.world.level.levelgen.NoiseGeneratorSettings end(Lnet/minecraft/data/worldgen/BootstrapContext;)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; # end -public net.minecraft.world.level.levelgen.NoiseGeneratorSettings overworld(Lnet/minecraft/data/worldgen/BootstrapContext;ZZ)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; # overworld -public net.minecraft.world.level.levelgen.NoiseGeneratorSettings floatingIslands(Lnet/minecraft/data/worldgen/BootstrapContext;)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; # floatingIslands -public net.minecraft.world.level.levelgen.NoiseGeneratorSettings nether(Lnet/minecraft/data/worldgen/BootstrapContext;)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; # nether -#endgroup public net.minecraft.world.level.levelgen.feature.featuresize.FeatureSizeType (Lcom/mojang/serialization/MapCodec;)V # constructor public net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacerType (Lcom/mojang/serialization/MapCodec;)V # constructor public net.minecraft.world.level.levelgen.feature.rootplacers.RootPlacerType (Lcom/mojang/serialization/MapCodec;)V # constructor @@ -433,49 +272,6 @@ private-f net.minecraft.world.level.storage.loot.LootPool bonusRolls # bonusRoll public net.minecraft.server.network.ServerConfigurationPacketListenerImpl finishCurrentTask(Lnet/minecraft/server/network/ConfigurationTask$Type;)V public com.mojang.blaze3d.vertex.VertexFormatElement$Usage$SetupState -# Below you will find particle constructor ATs -protected net.minecraft.client.particle.AttackSweepParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.BlockMarker (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/block/state/BlockState;)V # constructor -protected net.minecraft.client.particle.BreakingItemParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/renderer/item/ItemStackRenderState;)V # constructor -protected net.minecraft.client.particle.BubbleColumnUpParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor -protected net.minecraft.client.particle.BubbleParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor -protected net.minecraft.client.particle.BubblePopParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.CampfireSmokeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDZ)V # constructor -protected net.minecraft.client.particle.CritParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor -protected net.minecraft.client.particle.DragonBreathParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.DripParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;)V # constructor -protected net.minecraft.client.particle.EndRodParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.FallingDustParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDFFFLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.FireworkParticles$OverlayParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V # constructor -protected net.minecraft.client.particle.FireworkParticles$SparkParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/ParticleEngine;Lnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.FlameParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor -protected net.minecraft.client.particle.FlyStraightTowardsParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDII)V # constructor -protected net.minecraft.client.particle.FlyTowardsPositionParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor -protected net.minecraft.client.particle.GlowParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.GustSeedParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDII)V # constructor -protected net.minecraft.client.particle.HeartParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V # constructor -protected net.minecraft.client.particle.HugeExplosionSeedParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V # constructor -protected net.minecraft.client.particle.LavaParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V # constructor -protected net.minecraft.client.particle.MobAppearanceParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V # constructor -protected net.minecraft.client.particle.NoteParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDD)V # constructor -protected net.minecraft.client.particle.PlayerCloudParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.ReversePortalParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor -protected net.minecraft.client.particle.SculkChargeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.SculkChargePopParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.ShriekParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDI)V # constructor -protected net.minecraft.client.particle.SoulParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.SpellParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.SpitParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.SplashParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor -protected net.minecraft.client.particle.SquidInkParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDILnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.SuspendedParticle (Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/client/particle/SpriteSet;DDD)V # constructor -protected net.minecraft.client.particle.SuspendedTownParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V # constructor -protected net.minecraft.client.particle.TotemParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.VibrationSignalParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/gameevent/PositionSource;I)V # constructor -protected net.minecraft.client.particle.WakeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V # constructor -protected net.minecraft.client.particle.WaterCurrentDownParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V # constructor -# End of particle constructor ATs group - # EnchantmentHelper methods needed for adding custom enchantments public net.minecraft.world.item.enchantment.EnchantmentHelper runIterationOnItem(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/enchantment/EnchantmentHelper$EnchantmentVisitor;)V public net.minecraft.world.item.enchantment.EnchantmentHelper runIterationOnItem(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/entity/EquipmentSlot;Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/enchantment/EnchantmentHelper$EnchantmentInSlotVisitor;)V diff --git a/src/main/resources/META-INF/accesstransformergenerated.cfg b/src/main/resources/META-INF/accesstransformergenerated.cfg new file mode 100644 index 0000000000..76f5e7fedd --- /dev/null +++ b/src/main/resources/META-INF/accesstransformergenerated.cfg @@ -0,0 +1,380 @@ +# This file is generated based on the rules defined in the buildscript. DO NOT modify it manually. +# Add more rules in the buildscript and then run the generateAccessTransformers task to update this file. + +# render state shard classes +public net.minecraft.client.renderer.RenderStateShard$BooleanStateShard +public net.minecraft.client.renderer.RenderStateShard$ColorLogicStateShard +public net.minecraft.client.renderer.RenderStateShard$CullStateShard +public net.minecraft.client.renderer.RenderStateShard$DepthTestStateShard +public net.minecraft.client.renderer.RenderStateShard$EmptyTextureStateShard +public net.minecraft.client.renderer.RenderStateShard$LayeringStateShard +public net.minecraft.client.renderer.RenderStateShard$LightmapStateShard +public net.minecraft.client.renderer.RenderStateShard$LineStateShard +public net.minecraft.client.renderer.RenderStateShard$MultiTextureStateShard +public net.minecraft.client.renderer.RenderStateShard$MultiTextureStateShard$Entry +public net.minecraft.client.renderer.RenderStateShard$MultiTextureStateShard$Entry (Lnet/minecraft/resources/ResourceLocation;ZZ)V +public net.minecraft.client.renderer.RenderStateShard$OffsetTexturingStateShard +public net.minecraft.client.renderer.RenderStateShard$OutputStateShard +public net.minecraft.client.renderer.RenderStateShard$OverlayStateShard +public net.minecraft.client.renderer.RenderStateShard$ShaderStateShard +public net.minecraft.client.renderer.RenderStateShard$TextureStateShard +public net.minecraft.client.renderer.RenderStateShard$TexturingStateShard +public net.minecraft.client.renderer.RenderStateShard$TransparencyStateShard +public net.minecraft.client.renderer.RenderStateShard$WriteMaskStateShard + +# render state shards +public net.minecraft.client.renderer.RenderStateShard ADDITIVE_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard BLOCK_SHEET +public net.minecraft.client.renderer.RenderStateShard BLOCK_SHEET_MIPPED +public net.minecraft.client.renderer.RenderStateShard CLOUDS_TARGET +public net.minecraft.client.renderer.RenderStateShard COLOR_DEPTH_WRITE +public net.minecraft.client.renderer.RenderStateShard COLOR_WRITE +public net.minecraft.client.renderer.RenderStateShard CROSSHAIR_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard CRUMBLING_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard CULL +public net.minecraft.client.renderer.RenderStateShard DEFAULT_LINE +public net.minecraft.client.renderer.RenderStateShard DEFAULT_TEXTURING +public net.minecraft.client.renderer.RenderStateShard DEPTH_WRITE +public net.minecraft.client.renderer.RenderStateShard ENTITY_GLINT_TEXTURING +public net.minecraft.client.renderer.RenderStateShard EQUAL_DEPTH_TEST +public net.minecraft.client.renderer.RenderStateShard GLINT_TEXTURING +public net.minecraft.client.renderer.RenderStateShard GLINT_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard GREATER_DEPTH_TEST +public net.minecraft.client.renderer.RenderStateShard ITEM_ENTITY_TARGET +public net.minecraft.client.renderer.RenderStateShard LEQUAL_DEPTH_TEST +public net.minecraft.client.renderer.RenderStateShard LIGHTMAP +public net.minecraft.client.renderer.RenderStateShard LIGHTNING_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard MAIN_TARGET +public net.minecraft.client.renderer.RenderStateShard MOJANG_LOGO_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard NAUSEA_OVERLAY_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard NO_COLOR_LOGIC +public net.minecraft.client.renderer.RenderStateShard NO_CULL +public net.minecraft.client.renderer.RenderStateShard NO_DEPTH_TEST +public net.minecraft.client.renderer.RenderStateShard NO_LAYERING +public net.minecraft.client.renderer.RenderStateShard NO_LIGHTMAP +public net.minecraft.client.renderer.RenderStateShard NO_OVERLAY +public net.minecraft.client.renderer.RenderStateShard NO_SHADER +public net.minecraft.client.renderer.RenderStateShard NO_TEXTURE +public net.minecraft.client.renderer.RenderStateShard NO_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard OR_REVERSE_COLOR_LOGIC +public net.minecraft.client.renderer.RenderStateShard OUTLINE_TARGET +public net.minecraft.client.renderer.RenderStateShard OVERLAY +public net.minecraft.client.renderer.RenderStateShard OVERLAY_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard PARTICLES_TARGET +public net.minecraft.client.renderer.RenderStateShard PARTICLE_SHADER +public net.minecraft.client.renderer.RenderStateShard POLYGON_OFFSET_LAYERING +public net.minecraft.client.renderer.RenderStateShard POSITION_COLOR_LIGHTMAP_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_COLOR_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_COLOR_TEX_LIGHTMAP_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_TEXTURE_COLOR_SHADER +public net.minecraft.client.renderer.RenderStateShard POSITION_TEX_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ARMOR_CUTOUT_NO_CULL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ARMOR_ENTITY_GLINT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ARMOR_TRANSLUCENT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_BEACON_BEAM_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_BREEZE_WIND_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_CLOUDS_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_CRUMBLING_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_CUTOUT_MIPPED_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_CUTOUT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_END_GATEWAY_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_END_PORTAL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENERGY_SWIRL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_ALPHA_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_CUTOUT_NO_CULL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_CUTOUT_NO_CULL_Z_OFFSET_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_CUTOUT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_DECAL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_GLINT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_NO_OUTLINE_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_SHADOW_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_SMOOTH_CUTOUT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_SOLID_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_TRANSLUCENT_EMISSIVE_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ENTITY_TRANSLUCENT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_EYES_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GLINT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GLINT_TRANSLUCENT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GUI_GHOST_RECIPE_OVERLAY_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GUI_OVERLAY_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GUI_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_GUI_TEXT_HIGHLIGHT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_ITEM_ENTITY_TRANSLUCENT_CULL_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_LEASH_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_LIGHTNING_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_LINES_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_OUTLINE_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_SOLID_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_BACKGROUND_SEE_THROUGH_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_BACKGROUND_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_INTENSITY_SEE_THROUGH_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_INTENSITY_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_SEE_THROUGH_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TEXT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TRANSLUCENT_MOVING_BLOCK_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TRANSLUCENT_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_TRIPWIRE_SHADER +public net.minecraft.client.renderer.RenderStateShard RENDERTYPE_WATER_MASK_SHADER +public net.minecraft.client.renderer.RenderStateShard TRANSLUCENT_TARGET +public net.minecraft.client.renderer.RenderStateShard TRANSLUCENT_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard VIEW_OFFSET_Z_LAYERING +public net.minecraft.client.renderer.RenderStateShard VIEW_OFFSET_Z_LAYERING_FORWARD +public net.minecraft.client.renderer.RenderStateShard VIGNETTE_TRANSPARENCY +public net.minecraft.client.renderer.RenderStateShard WEATHER_TARGET +public net.minecraft.client.renderer.RenderStateShard WORLD_BORDER_LAYERING + +# block constructors +public net.minecraft.world.level.block.AbstractBannerBlock (Lnet/minecraft/world/item/DyeColor;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.AbstractCandleBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.AbstractChestBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;Ljava/util/function/Supplier;)V +public net.minecraft.world.level.block.AbstractFurnaceBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.AttachedStemBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.AzaleaBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BarrierBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BaseCoralFanBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BaseCoralPlantBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BaseCoralPlantTypeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BaseCoralWallFanBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BaseEntityBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BasePressurePlateBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;Lnet/minecraft/world/level/block/state/properties/BlockSetType;)V +public net.minecraft.world.level.block.BaseRailBlock (ZLnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BaseTorchBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BigDripleafBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BigDripleafStemBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BlastFurnaceBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BushBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.ButtonBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;ILnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CactusBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CakeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CandleCakeBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CartographyTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CarvedPumpkinBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.ChestBlock (Ljava/util/function/Supplier;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.ChorusFlowerBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.ChorusPlantBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CoralFanBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CoralPlantBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CoralWallFanBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CraftingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CreakingHeartBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CropBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.CrossCollisionBlock (FFFFFLnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.DeadBushBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.DecoratedPotBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.DiodeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.DirectionalBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.DirtPathBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.DispenserBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.DoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.EnchantingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.EndGatewayBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.EndPortalBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.EndRodBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.EnderChestBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.FarmBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.FletchingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.FungusBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.FurnaceBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.GrindstoneBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.GrowingPlantBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;Lnet/minecraft/core/Direction;Lnet/minecraft/world/phys/shapes/VoxelShape;Z)V +public net.minecraft.world.level.block.GrowingPlantBodyBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;Lnet/minecraft/core/Direction;Lnet/minecraft/world/phys/shapes/VoxelShape;Z)V +public net.minecraft.world.level.block.GrowingPlantHeadBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;Lnet/minecraft/core/Direction;Lnet/minecraft/world/phys/shapes/VoxelShape;ZD)V +public net.minecraft.world.level.block.HalfTransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.HangingRootsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.HorizontalDirectionalBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.IronBarsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.JigsawBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.JukeboxBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.KelpBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.KelpPlantBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.LadderBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.LecternBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.LeverBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.LiquidBlock (Lnet/minecraft/world/level/material/FlowingFluid;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.LoomBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.MangroveRootsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.NetherWartBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.NyliumBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.PinkPetalsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.PipeBlock (FLnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.PlayerHeadBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.PlayerWallHeadBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.PoweredRailBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.PressurePlateBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.PumpkinBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.RailBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.RedstoneTorchBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.RedstoneWallTorchBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.RepeaterBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.RodBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.RootsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SaplingBlock (Lnet/minecraft/world/level/block/grower/TreeGrower;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.ScaffoldingBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SeaPickleBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SeagrassBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SignBlock (Lnet/minecraft/world/level/block/state/properties/WoodType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SkullBlock (Lnet/minecraft/world/level/block/SkullBlock$Type;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SmithingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SmokerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SnowLayerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SnowyDirtBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SpawnerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SpongeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SpreadingSnowyDirtBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.StairBlock (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.StemBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.StructureBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.StructureVoidBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.SugarCaneBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.TallGrassBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.TorchBlock (Lnet/minecraft/core/particles/SimpleParticleType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.TransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.TrapDoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WallSkullBlock (Lnet/minecraft/world/level/block/SkullBlock$Type;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WallTorchBlock (Lnet/minecraft/core/particles/SimpleParticleType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WaterlilyBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WaterloggedTransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WeatheringCopperDoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WeatheringCopperGrateBlock (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WeatheringCopperTrapDoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WeightedPressurePlateBlock (ILnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WetSpongeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WitherSkullBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WitherWallSkullBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.WoolCarpetBlock (Lnet/minecraft/world/item/DyeColor;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V + +# particle constructors +public net.minecraft.client.particle.AshParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDFLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.AttackSweepParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.BaseAshSmokeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDFFFDDDFLnet/minecraft/client/particle/SpriteSet;FIFZ)V +public net.minecraft.client.particle.BlockMarker (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/block/state/BlockState;)V +public net.minecraft.client.particle.BreakingItemParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/renderer/item/ItemStackRenderState;)V +public net.minecraft.client.particle.BreakingItemParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/client/renderer/item/ItemStackRenderState;)V +public net.minecraft.client.particle.BubbleColumnUpParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.BubbleParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.BubblePopParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.CampfireSmokeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDZ)V +public net.minecraft.client.particle.CritParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.DragonBreathParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.DripParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;)V +public net.minecraft.client.particle.DripParticle$CoolingDripHangParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;Lnet/minecraft/core/particles/ParticleOptions;)V +public net.minecraft.client.particle.DripParticle$DripHangParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;Lnet/minecraft/core/particles/ParticleOptions;)V +public net.minecraft.client.particle.DripParticle$DripLandParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;)V +public net.minecraft.client.particle.DripParticle$DripstoneFallAndLandParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;Lnet/minecraft/core/particles/ParticleOptions;)V +public net.minecraft.client.particle.DripParticle$FallAndLandParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;Lnet/minecraft/core/particles/ParticleOptions;)V +public net.minecraft.client.particle.DripParticle$FallingParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;)V +public net.minecraft.client.particle.DripParticle$FallingParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;I)V +public net.minecraft.client.particle.DripParticle$HoneyFallAndLandParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/material/Fluid;Lnet/minecraft/core/particles/ParticleOptions;)V +public net.minecraft.client.particle.DustColorTransitionParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/core/particles/DustColorTransitionOptions;Lnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.DustParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/core/particles/DustParticleOptions;Lnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.DustParticleBase (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/core/particles/ScalableParticleOptionsBase;Lnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.DustPlumeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDFLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.EndRodParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.ExplodeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.FallingDustParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDFFFLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.FallingLeavesParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/client/particle/SpriteSet;FFZZFF)V +public net.minecraft.client.particle.FireworkParticles$OverlayParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.FireworkParticles$SparkParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/ParticleEngine;Lnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.FlameParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.FlyStraightTowardsParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDII)V +public net.minecraft.client.particle.FlyTowardsPositionParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.FlyTowardsPositionParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDZLnet/minecraft/client/particle/Particle$LifetimeAlpha;)V +public net.minecraft.client.particle.GlowParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.GustParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.GustSeedParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDII)V +public net.minecraft.client.particle.HeartParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.HugeExplosionParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.HugeExplosionSeedParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.ItemPickupParticle (Lnet/minecraft/client/renderer/entity/EntityRenderDispatcher;Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;)V +public net.minecraft.client.particle.LargeSmokeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.LavaParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.MobAppearanceParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.NoRenderParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.NoRenderParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.NoteParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDD)V +public net.minecraft.client.particle.Particle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.PlayerCloudParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.PortalParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.ReversePortalParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.RisingParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.SculkChargeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.SculkChargePopParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.ShriekParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDI)V +public net.minecraft.client.particle.SimpleAnimatedParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/client/particle/SpriteSet;F)V +public net.minecraft.client.particle.SingleQuadParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.SingleQuadParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.SmokeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDFLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.SnowflakeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.SonicBoomParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.SoulParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.SpellParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.SpitParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.SplashParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.SquidInkParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDILnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.SuspendedParticle (Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/client/particle/SpriteSet;DDD)V +public net.minecraft.client.particle.SuspendedParticle (Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/client/particle/SpriteSet;DDDDDD)V +public net.minecraft.client.particle.SuspendedTownParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.TextureSheetParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.TextureSheetParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDD)V +public net.minecraft.client.particle.TotemParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.TrackingEmitter (Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/core/particles/ParticleOptions;ILnet/minecraft/world/phys/Vec3;)V +public net.minecraft.client.particle.TrailParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/world/phys/Vec3;I)V +public net.minecraft.client.particle.TrialSpawnerDetectionParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDFLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.VibrationSignalParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDLnet/minecraft/world/level/gameevent/PositionSource;I)V +public net.minecraft.client.particle.WakeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.WaterCurrentDownParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.WaterDropParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDD)V +public net.minecraft.client.particle.WhiteAshParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDFLnet/minecraft/client/particle/SpriteSet;)V +public net.minecraft.client.particle.WhiteSmokeParticle (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDFLnet/minecraft/client/particle/SpriteSet;)V + +# recipe criteria +protected net.minecraft.data.recipes.RecipeProvider has(Lnet/minecraft/advancements/critereon/MinMaxBounds$Ints;Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/advancements/Criterion; +protected net.minecraft.data.recipes.RecipeProvider insideOf(Lnet/minecraft/world/level/block/Block;)Lnet/minecraft/advancements/Criterion; +protected net.minecraft.data.recipes.RecipeProvider inventoryTrigger([Lnet/minecraft/advancements/critereon/ItemPredicate$Builder;)Lnet/minecraft/advancements/Criterion; +protected net.minecraft.data.recipes.RecipeProvider inventoryTrigger([Lnet/minecraft/advancements/critereon/ItemPredicate;)Lnet/minecraft/advancements/Criterion; + +# skeleton step sound +protected net.minecraft.world.entity.monster.AbstractSkeleton getStepSound()Lnet/minecraft/sounds/SoundEvent; +protected net.minecraft.world.entity.monster.Skeleton getStepSound()Lnet/minecraft/sounds/SoundEvent; +protected net.minecraft.world.entity.monster.Stray getStepSound()Lnet/minecraft/sounds/SoundEvent; +protected net.minecraft.world.entity.monster.WitherSkeleton getStepSound()Lnet/minecraft/sounds/SoundEvent; + +# noise generator +public net.minecraft.world.level.levelgen.NoiseGeneratorSettings caves(Lnet/minecraft/data/worldgen/BootstrapContext;)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; +public net.minecraft.world.level.levelgen.NoiseGeneratorSettings end(Lnet/minecraft/data/worldgen/BootstrapContext;)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; +public net.minecraft.world.level.levelgen.NoiseGeneratorSettings floatingIslands(Lnet/minecraft/data/worldgen/BootstrapContext;)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; +public net.minecraft.world.level.levelgen.NoiseGeneratorSettings nether(Lnet/minecraft/data/worldgen/BootstrapContext;)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; +public net.minecraft.world.level.levelgen.NoiseGeneratorSettings overworld(Lnet/minecraft/data/worldgen/BootstrapContext;ZZ)Lnet/minecraft/world/level/levelgen/NoiseGeneratorSettings; + +# biome effects builder +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder ambientAdditionsSettings +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder ambientLoopSoundEvent +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder ambientMoodSettings +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder ambientParticle +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder backgroundMusic +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder backgroundMusicVolume +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder fogColor +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder foliageColorOverride +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder grassColorModifier +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder grassColorOverride +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder skyColor +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder waterColor +protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder waterFogColor + +# creative tabs +public net.minecraft.world.item.CreativeModeTabs BUILDING_BLOCKS +public net.minecraft.world.item.CreativeModeTabs COLORED_BLOCKS +public net.minecraft.world.item.CreativeModeTabs COMBAT +public net.minecraft.world.item.CreativeModeTabs FOOD_AND_DRINKS +public net.minecraft.world.item.CreativeModeTabs FUNCTIONAL_BLOCKS +public net.minecraft.world.item.CreativeModeTabs HOTBAR +public net.minecraft.world.item.CreativeModeTabs INGREDIENTS +public net.minecraft.world.item.CreativeModeTabs INVENTORY +public net.minecraft.world.item.CreativeModeTabs NATURAL_BLOCKS +public net.minecraft.world.item.CreativeModeTabs OP_BLOCKS +public net.minecraft.world.item.CreativeModeTabs REDSTONE_BLOCKS +public net.minecraft.world.item.CreativeModeTabs SEARCH +public net.minecraft.world.item.CreativeModeTabs SPAWN_EGGS +public net.minecraft.world.item.CreativeModeTabs TOOLS_AND_UTILITIES diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index d839c54b6e..53b17ead2e 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -18,3 +18,8 @@ license="LGPL v2.1" [[mixins]] config = "neoforge.mixins.json" + +[[accessTransformers]] + file="META-INF/accesstransformer.cfg" +[[accessTransformers]] + file="META-INF/accesstransformergenerated.cfg"