diff --git a/.gitattributes b/.gitattributes index fb08201822f..9271fb54d54 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,7 +2,6 @@ *.bat text eol=crlf *.patch text eol=lf *.java text eol=lf -*.gradle text eol=crlf *.png binary *.gif binary *.exe binary diff --git a/.github/workflows/build-prs.yml b/.github/workflows/build-prs.yml index e8419119b14..81877b19312 100644 --- a/.github/workflows/build-prs.yml +++ b/.github/workflows/build-prs.yml @@ -22,10 +22,10 @@ jobs: - name: Checkout repository uses: neoforged/actions/checkout@main - - name: Setup JDK 21 + - name: Setup JDK 25 uses: neoforged/actions/setup-java@main with: - java-version: 21 + java-version: 25 # Exclude minecraft sources from emitting annotation warnings since we cannot point to them anyway warning-file-path: '(?!.+\/projects\/neoforge\/src\/)[^:]+' diff --git a/.github/workflows/check-local-changes.yml b/.github/workflows/check-local-changes.yml index 23890b53d3c..c74272fe4f5 100644 --- a/.github/workflows/check-local-changes.yml +++ b/.github/workflows/check-local-changes.yml @@ -15,10 +15,10 @@ jobs: - name: Checkout repository uses: neoforged/actions/checkout@main - - name: Setup JDK 21 + - name: Setup JDK 25 uses: neoforged/actions/setup-java@main with: - java-version: 21 + java-version: 25 problem-matcher: false - name: Setup Gradle diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bff873504d4..eca676d5635 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,8 @@ on: branches: - '1.*' # Mainline release branches - '[0-9][0-9]w14[a-z]+' # w14 April Fools Snapshots + tags: + - 'release/*' # Manual releases permissions: contents: read @@ -17,10 +19,11 @@ jobs: release: uses: neoforged/actions/.github/workflows/gradle-publish.yml@main with: - java: 21 + java: 25 pre_gradle_tasks: setup - gradle_tasks: publish '-Pneogradle.runtime.platform.installer.debug=false' + gradle_tasks: publish version_labels: -beta, -stable + set_project_version: true # We only publish the main repository. This way we avoid publishing Kits if: ${{ github.repository == 'neoforged/NeoForge' }} diff --git a/.github/workflows/test-prs.yml b/.github/workflows/test-prs.yml index eac0691673b..d59d10090fa 100644 --- a/.github/workflows/test-prs.yml +++ b/.github/workflows/test-prs.yml @@ -19,10 +19,10 @@ jobs: - name: Checkout repository uses: neoforged/actions/checkout@main - - name: Setup JDK 21 + - name: Setup JDK 25 uses: neoforged/actions/setup-java@main with: - java-version: 21 + java-version: 25 problem-matcher: false - name: Setup Gradle diff --git a/build.gradle b/build.gradle index b1b68aa816f..975e6047bb8 100644 --- a/build.gradle +++ b/build.gradle @@ -3,19 +3,29 @@ import java.util.regex.Pattern import net.neoforged.neodev.CheckSplitSources plugins { - id 'net.neoforged.gradleutils' version '4.0.1' + id 'net.neoforged.gradleutils' version '5.1.0' id 'dev.lukebemish.immaculate' version '0.1.6' apply false id 'net.neoforged.licenser' version '0.7.5' id 'neoforge.formatting-conventions' id 'neoforge.versioning' } -ext.isPreReleaseVersion = project.minecraft_version.contains('w') || project.minecraft_version.contains('-') - -if (isPreReleaseVersion) { - project.version = "${project.neoforge_snapshot_next_stable}.0-alpha.${project.minecraft_version}.${(new Date()).format('yyyyMMdd.HHmmss', TimeZone.getTimeZone('UTC'))}" +// If an external version is defined, always use that +ext.isPreReleaseVersion = false + +final fixedProjectVersion = project.providers.gradleProperty("version").getOrElse(null) +if (fixedProjectVersion == null) { + if (project.minecraft_version.contains('-')) { + ext.isPreReleaseVersion = true + // Match the manual snapshot release suffix (e.g. -alpha.M+snapshot-N) with M=0 and a suffixed . + // Separate out the -snapshot-N or -rc-N suffix + final preReleaseSuffix = project.minecraft_version.split("-", 2)[1] + project.version = "${project.neoforge_snapshot_next_stable}.0-alpha.0+${preReleaseSuffix}.${(new Date()).format('yyyyMMdd.HHmmss', TimeZone.getTimeZone('UTC'))}" + } else { + project.version = gradleutils.version.toString() + } } else { - project.version = gradleutils.version.toString() + project.version = fixedProjectVersion } // Print version, generally useful to know - also appears on CI diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index f5ad6158393..86a18824eef 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -28,7 +28,7 @@ dependencies { // ../settings.gradle sets these version properties accordingly implementation "net.neoforged:moddev-gradle:${gradle.parent.ext.moddevgradle_plugin_version}" - implementation(platform("net.neoforged:minecraft-dependencies:${gradle.parent.ext.minecraft_dependencies_version}") { + implementation(platform("net.neoforged:minecraft-dependencies:${gradle.parent.ext.minecraft_version}") { exclude group: 'org.ow2.asm' // The platform requests a strictly lower version of ASM and we bump it }) diff --git a/buildSrc/src/main/groovy/neoforge.formatting-conventions.gradle b/buildSrc/src/main/groovy/neoforge.formatting-conventions.gradle index e8a22f07e4f..de2c7f8c445 100644 --- a/buildSrc/src/main/groovy/neoforge.formatting-conventions.gradle +++ b/buildSrc/src/main/groovy/neoforge.formatting-conventions.gradle @@ -70,6 +70,11 @@ immaculate { fileContents.replace('javax.annotation.Nullable', 'org.jspecify.annotations.Nullable') fileContents.replace('org.jetbrains.annotations.Nullable', 'org.jspecify.annotations.Nullable') } + + // Bump the version of the google formatter to add Java 25 support. + steps.named { it == 'googleFixImports' }.configureEach { + it.version('1.33.0') + } } } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java b/buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java index 0648b73dcbb..1b8880c70fc 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java @@ -12,27 +12,19 @@ abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts { @OutputFile abstract RegularFileProperty getRawClientJar(); - @OutputFile - abstract RegularFileProperty getCleanClientJar(); - /** * The unmodified downloaded server jar. */ @OutputFile abstract RegularFileProperty getRawServerJar(); - @OutputFile - abstract RegularFileProperty getCleanServerJar(); - @OutputFile abstract RegularFileProperty getCleanJoinedJar(); @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()); getAdditionalResults().put("vanillaDeobfuscated", getCleanJoinedJar().getAsFile()); } } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java b/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java index 64cecab2aab..cd91bf38d79 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/CreateUserDevConfig.java @@ -89,11 +89,6 @@ public void writeUserDevConfig() throws IOException { "--assetsDir", "{assets_root}"); } - Collections.addAll(args, - "--fml.mcVersion", getMinecraftVersion().get(), - "--fml.neoForgeVersion", getNeoForgeVersion().get(), - "--fml.neoFormVersion", getRawNeoFormVersion().get()); - Map systemProperties = new LinkedHashMap<>(); systemProperties.put("java.net.preferIPv6Addresses", "system"); @@ -107,6 +102,8 @@ public void writeUserDevConfig() throws IOException { Objects.requireNonNullElse(runType.mainClass, "NONE"), args, List.of( + "--sun-misc-unsafe-memory-access=allow", + "--enable-native-access=ALL-UNNAMED", "--add-opens", "java.base/java.lang.invoke=ALL-UNNAMED", "--add-exports", "jdk.naming.dns/com.sun.jndi.dns=java.naming"), runType == RunType.CLIENT || runType == RunType.JUNIT || runType == RunType.CLIENT_DATA, diff --git a/buildSrc/src/main/java/net/neoforged/neodev/GenerateBaseJar.java b/buildSrc/src/main/java/net/neoforged/neodev/GenerateBaseJar.java index 3ed9df1ccdb..53997210c29 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/GenerateBaseJar.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/GenerateBaseJar.java @@ -31,6 +31,7 @@ public void exec() { } args("--output", getOutput().get().getAsFile().getAbsolutePath()); args("--no-dist-annotation"); + args("--no-mod-manifest"); super.exec(); } } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/GenerateResourcePatches.java b/buildSrc/src/main/java/net/neoforged/neodev/GenerateResourcePatches.java new file mode 100644 index 00000000000..a646d5c570e --- /dev/null +++ b/buildSrc/src/main/java/net/neoforged/neodev/GenerateResourcePatches.java @@ -0,0 +1,62 @@ +package net.neoforged.neodev; + +import io.codechicken.diffpatch.cli.CliOperation; +import io.codechicken.diffpatch.cli.DiffOperation; +import io.codechicken.diffpatch.util.Input.MultiInput; +import io.codechicken.diffpatch.util.Output.MultiOutput; +import java.io.File; +import java.io.IOException; +import javax.inject.Inject; +import org.gradle.api.DefaultTask; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.tasks.InputDirectory; +import org.gradle.api.tasks.Optional; +import org.gradle.api.tasks.OutputDirectory; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.TaskAction; + +/** + * Generates patch files for all resources found in a given folder to facilitate injecting them into + * the moddev environment. + */ +abstract class GenerateResourcePatches extends DefaultTask { + @InputDirectory + public abstract DirectoryProperty getAdditionalResourcesDir(); + + @Optional + @OutputFile + public abstract RegularFileProperty getPatchesJar(); + + @Optional + @OutputDirectory + public abstract DirectoryProperty getPatchesFolder(); + + @Inject + public GenerateResourcePatches() {} + + @TaskAction + public void generateSourcePatches() throws IOException { + var emptyFolder = new File(getTemporaryDir(), "empty"); + emptyFolder.mkdir(); + + var builder = DiffOperation.builder() + .logTo(getLogger()::lifecycle) + .baseInput(MultiInput.folder(emptyFolder.toPath())) + .changedInput(MultiInput.folder(getAdditionalResourcesDir().get().getAsFile().toPath())) + .patchesOutput(getPatchesJar().isPresent() ? MultiOutput.detectedArchive(getPatchesJar().get().getAsFile().toPath()) : MultiOutput.folder(getPatchesFolder().getAsFile().get().toPath())) + .autoHeader(true) + .level(io.codechicken.diffpatch.util.LogLevel.WARN) + .summary(false) + .aPrefix("a/") + .bPrefix("b/") + .lineEnding("\n"); + + CliOperation.Result result = builder.build().operate(); + + int exit = result.exit; + if (exit != 0 && exit != 1) { + throw new RuntimeException("DiffPatch failed with exit code: " + exit); + } + } +} diff --git a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java index 9575e749914..e43cab7c57f 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java @@ -33,7 +33,7 @@ public void apply(Project project) { tasks.register("setup", Sync.class, task -> { task.setGroup(NeoDevPlugin.GROUP); task.setDescription("Replaces the contents of the base project sources with the unpatched, decompiled Minecraft source code."); - task.from(project.zipTree(createSources.flatMap(CreateMinecraftArtifacts::getSourcesArtifact))); + task.from(project.zipTree(createSources.flatMap(CreateMinecraftArtifacts::getGameSourcesArtifact))); task.into(project.file("src/main/java/")); task.include("**/*.java"); }); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java index de9d8670783..ff495dc6519 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java @@ -37,12 +37,14 @@ import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.Copy; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.Sync; import org.gradle.api.tasks.TaskProvider; import org.gradle.api.tasks.bundling.AbstractArchiveTask; import org.gradle.api.tasks.bundling.Jar; import org.gradle.api.tasks.bundling.Zip; +import org.gradle.language.jvm.tasks.ProcessResources; public class NeoDevPlugin implements Plugin { static final String GROUP = "neoforge development"; @@ -80,7 +82,7 @@ public void apply(Project project) { task.setGroup(INTERNAL_GROUP); task.getDestinationDirectory().set(neoDevBuildDir.map(d -> d.dir("artifacts"))); task.getArchiveFileName().set("base-sources-only.jar"); - task.from(project.zipTree(decompilationSetup.createArtifacts().flatMap(CreateMinecraftArtifacts::getSourcesArtifact))); + task.from(project.zipTree(decompilationSetup.createArtifacts().flatMap(CreateMinecraftArtifacts::getGameSourcesArtifact))); task.include("**/*.java"); }); @@ -90,9 +92,7 @@ public void apply(Project project) { 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.getNeoFormArtifact().set(mcAndNeoFormVersion.map(version -> "net.neoforged:neoform:" + version + "@zip")); }); @@ -147,6 +147,7 @@ public void apply(Project project) { // 5. Split source jar from 4. into client and server. var splitPatchedSources = tasks.register("splitPatchedSources", SplitMergedSources.class, task -> { task.setGroup(INTERNAL_GROUP); + task.getOriginalResourcesJar().set(decompilationSetup.vanillaResources.flatMap(Zip::getArchiveFile)); task.getMergedJar().set(applyPatches.flatMap(ApplyPatches::getPatchedJar)); task.getCommonJar().set(neoDevBuildDir.map(dir -> dir.file("artifacts/common-patched-sources.jar"))); task.getClientJar().set(neoDevBuildDir.map(dir -> dir.file("artifacts/client-patched-sources.jar"))); @@ -212,6 +213,17 @@ public void apply(Project project) { * OTHER TASKS */ + var generateAdditionalMinecraftJarResources = tasks.register("generateMinecraftModsToml", ProcessResources.class, task -> { + task.getInputs().property("minecraft_version", minecraftVersion.get()); + task.setGroup(INTERNAL_GROUP); + task.from(new File(project.getRootDir(), "src/main/templates/minecraft.neoforge.mods.toml"), spec -> { + spec.rename("(.*)", "META-INF/neoforge.mods.toml"); + spec.expand(Map.of("minecraft_version", minecraftVersion.get())); + }); + task.into(neoDevBuildDir.map(d -> d.dir("additional-minecraft-resources")).get()); + }); + var additionalMinecraftResourcesDir = project.getLayout().dir(generateAdditionalMinecraftJarResources.map(Copy::getDestinationDir)); + // Task to create a jar with both common and client classes. // We cannot add the client classes to the default `jar` task because it might be used // as a dependency for the compilation of the client classes, leading to a circular dependency. @@ -245,12 +257,17 @@ public void apply(Project project) { }); // Generate source patches that are based on the production environment (without separate interface injection) - var genProductionPatches = tasks.register("generateProductionSourcePatches", GenerateSourcePatches.class, task -> { + var genProductionSourcePatches = tasks.register("generateProductionSourcePatches", GenerateSourcePatches.class, task -> { task.setGroup(INTERNAL_GROUP); task.getOriginalJar().set(applyAt.flatMap(TransformSources::getOutputJar)); task.getModifiedSources().set(mergeSources.flatMap(AbstractArchiveTask::getArchiveFile)); task.getPatchesFolder().set(neoDevBuildDir.map(dir -> dir.dir("production-source-patches"))); }); + var genProductionResourcePatches = tasks.register("generateProductionResourcePatches", GenerateResourcePatches.class, task -> { + task.setGroup(INTERNAL_GROUP); + task.getAdditionalResourcesDir().set(additionalMinecraftResourcesDir); + task.getPatchesFolder().set(neoDevBuildDir.map(dir -> dir.dir("production-resource-patches"))); + }); // Update the patch/ folder with the current patches. tasks.register("genPatches", Sync.class, task -> { @@ -265,39 +282,29 @@ public void apply(Project project) { task.getManifest().attributes(Map.of("FML-System-Mods", "neoforge")); }); + var binaryPatchOutputs = configureBinaryPatchCreation( + project, + configurations, + createCleanArtifacts, + neoDevBuildDir, + additionalMinecraftResourcesDir); + // Universal jar = the jar that contains NeoForge classes // TODO: signing? var universalJar = tasks.register("universalJar", Jar.class, task -> { task.setGroup(INTERNAL_GROUP); task.getArchiveClassifier().set("universal"); + task.manifest(manifest -> { + manifest.attributes(Map.of("FML-System-Mods", "neoforge")); + }); - task.from(project.zipTree( - joinedJar.flatMap(AbstractArchiveTask::getArchiveFile))); + task.from(project.zipTree(joinedJar.flatMap(AbstractArchiveTask::getArchiveFile))); task.exclude("net/minecraft/**"); task.exclude("com/**"); task.exclude("mcp/**"); - - task.manifest(manifest -> { - manifest.attributes(Map.of("FML-System-Mods", "neoforge")); - // These attributes are used from NeoForgeVersion.java to find the NF version without command line arguments. - manifest.attributes( - Map.of( - "Specification-Title", "NeoForge", - "Specification-Vendor", "NeoForge", - "Specification-Version", project.getVersion().toString().substring(0, project.getVersion().toString().lastIndexOf(".")), - "Implementation-Title", project.getGroup(), - "Implementation-Version", project.getVersion(), - "Implementation-Vendor", "NeoForged"), - "net/neoforged/neoforge/internal/versions/neoforge/"); - manifest.attributes( - Map.of( - "Specification-Title", "Minecraft", - "Specification-Vendor", "Mojang", - "Specification-Version", minecraftVersion, - "Implementation-Title", "MCP", - "Implementation-Version", mcAndNeoFormVersion, - "Implementation-Vendor", "NeoForged"), - "net/neoforged/neoforge/versions/neoform/"); + task.from(binaryPatchOutputs, spec -> { + spec.into("net/neoforged/neoforge/common/"); + spec.rename(s -> "patches.lzma"); }); }); @@ -305,12 +312,6 @@ public void apply(Project project) { jarJarTask.configure(task -> task.setGroup(INTERNAL_GROUP)); universalJar.configure(task -> task.from(jarJarTask)); - var binaryPatchOutputs = configureBinaryPatchCreation( - project, - configurations, - createCleanArtifacts, - neoDevBuildDir); - var installerRepositoryUrls = getInstallerRepositoryUrls(project); // Launcher profile = the version.json file used by the Minecraft launcher. var createLauncherProfile = tasks.register("createLauncherProfile", CreateLauncherProfile.class, task -> { @@ -319,7 +320,7 @@ public void apply(Project project) { task.getNeoForgeVersion().set(neoForgeVersion); task.getRawNeoFormVersion().set(rawNeoFormVersion); task.setLibraries(configurations.launcherProfileClasspath); - task.setMinecraftLibraries(configurations.neoFormClasspath); + task.setMinecraftLibraries(configurations.minecraftClientClasspath); task.getRepositoryURLs().set(installerRepositoryUrls); task.getLauncherProfile().set(neoDevBuildDir.map(dir -> dir.file("launcher-profile.json"))); }); @@ -443,7 +444,10 @@ public void apply(Project project) { task.from(binaryPatchOutputs, spec -> { spec.rename(s -> "patches.lzma"); }); - task.from(genProductionPatches.flatMap(GenerateSourcePatches::getPatchesFolder), spec -> { + task.from(genProductionSourcePatches.flatMap(GenerateSourcePatches::getPatchesFolder), spec -> { + spec.into("patches/"); + }); + task.from(genProductionResourcePatches.flatMap(GenerateResourcePatches::getPatchesFolder), spec -> { spec.into("patches/"); }); }); @@ -518,14 +522,15 @@ private static Provider configureBinaryPatchCreation( Project project, NeoDevConfigurations neoDevConfigurations, TaskProvider createCleanArtifacts, - Provider neoDevBuildDir) { + Provider neoDevBuildDir, + Provider additionalMinecraftResources) { var tasks = project.getTasks(); var clientBaseJar = setupBinaryPatchBaseJar(project, neoDevBuildDir, BinaryPatchBaseType.CLIENT, neoDevConfigurations, createCleanArtifacts); var serverBaseJar = setupBinaryPatchBaseJar(project, neoDevBuildDir, BinaryPatchBaseType.SERVER, neoDevConfigurations, createCleanArtifacts); var joinedBaseJar = setupBinaryPatchBaseJar(project, neoDevBuildDir, BinaryPatchBaseType.JOINED, neoDevConfigurations, createCleanArtifacts); - var clientModifiedJar = setupBinaryPatchModifiedJar(project, neoDevBuildDir, BinaryPatchBaseType.CLIENT); - var serverModifiedJar = setupBinaryPatchModifiedJar(project, neoDevBuildDir, BinaryPatchBaseType.SERVER); + var clientModifiedJar = setupBinaryPatchModifiedJar(project, neoDevBuildDir, BinaryPatchBaseType.CLIENT, additionalMinecraftResources); + var serverModifiedJar = setupBinaryPatchModifiedJar(project, neoDevBuildDir, BinaryPatchBaseType.SERVER, additionalMinecraftResources); var binpatcherConfig = neoDevConfigurations.getExecutableTool(Tools.BINPATCHER); var generatePatchBundles = tasks.register("generatePatchBundle", GenerateBinaryPatches.class, task -> { @@ -541,6 +546,7 @@ private static Provider configureBinaryPatchCreation( // Since we're filtering by *.class, the modified jar for client and joined is identical. They differ in manifest only. task.getModifiedJoinedJar().set(clientModifiedJar); task.getInclude().add("**/*.class"); + task.getInclude().add("META-INF/neoforge.mods.toml"); task.getOutputFile().set(neoDevBuildDir.map(dir -> dir.file("patches.lzma"))); }); @@ -603,7 +609,7 @@ static DecompilationSetup configureMinecraftDecompilation(Project project) { var minecraftArtifactsDir = neoDevBuildDir.map(dir -> dir.dir("artifacts")); var createSources = tasks.register("createSourceArtifacts", CreateMinecraftArtifacts.class, task -> { task.setGroup(INTERNAL_GROUP); - task.getSourcesArtifact().set(minecraftArtifactsDir.map(dir -> dir.file("base-sources.jar"))); + task.getGameSourcesArtifact().set(minecraftArtifactsDir.map(dir -> dir.file("base-sources.jar"))); task.getNeoFormArtifact().set(mcAndNeoFormVersion.map(version -> "net.neoforged:neoform:" + version + "@zip")); }); @@ -611,9 +617,8 @@ static DecompilationSetup configureMinecraftDecompilation(Project project) { task.setGroup(INTERNAL_GROUP); task.getDestinationDirectory().set(minecraftArtifactsDir); task.getArchiveFileName().set("minecraft-resources.jar"); - task.from(project.zipTree(createSources.flatMap(CreateMinecraftArtifacts::getSourcesArtifact))); - // TODO: we are manually excluding the signing info, maybe NFRT should handle it? - task.exclude("**/*.java", "META-INF/*.RSA", "META-INF/*.SF"); + task.from(project.zipTree(createSources.flatMap(CreateMinecraftArtifacts::getGameSourcesArtifact))); + task.exclude("**/*.java"); }); return new DecompilationSetup(createSources, vanillaResources); @@ -666,7 +671,8 @@ private static Provider setupBinaryPatchBaseJar( private static Provider setupBinaryPatchModifiedJar( Project project, Provider neoDevBuildDir, - BinaryPatchBaseType type) { + BinaryPatchBaseType type, + Provider extraResourcesDir) { var tasks = project.getTasks(); var binpatchesDir = neoDevBuildDir.map(dir -> dir.dir("artifacts/binpatches")); @@ -690,6 +696,7 @@ private static Provider setupBinaryPatchModifiedJar( spec.exclude("net/neoforged/**"); }); } + task.from(extraResourcesDir); }); return modifiedJar.flatMap(AbstractArchiveTask::getArchiveFile); @@ -720,6 +727,7 @@ private void setupProductionClientTest( task.getNeoForgeVersion().set(neoForgeVersion); task.getInstallationDir().set(installClient.flatMap(InstallProductionClient::getInstallationDir)); task.getOriginalClientJar().set(originalClientJar); + task.getJavaRuntimeVersion().set(project.getProviders().gradleProperty("java_version").map(Integer::parseInt)); }; project.getTasks().register("runProductionClient", RunProductionClient.class, task -> { task.setGroup(GROUP); @@ -747,12 +755,14 @@ private void setupProductionServerTest(Project project, TaskProvider { task.setGroup(GROUP); task.setDescription("Tests the production server installed by installProductionServer."); task.getInstallationDir().set(installServer.flatMap(InstallProductionServer::getInstallationDir)); + task.getJavaRuntimeVersion().set(project.getProviders().gradleProperty("java_version").map(Integer::parseInt)); }); } } diff --git a/buildSrc/src/main/java/net/neoforged/neodev/SplitMergedSources.java b/buildSrc/src/main/java/net/neoforged/neodev/SplitMergedSources.java index d7ea6f769a9..9872d339df5 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/SplitMergedSources.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/SplitMergedSources.java @@ -4,6 +4,8 @@ import java.io.BufferedOutputStream; import java.io.IOException; import java.nio.file.Files; +import java.util.jar.Attributes; +import java.util.jar.JarFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import javax.inject.Inject; @@ -22,6 +24,9 @@ abstract class SplitMergedSources extends DefaultTask { @Inject public SplitMergedSources() {} + @InputFile + abstract RegularFileProperty getOriginalResourcesJar(); + @InputFile abstract RegularFileProperty getMergedJar(); @@ -34,21 +39,32 @@ public SplitMergedSources() {} @TaskAction public void splitMergedJar() throws IOException { try ( + var originalResources = new JarFile(getOriginalResourcesJar().get().getAsFile()); var merged = new ZipInputStream(new BufferedInputStream(Files.newInputStream(getMergedJar().get().getAsFile().toPath()))); var common = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(getCommonJar().get().getAsFile().toPath()))); var client = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(getClientJar().get().getAsFile().toPath())))) { + + var manifest = originalResources.getManifest(); + var sourceDistName = new Attributes.Name("Minecraft-Dist"); + for (var entry = merged.getNextEntry(); entry != null; entry = merged.getNextEntry()) { if (entry.isDirectory()) { continue; } - var bytes = merged.readAllBytes(); - if (new String(bytes).contains("\n@OnlyIn(Dist.CLIENT)")) { + + var fileEntry = manifest.getEntries().get(entry.getName().replace(".java", ".class")); + String sourceDist = null; + if (fileEntry != null) { + sourceDist = fileEntry.getValue(sourceDistName); + } + + if ("client".equals(sourceDist)) { client.putNextEntry(entry); - client.write(bytes); + merged.transferTo(client); client.closeEntry(); } else { common.putNextEntry(entry); - common.write(bytes); + merged.transferTo(common); common.closeEntry(); } } 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 9d04f9dfb18..a1bcca6748d 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionClient.java @@ -33,6 +33,7 @@ import org.gradle.api.tasks.JavaExec; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.TaskAction; +import org.gradle.jvm.toolchain.JavaLanguageVersion; import org.gradle.process.ExecOperations; import org.gradle.process.JavaExecSpec; @@ -87,9 +88,13 @@ public abstract class RunProductionClient extends JavaExec { @InputFile public abstract RegularFileProperty getOriginalClientJar(); + @Input + public abstract Property getJavaRuntimeVersion(); + @Inject public RunProductionClient(ExecOperations execOperations) { this.execOperations = execOperations; + getJavaLauncher().set(getJavaToolchainService().launcherFor(spec -> spec.getLanguageVersion().set(getJavaRuntimeVersion().map(JavaLanguageVersion::of)))); } @TaskAction @@ -138,6 +143,8 @@ public void exec() { placeholders.put("classpath_separator", File.pathSeparator); execOperations.javaexec(spec -> { + spec.executable(getJavaLauncher().get().getExecutablePath().getAsFile()); + // The JVM args at this point may include debugging options when started through IntelliJ spec.jvmArgs(getJvmArguments().get()); spec.workingDir(installDir); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionServer.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionServer.java index 06809c00b24..7f714479dc5 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionServer.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/RunProductionServer.java @@ -2,9 +2,12 @@ import javax.inject.Inject; import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputDirectory; import org.gradle.api.tasks.JavaExec; import org.gradle.api.tasks.TaskAction; +import org.gradle.jvm.toolchain.JavaLanguageVersion; import org.gradle.process.ExecOperations; /** @@ -23,9 +26,13 @@ public abstract class RunProductionServer extends JavaExec { @InputDirectory public abstract DirectoryProperty getInstallationDir(); + @Input + public abstract Property getJavaRuntimeVersion(); + @Inject public RunProductionServer(ExecOperations execOperations) { this.execOperations = execOperations; + getJavaLauncher().set(getJavaToolchainService().launcherFor(spec -> spec.getLanguageVersion().set(getJavaRuntimeVersion().map(JavaLanguageVersion::of)))); } @TaskAction @@ -34,6 +41,8 @@ public void exec() { var installDir = getInstallationDir().getAsFile().get().toPath(); execOperations.javaexec(spec -> { + spec.executable(getJavaLauncher().get().getExecutablePath().getAsFile()); + // The JVM args at this point may include debugging options when started through IntelliJ spec.jvmArgs(getJvmArguments().get()); spec.workingDir(installDir); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionClient.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionClient.java index c60913d7e86..a1c50beb792 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionClient.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionClient.java @@ -25,6 +25,7 @@ public TestProductionClient(ExecOperations execOperations) { @Override public void exec() { var selfTestReport = new File(getTemporaryDir(), "client_self_test.txt"); + selfTestReport.delete(); environment("NEOFORGE_CLIENT_SELFTEST", selfTestReport.getAbsolutePath()); diff --git a/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionServer.java b/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionServer.java index edb04f5f31a..faee337d739 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionServer.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/e2e/TestProductionServer.java @@ -28,6 +28,7 @@ public TestProductionServer(ExecOperations execOperations) { @Override public void exec() { var selfTestReport = new File(getTemporaryDir(), "server_self_test.txt"); + selfTestReport.delete(); environment("NEOFORGE_DEDICATED_SERVER_SELFTEST", selfTestReport.getAbsolutePath()); 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 c0d958685da..b72d06bded9 100644 --- a/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateInstallerProfile.java +++ b/buildSrc/src/main/java/net/neoforged/neodev/installer/CreateInstallerProfile.java @@ -18,7 +18,6 @@ import net.neoforged.neodev.utils.FileUtils; import net.neoforged.neodev.utils.MavenIdentifier; import org.gradle.api.DefaultTask; -import org.gradle.api.GradleException; import org.gradle.api.artifacts.Configuration; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.provider.ListProperty; @@ -106,12 +105,8 @@ private void addProcessor(List processors, @Nullable List(); var neoFormVersion = getMcAndNeoFormVersion().get(); - data.put("MOJMAPS", new LauncherDataEntry(clientMappingsCoordinate, serverMappingsCoordinate)); data.put("BINPATCH", new LauncherDataEntry("/data/client.lzma", "/data/client.lzma")); var patchedClientCoordinate = new MavenIdentifier("net.neoforged", "minecraft-client-patched", getNeoForgeVersion().get(), "", "jar"); @@ -131,35 +126,18 @@ public void createInstallerProfile() throws IOException { "--from", "data/win_args.txt", "--to", "{ROOT}/libraries/net/neoforged/neoforge/%s/win_args.txt".formatted(getNeoForgeVersion().get()), "--from", "data/unix_args.txt", "--to", "{ROOT}/libraries/net/neoforged/neoforge/%s/unix_args.txt".formatted(getNeoForgeVersion().get()))); - var neoformMappingsDependency = "net.neoforged:neoform:" + getMcAndNeoFormVersion().get() + ":mappings@tsrg.lzma"; - // Validate it will actually be downloaded - if (getLibraryFiles().get().stream().noneMatch(l -> { - var identifier = l.getIdentifier().get(); - return identifier.artifactNotation().equals(neoformMappingsDependency); - })) { - throw new GradleException("Libraries list must contain NeoForm mappings: " + neoformMappingsDependency); - } - - // This task will be auto-replaced by legacyinstaller and is mostly here for other launchers that - // never implemented the optimization of downloading mojmaps ahead of time. - commonProcessor.accept(InstallerProcessor.INSTALLERTOOLS, - List.of("--task", "DOWNLOAD_MOJMAPS", "--version", getMinecraftVersion().get(), "--side", "{SIDE}", "--output", "{MOJMAPS}")); - commonProcessor.accept( InstallerProcessor.INSTALLERTOOLS, List.of( "--task", "PROCESS_MINECRAFT_JAR", + "--no-mod-manifest", "--input", "{MINECRAFT_JAR}", - "--input-mappings", - "{MOJMAPS}", "--output", "{PATCHED}", "--extract-libraries-to", "{ROOT}/libraries/", - "--neoform-data", - String.format("[%s]", neoformMappingsDependency), "--apply-patches", "{BINPATCH}")); diff --git a/coremods/build.gradle b/coremods/build.gradle index c4c5327e035..313ab18fa76 100644 --- a/coremods/build.gradle +++ b/coremods/build.gradle @@ -20,7 +20,7 @@ java { } dependencies { - compileOnly(platform("net.neoforged:minecraft-dependencies:${project.minecraft_dependencies_version}")) + compileOnly(platform("net.neoforged:minecraft-dependencies:${project.minecraft_version}")) compileOnly "org.slf4j:slf4j-api" compileOnly "com.google.code.gson:gson" diff --git a/gradle.properties b/gradle.properties index 7cd196dd81f..c165c1f4977 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,28 +10,26 @@ org.gradle.debug=false #org.gradle.warning.mode=fail # renovate: net.neoforged:moddev-gradle -moddevgradle_plugin_version=2.0.123 +moddevgradle_plugin_version=2.0.126 # renovate: io.codechicken:DiffPatch diffpatch_version=2.0.0.35 -java_version=21 +java_version=25 -minecraft_version=1.21.11_unobfuscated -neoform_version=2 +minecraft_version=26.1-snapshot-4 +neoform_version=1 # on snapshot versions, used to prefix the version -neoforge_snapshot_next_stable=26.1 -# TODO: delete ;) -minecraft_dependencies_version=1.21.11 -neoForge.neoFormRuntime.launcherManifestUrl=https://shartte.github.io/Minecraft1.21.11UnobfuscatedMeta/manifest.json +# should always have 3 components (major.minor.hotfix) +neoforge_snapshot_next_stable=26.1.0 # renovate: net.neoforged.jst:jst-cli-bundle jst_version=1.0.67 legacyinstaller_version=3.0.+ # renovate: net.neoforged.installertools:installertools -installertools_version=4.0.6 +installertools_version=4.0.12 # renovate: org.ow2.asm:asm -asm_version=9.8 +asm_version=9.9.1 mergetool_version=2.0.0 accesstransformers_version=11.0.1 @@ -42,7 +40,7 @@ nightconfig_version=3.8.3 jetbrains_annotations_version=24.0.1 apache_maven_artifact_version=3.9.9 jarjar_version=0.4.1 -fancy_mod_loader_version=10.0.34 +fancy_mod_loader_version=11.0.0 typetools_version=0.6.3 mixin_extras_version=0.5.0 diff --git a/patches/com/mojang/blaze3d/opengl/GlBackend.java.patch b/patches/com/mojang/blaze3d/opengl/GlBackend.java.patch new file mode 100644 index 00000000000..66ff071c3f5 --- /dev/null +++ b/patches/com/mojang/blaze3d/opengl/GlBackend.java.patch @@ -0,0 +1,25 @@ +--- a/com/mojang/blaze3d/opengl/GlBackend.java ++++ b/com/mojang/blaze3d/opengl/GlBackend.java +@@ -25,6 +_,13 @@ + public WindowAndDevice createDeviceWithWindow( + int width, int height, String title, long monitor, ShaderSource defaultShaderSource, GpuDebugOptions debugOptions + ) throws BackendCreationException { ++ var earlyLoadingScreen = net.neoforged.fml.loading.EarlyLoadingScreenController.current(); ++ if (earlyLoadingScreen != null) { ++ var window = earlyLoadingScreen.takeOverGlfwWindow(); ++ GLFW.glfwSetWindowTitle(window, title); ++ return new WindowAndDevice(window, net.neoforged.neoforge.client.ClientHooks.createGpuDevice(window, defaultShaderSource, debugOptions)); ++ } ++ + GLFWErrorCapture glfwErrors = new GLFWErrorCapture(); + + WindowAndDevice error; +@@ -54,7 +_,7 @@ + throw new BackendCreationException("Failed to create window with OpenGL context"); + } + +- error = new WindowAndDevice(window, new GlDevice(window, defaultShaderSource, debugOptions)); ++ error = new WindowAndDevice(window, net.neoforged.neoforge.client.ClientHooks.createGpuDevice(window, defaultShaderSource, debugOptions)); + } + + return error; diff --git a/patches/com/mojang/blaze3d/opengl/GlCommandEncoder.java.patch b/patches/com/mojang/blaze3d/opengl/GlCommandEncoder.java.patch index 28179079ea5..61ba49a16e8 100644 --- a/patches/com/mojang/blaze3d/opengl/GlCommandEncoder.java.patch +++ b/patches/com/mojang/blaze3d/opengl/GlCommandEncoder.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/opengl/GlCommandEncoder.java +++ b/com/mojang/blaze3d/opengl/GlCommandEncoder.java -@@ -201,7 +_,8 @@ +@@ -203,7 +_,8 @@ throw new IllegalStateException("Close the existing render pass before creating a new one!"); } else { this.verifyDepthTexture(depthTexture); @@ -10,7 +10,7 @@ GL11.glDrawBuffer(0); GL11.glClearDepth(clearDepth); GlStateManager._depthMask(true); -@@ -213,6 +_,23 @@ +@@ -215,6 +_,23 @@ } } @@ -34,7 +34,31 @@ private void verifyColorTexture(GpuTexture colorTexture) { if (!colorTexture.getFormat().hasColorAspect()) { throw new IllegalStateException("Trying to clear a non-color texture as color"); -@@ -635,11 +_,22 @@ +@@ -636,16 +_,46 @@ + } else if (destination.getDepthOrLayers() > 1) { + throw new UnsupportedOperationException("Textures with multiple depths or layers are not yet supported for copying"); + } else { ++ var sourceFormat = source.getFormat(); ++ var destFormat = destination.getFormat(); ++ ++ if (sourceFormat.hasDepthAspect() || sourceFormat.hasStencilAspect()) { ++ if (sourceFormat != destFormat) { ++ throw new IllegalArgumentException( ++ "When copying depth or stencil data, the source and destination texture formats must be identical. Source: " ++ + sourceFormat + ", Destination: " + destFormat ++ ); ++ } ++ } ++ ++ if (sourceFormat.hasColorAspect() != destFormat.hasColorAspect()) { ++ throw new IllegalArgumentException( ++ "Source and destination texture formats must have consistent color aspects. Source: " ++ + sourceFormat + ", Destination: " + destFormat ++ ); ++ } ++ + GlStateManager.clearGlErrors(); + GlStateManager._disableScissorTest(); boolean isDepth = source.getFormat().hasDepthAspect(); int sourceId = ((GlTexture)source).glId(); int destId = ((GlTexture)destination).glId(); @@ -60,7 +84,7 @@ int error = GlStateManager._getError(); if (error != 0) { throw new IllegalStateException( -@@ -971,6 +_,26 @@ +@@ -1000,6 +_,26 @@ GlStateManager._scissorBox(renderPass.getScissorX(), renderPass.getScissorY(), renderPass.getScissorWidth(), renderPass.getScissorHeight()); } else { GlStateManager._disableScissorTest(); diff --git a/patches/com/mojang/blaze3d/opengl/GlDevice.java.patch b/patches/com/mojang/blaze3d/opengl/GlDevice.java.patch index 462cfe65c08..f104ede3886 100644 --- a/patches/com/mojang/blaze3d/opengl/GlDevice.java.patch +++ b/patches/com/mojang/blaze3d/opengl/GlDevice.java.patch @@ -1,15 +1,15 @@ --- a/com/mojang/blaze3d/opengl/GlDevice.java +++ b/com/mojang/blaze3d/opengl/GlDevice.java -@@ -63,6 +_,8 @@ - private final Set enabledExtensions = new HashSet<>(); +@@ -65,6 +_,8 @@ private final int uniformOffsetAlignment; private final int maxSupportedAnisotropy; + private final long windowHandle; + private final net.neoforged.neoforge.client.blaze3d.GpuDeviceProperties deviceProperties; + private final net.neoforged.neoforge.client.blaze3d.GpuDeviceFeatures enabledFeatures; - public GlDevice(long windowHandle, int debugLevel, boolean synchronousLogs, ShaderSource defaultShaderSource, boolean wantsDebugLabels) { + public GlDevice(long windowHandle, ShaderSource defaultShaderSource, GpuDebugOptions debugOptions) { GLFW.glfwMakeContextCurrent(windowHandle); -@@ -87,6 +_,9 @@ +@@ -90,6 +_,9 @@ } else { this.maxSupportedAnisotropy = 1; } @@ -19,7 +19,7 @@ } public GlDebugLabel debugLabels() { -@@ -208,6 +_,67 @@ +@@ -235,6 +_,67 @@ } } @@ -87,7 +87,7 @@ @Override public GpuTextureView createTextureView(GpuTexture texture) { return this.createTextureView(texture, 0, texture.getMipLevels()); -@@ -455,5 +_,15 @@ +@@ -497,5 +_,15 @@ String string = this.id + " (" + this.type + ")"; return !this.defines.isEmpty() ? string + " with " + this.defines : string; } diff --git a/patches/com/mojang/blaze3d/opengl/GlStateManager.java.patch b/patches/com/mojang/blaze3d/opengl/GlStateManager.java.patch index 89926e14942..4768b4e582c 100644 --- a/patches/com/mojang/blaze3d/opengl/GlStateManager.java.patch +++ b/patches/com/mojang/blaze3d/opengl/GlStateManager.java.patch @@ -8,11 +8,10 @@ private static final GlStateManager.ScissorState SCISSOR = new GlStateManager.ScissorState(); private static int activeTexture; private static final int TEXTURE_COUNT = 12; -@@ -597,5 +_,120 @@ - @OnlyIn(Dist.CLIENT) +@@ -598,4 +_,119 @@ private static class TextureState { public int binding; -+ } + } + + public static void _disableStencilTest() { + RenderSystem.assertOnRenderThread(); @@ -127,5 +126,5 @@ + public int backStencilFail = GL11.GL_KEEP; + public int backDepthFail = GL11.GL_KEEP; + public int backPass = GL11.GL_KEEP; - } ++ } } diff --git a/patches/com/mojang/blaze3d/opengl/GlTextureView.java.patch b/patches/com/mojang/blaze3d/opengl/GlTextureView.java.patch new file mode 100644 index 00000000000..74acbd67eb9 --- /dev/null +++ b/patches/com/mojang/blaze3d/opengl/GlTextureView.java.patch @@ -0,0 +1,37 @@ +--- a/com/mojang/blaze3d/opengl/GlTextureView.java ++++ b/com/mojang/blaze3d/opengl/GlTextureView.java +@@ -45,10 +_,11 @@ + + public int getFbo(DirectStateAccess dsa, @Nullable GpuTexture depth) { + int depthId = depth == null ? 0 : ((GlTexture)depth).id; ++ var useStencil = depth != null && depth.getFormat().hasStencilAspect(); + if (this.firstFboDepthId == depthId) { + return this.firstFboId; + } else if (this.firstFboId == -1) { +- this.firstFboId = this.createFbo(dsa, depthId); ++ this.firstFboId = this.createFbo(dsa, depthId, useStencil); + this.firstFboDepthId = depthId; + return this.firstFboId; + } else { +@@ -56,13 +_,19 @@ + this.fboCache = new Int2IntArrayMap(); + } + +- return this.fboCache.computeIfAbsent(depthId, _depthId -> this.createFbo(dsa, _depthId)); ++ return this.fboCache.computeIfAbsent(depthId, _depthId -> this.createFbo(dsa, _depthId, useStencil)); + } + } + ++ /** @deprecated use overload that takes useStencil */ + private int createFbo(DirectStateAccess dsa, int depthid) { ++ return createFbo(dsa, depthid, false); ++ } ++ ++ // Neo: Allow for stencil use ++ private int createFbo(DirectStateAccess dsa, int depthid, boolean useStencil) { + int fbo = dsa.createFrameBufferObject(); +- dsa.bindFrameBufferTextures(fbo, this.texture().id, depthid, this.baseMipLevel(), 0); ++ dsa.bindFrameBufferTextures(fbo, this.texture().id, depthid, this.baseMipLevel(), 0, useStencil); + return fbo; + } + diff --git a/patches/com/mojang/blaze3d/platform/Window.java.patch b/patches/com/mojang/blaze3d/platform/Window.java.patch index 14276570a2b..3b238a73068 100644 --- a/patches/com/mojang/blaze3d/platform/Window.java.patch +++ b/patches/com/mojang/blaze3d/platform/Window.java.patch @@ -1,25 +1,23 @@ --- a/com/mojang/blaze3d/platform/Window.java +++ b/com/mojang/blaze3d/platform/Window.java -@@ -95,6 +_,10 @@ - GLFW.glfwWindowHint(139267, 3); - GLFW.glfwWindowHint(139272, 204801); - GLFW.glfwWindowHint(139270, 1); +@@ -109,6 +_,16 @@ + debugOptions + ); + this.handle = windowAndDevice.window(); ++ // Neo: If the window was taken over from EarlyLoadingScreen, inherit a potentially resized window size + var earlyLoadingScreen = net.neoforged.fml.loading.EarlyLoadingScreenController.current(); + if (earlyLoadingScreen != null) { -+ this.handle = takeOverWindow(earlyLoadingScreen, title); -+ } else { - this.handle = GLFW.glfwCreateWindow(this.width, this.height, title, this.fullscreen && initialMonitor != null ? initialMonitor.getMonitor() : 0L, 0L); ++ var width = new int[1]; ++ var height = new int[1]; ++ GLFW.glfwGetWindowSize(this.handle, width, height); ++ // The window height and width can be 0 if minimized ++ this.width = this.windowedWidth = Math.max(width[0], 1); ++ this.height = this.windowedHeight = Math.max(height[0], 1); ++ } + RenderSystem.initRenderer(windowAndDevice.device()); if (initialMonitor != null) { VideoMode mode = initialMonitor.getPreferredVidMode(this.fullscreen ? this.preferredFullscreenVideoMode : Optional.empty()); -@@ -107,6 +_,7 @@ - this.windowedX = this.x = actualX[0]; - this.windowedY = this.y = actualY[0]; - } -+ } - - this.setMode(); - this.refreshFramebufferSize(); -@@ -208,8 +_,10 @@ +@@ -239,8 +_,10 @@ } public void defaultErrorCallback(int errorCode, long description) { @@ -31,31 +29,3 @@ LOGGER.error("########## GL ERROR ##########"); LOGGER.error("@ {}", this.errorSection); LOGGER.error("{}: {}", errorCode, errorString); -@@ -515,5 +_,27 @@ - private WindowInitFailed(String message) { - super(message); - } -+ } -+ -+ // Neo take over window and its properties from early display -+ private long takeOverWindow(net.neoforged.fml.loading.EarlyLoadingScreenController earlyLoadingScreen, String title) { -+ long window = earlyLoadingScreen.takeOverGlfwWindow(); -+ -+ GLFW.glfwSetWindowTitle(window, title); -+ -+ var x = new int[1]; -+ var y = new int[1]; -+ GLFW.glfwGetWindowPos(window, x, y); -+ this.x = this.windowedX = x[0]; -+ this.y = this.windowedY = y[0]; -+ -+ var width = new int[1]; -+ var height = new int[1]; -+ GLFW.glfwGetWindowSize(window, width, height); -+ // The window height and width can be 0 if minimized -+ this.width = this.windowedWidth = Math.max(width[0], 1); -+ this.height = this.windowedHeight = Math.max(height[0], 1); -+ -+ return window; - } - } diff --git a/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch b/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch index 25f2bfea798..9de2695dfd3 100644 --- a/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch +++ b/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch @@ -1,27 +1,17 @@ --- a/com/mojang/blaze3d/systems/RenderSystem.java +++ b/com/mojang/blaze3d/systems/RenderSystem.java -@@ -77,6 +_,7 @@ +@@ -74,6 +_,7 @@ private static @Nullable DynamicUniforms dynamicUniforms; private static final ScissorState scissorStateForRenderTypeDraws = new ScissorState(); - private static SamplerCache samplerCache = new SamplerCache(); + private static final SamplerCache samplerCache = new SamplerCache(); + private static final net.neoforged.neoforge.client.pipeline.PipelineModifierStack PIPELINE_MODIFIERS = new net.neoforged.neoforge.client.pipeline.PipelineModifierStack(); public static SamplerCache getSamplerCache() { return samplerCache; -@@ -180,7 +_,7 @@ +@@ -390,4 +_,38 @@ + @OnlyIn(Dist.CLIENT) + record GpuAsyncTask(Runnable callback, GpuFence fence) { } - - public static void initRenderer(long windowHandle, int logVerbosity, boolean synchronousLogs, ShaderSource shaderSource, boolean wantsDebugLabels) { -- DEVICE = new GlDevice(windowHandle, logVerbosity, synchronousLogs, shaderSource, wantsDebugLabels); -+ DEVICE = net.neoforged.neoforge.client.ClientHooks.createGpuDevice(windowHandle, logVerbosity, synchronousLogs, shaderSource, wantsDebugLabels); - apiDescription = getDevice().getImplementationInformation(); - dynamicUniforms = new DynamicUniforms(); - samplerCache.initialize(); -@@ -310,6 +_,40 @@ - if (shaderLights != null) { - renderPass.setUniform("Lighting", shaderLights); - } -+ } + + /** + * Neo: Push the provided {@link net.neoforged.neoforge.client.pipeline.PipelineModifier PipelineModifier} to be applied to subsequent rendering. @@ -55,6 +45,5 @@ + @org.jetbrains.annotations.ApiStatus.Internal + public static void ensurePipelineModifiersEmpty() { + PIPELINE_MODIFIERS.ensureEmpty(); - } - - @OnlyIn(Dist.CLIENT) ++ } + } diff --git a/patches/com/mojang/blaze3d/vertex/VertexConsumer.java.patch b/patches/com/mojang/blaze3d/vertex/VertexConsumer.java.patch index 36d198af7c3..223f947aee2 100644 --- a/patches/com/mojang/blaze3d/vertex/VertexConsumer.java.patch +++ b/patches/com/mojang/blaze3d/vertex/VertexConsumer.java.patch @@ -4,12 +4,12 @@ long packedUv = quad.packedUV(vertex); float brightnessForVertex = brightness[vertex]; int color = ARGB.colorFromFloat(a, brightnessForVertex * r, brightnessForVertex * g, brightnessForVertex * b); -+ color = ARGB.multiply(color, ARGB.toABGR(quad.bakedColors().color(vertex))); // Neo: apply baked color from the quad - int light = LightTexture.lightCoordsWithEmission(lightmapCoord[vertex], lightEmission); ++ color = ARGB.multiply(color, quad.bakedColors().color(vertex)); // Neo: apply baked color from the quad + int light = LightCoordsUtil.lightCoordsWithEmission(lightmapCoord[vertex], lightEmission); Vector3f pos = matrix.transformPosition(position, new Vector3f()); float u = UVPair.unpackU(packedUv); float v = UVPair.unpackV(packedUv); -+ applyBakedNormals(pos, quad.bakedNormals(), vertex, pose.normal()); // Neo: apply baked normals from the quad ++ applyBakedNormals(normal, quad.bakedNormals(), vertex, pose.normal()); // Neo: apply baked normals from the quad this.addVertex(pos.x(), pos.y(), pos.z(), color, u, v, overlayCoords, light, normal.x(), normal.y(), normal.z()); } } diff --git a/patches/com/mojang/blaze3d/vertex/VertexFormatElement.java.patch b/patches/com/mojang/blaze3d/vertex/VertexFormatElement.java.patch index 4c61cc056c5..bb061e04184 100644 --- a/patches/com/mojang/blaze3d/vertex/VertexFormatElement.java.patch +++ b/patches/com/mojang/blaze3d/vertex/VertexFormatElement.java.patch @@ -1,9 +1,9 @@ --- a/com/mojang/blaze3d/vertex/VertexFormatElement.java +++ b/com/mojang/blaze3d/vertex/VertexFormatElement.java -@@ -71,6 +_,15 @@ - return ELEMENTS.stream().filter(element -> (mask & element.mask()) != 0); +@@ -72,6 +_,15 @@ } + @OnlyIn(Dist.CLIENT) + public static int findNextId() { + for (int i = 0; i < BY_ID.length; i++) { + if (BY_ID[i] == null) { @@ -13,6 +13,6 @@ + throw new IllegalStateException("VertexFormatElement count limit exceeded"); + } + - @OnlyIn(Dist.CLIENT) public static enum Type { FLOAT(4, "Float"), + UBYTE(1, "Unsigned Byte"), diff --git a/patches/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java.patch b/patches/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java.patch index 9d65a2c386b..3a111ccc44f 100644 --- a/patches/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java.patch +++ b/patches/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java +++ b/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java -@@ -123,7 +_,7 @@ +@@ -131,7 +_,7 @@ private void drawIcons(GuiGraphics graphics) { int pendingInvitesCount = this.numberOfPendingInvites; int spacing = 24; diff --git a/patches/net/minecraft/SharedConstants.java.patch b/patches/net/minecraft/SharedConstants.java.patch index d9f25b75a12..1c405986f76 100644 --- a/patches/net/minecraft/SharedConstants.java.patch +++ b/patches/net/minecraft/SharedConstants.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/SharedConstants.java +++ b/net/minecraft/SharedConstants.java -@@ -123,7 +_,8 @@ - public static final boolean USE_WORKFLOWS_HOOKS = false; +@@ -122,7 +_,8 @@ + public static final float MAXIMUM_BLOCK_EXPLOSION_RESISTANCE = 3600000.0F; public static final boolean USE_DEVONLY = false; public static boolean CHECK_DATA_FIXER_SCHEMA = true; - public static boolean IS_RUNNING_IN_IDE; @@ -10,7 +10,7 @@ public static final int WORLD_RESOLUTION = 16; public static final int MAX_CHAT_LENGTH = 256; public static final int MAX_USER_INPUT_COMMAND_LENGTH = 32500; -@@ -216,6 +_,7 @@ +@@ -215,6 +_,7 @@ } static { diff --git a/patches/net/minecraft/client/ClientClockManager.java.patch b/patches/net/minecraft/client/ClientClockManager.java.patch new file mode 100644 index 00000000000..ee89de03d75 --- /dev/null +++ b/patches/net/minecraft/client/ClientClockManager.java.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/client/ClientClockManager.java ++++ b/net/minecraft/client/ClientClockManager.java +@@ -24,7 +_,11 @@ + + for (ClientClockManager.ClockInstance instance : this.clocks.values()) { + if (!instance.paused) { +- instance.totalTicks += gameTimeDelta; ++ // Neo: support variable-speed clocks ++ float timeStep = instance.fractionalTick + gameTimeDelta * instance.speed; ++ long result = (long)timeStep; ++ instance.fractionalTick = (timeStep - result); ++ instance.totalTicks += result; + } + } + } +@@ -35,6 +_,9 @@ + ClientClockManager.ClockInstance clock = this.getInstance((Holder)definition); + clock.totalTicks = state.totalTicks(); + clock.paused = state.paused(); ++ // Neo: Handle extended state sent by server ++ clock.fractionalTick = state.fractionalTick(); ++ clock.speed = state.speed(); + }); + } + +@@ -47,5 +_,7 @@ + private static class ClockInstance { + private long totalTicks; + private boolean paused; ++ private float speed = 1; ++ private float fractionalTick = 0; + } + } diff --git a/patches/net/minecraft/client/KeyboardHandler.java.patch b/patches/net/minecraft/client/KeyboardHandler.java.patch index dc6136a0afe..8f797b464f3 100644 --- a/patches/net/minecraft/client/KeyboardHandler.java.patch +++ b/patches/net/minecraft/client/KeyboardHandler.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/KeyboardHandler.java +++ b/net/minecraft/client/KeyboardHandler.java -@@ -506,7 +_,11 @@ +@@ -511,7 +_,11 @@ if (screen != null) { try { if (action != 1 && action != 2) { @@ -13,7 +13,7 @@ if (options.keyDebugModifier.matches(event)) { this.usedDebugKeyAsModifier = false; } -@@ -515,7 +_,11 @@ +@@ -520,7 +_,11 @@ } } else { screen.afterKeyboardAction(); @@ -26,7 +26,7 @@ if (this.minecraft.screen == null) { InputConstants.Key key = InputConstants.getKey(event); KeyMapping.set(key, false); -@@ -591,6 +_,7 @@ +@@ -596,6 +_,7 @@ } } } @@ -34,7 +34,7 @@ } } -@@ -599,7 +_,9 @@ +@@ -604,7 +_,9 @@ Screen screen = this.minecraft.screen; if (screen != null && this.minecraft.getOverlay() == null) { try { diff --git a/patches/net/minecraft/client/Minecraft.java.patch b/patches/net/minecraft/client/Minecraft.java.patch index cb0cc8d797a..21c8ded58c3 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 -@@ -429,7 +_,6 @@ +@@ -431,7 +_,6 @@ } }, Util.nonCriticalIoPool()); LOGGER.info("Setting user: {}", this.user.getName()); @@ -8,8 +8,27 @@ this.demo = gameConfig.game.demo; this.allowsMultiplayer = !gameConfig.game.disableMultiplayer; this.allowsChat = !gameConfig.game.disableChat; -@@ -481,21 +_,25 @@ - LOGGER.error("Couldn't set icon", (Throwable)var18); +@@ -461,6 +_,9 @@ + } + + Util.timeSource = RenderSystem.initBackendSystem(); ++ ++ // Neo: Enable GL debug labels and synchronous GL debug output via FML config ++ boolean enableGlDebug = net.neoforged.fml.loading.FMLConfig.getBoolConfigValue(net.neoforged.fml.loading.FMLConfig.ConfigValue.DEBUG_OPENGL); + GpuBackend[] backends = new GpuBackend[]{new GlBackend()}; + this.window = new Window( + this, +@@ -469,7 +_,7 @@ + this.createTitle(), + backends, + (id, type) -> this.getShaderManager().getShader(id, type), +- new GpuDebugOptions(this.options.glDebugVerbosity, SharedConstants.DEBUG_SYNCHRONOUS_GL_LOGS, gameConfig.game.renderDebugLabels) ++ new GpuDebugOptions(this.options.glDebugVerbosity, SharedConstants.DEBUG_SYNCHRONOUS_GL_LOGS || enableGlDebug, gameConfig.game.renderDebugLabels || enableGlDebug) + ); + this.setWindowActive(true); + this.window.setWindowCloseCallback(new Runnable() { +@@ -495,14 +_,16 @@ + LOGGER.error("Couldn't set icon", (Throwable)var19); } + // FORGE: Move mouse and keyboard handler setup further below @@ -17,17 +36,6 @@ - this.mouseHandler.setup(this.window); this.keyboardHandler = new KeyboardHandler(this); - this.keyboardHandler.setup(this.window); -+ // Neo: Enable GL debug labels and synchronous GL debug output via FML config -+ boolean enableGlDebug = net.neoforged.fml.loading.FMLConfig.getBoolConfigValue(net.neoforged.fml.loading.FMLConfig.ConfigValue.DEBUG_OPENGL); - RenderSystem.initRenderer( - this.window.handle(), - this.options.glDebugVerbosity, -- SharedConstants.DEBUG_SYNCHRONOUS_GL_LOGS, -+ SharedConstants.DEBUG_SYNCHRONOUS_GL_LOGS || enableGlDebug, - (id, type) -> this.getShaderManager().getShader(id, type), -- gameConfig.game.renderDebugLabels -+ gameConfig.game.renderDebugLabels || enableGlDebug - ); this.options.applyGraphicsPreset(this.options.graphicsPreset().get()); LOGGER.info("Using optional rendering extensions: {}", String.join(", ", RenderSystem.getDevice().getEnabledExtensions())); - this.mainRenderTarget = new MainTarget(this.window.getWidth(), this.window.getHeight()); @@ -39,7 +47,7 @@ this.resourcePackRepository.reload(); this.options.loadSelectedResourcePacks(this.resourcePackRepository); this.languageManager = new LanguageManager(this.options.languageCode, languageData -> { -@@ -534,6 +_,7 @@ +@@ -541,6 +_,7 @@ RenderSystem.setupDefaultState(); this.window.setErrorSection("Post startup"); this.blockColors = BlockColors.createDefault(); @@ -47,7 +55,7 @@ this.modelManager = new ModelManager(this.blockColors, this.atlasManager, this.playerSkinRenderCache); this.resourceManager.registerReloadListener(this.modelManager); EquipmentAssetManager equipmentAssets = new EquipmentAssetManager(); -@@ -591,6 +_,7 @@ +@@ -598,6 +_,7 @@ this.resourceManager.registerReloadListener(this.particleResources); this.particleEngine = new ParticleEngine(this.level, this.particleResources); this.particleResources.onReload(this.particleEngine::clearParticles); @@ -55,7 +63,7 @@ this.waypointStyles = new WaypointStyleManager(); this.resourceManager.registerReloadListener(this.waypointStyles); this.gameRenderer = new GameRenderer(this, this.entityRenderDispatcher.getItemInHandRenderer(), this.renderBuffers, this.blockRenderer); -@@ -607,6 +_,9 @@ +@@ -614,6 +_,9 @@ this.gpuWarnlistManager = new GpuWarnlistManager(); this.resourceManager.registerReloadListener(this.gpuWarnlistManager); this.resourceManager.registerReloadListener(this.regionalCompliancies); @@ -65,7 +73,7 @@ this.gui = new Gui(this); RealmsClient realmsClient = RealmsClient.getOrCreate(this); this.realmsDataFetcher = new RealmsDataFetcher(realmsClient); -@@ -640,6 +_,7 @@ +@@ -647,6 +_,7 @@ } } @@ -73,7 +81,7 @@ this.window.updateVsync(this.options.enableVsync().get()); this.window.updateRawMouseInput(this.options.rawMouseInput().get()); this.window.setAllowCursorChanges(this.options.allowCursorChanges().get()); -@@ -665,8 +_,8 @@ +@@ -672,8 +_,8 @@ .createReload(Util.backgroundExecutor().forName("resourceLoad"), this, RESOURCE_RELOAD_INITIAL_TASK, packs); GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS); Minecraft.GameLoadCookie loadCookie = new Minecraft.GameLoadCookie(realmsClient, gameConfig.quickPlay); @@ -84,7 +92,7 @@ this.selfTest(); } -@@ -701,6 +_,7 @@ +@@ -708,6 +_,7 @@ } private void onResourceLoadFinished(Minecraft.@Nullable GameLoadCookie loadCookie) { @@ -92,7 +100,7 @@ if (!this.gameLoadFinished) { this.gameLoadFinished = true; this.onGameLoadFinished(loadCookie); -@@ -737,6 +_,8 @@ +@@ -744,6 +_,8 @@ nextStep = () -> this.setScreen(screen); } @@ -101,7 +109,7 @@ return nextStep; } -@@ -789,7 +_,7 @@ +@@ -796,7 +_,7 @@ private String createTitle() { StringBuilder builder = new StringBuilder("Minecraft"); if (checkModStatus().shouldReportAsModified()) { @@ -110,7 +118,7 @@ } builder.append(" "); -@@ -825,7 +_,7 @@ +@@ -832,7 +_,7 @@ } private void rollbackResourcePacks(Throwable t, Minecraft.@Nullable GameLoadCookie loadCookie) { @@ -119,7 +127,7 @@ this.clearResourcePacksOnError(t, null, loadCookie); } else { Util.throwAsRuntime(t); -@@ -881,6 +_,8 @@ +@@ -888,6 +_,8 @@ DiscontinuousFrame tickFrame = TracyClient.createDiscontinuousFrame("Client Tick"); try { @@ -128,7 +136,7 @@ boolean oomRecovery = false; while (this.running) { -@@ -984,7 +_,7 @@ +@@ -992,7 +_,7 @@ minecraft.soundManager.emergencyShutdown(); } @@ -137,7 +145,7 @@ } public boolean isEnforceUnicode() { -@@ -1111,9 +_,7 @@ +@@ -1119,9 +_,7 @@ LOGGER.error("setScreen called from non-game thread"); } @@ -148,7 +156,7 @@ this.setLastInputType(InputType.NONE); } -@@ -1135,6 +_,19 @@ +@@ -1143,6 +_,19 @@ } } @@ -168,7 +176,7 @@ this.screen = screen; if (this.screen != null) { this.screen.added(); -@@ -1163,6 +_,7 @@ +@@ -1171,6 +_,7 @@ public void destroy() { try { @@ -176,7 +184,7 @@ LOGGER.info("Stopping!"); try { -@@ -1184,6 +_,7 @@ +@@ -1192,6 +_,7 @@ } this.close(); @@ -184,17 +192,7 @@ } finally { Util.timeSource = System::nanoTime; if (this.delayedCrash == null) { -@@ -1302,7 +_,9 @@ - .clearColorAndDepthTextures(mainRenderTarget.getColorTexture(), 0, mainRenderTarget.getDepthTexture(), 1.0); - profiler.push("gameRenderer"); - if (!this.noRender) { -+ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePre(this.deltaTracker); - this.gameRenderer.render(this.deltaTracker, advanceGameTime); -+ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePost(this.deltaTracker); - } - - profiler.popPush("blit"); -@@ -1336,9 +_,13 @@ +@@ -1309,9 +_,13 @@ this.window.setErrorSection("Post render"); this.frames++; boolean previouslyPaused = this.pause; @@ -209,7 +207,17 @@ if (!previouslyPaused && this.pause) { this.soundManager.pauseAllExcept(SoundSource.MUSIC, SoundSource.UI); } -@@ -1414,10 +_,13 @@ +@@ -1351,7 +_,9 @@ + .clearColorAndDepthTextures(mainRenderTarget.getColorTexture(), 0, mainRenderTarget.getDepthTexture(), 1.0); + profiler.popPush("gameRenderer"); + if (!this.noRender) { ++ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePre(this.deltaTracker); + this.gameRenderer.render(this.deltaTracker, renderLevel); ++ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePost(this.deltaTracker); + } + + profiler.popPush("blit"); +@@ -1426,10 +_,13 @@ this.window.setGuiScale(guiScale); if (this.screen != null) { this.screen.resize(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight()); @@ -223,7 +231,7 @@ this.gameRenderer.resize(this.window.getWidth(), this.window.getHeight()); this.mouseHandler.setIgnoreFirstMove(); } -@@ -1564,6 +_,7 @@ +@@ -1580,6 +_,7 @@ } public void stop() { @@ -231,7 +239,7 @@ this.running = false; } -@@ -1595,8 +_,16 @@ +@@ -1611,8 +_,16 @@ BlockPos pos = blockHit.getBlockPos(); if (!this.level.getBlockState(pos).isAir()) { Direction direction = blockHit.getDirection(); @@ -250,36 +258,35 @@ this.player.swing(InteractionHand.MAIN_HAND); } } -@@ -1627,9 +_,16 @@ +@@ -1649,9 +_,16 @@ return false; } else { boolean endAttack = false; + var inputEvent = net.neoforged.neoforge.client.ClientHooks.onClickInput(0, this.options.keyAttack, InteractionHand.MAIN_HAND); - PiercingWeapon piercingWeapon = heldItem.get(DataComponents.PIERCING_WEAPON); + if (inputEvent.isCanceled()) { + if (inputEvent.shouldSwingHand()) + this.player.swing(InteractionHand.MAIN_HAND); + return endAttack; + } - if (piercingWeapon != null && !this.gameMode.isSpectator()) { + PiercingWeapon piercingWeapon = heldItem.get(DataComponents.PIERCING_WEAPON); + if (piercingWeapon != null) { this.gameMode.piercingAttack(piercingWeapon); + if (inputEvent.shouldSwingHand()) this.player.swing(InteractionHand.MAIN_HAND); return true; } else { -@@ -1656,9 +_,10 @@ +@@ -1678,8 +_,10 @@ } this.player.resetAttackStrengthTicker(); + net.neoforged.neoforge.common.CommonHooks.onEmptyLeftClick(this.player); } -- if (!this.player.isSpectator()) { -+ if (!this.player.isSpectator() && inputEvent.shouldSwingHand()) { - this.player.swing(InteractionHand.MAIN_HAND); - } - -@@ -1677,6 +_,11 @@ ++ if (inputEvent.shouldSwingHand()) + this.player.swing(InteractionHand.MAIN_HAND); + return endAttack; + } +@@ -1696,6 +_,11 @@ } for (InteractionHand hand : InteractionHand.values()) { @@ -291,16 +298,16 @@ ItemStack heldItem = this.player.getItemInHand(hand); if (!heldItem.isItemEnabled(this.level.enabledFeatures())) { return; -@@ -1698,7 +_,7 @@ - } +@@ -1712,7 +_,7 @@ - if (result instanceof InteractionResult.Success success) { -- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) { -+ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { - this.player.swing(hand); - } + if (this.player.isWithinEntityInteractionRange(entity, 0.0) + && this.gameMode.interact(this.player, entity, entityHit, hand) instanceof InteractionResult.Success success) { +- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) { ++ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { + this.player.swing(hand); + } -@@ -1711,7 +_,7 @@ +@@ -1724,7 +_,7 @@ int oldCount = heldItem.getCount(); InteractionResult useResult = this.gameMode.useItemOn(this.player, hand, blockHit); if (useResult instanceof InteractionResult.Success success) { @@ -309,7 +316,7 @@ this.player.swing(hand); if (!heldItem.isEmpty() && (heldItem.getCount() != oldCount || this.player.hasInfiniteMaterials())) { this.gameRenderer.itemInHandRenderer.itemUsed(hand); -@@ -1727,6 +_,9 @@ +@@ -1740,8 +_,11 @@ } } @@ -317,9 +324,12 @@ + net.neoforged.neoforge.common.CommonHooks.onEmptyClick(this.player, hand); + if (!heldItem.isEmpty() && this.gameMode.useItem(this.player, hand) instanceof InteractionResult.Success success) { - if (success.swingSource() == InteractionResult.SwingSource.CLIENT) { +- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) { ++ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { this.player.swing(hand); -@@ -1746,6 +_,10 @@ + } + +@@ -1759,6 +_,10 @@ public void tick() { this.clientTickCount++; @@ -330,7 +340,7 @@ if (this.level != null && !this.pause) { this.level.tickRateManager().tick(); } -@@ -1836,6 +_,7 @@ +@@ -1849,6 +_,7 @@ this.tutorial.tick(); @@ -338,7 +348,7 @@ try { this.level.tick(() -> true); } catch (Throwable var6) { -@@ -1849,6 +_,7 @@ +@@ -1862,6 +_,7 @@ throw new ReportedException(report); } @@ -346,7 +356,7 @@ } profiler.popPush("animateTick"); -@@ -1873,6 +_,10 @@ +@@ -1886,6 +_,10 @@ profiler.popPush("keyboard"); this.keyboardHandler.tick(); profiler.pop(); @@ -357,7 +367,7 @@ } private boolean isLevelRunningNormally() { -@@ -2089,6 +_,7 @@ +@@ -2102,6 +_,7 @@ } public void setLevel(ClientLevel level) { @@ -365,7 +375,7 @@ this.level = level; this.updateLevelInEngines(level); } -@@ -2150,13 +_,16 @@ +@@ -2163,13 +_,16 @@ IntegratedServer server = this.singleplayerServer; this.singleplayerServer = null; this.gameRenderer.resetData(); @@ -382,7 +392,7 @@ } if (server != null) { -@@ -2179,6 +_,7 @@ +@@ -2192,6 +_,7 @@ } finally { this.clientLevelTeardownInProgress = false; } @@ -390,7 +400,7 @@ } public void clearDownloadedResourcePacks() { -@@ -2311,6 +_,7 @@ +@@ -2324,6 +_,7 @@ private void pickBlock() { if (this.hitResult != null && this.hitResult.getType() != HitResult.Type.MISS) { @@ -398,3 +408,19 @@ boolean includeData = this.hasControlDown(); switch (this.hitResult) { case BlockHitResult blockHitResult: +@@ -2390,7 +_,14 @@ + systemReport.setDetail("Backend API", RenderSystem::getApiDescription); + systemReport.setDetail("Window size", () -> minecraft != null ? minecraft.window.getWidth() + "x" + minecraft.window.getHeight() : ""); + systemReport.setDetail("GFLW Platform", Window::getPlatform); +- systemReport.setDetail("Render Extensions", () -> String.join(", ", RenderSystem.getDevice().getEnabledExtensions())); ++ systemReport.setDetail("Render Extensions", () -> { ++ GpuDevice device = RenderSystem.tryGetDevice(); ++ if (device == null) { ++ return ""; ++ } else { ++ return String.join(", ", device.getEnabledExtensions()); ++ } ++ }); + systemReport.setDetail("GL debug messages", () -> { + GpuDevice device = RenderSystem.tryGetDevice(); + if (device == null) { diff --git a/patches/net/minecraft/client/Options.java.patch b/patches/net/minecraft/client/Options.java.patch index 38a4ef63cea..f5df0ab8520 100644 --- a/patches/net/minecraft/client/Options.java.patch +++ b/patches/net/minecraft/client/Options.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/Options.java +++ b/net/minecraft/client/Options.java -@@ -867,9 +_,10 @@ +@@ -869,9 +_,10 @@ } }, new OptionInstance.LazyEnum<>( @@ -12,7 +12,7 @@ && !Minecraft.getInstance().getSoundManager().getAvailableSoundDevices().contains(device) ? Optional.empty() : Optional.of(device), -@@ -998,7 +_,7 @@ +@@ -1000,7 +_,7 @@ this.incompatibleResourcePacks.clear(); for (Pack entry : packRepository.getSelectedPacks()) { @@ -21,7 +21,7 @@ this.resourcePacks.add(entry.getId()); if (!entry.getCompatibility().isCompatible()) { this.incompatibleResourcePacks.add(entry.getId()); -@@ -1369,6 +_,7 @@ +@@ -1371,6 +_,7 @@ } public Options(Minecraft minecraft, File workingDirectory) { @@ -29,7 +29,7 @@ this.minecraft = minecraft; this.optionsFile = new File(workingDirectory, "options.txt"); boolean largeDistances = Runtime.getRuntime().maxMemory() >= 1000000000L; -@@ -1392,6 +_,7 @@ +@@ -1394,6 +_,7 @@ value -> this.setGraphicsPresetToCustom() ); this.syncWrites = Util.getPlatform() == Util.OS.WINDOWS; @@ -37,7 +37,7 @@ this.load(); } -@@ -1521,10 +_,15 @@ +@@ -1523,10 +_,15 @@ access.process("musicFrequency", this.musicFrequency); for (KeyMapping keyMapping : this.keyMappings) { @@ -55,7 +55,7 @@ } } -@@ -1812,6 +_,23 @@ +@@ -1822,6 +_,23 @@ } repository.setSelected(selected); diff --git a/patches/net/minecraft/client/Screenshot.java.patch b/patches/net/minecraft/client/Screenshot.java.patch index 718585c60d0..8f35e64518d 100644 --- a/patches/net/minecraft/client/Screenshot.java.patch +++ b/patches/net/minecraft/client/Screenshot.java.patch @@ -15,7 +15,7 @@ .execute( () -> { @@ -49,11 +_,15 @@ - NativeImage e = image; + NativeImage twrVar0$ = image; try { - image.writeToFile(file); diff --git a/patches/net/minecraft/client/data/Main.java.patch b/patches/net/minecraft/client/data/Main.java.patch index df633f3c879..c6329d679e3 100644 --- a/patches/net/minecraft/client/data/Main.java.patch +++ b/patches/net/minecraft/client/data/Main.java.patch @@ -17,12 +17,12 @@ boolean client = allOptions || optionSet.has(clientOption); - Bootstrap.bootStrap(); - ClientBootstrap.bootstrap(); -- DataGenerator generator = new DataGenerator(output, SharedConstants.getCurrentVersion(), true); +- DataGenerator generator = new DataGenerator.Cached(output, SharedConstants.getCurrentVersion(), true); + java.util.Collection existingPacks = optionSet.valuesOf(existing).stream().map(Paths::get).toList(); + java.util.Set mods = new java.util.HashSet<>(optionSet.valuesOf(mod)); + boolean isFlat = mods.isEmpty() || optionSet.has(flat); + boolean validate = optionSet.has(validateSpec); -+ DataGenerator generator = new DataGenerator(isFlat ? output : output.resolve("minecraft"), SharedConstants.getCurrentVersion(), true); ++ DataGenerator generator = new DataGenerator.Cached(isFlat ? output : output.resolve("minecraft"), SharedConstants.getCurrentVersion(), true); + if (mods.contains("minecraft") || mods.isEmpty()) { addClientProviders(generator, client); - generator.run(); diff --git a/patches/net/minecraft/client/data/models/BlockModelGenerators.java.patch b/patches/net/minecraft/client/data/models/BlockModelGenerators.java.patch index e668a4fa2de..aa2227365b6 100644 --- a/patches/net/minecraft/client/data/models/BlockModelGenerators.java.patch +++ b/patches/net/minecraft/client/data/models/BlockModelGenerators.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/data/models/BlockModelGenerators.java +++ b/net/minecraft/client/data/models/BlockModelGenerators.java -@@ -4595,4 +_,16 @@ +@@ -4592,4 +_,16 @@ return this; } } diff --git a/patches/net/minecraft/client/data/models/ModelProvider.java.patch b/patches/net/minecraft/client/data/models/ModelProvider.java.patch index 5e705b41096..ac205635c7c 100644 --- a/patches/net/minecraft/client/data/models/ModelProvider.java.patch +++ b/patches/net/minecraft/client/data/models/ModelProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/data/models/ModelProvider.java +++ b/net/minecraft/client/data/models/ModelProvider.java -@@ -36,20 +_,58 @@ +@@ -34,20 +_,58 @@ private final PackOutput.PathProvider blockStatePathProvider; private final PackOutput.PathProvider itemInfoPathProvider; private final PackOutput.PathProvider modelPathProvider; @@ -25,28 +25,28 @@ + } + + /** -+ * Returns a {@link Stream stream} containing all {@link Block blocks} which must have their models/block states generated or {@link Stream#empty() empty} if none are desired. ++ * Returns a {@link java.util.stream.Stream stream} containing all {@link Block blocks} which must have their models/block states generated or {@link java.util.stream.Stream#empty() empty} if none are desired. + *

+ * When using providers for specific {@link Block block} usages, it is best to override this method returning the exact {@link Block blocks} which must be generated, -+ * or {@link Stream#empty() empty} if generating only {@link Item item} models. ++ * or {@link java.util.stream.Stream#empty() empty} if generating only {@link Item item} models. + *

+ * Default implementation generates models for {@link Block blocks} matching the given {@code modId}. + * @see #getKnownItems() + */ -+ protected Stream> getKnownBlocks() { ++ protected java.util.stream.Stream> getKnownBlocks() { + return BuiltInRegistries.BLOCK.listElements().filter(holder -> holder.getKey().identifier().getNamespace().equals(modId)); + } + + /** -+ * Returns a {@link Stream stream} containing all {@link Item items} which must have their models/client items generated or {@link Stream#empty() empty} if none are desired. ++ * Returns a {@link java.util.stream.Stream stream} containing all {@link Item items} which must have their models/client items generated or {@link java.util.stream.Stream#empty() empty} if none are desired. + *

+ * When using providers for specific {@link Item item} usages, it is best to override this method returning the exact {@link Item items} which must be generated, -+ * or {@link Stream#empty() empty} if generating only {@link Block block} models (which have no respective {@link Item item}). ++ * or {@link java.util.stream.Stream#empty() empty} if generating only {@link Block block} models (which have no respective {@link Item item}). + *

+ * Default implementation generates models for {@link Item items} matching the given {@code modId}. + * @see #getKnownBlocks() + */ -+ protected Stream> getKnownItems() { ++ protected java.util.stream.Stream> getKnownItems() { + return BuiltInRegistries.ITEM.listElements().filter(holder -> holder.getKey().identifier().getNamespace().equals(modId)); } @@ -63,7 +63,7 @@ blockStateGenerators.validate(); itemModels.finalizeAndValidate(); return CompletableFuture.allOf( -@@ -61,12 +_,22 @@ +@@ -59,12 +_,22 @@ @Override public String getName() { @@ -74,9 +74,9 @@ @OnlyIn(Dist.CLIENT) private static class BlockStateGeneratorCollector implements Consumer { private final Map generators = new HashMap<>(); -+ private final Supplier>> knownBlocks; ++ private final Supplier>> knownBlocks; + -+ public BlockStateGeneratorCollector(Supplier>> knownBlocks) { ++ public BlockStateGeneratorCollector(Supplier>> knownBlocks) { + this.knownBlocks = knownBlocks; + } + @@ -87,24 +87,27 @@ public void accept(BlockModelDefinitionGenerator generator) { Block block = generator.block(); -@@ -77,8 +_,8 @@ +@@ -75,11 +_,8 @@ } public void validate() { -- Stream> holders = BuiltInRegistries.BLOCK.listElements().filter(entry -> true); -- List missingDefinitions = holders.filter(e -> !this.generators.containsKey(e.value())).map(e -> e.key().identifier()).toList(); +- List missingDefinitions = BuiltInRegistries.BLOCK +- .listElements() +- .filter(e -> !this.generators.containsKey(e.value())) +- .map(e -> e.key().identifier()) +- .toList(); + var holders = knownBlocks.get(); + List missingDefinitions = holders.filter(e -> !this.generators.containsKey(e.value())).map(e -> e.unwrapKey().orElseThrow().identifier()).toList(); if (!missingDefinitions.isEmpty()) { throw new IllegalStateException("Missing blockstate definitions for: " + missingDefinitions); } -@@ -95,6 +_,16 @@ +@@ -96,6 +_,16 @@ private static class ItemInfoCollector implements ItemModelOutput { private final Map itemInfos = new HashMap<>(); private final Map copies = new HashMap<>(); -+ private final Supplier>> knownItems; ++ private final Supplier>> knownItems; + -+ public ItemInfoCollector(Supplier>> knownItems) { ++ public ItemInfoCollector(Supplier>> knownItems) { + this.knownItems = knownItems; + } + @@ -115,16 +118,16 @@ @Override public void accept(Item item, ItemModel.Unbaked model, ClientItem.Properties properties) { -@@ -114,7 +_,7 @@ +@@ -115,7 +_,7 @@ } public void finalizeAndValidate() { - BuiltInRegistries.ITEM.forEach(item -> { -+ knownItems.get().map(Holder::value).forEach(item -> { ++ knownItems.get().map(net.minecraft.core.Holder::value).forEach(item -> { if (!this.copies.containsKey(item)) { if (item instanceof BlockItem blockItem && !this.itemInfos.containsKey(blockItem)) { Identifier targetModel = ModelLocationUtils.getModelLocation(blockItem.getBlock()); -@@ -130,10 +_,9 @@ +@@ -131,10 +_,9 @@ this.register(acceptor, donorInfo); } }); diff --git a/patches/net/minecraft/client/gui/Font.java.patch b/patches/net/minecraft/client/gui/Font.java.patch index ea4cc33cfcf..5dc0cf8cfd1 100644 --- a/patches/net/minecraft/client/gui/Font.java.patch +++ b/patches/net/minecraft/client/gui/Font.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/Font.java +++ b/net/minecraft/client/gui/Font.java -@@ -41,6 +_,8 @@ +@@ -42,6 +_,8 @@ private final RandomSource random = RandomSource.create(); private final Font.Provider provider; private final StringSplitter splitter; @@ -9,7 +9,7 @@ public Font(Font.Provider provider) { this.provider = provider; -@@ -215,6 +_,8 @@ +@@ -216,6 +_,8 @@ public StringSplitter getSplitter() { return this.splitter; } diff --git a/patches/net/minecraft/client/gui/GuiGraphics.java.patch b/patches/net/minecraft/client/gui/GuiGraphics.java.patch index 9fac8b860ae..40ca9ee7b0f 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 -@@ -100,6 +_,7 @@ +@@ -101,6 +_,7 @@ private @Nullable Runnable deferredTooltip; private @Nullable Style hoveredTextStyle; private @Nullable Style clickableTextStyle; @@ -39,7 +39,7 @@ } public void setTooltipForNextFrame(Font font, List texts, Optional optionalImage, int xo, int yo) { -@@ -899,10 +_,7 @@ +@@ -899,11 +_,7 @@ } public void setTooltipForNextFrame(Font font, List texts, Optional optionalImage, int xo, int yo, @Nullable Identifier style) { @@ -47,11 +47,20 @@ - .map(Component::getVisualOrderText) - .map(ClientTooltipComponent::create) - .collect(Util.toMutableList()); +- optionalImage.ifPresent(image -> components.add(components.isEmpty() ? 0 : 1, ClientTooltipComponent.create(image))); + List components = net.neoforged.neoforge.client.ClientHooks.gatherTooltipComponents(this.tooltipStack, texts, optionalImage, xo, guiWidth(), guiHeight(), font); - optionalImage.ifPresent(image -> components.add(components.isEmpty() ? 0 : 1, ClientTooltipComponent.create(image))); this.setTooltipForNextFrameInternal(font, components, xo, yo, DefaultTooltipPositioner.INSTANCE, style, false); } -@@ -916,13 +_,14 @@ + +@@ -918,7 +_,6 @@ + @Nullable Identifier style + ) { + List components = tooltip.stream().map(ClientTooltipComponent::create).collect(Collectors.toList()); +- component.ifPresent(tooltipComponent -> components.add(components.isEmpty() ? 0 : 1, ClientTooltipComponent.create(tooltipComponent))); + this.setTooltipForNextFrameInternal(font, components, xo, yo, positioner, style, replaceExisting); + } + +@@ -931,13 +_,14 @@ } public void setComponentTooltipForNextFrame(Font font, List lines, int xo, int yo) { @@ -68,7 +77,7 @@ xo, yo, DefaultTooltipPositioner.INSTANCE, -@@ -931,6 +_,28 @@ +@@ -946,6 +_,28 @@ ); } @@ -97,7 +106,7 @@ public void setTooltipForNextFrame(Font font, List lines, int xo, int yo) { this.setTooltipForNextFrame(font, lines, xo, yo, null); } -@@ -954,12 +_,24 @@ +@@ -969,12 +_,24 @@ ) { if (!lines.isEmpty()) { if (this.deferredTooltip == null || replaceExisting) { @@ -123,7 +132,7 @@ int textWidth = 0; int tempHeight = lines.size() == 1 ? -2 : 0; -@@ -978,7 +_,8 @@ +@@ -993,7 +_,8 @@ int x = positionedTooltip.x(); int y = positionedTooltip.y(); this.pose.pushMatrix(); @@ -133,7 +142,7 @@ int localY = y; for (int i = 0; i < lines.size(); i++) { -@@ -1169,6 +_,31 @@ +@@ -1185,6 +_,31 @@ public void submitProfilerChartRenderState(List chartData, int x0, int y0, int x1, int y1) { this.guiRenderState.submitPicturesInPictureState(new GuiProfilerChartRenderState(chartData, x0, y0, x1, y1, this.scissorStack.peek())); diff --git a/patches/net/minecraft/client/gui/components/BossHealthOverlay.java.patch b/patches/net/minecraft/client/gui/components/BossHealthOverlay.java.patch index bdded37b67d..750e82f0790 100644 --- a/patches/net/minecraft/client/gui/components/BossHealthOverlay.java.patch +++ b/patches/net/minecraft/client/gui/components/BossHealthOverlay.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/components/BossHealthOverlay.java +++ b/net/minecraft/client/gui/components/BossHealthOverlay.java -@@ -67,6 +_,8 @@ +@@ -68,6 +_,8 @@ for (LerpingBossEvent event : this.events.values()) { int xLeft = screenWidth / 2 - 91; @@ -9,7 +9,7 @@ this.drawBar(graphics, xLeft, yOffset, event); Component msg = event.getName(); int width = this.minecraft.font.width(msg); -@@ -74,6 +_,8 @@ +@@ -75,6 +_,8 @@ int y = yOffset - 9; graphics.drawString(this.minecraft.font, msg, x, y, -1); yOffset += 10 + 9; diff --git a/patches/net/minecraft/client/gui/components/EditBox.java.patch b/patches/net/minecraft/client/gui/components/EditBox.java.patch index c7d35711267..1fb80f659c7 100644 --- a/patches/net/minecraft/client/gui/components/EditBox.java.patch +++ b/patches/net/minecraft/client/gui/components/EditBox.java.patch @@ -1,13 +1,53 @@ --- a/net/minecraft/client/gui/components/EditBox.java +++ b/net/minecraft/client/gui/components/EditBox.java -@@ -619,6 +_,10 @@ - this.hint = (Component)(hasNoStyle ? hint.copy().withStyle(DEFAULT_HINT_STYLE) : hint); +@@ -61,6 +_,7 @@ + private long focusedTime = Util.getMillis(); + private int textX; + private int textY; ++ private java.util.function.Predicate filter = _ -> true; // Neo: Add back text input filtering + + public EditBox(Font font, int width, int height, Component narration) { + this(font, 0, 0, width, height, narration); +@@ -95,6 +_,8 @@ } -+ public boolean getTextShadow() { -+ return this.textShadow; + public void setValue(String value) { ++ if (!this.filter.test(value)) return; // Neo: Allow value filtering ++ + if (value.length() > this.maxLength) { + this.value = value.substring(0, this.maxLength); + } else { +@@ -128,6 +_,14 @@ + this.updateTextPosition(); + } + ++ /** ++ * Sets a filter on the edit box that will only allow strings that pass the given predicate to be ++ * inserted. ++ */ ++ public void setFilter(java.util.function.Predicate filter) { ++ this.filter = filter; + } + + public void insertText(String input) { + int start = Math.min(this.cursorPos, this.highlightPos); + int end = Math.max(this.cursorPos, this.highlightPos); +@@ -144,6 +_,7 @@ + insertionLength = maxInsertionLength; + } + ++ if (!filter.test(text)) return; // Neo: filter inputs + this.value = new StringBuilder(this.value).replace(start, end, text).toString(); + this.setCursorPosition(start + insertionLength); + this.setHighlightPos(this.cursorPos); +@@ -604,6 +_,10 @@ + public void setHint(Component hint) { + boolean hasNoStyle = hint.getStyle().equals(Style.EMPTY); + this.hint = (Component)(hasNoStyle ? hint.copy().withStyle(DEFAULT_HINT_STYLE) : hint); ++ } ++ ++ public boolean getTextShadow() { ++ return this.textShadow; + } + @FunctionalInterface - @OnlyIn(Dist.CLIENT) - public interface TextFormatter { diff --git a/patches/net/minecraft/client/gui/components/debug/DebugEntryLookingAtEntity.java.patch b/patches/net/minecraft/client/gui/components/debug/DebugEntryLookingAtEntity.java.patch index 3adab5a2cb6..37a354bfb82 100644 --- a/patches/net/minecraft/client/gui/components/debug/DebugEntryLookingAtEntity.java.patch +++ b/patches/net/minecraft/client/gui/components/debug/DebugEntryLookingAtEntity.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/client/gui/components/debug/DebugEntryLookingAtEntity.java +++ b/net/minecraft/client/gui/components/debug/DebugEntryLookingAtEntity.java -@@ -25,6 +_,9 @@ +@@ -24,6 +_,9 @@ if (entity != null) { result.add(ChatFormatting.UNDERLINE + "Targeted Entity"); - result.add(String.valueOf(BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()))); + result.add(entity.typeHolder().getRegisteredName()); + + // Neo: Add entity type tags for the targeted entity + entity.getType().getTags().map(tag -> "#" + tag.location()).forEach(result::add); diff --git a/patches/net/minecraft/client/gui/components/debug/DebugScreenEntries.java.patch b/patches/net/minecraft/client/gui/components/debug/DebugScreenEntries.java.patch index cb355f41b0b..1f8dd9b3f92 100644 --- a/patches/net/minecraft/client/gui/components/debug/DebugScreenEntries.java.patch +++ b/patches/net/minecraft/client/gui/components/debug/DebugScreenEntries.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/components/debug/DebugScreenEntries.java +++ b/net/minecraft/client/gui/components/debug/DebugScreenEntries.java -@@ -101,6 +_,7 @@ +@@ -105,6 +_,7 @@ SIMPLE_PERFORMANCE_IMPACTORS, DebugScreenEntryStatus.IN_OVERLAY ); diff --git a/patches/net/minecraft/client/gui/components/debug/DebugScreenEntryList.java.patch b/patches/net/minecraft/client/gui/components/debug/DebugScreenEntryList.java.patch index f2dd7b88798..a8b05cb465d 100644 --- a/patches/net/minecraft/client/gui/components/debug/DebugScreenEntryList.java.patch +++ b/patches/net/minecraft/client/gui/components/debug/DebugScreenEntryList.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/client/gui/components/debug/DebugScreenEntryList.java +++ b/net/minecraft/client/gui/components/debug/DebugScreenEntryList.java -@@ -166,7 +_,8 @@ +@@ -163,7 +_,8 @@ + } } - } - -- this.currentlyEnabled.sort(Identifier::compareTo); + }); +- this.currentlyEnabled.sort(Comparator.naturalOrder()); + // Neo: Sort enabled debug entries to match order displayed in config screen + this.currentlyEnabled.sort(net.neoforged.neoforge.common.CommonHooks.CMP_BY_NAMESPACE_VANILLA_FIRST); this.currentlyEnabledVersion++; diff --git a/patches/net/minecraft/client/gui/components/toasts/ToastManager.java.patch b/patches/net/minecraft/client/gui/components/toasts/ToastManager.java.patch index adf9d60fc4a..34c5be709c9 100644 --- a/patches/net/minecraft/client/gui/components/toasts/ToastManager.java.patch +++ b/patches/net/minecraft/client/gui/components/toasts/ToastManager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/components/toasts/ToastManager.java +++ b/net/minecraft/client/gui/components/toasts/ToastManager.java -@@ -142,6 +_,7 @@ +@@ -143,6 +_,7 @@ } public void addToast(Toast toast) { diff --git a/patches/net/minecraft/client/gui/font/AtlasGlyphProvider.java.patch b/patches/net/minecraft/client/gui/font/AtlasGlyphProvider.java.patch index 80f3a4240c4..5ad7ac27448 100644 --- a/patches/net/minecraft/client/gui/font/AtlasGlyphProvider.java.patch +++ b/patches/net/minecraft/client/gui/font/AtlasGlyphProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/font/AtlasGlyphProvider.java +++ b/net/minecraft/client/gui/font/AtlasGlyphProvider.java -@@ -93,6 +_,15 @@ +@@ -98,6 +_,15 @@ buffer.addVertex(pose, x1, y0, z).setUv(this.sprite.getU1(), this.sprite.getV0()).setColor(color).setLight(packedLightCoords); } diff --git a/patches/net/minecraft/client/gui/render/GuiRenderer.java.patch b/patches/net/minecraft/client/gui/render/GuiRenderer.java.patch index e78b1b8b91e..ff269a22fc1 100644 --- a/patches/net/minecraft/client/gui/render/GuiRenderer.java.patch +++ b/patches/net/minecraft/client/gui/render/GuiRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/render/GuiRenderer.java +++ b/net/minecraft/client/gui/render/GuiRenderer.java -@@ -108,7 +_,8 @@ +@@ -109,7 +_,8 @@ private final MultiBufferSource.BufferSource bufferSource; private final SubmitNodeCollector submitNodeCollector; private final FeatureRenderDispatcher featureRenderDispatcher; @@ -10,7 +10,7 @@ private @Nullable GpuTexture itemsAtlas; private @Nullable GpuTextureView itemsAtlasView; private @Nullable GpuTexture itemsAtlasDepth; -@@ -127,19 +_,13 @@ +@@ -128,19 +_,13 @@ MultiBufferSource.BufferSource bufferSource, SubmitNodeCollector submitNodeCollector, FeatureRenderDispatcher featureRenderDispatcher, @@ -32,7 +32,7 @@ } public void incrementFrameNumber() { -@@ -159,6 +_,7 @@ +@@ -160,6 +_,7 @@ this.renderState.reset(); this.firstDrawIndexAfterBlur = Integer.MAX_VALUE; this.clearUnusedOversizedItemRenderers(); @@ -40,7 +40,7 @@ if (SharedConstants.DEBUG_SHUFFLE_UI_RENDERING_ORDER) { RenderPipeline.updateSortKeySeed(); TextureSetup.updateSortKeySeed(); -@@ -424,14 +_,31 @@ +@@ -429,14 +_,31 @@ private void preparePictureInPicture() { int guiScale = Minecraft.getInstance().getWindow().getGuiScale(); @@ -75,7 +75,7 @@ } private void renderItemToAtlas(TrackingItemStackRenderState itemStackRenderState, PoseStack poseStack, int renderX, int renderY, int singleItemTextureSize) { -@@ -706,7 +_,7 @@ +@@ -711,7 +_,7 @@ this.itemsAtlasDepthView.close(); } diff --git a/patches/net/minecraft/client/gui/render/pip/PictureInPictureRenderer.java.patch b/patches/net/minecraft/client/gui/render/pip/PictureInPictureRenderer.java.patch index 828aff7f527..46bbc5b5917 100644 --- a/patches/net/minecraft/client/gui/render/pip/PictureInPictureRenderer.java.patch +++ b/patches/net/minecraft/client/gui/render/pip/PictureInPictureRenderer.java.patch @@ -2,12 +2,12 @@ +++ b/net/minecraft/client/gui/render/pip/PictureInPictureRenderer.java @@ -93,7 +_,9 @@ if (this.texture == null) { - this.texture = device.createTexture(() -> "UI " + this.getTextureLabel() + " texture", 12, TextureFormat.RGBA8, width, height, 1, 1); + this.texture = device.createTexture(() -> "UI " + this.getTextureLabel() + " texture", 13, TextureFormat.RGBA8, width, height, 1, 1); this.textureView = device.createTextureView(this.texture); -- this.depthTexture = device.createTexture(() -> "UI " + this.getTextureLabel() + " depth texture", 8, TextureFormat.DEPTH32, width, height, 1, 1); +- this.depthTexture = device.createTexture(() -> "UI " + this.getTextureLabel() + " depth texture", 9, TextureFormat.DEPTH32, width, height, 1, 1); + // Neo: copy stencil setting from main target + TextureFormat depthFormat = net.minecraft.client.Minecraft.getInstance().getMainRenderTarget().getDepthTexture().getFormat(); -+ this.depthTexture = device.createTexture(() -> "UI " + this.getTextureLabel() + " depth texture", 8, depthFormat, width, height, 1, 1); ++ this.depthTexture = device.createTexture(() -> "UI " + this.getTextureLabel() + " depth texture", 9, depthFormat, width, height, 1, 1); this.depthTextureView = device.createTextureView(this.depthTexture); } diff --git a/patches/net/minecraft/client/gui/screens/ChatScreen.java.patch b/patches/net/minecraft/client/gui/screens/ChatScreen.java.patch index 70a0a7db18a..d024cd11e7a 100644 --- a/patches/net/minecraft/client/gui/screens/ChatScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/ChatScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/ChatScreen.java +++ b/net/minecraft/client/gui/screens/ChatScreen.java -@@ -115,7 +_,10 @@ +@@ -120,7 +_,10 @@ } else if (event.isConfirmation()) { this.handleChatInput(this.input.getValue(), true); this.exitReason = ChatScreen.ExitReason.DONE; diff --git a/patches/net/minecraft/client/gui/screens/ConnectScreen.java.patch b/patches/net/minecraft/client/gui/screens/ConnectScreen.java.patch index 4eaef2d7a73..fd08080702c 100644 --- a/patches/net/minecraft/client/gui/screens/ConnectScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/ConnectScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/ConnectScreen.java +++ b/net/minecraft/client/gui/screens/ConnectScreen.java -@@ -104,6 +_,8 @@ +@@ -109,6 +_,8 @@ } if (resolvedAddress.isEmpty()) { diff --git a/patches/net/minecraft/client/gui/screens/Screen.java.patch b/patches/net/minecraft/client/gui/screens/Screen.java.patch index 0beb1e7adde..241aed1101a 100644 --- a/patches/net/minecraft/client/gui/screens/Screen.java.patch +++ b/patches/net/minecraft/client/gui/screens/Screen.java.patch @@ -61,7 +61,7 @@ private void scheduleNarration(long delay, boolean ignoreSuppression) { this.nextNarrationTime = Util.getMillis() + delay; if (ignoreSuppression) { -@@ -616,6 +_,14 @@ +@@ -614,6 +_,14 @@ public @Nullable Music getBackgroundMusic() { return null; diff --git a/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch b/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch index 63851481a78..df8b7c33d40 100644 --- a/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch @@ -36,7 +36,7 @@ if (this.splash != null && !this.minecraft.options.hideSplashTexts().get()) { this.splash.render(graphics, this.width, this.font, widgetFade); } -@@ -312,7 +_,13 @@ +@@ -310,7 +_,13 @@ versionString = versionString + I18n.get("menu.modded"); } diff --git a/patches/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch b/patches/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch index b9379e5ec91..8311fcd6286 100644 --- a/patches/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java +++ b/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java -@@ -51,6 +_,7 @@ +@@ -50,6 +_,7 @@ private final Map tabs = Maps.newLinkedHashMap(); private @Nullable AdvancementTab selectedTab; private boolean isScrolling; @@ -8,7 +8,7 @@ public AdvancementsScreen(ClientAdvancements advancements) { this(advancements, null); -@@ -75,6 +_,16 @@ +@@ -74,6 +_,16 @@ this.advancements.setSelectedTab(this.selectedTab == null ? null : this.selectedTab.getRootNode().holder(), true); } @@ -23,9 +23,9 @@ + } + this.layout.addToFooter(Button.builder(CommonComponents.GUI_DONE, button -> this.onClose()).width(200).build()); - this.layout.visitWidgets(x$0 -> { - AbstractWidget var10000 = this.addRenderableWidget(x$0); -@@ -108,7 +_,7 @@ + this.layout.visitWidgets(x$0 -> this.addRenderableWidget(x$0)); + this.repositionElements(); +@@ -105,7 +_,7 @@ int yo = (this.height - 140) / 2; for (AdvancementTab tab : this.tabs.values()) { @@ -34,7 +34,7 @@ this.advancements.setSelectedTab(tab.getRootNode().holder(), true); break; } -@@ -134,6 +_,11 @@ +@@ -131,6 +_,11 @@ super.render(graphics, mouseX, mouseY, a); int xo = (this.width - 252) / 2; int yo = (this.height - 140) / 2; @@ -46,7 +46,7 @@ graphics.nextStratum(); this.renderInside(graphics, xo, yo); graphics.nextStratum(); -@@ -199,10 +_,12 @@ +@@ -196,10 +_,12 @@ graphics.blit(RenderPipelines.GUI_TEXTURED, WINDOW_LOCATION, xo, yo, 0.0F, 0.0F, 252, 140, 256, 256); if (this.tabs.size() > 1) { for (AdvancementTab tab : this.tabs.values()) { @@ -59,7 +59,7 @@ tab.drawIcon(graphics, xo, yo); } } -@@ -221,7 +_,7 @@ +@@ -218,7 +_,7 @@ if (this.tabs.size() > 1) { for (AdvancementTab tab : this.tabs.values()) { diff --git a/patches/net/minecraft/client/gui/screens/debug/DebugOptionsScreen.java.patch b/patches/net/minecraft/client/gui/screens/debug/DebugOptionsScreen.java.patch index 59c1d2ae177..dc0dd5ae9c4 100644 --- a/patches/net/minecraft/client/gui/screens/debug/DebugOptionsScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/debug/DebugOptionsScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/debug/DebugOptionsScreen.java +++ b/net/minecraft/client/gui/screens/debug/DebugOptionsScreen.java -@@ -184,6 +_,10 @@ +@@ -192,6 +_,10 @@ DebugScreenEntry entry = DebugScreenEntries.getEntry(location); this.isAllowed = entry != null && entry.isAllowed(DebugOptionsScreen.this.minecraft.showOnlyReducedInfo()); String name = location.getPath(); @@ -11,7 +11,7 @@ if (this.isAllowed) { this.name = name; } else { -@@ -244,8 +_,11 @@ +@@ -252,8 +_,11 @@ public void renderContent(GuiGraphics graphics, int mouseX, int mouseY, boolean hovered, float a) { int x = this.getContentX(); int y = this.getContentY(); @@ -24,7 +24,7 @@ if (!this.isAllowed && hovered && mouseX < buttonsStartX) { graphics.setTooltipForNextFrame(DebugOptionsScreen.NOT_ALLOWED_TOOLTIP, mouseX, mouseY); } -@@ -308,6 +_,9 @@ +@@ -317,6 +_,9 @@ public void updateSearch(String value) { this.clearEntries(); @@ -34,7 +34,7 @@ List> all = new ArrayList<>(DebugScreenEntries.allEntries().entrySet()); all.sort(COMPARATOR); DebugEntryCategory currentCategory = null; -@@ -322,6 +_,7 @@ +@@ -331,6 +_,7 @@ this.addEntry(DebugOptionsScreen.this.new OptionEntry(entry.getKey())); } 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 83f9d08ab31..5e2f6c9dce5 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 -@@ -114,6 +_,7 @@ +@@ -123,6 +_,7 @@ this.onStopHovering(previouslyHoveredSlot); } @@ -8,7 +8,7 @@ graphics.pose().popMatrix(); } -@@ -197,7 +_,7 @@ +@@ -206,7 +_,7 @@ ItemStack item = this.hoveredSlot.getItem(); if (this.menu.getCarried().isEmpty() || this.showTooltipWithItemInHand(item)) { graphics.setTooltipForNextFrame( @@ -17,7 +17,7 @@ ); } } -@@ -213,7 +_,8 @@ +@@ -222,7 +_,8 @@ private void renderFloatingItem(GuiGraphics graphics, ItemStack carried, int x, int y, @Nullable String itemCount) { graphics.renderItem(carried, x, y); @@ -27,7 +27,7 @@ } protected void renderLabels(GuiGraphics graphics, int xm, int ym) { -@@ -268,6 +_,13 @@ +@@ -277,6 +_,13 @@ graphics.fill(x, y, x + 16, y + 16, -2130706433); } @@ -41,7 +41,7 @@ int seed = slot.x + slot.y * this.imageWidth; if (slot.isFake()) { graphics.renderFakeItem(itemStack, x, y, seed); -@@ -275,7 +_,8 @@ +@@ -284,7 +_,8 @@ graphics.renderItem(itemStack, x, y, seed); } @@ -51,7 +51,7 @@ } } -@@ -315,7 +_,8 @@ +@@ -324,7 +_,8 @@ if (super.mouseClicked(event, doubleClick)) { return true; } else { @@ -61,7 +61,7 @@ Slot slot = this.getHoveredSlot(event.x(), event.y()); this.doubleclick = this.lastClickSlot == slot && doubleClick; this.skipNextRelease = false; -@@ -325,6 +_,7 @@ +@@ -334,6 +_,7 @@ int xo = this.leftPos; int yo = this.topPos; boolean clickedOutside = this.hasClickedOutside(event.x(), event.y(), xo, yo); @@ -69,16 +69,16 @@ int slotId = -1; if (slot != null) { slotId = slot.index; -@@ -350,7 +_,7 @@ +@@ -359,7 +_,7 @@ } } else if (!this.isQuickCrafting) { if (this.menu.getCarried().isEmpty()) { - if (cloning) { + if (this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey)) { - this.slotClicked(slot, slotId, event.button(), ClickType.CLONE); + this.slotClicked(slot, slotId, event.button(), ContainerInput.CLONE); } else { boolean quickKey = slotId != -999 && event.hasShiftDown(); -@@ -374,7 +_,7 @@ +@@ -383,7 +_,7 @@ this.quickCraftingType = 0; } else if (event.button() == 1) { this.quickCraftingType = 1; @@ -87,7 +87,7 @@ this.quickCraftingType = 2; } } -@@ -451,10 +_,13 @@ +@@ -453,10 +_,13 @@ @Override public boolean mouseReleased(MouseButtonEvent event) { @@ -101,25 +101,25 @@ int slotId = -1; if (slot != null) { slotId = slot.index; -@@ -471,7 +_,7 @@ +@@ -473,7 +_,7 @@ if (target != null && target.mayPickup(this.minecraft.player) && target.hasItem() - && target.container == slot.container + && target.isSameInventory(slot) && AbstractContainerMenu.canItemQuickReplace(target, this.lastQuickMoved, true)) { - this.slotClicked(target, target.index, event.button(), ClickType.QUICK_MOVE); + this.slotClicked(target, target.index, event.button(), ContainerInput.QUICK_MOVE); } -@@ -536,7 +_,7 @@ - - this.slotClicked(null, -999, AbstractContainerMenu.getQuickcraftMask(2, this.quickCraftingType), ClickType.QUICK_CRAFT); +@@ -532,7 +_,7 @@ + } else if (this.isQuickCrafting && !this.quickCraftSlots.isEmpty()) { + this.quickCraftToSlots(); } else if (!this.menu.getCarried().isEmpty()) { - if (this.minecraft.options.keyPickItem.matchesMouse(event)) { + if (this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey)) { - this.slotClicked(slot, slotId, event.button(), ClickType.CLONE); + this.slotClicked(slot, slotId, event.button(), ContainerInput.CLONE); } else { boolean quickKey = slotId != -999 && event.hasShiftDown(); -@@ -605,34 +_,40 @@ +@@ -601,34 +_,40 @@ @Override public boolean keyPressed(KeyEvent event) { @@ -136,11 +136,11 @@ if (this.hoveredSlot != null && this.hoveredSlot.hasItem()) { - if (this.minecraft.options.keyPickItem.matches(event)) { + if (this.minecraft.options.keyPickItem.isActiveAndMatches(key)) { - this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 0, ClickType.CLONE); + this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 0, ContainerInput.CLONE); - } else if (this.minecraft.options.keyDrop.matches(event)) { + handled = true; + } else if (this.minecraft.options.keyDrop.isActiveAndMatches(key)) { - this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, event.hasControlDown() ? 1 : 0, ClickType.THROW); + this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, event.hasControlDown() ? 1 : 0, ContainerInput.THROW); + handled = true; } + } else if (this.minecraft.options.keyDrop.isActiveAndMatches(key)) { @@ -157,17 +157,17 @@ if (this.menu.getCarried().isEmpty() && this.hoveredSlot != null) { - if (this.minecraft.options.keySwapOffhand.matches(event)) { + if (this.minecraft.options.keySwapOffhand.isActiveAndMatches(key)) { - this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 40, ClickType.SWAP); + this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 40, ContainerInput.SWAP); return true; } for (int i = 0; i < 9; i++) { - if (this.minecraft.options.keyHotbarSlots[i].matches(event)) { + if (this.minecraft.options.keyHotbarSlots[i].isActiveAndMatches(key)) { - this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, i, ClickType.SWAP); + this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, i, ContainerInput.SWAP); return true; } -@@ -675,6 +_,18 @@ +@@ -690,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 17884289edd..0d68a81e441 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch @@ -8,8 +8,8 @@ + private net.neoforged.neoforge.client.gui.CreativeTabsScreenPage currentPage = new net.neoforged.neoforge.client.gui.CreativeTabsScreenPage(new java.util.ArrayList<>()); public CreativeModeInventoryScreen(LocalPlayer player, FeatureFlagSet enabledFeatures, boolean displayOperatorCreativeTab) { - super(new CreativeModeInventoryScreen.ItemPickerMenu(player), player.getInventory(), CommonComponents.EMPTY); -@@ -153,9 +_,11 @@ + super(new CreativeModeInventoryScreen.ItemPickerMenu(player), player.getInventory(), CommonComponents.EMPTY, 195, 136); +@@ -151,9 +_,11 @@ return false; } else { if (searchTrees != null) { @@ -24,7 +24,7 @@ } return true; -@@ -165,7 +_,7 @@ +@@ -163,7 +_,7 @@ private void refreshCurrentTabContents(Collection displayList) { int oldRowIndex = this.menu.getRowIndexForScroll(this.scrollOffs); this.menu.items.clear(); @@ -33,7 +33,7 @@ this.refreshSearchResults(); } else { this.menu.items.addAll(displayList); -@@ -331,6 +_,34 @@ +@@ -329,6 +_,34 @@ protected void init() { if (this.minecraft.player.hasInfiniteMaterials()) { 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); -@@ -378,7 +_,7 @@ +@@ -376,7 +_,7 @@ public boolean charTyped(CharacterEvent event) { if (this.ignoreTextInput) { return false; @@ -77,7 +77,7 @@ return false; } else { String oldContents = this.searchBox.getValue(); -@@ -397,7 +_,7 @@ +@@ -395,7 +_,7 @@ @Override public boolean keyPressed(KeyEvent event) { this.ignoreTextInput = false; @@ -86,7 +86,7 @@ if (this.minecraft.options.keyChat.matches(event)) { this.ignoreTextInput = true; this.selectTab(CreativeModeTabs.searchTab()); -@@ -433,6 +_,7 @@ +@@ -431,6 +_,7 @@ } private void refreshSearchResults() { @@ -94,7 +94,7 @@ this.menu.items.clear(); this.visibleTags.clear(); String searchTerm = this.searchBox.getValue(); -@@ -445,10 +_,10 @@ +@@ -443,10 +_,10 @@ SearchTree tree; if (searchTerm.startsWith("#")) { searchTerm = searchTerm.substring(1); @@ -103,11 +103,11 @@ this.updateVisibleTags(searchTerm); } else { - tree = searchTrees.creativeNameSearch(); -+ tree = searchTrees.creativeNameSearch(net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.getTagSearchKey(selectedTab)); ++ tree = searchTrees.creativeNameSearch(net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.getNameSearchKey(selectedTab)); } this.menu.items.addAll(tree.search(searchTerm.toLowerCase(Locale.ROOT))); -@@ -476,7 +_,7 @@ +@@ -474,7 +_,7 @@ @Override protected void renderLabels(GuiGraphics graphics, int xm, int ym) { if (selectedTab.showTitle()) { @@ -116,7 +116,7 @@ } } -@@ -486,7 +_,7 @@ +@@ -484,7 +_,7 @@ double xm = event.x() - this.leftPos; double ym = event.y() - this.topPos; @@ -125,7 +125,7 @@ if (this.checkTabClicked(tab, xm, ym)) { return true; } -@@ -508,7 +_,7 @@ +@@ -506,7 +_,7 @@ double ym = event.y() - this.topPos; this.scrolling = false; @@ -134,7 +134,7 @@ if (this.checkTabClicked(tab, xm, ym)) { this.selectTab(tab); return true; -@@ -526,6 +_,7 @@ +@@ -524,6 +_,7 @@ private void selectTab(CreativeModeTab tab) { CreativeModeTab oldTab = selectedTab; selectedTab = tab; @@ -142,7 +142,7 @@ this.quickCraftSlots.clear(); this.menu.items.clear(); this.clearDraggingState(); -@@ -602,13 +_,15 @@ +@@ -600,13 +_,15 @@ this.originalSlots = null; } @@ -159,22 +159,12 @@ this.refreshSearchResults(); } else { -@@ -671,18 +_,24 @@ +@@ -669,8 +_,14 @@ this.effects.render(graphics, mouseX, mouseY); super.render(graphics, mouseX, mouseY, a); - for (CreativeModeTab tab : CreativeModeTabs.tabs()) { - if (this.checkTabHovering(graphics, tab, mouseX, mouseY)) { -- break; -- } -- } -- - if (this.destroyItemSlot != null - && selectedTab.getType() == CreativeModeTab.Type.INVENTORY - && this.isHovering(this.destroyItemSlot.x, this.destroyItemSlot.y, 16, 16, mouseX, mouseY)) { - graphics.setTooltipForNextFrame(this.font, TRASH_SLOT_TOOLTIP, mouseX, mouseY); - } - + if (this.pages.size() != 1) { + Component page = Component.literal(String.format("%d / %d", this.pages.indexOf(this.currentPage) + 1, this.pages.size())); + // TODO 1.21.6: This previously bumped Z by 300, investigate if this needs nextStratum @@ -183,14 +173,10 @@ + + for (CreativeModeTab creativemodetab : currentPage.getVisibleTabs()) { + if (this.checkTabHovering(graphics, creativemodetab, mouseX, mouseY)) { -+ break; -+ } -+ } -+ - this.renderTooltip(graphics, mouseX, mouseY); - } - -@@ -695,10 +_,10 @@ + break; + } + } +@@ -691,10 +_,10 @@ public List getTooltipFromContainerItem(ItemStack itemStack) { boolean isCreativeSlot = this.hoveredSlot != null && this.hoveredSlot instanceof CreativeModeInventoryScreen.CustomCreativeSlot; boolean isSingleCategoryTab = selectedTab.getType() == CreativeModeTab.Type.CATEGORY; @@ -203,7 +189,7 @@ if (originalLines.isEmpty()) { return originalLines; } else if (isSingleCategoryTab && isCreativeSlot) { -@@ -716,7 +_,7 @@ +@@ -712,7 +_,7 @@ int i = 1; for (CreativeModeTab tab : CreativeModeTabs.tabs()) { @@ -212,7 +198,7 @@ linesToDisplay.add(i++, tab.getDisplayName().copy().withStyle(ChatFormatting.BLUE)); } } -@@ -727,7 +_,7 @@ +@@ -723,7 +_,7 @@ @Override protected void renderBg(GuiGraphics graphics, float a, int xm, int ym) { @@ -221,7 +207,7 @@ if (tab != selectedTab) { this.renderTabButton(graphics, xm, ym, tab); } -@@ -754,10 +_,11 @@ +@@ -750,10 +_,11 @@ int yscr = this.topPos + 18; int yscr2 = yscr + 112; if (selectedTab.canScroll()) { @@ -235,7 +221,7 @@ this.renderTabButton(graphics, xm, ym, selectedTab); if (selectedTab.getType() == CreativeModeTab.Type.INVENTORY) { InventoryScreen.renderEntityInInventoryFollowsMouse( -@@ -767,7 +_,7 @@ +@@ -763,7 +_,7 @@ } private int getTabX(CreativeModeTab tab) { @@ -244,7 +230,7 @@ int spacing = 27; int x = 27 * pos; if (tab.isAlignedRight()) { -@@ -779,7 +_,7 @@ +@@ -775,7 +_,7 @@ private int getTabY(CreativeModeTab tab) { int y = 0; @@ -253,7 +239,7 @@ y -= 32; } else { y += this.imageHeight; -@@ -807,8 +_,8 @@ +@@ -803,8 +_,8 @@ protected void renderTabButton(GuiGraphics graphics, int mouseX, int mouseY, CreativeModeTab tab) { boolean selected = tab == selectedTab; @@ -264,7 +250,7 @@ int x = this.leftPos + this.getTabX(tab); int y = this.topPos - (isTop ? 28 : -(this.imageHeight - 4)); Identifier[] sprites; -@@ -822,6 +_,7 @@ +@@ -818,6 +_,7 @@ graphics.requestCursor(CursorTypes.POINTING_HAND); } @@ -272,7 +258,7 @@ graphics.blitSprite(RenderPipelines.GUI_TEXTURED, sprites[Mth.clamp(pos, 0, sprites.length)], x, y, 26, 32); int iconX = x + 13 - 8; int iconY = y + 16 - 8 + (isTop ? 1 : -1); -@@ -858,6 +_,14 @@ +@@ -854,6 +_,14 @@ } } @@ -287,7 +273,7 @@ @OnlyIn(Dist.CLIENT) private static class CustomCreativeSlot extends Slot { public CustomCreativeSlot(Container container, int slot, int x, int y) { -@@ -1038,6 +_,22 @@ +@@ -1034,6 +_,22 @@ @Override public boolean mayPickup(Player player) { return this.target.mayPickup(player); diff --git a/patches/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java.patch b/patches/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java.patch index 19d8163de6b..898ac12fcc0 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java.patch @@ -49,17 +49,21 @@ int textX = x0 + 32; int textY = y0 + 7; int maxTextWidth = textureWidth - 32 - 7; -@@ -101,7 +_,12 @@ +@@ -100,8 +_,15 @@ + isCompact = true; } - if (isCompact && mouseX >= x0 && mouseX <= x0 + textureWidth && mouseY >= y0 && mouseY <= y0 + yStep) { +- if (isCompact && mouseX >= x0 && mouseX <= x0 + textureWidth && mouseY >= y0 && mouseY <= y0 + yStep) { - graphics.setTooltipForNextFrame(this.screen.getFont(), List.of(effectText, duration), Optional.empty(), mouseX, mouseY); -+ // Neo: Allow mods to adjust the tooltip shown when hovering a mob effect. -+ var list = List.of(effectText, duration); ++ if (mouseX >= x0 && mouseX <= x0 + textureWidth && mouseY >= y0 && mouseY <= y0 + yStep) { ++ // Neo: Allow mods to create or adjust the tooltip shown when hovering over a mob effect. ++ var list = isCompact ? List.of(effectText, duration) : List.of(); + if (effectInstance != null) { -+ list = net.neoforged.neoforge.client.ClientHooks.getEffectTooltip(screen, effectInstance, List.of(effectText, duration)); ++ list = net.neoforged.neoforge.client.ClientHooks.getEffectTooltip(screen, effectInstance, list); ++ } ++ if (!list.isEmpty()) { ++ graphics.setTooltipForNextFrame(this.screen.getFont(), list, Optional.empty(), mouseX, mouseY); + } -+ graphics.setTooltipForNextFrame(this.screen.getFont(), list, Optional.empty(), mouseX, mouseY); } } 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 951064da708..c7e42c45dca 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch @@ -9,7 +9,7 @@ graphics.blitSprite(RenderPipelines.GUI_TEXTURED, ENCHANTMENT_SLOT_DISABLED_SPRITE, leftPos, yo + 14 + 19 * i, 108, 19); graphics.blitSprite(RenderPipelines.GUI_TEXTURED, DISABLED_LEVEL_SPRITES[i], leftPos + 1, yo + 15 + 19 * i, 16, 16); graphics.drawWordWrap(this.font, message, leftPosText, yo + 16 + 19 * i, textWidth, ARGB.opaque((col & 16711422) >> 1), false); -@@ -162,15 +_,18 @@ +@@ -161,15 +_,18 @@ .registryAccess() .lookupOrThrow(Registries.ENCHANTMENT) .get(this.menu.enchantClue[i]); diff --git a/patches/net/minecraft/client/gui/screens/inventory/MerchantScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/MerchantScreen.java.patch index 1b27b598d2f..d73833162d3 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/MerchantScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/MerchantScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/inventory/MerchantScreen.java +++ b/net/minecraft/client/gui/screens/inventory/MerchantScreen.java -@@ -235,7 +_,11 @@ +@@ -233,7 +_,11 @@ graphics.renderItemDecorations(this.font, costA, sellItem1X, decorHeight); } else { graphics.renderItemDecorations(this.font, baseCostA, sellItem1X, decorHeight, baseCostA.getCount() == 1 ? "1" : null); 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 c1e468ee8dc..67d402752c0 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 -@@ -39,7 +_,7 @@ +@@ -40,7 +_,7 @@ this.addEntry(new KeyBindsList.CategoryEntry(category)); } @@ -9,7 +9,7 @@ int width = minecraft.font.width(name); if (width > this.maxNameWidth) { this.maxNameWidth = width; -@@ -126,6 +_,7 @@ +@@ -132,6 +_,7 @@ ) .build(); this.resetButton = Button.builder(RESET_BUTTON_TITLE, button -> { @@ -17,7 +17,7 @@ key.setKey(key.getDefaultKey()); KeyBindsList.this.resetMappingAndUpdateButtons(); }).bounds(0, 0, 50, 20).createNarration(defaultNarrationSupplier -> Component.translatable("narrator.controls.reset", name)).build(); -@@ -167,13 +_,13 @@ +@@ -173,13 +_,13 @@ MutableComponent tooltip = Component.empty(); if (!this.key.isUnbound()) { for (KeyMapping otherKey : KeyBindsList.this.minecraft.options.keyMappings) { diff --git a/patches/net/minecraft/client/gui/screens/packs/PackSelectionModel.java.patch b/patches/net/minecraft/client/gui/screens/packs/PackSelectionModel.java.patch index fa204f975d5..f05694baec5 100644 --- a/patches/net/minecraft/client/gui/screens/packs/PackSelectionModel.java.patch +++ b/patches/net/minecraft/client/gui/screens/packs/PackSelectionModel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/packs/PackSelectionModel.java +++ b/net/minecraft/client/gui/screens/packs/PackSelectionModel.java -@@ -33,9 +_,9 @@ +@@ -34,9 +_,9 @@ this.onListChanged = onListChanged; this.iconGetter = iconGetter; this.repository = repository; @@ -12,7 +12,7 @@ this.unselected.removeAll(this.selected); this.output = output; } -@@ -61,7 +_,7 @@ +@@ -62,7 +_,7 @@ this.repository.reload(); this.selected.retainAll(this.repository.getAvailablePacks()); this.unselected.clear(); diff --git a/patches/net/minecraft/client/gui/screens/worldselection/AbstractGameRulesScreen.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/AbstractGameRulesScreen.java.patch new file mode 100644 index 00000000000..eba1231038f --- /dev/null +++ b/patches/net/minecraft/client/gui/screens/worldselection/AbstractGameRulesScreen.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/client/gui/screens/worldselection/AbstractGameRulesScreen.java ++++ b/net/minecraft/client/gui/screens/worldselection/AbstractGameRulesScreen.java +@@ -314,6 +_,12 @@ + this.addEntry(gameRule, (x$0, x$1, x$2, x$3) -> AbstractGameRulesScreen.this.new IntegerRuleEntry(x$0, x$1, x$2, x$3)); + } + ++ @Override ++ public void visit(GameRule gameRule) { ++ // Neo: Append custom entries for none bool/int game rules ++ net.neoforged.neoforge.client.gamerules.GameRuleEntryFactoryManager.appendGameRuleEntry(AbstractGameRulesScreen.this, gameRule, this::addEntry); ++ } ++ + private void addEntry(GameRule gameRule, AbstractGameRulesScreen.EntryFactory factory) { + Component readableName = Component.translatable(gameRule.getDescriptionId()); + if (AbstractGameRulesScreen.RuleList.matchesFilter( 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 134ab4bb2da..b62769bbf8c 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java +++ b/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java -@@ -163,6 +_,7 @@ - ) { +@@ -162,6 +_,7 @@ queueLoadScreen(minecraft, PREPARING_WORLD_DATA); + long start = Util.getMillis(); PackRepository vanillaOnlyPackRepository = new PackRepository(new ServerPacksSource(minecraft.directoryValidator())); + net.neoforged.neoforge.resource.ResourcePackLoader.populatePackRepository(vanillaOnlyPackRepository, net.minecraft.server.packs.PackType.SERVER_DATA, false); WorldDataConfiguration dataConfig = SharedConstants.IS_RUNNING_IN_IDE diff --git a/patches/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch index f7e3de3dfbc..dd2fe79e6e8 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java +++ b/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java -@@ -215,7 +_,10 @@ +@@ -218,7 +_,10 @@ backupWarning = Component.translatable("selectWorld.backupWarning.customized"); } else { backupQuestion = Component.translatable("selectWorld.backupQuestion.experimental"); @@ -12,7 +12,7 @@ } this.minecraft.setScreen(new BackupConfirmScreen(cancelCallback, (backup, eraseCache) -> { -@@ -270,6 +_,7 @@ +@@ -273,6 +_,7 @@ try { levelDataTag = worldAccess.getDataTag(); summary = worldAccess.getSummary(levelDataTag); @@ -20,7 +20,7 @@ } catch (NbtException | ReportedNbtException | IOException var10) { this.minecraft.setScreen(new RecoverWorldDataScreen(this.minecraft, success -> { if (success) { -@@ -379,11 +_,20 @@ +@@ -382,11 +_,20 @@ WorldData data = worldStem.worldData(); boolean oldCustomized = data.worldGenOptions().isOldCustomizedWorld(); boolean unstable = data.worldGenSettingsLifecycle() != Lifecycle.stable(); 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 b5855b5ca53..d7ca415c86f 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java +++ b/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java -@@ -82,6 +_,7 @@ +@@ -83,6 +_,7 @@ private static final Identifier WARNING_SPRITE = Identifier.withDefaultNamespace("world_list/warning"); private static final Identifier JOIN_HIGHLIGHTED_SPRITE = Identifier.withDefaultNamespace("world_list/join_highlighted"); private static final Identifier JOIN_SPRITE = Identifier.withDefaultNamespace("world_list/join"); @@ -8,7 +8,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private static final Component FROM_NEWER_TOOLTIP_1 = Component.translatable("selectWorld.tooltip.fromNewerVersion1").withStyle(ChatFormatting.RED); private static final Component FROM_NEWER_TOOLTIP_2 = Component.translatable("selectWorld.tooltip.fromNewerVersion2").withStyle(ChatFormatting.RED); -@@ -512,6 +_,7 @@ +@@ -515,6 +_,7 @@ this.infoText.setPosition(textX, this.getContentY() + 9 + 9 + 3); this.infoText.render(graphics, mouseX, mouseY, a); graphics.blit(RenderPipelines.GUI_TEXTURED, this.icon.textureLocation(), this.getContentX(), this.getContentY(), 0.0F, 0.0F, 32, 32, 32, 32); @@ -16,7 +16,7 @@ if (this.list.entryType == WorldSelectionList.EntryType.SINGLEPLAYER && (this.minecraft.options.touchscreen().get() || hovered)) { graphics.fill(this.getContentX(), this.getContentY(), this.getContentX() + 32, this.getContentY() + 32, -1601138544); int relX = mouseX - this.getContentX(); -@@ -776,6 +_,19 @@ +@@ -779,6 +_,19 @@ @Override public LevelSummary getLevelSummary() { return this.summary; diff --git a/patches/net/minecraft/client/main/Main.java.patch b/patches/net/minecraft/client/main/Main.java.patch index d273e1cfe91..0ee3cb194ab 100644 --- a/patches/net/minecraft/client/main/Main.java.patch +++ b/patches/net/minecraft/client/main/Main.java.patch @@ -41,3 +41,17 @@ ), new GameConfig.QuickPlayData(quickPlayLogPath, quickPlayVariant) ); +@@ -197,8 +_,11 @@ + CrashReportCategory initialization = report.addCategory("Initialization"); + NativeModuleLister.addCrashSection(initialization); + Minecraft.fillReport(null, null, launchedVersion, null, report); +- Minecraft.crash(null, gameDir, report); +- return; ++ // Neo: Instead of crash(...), we show the error immediately using our earlydisplay GUI ++ int exitCode = Minecraft.saveReport(gameDir, report); ++ net.neoforged.fml.startup.FatalErrorReporting.reportFatalError(var75); ++ System.exit(exitCode); ++ return; // Neo: Rethrow to let early error screen handle it + } + + Thread shutdownThread = new Thread("Client Shutdown Thread") { diff --git a/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch b/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch index 0af4b5e51af..2d043cb1bde 100644 --- a/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch +++ b/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/model/geom/LayerDefinitions.java +++ b/net/minecraft/client/model/geom/LayerDefinitions.java -@@ -523,6 +_,7 @@ +@@ -518,6 +_,7 @@ result.put(ModelLayers.createHangingSignModelName(woodType, attachmentType), hangingSignModel); } }); diff --git a/patches/net/minecraft/client/model/geom/ModelLayers.java.patch b/patches/net/minecraft/client/model/geom/ModelLayers.java.patch index 63abc84ff78..c998121fa96 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 -@@ -339,15 +_,18 @@ +@@ -327,15 +_,18 @@ } public static ModelLayerLocation createStandingSignModelName(WoodType type) { diff --git a/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch b/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch index 3ac2ebaf07f..8e0cc0fe3df 100644 --- a/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/client/multiplayer/ClientChunkCache.java +++ b/net/minecraft/client/multiplayer/ClientChunkCache.java -@@ -64,6 +_,7 @@ - int index = this.storage.getIndex(pos.x, pos.z); +@@ -65,6 +_,7 @@ + int index = this.storage.getIndex(pos.x(), pos.z()); LevelChunk currentChunk = this.storage.getChunk(index); - if (isValidChunk(currentChunk, pos.x, pos.z)) { + if (isValidChunk(currentChunk, pos.x(), pos.z())) { + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkEvent.Unload(currentChunk)); this.storage.drop(index, currentChunk); } } -@@ -123,6 +_,7 @@ +@@ -124,6 +_,7 @@ } this.level.onChunkLoaded(pos); diff --git a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch index 1454037afba..b86b044ab0b 100644 --- a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch @@ -20,7 +20,7 @@ } public ServerLinks serverLinks() { -@@ -157,6 +_,33 @@ +@@ -158,6 +_,33 @@ @Override public void handleCustomPayload(ClientboundCustomPayloadPacket packet) { @@ -54,7 +54,7 @@ CustomPacketPayload payload = packet.payload(); if (!(payload instanceof DiscardedPayload)) { PacketUtils.ensureRunningOnSameThread(packet, this, this.minecraft.packetProcessor()); -@@ -347,6 +_,8 @@ +@@ -348,6 +_,8 @@ } public void send(Packet packet) { @@ -63,7 +63,7 @@ this.connection.send(packet); } -@@ -498,5 +_,15 @@ +@@ -505,5 +_,15 @@ @OnlyIn(Dist.CLIENT) private record PendingRequest(UUID id, URL url, String hash) { } diff --git a/patches/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java.patch b/patches/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java.patch index b46f2594e63..c6a279127a2 100644 --- a/patches/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java +++ b/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java -@@ -51,6 +_,9 @@ +@@ -52,6 +_,9 @@ private @Nullable KnownPacksManager knownPacks; protected ChatComponent.@Nullable State chatState; private boolean seenCodeOfConduct; @@ -10,7 +10,7 @@ public ClientConfigurationPacketListenerImpl(Minecraft minecraft, Connection connection, CommonListenerCookie cookie) { super(minecraft, connection, cookie); -@@ -90,6 +_,11 @@ +@@ -91,6 +_,11 @@ @Override public void handleEnabledFeatures(ClientboundUpdateEnabledFeaturesPacket packet) { this.enabledFeatures = FeatureFlags.REGISTRY.fromNames(packet.features()); @@ -22,7 +22,7 @@ } @Override -@@ -154,7 +_,7 @@ +@@ -155,7 +_,7 @@ ); this.connection .setupInboundProtocol( @@ -31,7 +31,7 @@ new ClientPacketListener( this.minecraft, this.connection, -@@ -172,13 +_,21 @@ +@@ -173,13 +_,21 @@ this.customReportDetails, this.serverLinks(), this.seenPlayers, @@ -52,10 +52,10 @@ this.connection - .setupOutboundProtocol(GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(registries), new GameProtocols.Context() { + .setupOutboundProtocol(GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(registries, connectionType), new GameProtocols.Context() { - @Override - public boolean hasInfiniteMaterials() { - return true; -@@ -195,6 +_,53 @@ + { + Objects.requireNonNull(ClientConfigurationPacketListenerImpl.this); + } +@@ -200,6 +_,53 @@ public void onDisconnect(DisconnectionDetails reason) { super.onDisconnect(reason); this.minecraft.clearDownloadedResourcePacks(); diff --git a/patches/net/minecraft/client/multiplayer/ClientDebugSubscriber.java.patch b/patches/net/minecraft/client/multiplayer/ClientDebugSubscriber.java.patch new file mode 100644 index 00000000000..62e2657c96b --- /dev/null +++ b/patches/net/minecraft/client/multiplayer/ClientDebugSubscriber.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/client/multiplayer/ClientDebugSubscriber.java ++++ b/net/minecraft/client/multiplayer/ClientDebugSubscriber.java +@@ -64,6 +_,8 @@ + addFlag(subscriptions, DebugSubscriptions.VILLAGE_SECTIONS, SharedConstants.DEBUG_VILLAGE_SECTIONS); + } + ++ // Neo: Allow requesting custom subscriptions ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.AddDebugSubscriptionFlagsEvent((subscription, flag) -> addFlag(subscriptions, subscription, flag))); + return subscriptions; + } + diff --git a/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch b/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch index bb0ad535fe1..d6bdad6b543 100644 --- a/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/ClientLevel.java +++ b/net/minecraft/client/multiplayer/ClientLevel.java -@@ -135,7 +_,7 @@ +@@ -137,7 +_,7 @@ private final @Nullable EndFlashState endFlashState; private final Minecraft minecraft = Minecraft.getInstance(); private final List players = Lists.newArrayList(); @@ -9,7 +9,7 @@ private final Map mapData = Maps.newHashMap(); private int skyFlashTime; private final Object2ObjectArrayMap tintCaches = Util.make(new Object2ObjectArrayMap<>(3), cache -> { -@@ -143,6 +_,7 @@ +@@ -145,6 +_,7 @@ cache.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.FOLIAGE_COLOR_RESOLVER))); cache.put(BiomeColors.DRY_FOLIAGE_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.DRY_FOLIAGE_COLOR_RESOLVER))); cache.put(BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.WATER_COLOR_RESOLVER))); @@ -17,15 +17,15 @@ }); private final ClientChunkCache chunkSource; private final Deque lightUpdateQueue = Queues.newArrayDeque(); -@@ -155,6 +_,7 @@ +@@ -156,6 +_,7 @@ + private final EnvironmentAttributeSystem environmentAttributes; private final int seaLevel; - private boolean tickDayTime; private static final Set MARKER_PARTICLE_ITEMS = Set.of(Items.BARRIER, Items.LIGHT); + private final net.neoforged.neoforge.model.data.ModelDataManager modelDataManager = new net.neoforged.neoforge.model.data.ModelDataManager(this); public void handleBlockChangedAck(int sequence) { if (SharedConstants.DEBUG_BLOCK_BREAK) { -@@ -200,10 +_,15 @@ +@@ -201,10 +_,15 @@ @Override public boolean setBlock(BlockPos pos, BlockState blockState, @Block.UpdateFlags int updateFlags, int updateLimit) { if (this.blockStatePredictionHandler.isPredicting()) { @@ -41,7 +41,7 @@ } return success; -@@ -240,6 +_,7 @@ +@@ -241,6 +_,7 @@ if (this.canHaveWeather()) { this.prepareWeather(); } @@ -49,19 +49,10 @@ } private EnvironmentAttributeSystem.Builder addEnvironmentAttributeLayers(EnvironmentAttributeSystem.Builder environmentAttributes) { -@@ -319,7 +_,7 @@ - private void tickTime() { - this.clientLevelData.setGameTime(this.clientLevelData.getGameTime() + 1L); - if (this.tickDayTime) { -- this.clientLevelData.setDayTime(this.clientLevelData.getDayTime() + 1L); -+ this.clientLevelData.setDayTime(this.clientLevelData.getDayTime() + advanceDaytime()); - } - } - -@@ -354,7 +_,11 @@ +@@ -350,7 +_,11 @@ entity.setOldPosAndRot(); entity.tickCount++; - Profiler.get().push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString()); + Profiler.get().push(entity.typeHolder()::getRegisteredName); - entity.tick(); + // Neo: Permit cancellation of Entity#tick via EntityTickEvent.Pre + if (!net.neoforged.neoforge.event.EventHooks.fireEntityTickPre(entity).isCanceled()) { @@ -71,7 +62,7 @@ Profiler.get().pop(); for (Entity passenger : entity.getPassengers()) { -@@ -405,8 +_,10 @@ +@@ -401,8 +_,10 @@ } public void addEntity(Entity entity) { @@ -82,7 +73,7 @@ } public void removeEntity(int id, Entity.RemovalReason reason) { -@@ -552,6 +_,13 @@ +@@ -548,6 +_,13 @@ public void playSeededSound( @Nullable Entity except, double x, double y, double z, Holder sound, SoundSource source, float volume, float pitch, long seed ) { @@ -96,7 +87,7 @@ if (except == this.minecraft.player) { this.playSound(x, y, z, sound.value(), source, volume, pitch, false, seed); } -@@ -561,6 +_,12 @@ +@@ -557,6 +_,12 @@ public void playSeededSound( @Nullable Entity except, Entity sourceEntity, Holder sound, SoundSource source, float volume, float pitch, long seed ) { @@ -163,7 +154,7 @@ } } -@@ -1088,6 +_,7 @@ +@@ -1078,6 +_,7 @@ } public void setDifficulty(Difficulty difficulty) { @@ -171,7 +162,7 @@ this.difficulty = difficulty; } -@@ -1129,6 +_,9 @@ +@@ -1124,6 +_,9 @@ ClientLevel.this.dragonParts.addAll(Arrays.asList(dragon.getSubEntities())); break; default: @@ -181,7 +172,7 @@ } } -@@ -1142,10 +_,62 @@ +@@ -1137,10 +_,38 @@ ClientLevel.this.dragonParts.removeAll(Arrays.asList(dragon.getSubEntities())); break; default: @@ -218,29 +209,5 @@ + return constantAmbientLight ? 0.9F : 1.0F; + float yFactor = constantAmbientLight ? 0.9F : normalY < 0 ? 0.5F : 1.0F; + return Math.min(normalX * normalX * 0.6F + normalY * normalY * yFactor + normalZ * normalZ * 0.8F, 1.0F); -+ } -+ -+ // Neo: Variable day time code -+ -+ private float dayTimeFraction = 0.0f; -+ private float dayTimePerTick = -1.0f; -+ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public void setDayTimeFraction(float dayTimeFraction) { -+ this.dayTimeFraction = dayTimeFraction; -+ } -+ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public float getDayTimeFraction() { -+ return dayTimeFraction; -+ } -+ -+ public float getDayTimePerTick() { -+ return dayTimePerTick; -+ } -+ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public void setDayTimePerTick(float dayTimePerTick) { -+ this.dayTimePerTick = dayTimePerTick; } } diff --git a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch index 49868237b29..b30f059e218 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 -@@ -413,6 +_,7 @@ +@@ -417,6 +_,7 @@ private final ChunkBatchSizeCalculator chunkBatchSizeCalculator = new ChunkBatchSizeCalculator(); private final PingDebugMonitor pingDebugMonitor; private final ClientDebugSubscriber debugSubscriber; @@ -8,7 +8,7 @@ private @Nullable LevelLoadTracker levelLoadTracker; private boolean serverEnforcesSecureChat; private volatile boolean closed; -@@ -444,7 +_,8 @@ +@@ -449,7 +_,8 @@ minecraft.gui.getChat().restoreState(cookie.chatState()); } @@ -17,8 +17,8 @@ + this.potionBrewing = PotionBrewing.bootstrap(this.enabledFeatures, this.registryAccess); this.fuelValues = FuelValues.vanillaBurnTimes(cookie.receivedRegistries(), this.enabledFeatures); this.levelLoadTracker = cookie.levelLoadTracker(); - } -@@ -522,12 +_,13 @@ + this.clockManager = new ClientClockManager(); +@@ -528,12 +_,13 @@ this.debugSubscriber.clear(); this.minecraft.levelRenderer.debugRenderer.refreshRendererList(); this.minecraft.player.resetPos(); @@ -33,7 +33,7 @@ this.minecraft.player.setReducedDebugInfo(packet.reducedDebugInfo()); this.minecraft.player.setShowDeathScreen(packet.showDeathScreen()); this.minecraft.player.setDoLimitedCrafting(packet.doLimitedCrafting()); -@@ -957,7 +_,8 @@ +@@ -963,7 +_,8 @@ this.customReportDetails, this.serverLinks(), this.seenPlayers, @@ -43,7 +43,7 @@ ) ) ); -@@ -1278,7 +_,7 @@ +@@ -1286,7 +_,7 @@ } this.setClientLoaded(false); @@ -52,7 +52,7 @@ newPlayer.setId(oldPlayer.getId()); this.minecraft.player = newPlayer; if (dimensionChanged) { -@@ -1306,6 +_,7 @@ +@@ -1314,6 +_,7 @@ newPlayer.getAttributes().assignBaseValues(oldPlayer.getAttributes()); } @@ -60,7 +60,7 @@ this.level.addEntity(newPlayer); newPlayer.input = new KeyboardInput(this.minecraft.options); this.minecraft.gameMode.adjustPlayer(newPlayer); -@@ -1459,7 +_,7 @@ +@@ -1467,7 +_,7 @@ ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(blockEntity.problemPath(), LOGGER); try { @@ -69,7 +69,7 @@ } catch (Throwable var7) { try { reporter.close(); -@@ -1581,7 +_,13 @@ +@@ -1589,7 +_,13 @@ } } @@ -83,7 +83,7 @@ if (this.levelLoadTracker == null) { this.levelLoadTracker = new LevelLoadTracker(); } -@@ -1591,7 +_,7 @@ +@@ -1599,7 +_,7 @@ loadingScreen.update(this.levelLoadTracker, reason); } else { this.minecraft.gui.getChat().preserveCurrentChatScreen(); @@ -92,7 +92,7 @@ } } -@@ -1640,7 +_,9 @@ +@@ -1648,7 +_,9 @@ @Override public void handleCommands(ClientboundCommandsPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.minecraft.packetProcessor()); @@ -103,7 +103,7 @@ } @Override -@@ -1659,6 +_,8 @@ +@@ -1667,6 +_,8 @@ public void handleUpdateRecipes(ClientboundUpdateRecipesPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.minecraft.packetProcessor()); this.recipes = new ClientRecipeContainer(packet.itemSets(), packet.stonecutterRecipes()); @@ -112,7 +112,7 @@ } @Override -@@ -1783,8 +_,11 @@ +@@ -1791,8 +_,11 @@ }); pendingTags.forEach(Registry.PendingTags::apply); this.fuelValues = FuelValues.vanillaBurnTimes(this.registryAccess, this.enabledFeatures); @@ -126,7 +126,7 @@ } @Override -@@ -2590,6 +_,8 @@ +@@ -2611,6 +_,8 @@ } public void sendChat(String content) { @@ -135,7 +135,7 @@ Instant timeStamp = Instant.now(); long salt = Crypt.SaltSupplier.getLong(); LastSeenMessagesTracker.Update lastSeenUpdate = this.lastSeenMessages.generateAndApplyUpdate(); -@@ -2598,6 +_,7 @@ +@@ -2619,6 +_,7 @@ } public void sendCommand(String command) { @@ -143,7 +143,7 @@ SignableCommand signableCommand = SignableCommand.of(this.commands.parse(command, this.suggestionsProvider)); if (signableCommand.arguments().isEmpty()) { this.send(new ServerboundChatCommandPacket(command)); -@@ -2614,6 +_,8 @@ +@@ -2635,6 +_,8 @@ } public void sendUnattendedCommand(String command, @Nullable Screen screenAfterCommand) { @@ -152,7 +152,7 @@ switch (this.verifyCommand(command)) { case NO_ISSUES: this.send(new ServerboundChatCommandPacket(command)); -@@ -2772,6 +_,10 @@ +@@ -2801,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 a90a4654790..5b02a32b2ff 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 -@@ -126,11 +_,12 @@ +@@ -128,11 +_,12 @@ } else if (oldState.isAir()) { return false; } else { @@ -15,7 +15,7 @@ } if (SharedConstants.DEBUG_BLOCK_BREAK) { -@@ -157,6 +_,7 @@ +@@ -159,6 +_,7 @@ } this.startPrediction(this.minecraft.level, sequence -> { @@ -23,7 +23,7 @@ this.destroyBlock(pos); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence); }); -@@ -170,6 +_,7 @@ +@@ -172,6 +_,7 @@ this.connection .send(new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, this.destroyBlockPos, direction)); } @@ -31,7 +31,7 @@ BlockState state = this.minecraft.level.getBlockState(pos); this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, pos, state, 0.0F); -@@ -180,9 +_,12 @@ +@@ -182,9 +_,12 @@ this.startPrediction(this.minecraft.level, sequence -> { boolean notAir = !state.isAir(); if (notAir && this.destroyProgress == 0.0F) { @@ -44,7 +44,7 @@ if (notAir && state.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), pos) >= 1.0F) { this.destroyBlock(pos); } else { -@@ -194,7 +_,7 @@ +@@ -196,7 +_,7 @@ this.minecraft.level.destroyBlockProgress(this.minecraft.player.getId(), this.destroyBlockPos, this.getDestroyStage()); } @@ -53,7 +53,7 @@ }); } -@@ -233,6 +_,7 @@ +@@ -235,6 +_,7 @@ } this.startPrediction(this.minecraft.level, sequence -> { @@ -61,7 +61,7 @@ this.destroyBlock(pos); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence); }); -@@ -244,8 +_,8 @@ +@@ -246,8 +_,8 @@ return false; } else { this.destroyProgress = this.destroyProgress + state.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), pos); @@ -72,7 +72,7 @@ this.minecraft .getSoundManager() .play( -@@ -262,6 +_,7 @@ +@@ -264,6 +_,7 @@ this.destroyTicks++; this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, pos, state, Mth.clamp(this.destroyProgress, 0.0F, 1.0F)); @@ -80,7 +80,7 @@ if (this.destroyProgress >= 1.0F) { this.isDestroying = false; if (SharedConstants.DEBUG_BLOCK_BREAK) { -@@ -304,7 +_,7 @@ +@@ -306,7 +_,7 @@ private boolean sameDestroyTarget(BlockPos pos) { ItemStack selected = this.minecraft.player.getMainHandItem(); @@ -89,7 +89,7 @@ } private void ensureHasSentCarriedItem() { -@@ -332,12 +_,23 @@ +@@ -334,12 +_,23 @@ private InteractionResult performUseItemOn(LocalPlayer player, InteractionHand hand, BlockHitResult blockHit) { BlockPos pos = blockHit.getBlockPos(); ItemStack itemStack = player.getItemInHand(hand); @@ -115,7 +115,7 @@ BlockState blockState = this.minecraft.level.getBlockState(pos); if (!this.connection.isFeatureEnabled(blockState.getBlock().requiredFeatures())) { return InteractionResult.FAIL; -@@ -356,7 +_,10 @@ +@@ -358,7 +_,10 @@ } } @@ -127,7 +127,7 @@ UseOnContext context = new UseOnContext(player, hand, blockHit); InteractionResult success; if (player.hasInfiniteMaterials()) { -@@ -387,6 +_,11 @@ +@@ -389,6 +_,11 @@ interactionResult.setValue(InteractionResult.PASS); return packet; } else { @@ -139,7 +139,7 @@ InteractionResult resultHolder = itemStack.use(this.minecraft.level, player, hand); ItemStack result; if (resultHolder instanceof InteractionResult.Success success) { -@@ -397,6 +_,8 @@ +@@ -399,6 +_,8 @@ if (result != itemStack) { player.setItemInHand(hand, result); @@ -148,13 +148,13 @@ } interactionResult.setValue(resultHolder); -@@ -434,6 +_,9 @@ +@@ -432,6 +_,9 @@ this.ensureHasSentCarriedItem(); Vec3 location = hitResult.getLocation().subtract(entity.getX(), entity.getY(), entity.getZ()); - this.connection.send(ServerboundInteractPacket.createInteractionPacket(entity, player.isShiftKeyDown(), hand, location)); + this.connection.send(new ServerboundInteractPacket(entity.getId(), hand, location, player.isShiftKeyDown())); + if (this.localPlayerMode == GameType.SPECTATOR) return InteractionResult.PASS; // don't fire for spectators to match non-specific EntityInteract + InteractionResult cancelResult = net.neoforged.neoforge.common.CommonHooks.onInteractEntityAt(player, entity, hitResult, hand); + if(cancelResult != null) return cancelResult; - return (InteractionResult)(this.localPlayerMode == GameType.SPECTATOR ? InteractionResult.PASS : entity.interactAt(player, location, hand)); + return (InteractionResult)(this.localPlayerMode == GameType.SPECTATOR ? InteractionResult.PASS : player.interactOn(entity, hand, location)); } diff --git a/patches/net/minecraft/client/multiplayer/RegistryDataCollector.java.patch b/patches/net/minecraft/client/multiplayer/RegistryDataCollector.java.patch new file mode 100644 index 00000000000..ed0001baa0e --- /dev/null +++ b/patches/net/minecraft/client/multiplayer/RegistryDataCollector.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/multiplayer/RegistryDataCollector.java ++++ b/net/minecraft/client/multiplayer/RegistryDataCollector.java +@@ -156,6 +_,7 @@ + pendingComponents.apply(); + } + }); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.DefaultDataComponentsBoundEvent(true, !includeSharedRegistries)); + } + + public RegistryAccess.Frozen collectGameRegistries( diff --git a/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch b/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch index 86b4d049b07..600751ff9f1 100644 --- a/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch +++ b/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch @@ -25,7 +25,7 @@ - this.creativeByTagSearch = CompletableFuture.supplyAsync( + CompletableFuture previous = net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.getTagSearchTree(key); + net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.putTagSearchTree(key, CompletableFuture.supplyAsync( - () -> new IdSearchTree<>(itemStack -> itemStack.getTags().map(TagKey::location), items), Util.backgroundExecutor() + () -> new IdSearchTree<>(itemStack -> itemStack.tags().map(TagKey::location), items), Util.backgroundExecutor() - ); + )); previous.cancel(true); @@ -60,7 +60,7 @@ + net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.putNameSearchTree(key, CompletableFuture.supplyAsync( () -> new FullTextSearchTree<>( itemStack -> getTooltipLines(Stream.of(itemStack), tooltipContext, tooltipFlag), - itemStack -> itemStack.getItemHolder().unwrapKey().map(ResourceKey::identifier).stream(), + itemStack -> itemStack.typeHolder().unwrapKey().map(ResourceKey::identifier).stream(), itemStacks ), Util.backgroundExecutor() diff --git a/patches/net/minecraft/client/particle/PortalParticle.java.patch b/patches/net/minecraft/client/particle/PortalParticle.java.patch index 64a26a71739..7a4f64856eb 100644 --- a/patches/net/minecraft/client/particle/PortalParticle.java.patch +++ b/patches/net/minecraft/client/particle/PortalParticle.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/particle/PortalParticle.java +++ b/net/minecraft/client/particle/PortalParticle.java -@@ -82,6 +_,7 @@ +@@ -75,6 +_,7 @@ this.x = this.xStart + this.xd * var4; this.y = this.yStart + this.yd * var4 + (1.0F - pos); this.z = this.zStart + this.zd * var4; diff --git a/patches/net/minecraft/client/particle/TerrainParticle.java.patch b/patches/net/minecraft/client/particle/TerrainParticle.java.patch index 2f373b61335..20adb8cd505 100644 --- a/patches/net/minecraft/client/particle/TerrainParticle.java.patch +++ b/patches/net/minecraft/client/particle/TerrainParticle.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/particle/TerrainParticle.java +++ b/net/minecraft/client/particle/TerrainParticle.java -@@ -31,7 +_,7 @@ +@@ -30,7 +_,7 @@ this.rCol = 0.6F; this.gCol = 0.6F; this.bCol = 0.6F; @@ -9,7 +9,7 @@ int col = Minecraft.getInstance().getBlockColors().getColor(blockState, level, pos, 0); this.rCol *= (col >> 16 & 0xFF) / 255.0F; this.gCol *= (col >> 8 & 0xFF) / 255.0F; -@@ -80,8 +_,14 @@ +@@ -73,8 +_,14 @@ ) { BlockState state = options.getState(); return !state.isAir() && !state.is(Blocks.MOVING_PISTON) && state.shouldSpawnTerrainParticles() diff --git a/patches/net/minecraft/client/particle/VibrationSignalParticle.java.patch b/patches/net/minecraft/client/particle/VibrationSignalParticle.java.patch index b6185a932d5..430bec94f0a 100644 --- a/patches/net/minecraft/client/particle/VibrationSignalParticle.java.patch +++ b/patches/net/minecraft/client/particle/VibrationSignalParticle.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/particle/VibrationSignalParticle.java +++ b/net/minecraft/client/particle/VibrationSignalParticle.java -@@ -78,6 +_,7 @@ +@@ -79,6 +_,7 @@ this.x = Mth.lerp(alpha, this.x, destination.x()); this.y = Mth.lerp(alpha, this.y, destination.y()); this.z = Mth.lerp(alpha, this.z, destination.z()); diff --git a/patches/net/minecraft/client/renderer/GameRenderer.java.patch b/patches/net/minecraft/client/renderer/GameRenderer.java.patch index bb8c2d5527c..61b28cee00f 100644 --- a/patches/net/minecraft/client/renderer/GameRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/GameRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/GameRenderer.java +++ b/net/minecraft/client/renderer/GameRenderer.java -@@ -168,14 +_,14 @@ +@@ -175,14 +_,14 @@ bufferSource, this.submitNodeStorage, this.featureRenderDispatcher, @@ -23,7 +23,7 @@ ); this.screenEffectRenderer = new ScreenEffectRenderer(minecraft, atlasManager, bufferSource); } -@@ -245,6 +_,7 @@ +@@ -253,6 +_,7 @@ break; case null: default: @@ -31,7 +31,7 @@ this.clearPostEffect(); } } -@@ -381,7 +_,7 @@ +@@ -389,7 +_,7 @@ fov *= Mth.lerp(effectScale, 1.0F, 0.85714287F); } @@ -40,7 +40,7 @@ } } -@@ -397,6 +_,10 @@ +@@ -405,6 +_,10 @@ return; } @@ -51,7 +51,7 @@ hurt /= camera.hurtDuration; hurt = Mth.sin(hurt * hurt * hurt * hurt * (float) Math.PI); float rr = camera.getHurtDir(); -@@ -534,7 +_,8 @@ +@@ -547,7 +_,8 @@ } } else if (resourcesLoaded && this.minecraft.screen != null) { try { @@ -61,7 +61,7 @@ } catch (Throwable var14) { CrashReport report = CrashReport.forThrowable(var14, "Rendering screen"); CrashReportCategory category = report.addCategory("Screen render details"); -@@ -792,6 +_,9 @@ +@@ -811,6 +_,9 @@ fogColor, !shouldCreateBossFog ); diff --git a/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch b/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch index 3836b69ee74..a3f9183dddb 100644 --- a/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch +++ b/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch @@ -6,9 +6,9 @@ public class ItemBlockRenderTypes { + @Deprecated private static final Map TYPE_BY_BLOCK = Util.make(Maps.newHashMap(), map -> { - ChunkSectionLayer tripwire = ChunkSectionLayer.TRIPWIRE; - map.put(Blocks.TRIPWIRE, tripwire); -@@ -361,6 +_,8 @@ + ChunkSectionLayer cutout = ChunkSectionLayer.CUTOUT; + map.put(Blocks.GRASS_BLOCK, cutout); +@@ -360,6 +_,8 @@ }); private static boolean cutoutLeaves; @@ -17,7 +17,7 @@ public static ChunkSectionLayer getChunkRenderType(BlockState state) { Block block = state.getBlock(); if (block instanceof LeavesBlock) { -@@ -371,6 +_,8 @@ +@@ -370,6 +_,8 @@ } } @@ -26,7 +26,7 @@ public static RenderType getMovingBlockRenderType(BlockState state) { Block block = state.getBlock(); if (block instanceof LeavesBlock) { -@@ -390,6 +_,8 @@ +@@ -388,6 +_,8 @@ } } @@ -35,7 +35,7 @@ public static RenderType getRenderType(BlockState state) { ChunkSectionLayer renderType = getChunkRenderType(state); return renderType == ChunkSectionLayer.TRANSLUCENT ? Sheets.translucentBlockItemSheet() : Sheets.cutoutBlockSheet(); -@@ -402,5 +_,30 @@ +@@ -400,5 +_,30 @@ public static void setCutoutLeaves(boolean cutoutLeaves) { ItemBlockRenderTypes.cutoutLeaves = cutoutLeaves; diff --git a/patches/net/minecraft/client/renderer/LevelEventHandler.java.patch b/patches/net/minecraft/client/renderer/LevelEventHandler.java.patch index dee703453b8..2beb13e0498 100644 --- a/patches/net/minecraft/client/renderer/LevelEventHandler.java.patch +++ b/patches/net/minecraft/client/renderer/LevelEventHandler.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/LevelEventHandler.java +++ b/net/minecraft/client/renderer/LevelEventHandler.java -@@ -313,8 +_,8 @@ +@@ -301,8 +_,8 @@ break; case 2001: BlockState blockState = Block.stateById(data); diff --git a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch index fb81918512f..d03bd44cab0 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 -@@ -490,7 +_,7 @@ +@@ -496,7 +_,7 @@ profiler.push("entities"); this.extractVisibleEntities(camera, frustum, deltaTracker, this.levelRenderState); profiler.popPush("blockEntities"); @@ -9,10 +9,10 @@ profiler.popPush("blockOutline"); this.extractBlockOutline(camera, this.levelRenderState); profiler.popPush("blockBreaking"); -@@ -508,6 +_,13 @@ - this.minecraft.options.getEffectiveRenderDistance() * 16, - this.levelRenderState.worldBorderRenderState +@@ -516,6 +_,13 @@ ); + profiler.popPush("particles"); + this.minecraft.particleEngine.extract(this.particlesRenderState, new Frustum(frustum).offset(-3.0F), camera, deltaPartialTick); + profiler.popPush("neoforge_custom"); + this.levelRenderState.customWeatherEffectRenderer = net.neoforged.neoforge.client.CustomEnvironmentEffectsRendererManager.getCustomWeatherEffectRenderer(this.level, camera.position()); + this.levelRenderState.customSkyboxRenderer = net.neoforged.neoforge.client.CustomEnvironmentEffectsRendererManager.getCustomSkyboxRenderer(this.level, camera.position()); @@ -23,7 +23,7 @@ profiler.pop(); profiler.popPush("debug"); this.debugRenderer.emitGizmos(frustum, cameraPos.x, cameraPos.y, cameraPos.z, deltaTracker.getGameTimeDeltaPartialTick(false)); -@@ -520,7 +_,7 @@ +@@ -528,7 +_,7 @@ this.targets.main = frame.importExternal("main", this.minecraft.getMainRenderTarget()); int screenWidth = this.minecraft.getMainRenderTarget().width; int screenHeight = this.minecraft.getMainRenderTarget().height; @@ -32,7 +32,7 @@ PostChain transparencyChain = this.getTransparencyChain(); if (transparencyChain != null) { this.targets.translucent = frame.createInternal("translucent", screenSizeTargetDescriptor); -@@ -534,6 +_,9 @@ +@@ -542,6 +_,9 @@ this.targets.entityOutline = frame.importExternal("entity_outline", this.entityOutlineTarget); } @@ -42,7 +42,7 @@ FramePass clearPass = frame.addPass("clear"); this.targets.main = clearPass.readsAndWrites(this.targets.main); clearPass.executes( -@@ -550,7 +_,7 @@ +@@ -558,7 +_,7 @@ } ); if (shouldRenderSky) { @@ -51,15 +51,7 @@ } this.addMainPass(frame, frustum, modelViewMatrix, terrainFog, renderOutline, this.levelRenderState, deltaTracker, profiler); -@@ -560,19 +_,19 @@ - } - - this.minecraft.particleEngine.extract(this.particlesRenderState, new Frustum(frustum).offset(-3.0F), camera, deltaPartialTick); -- this.addParticlesPass(frame, terrainFog); -+ this.addParticlesPass(frame, terrainFog, modelViewMatrix); - CloudStatus cloudsType = this.minecraft.options.getCloudsType(); - if (cloudsType != CloudStatus.OFF) { - int cloudColor = camera.attributeProbe().getValue(EnvironmentAttributes.CLOUD_COLOR, deltaPartialTick); +@@ -573,12 +_,12 @@ if (ARGB.alpha(cloudColor) > 0) { float cloudHeight = camera.attributeProbe().getValue(EnvironmentAttributes.CLOUD_HEIGHT, deltaPartialTick); this.addCloudsPass( @@ -74,7 +66,7 @@ if (transparencyChain != null) { transparencyChain.addToFrame(frame, screenWidth, screenHeight, this.targets); } -@@ -648,6 +_,9 @@ +@@ -663,6 +_,9 @@ ChunkSectionsToRender chunkSectionsToRender = this.prepareChunkRenders(modelViewMatrix, camX, camY, camZ); chunkSectionsToRender.renderGroup(ChunkSectionLayerGroup.OPAQUE, this.chunkLayerSampler); @@ -82,57 +74,40 @@ + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLevelStageEvent.AfterOpaqueBlocks(this, this.levelRenderState, null, modelViewMatrix, this.getRenderableSections())); + profiler.pop(); this.minecraft.gameRenderer.getLighting().setupFor(Lighting.Entry.LEVEL); - if (itemEntityTarget != null) { - itemEntityTarget.get().copyDepthFrom(this.minecraft.getMainRenderTarget()); -@@ -682,6 +_,8 @@ - bufferSource.endBatch(Sheets.hangingSignSheet()); - bufferSource.endBatch(Sheets.chestSheet()); + if (this.shouldShowEntityOutlines() && entityOutlineTarget != null) { + RenderTarget outlineTarget = entityOutlineTarget.get(); +@@ -680,6 +_,9 @@ + this.submitBlockEntities(poseStack, levelRenderState, this.submitNodeStorage); + profiler.popPush("submitParticles"); + this.particlesRenderState.submit(this.submitNodeStorage, levelRenderState.cameraRenderState); ++ Profiler.get().push("neoforge_render_after_particles"); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLevelStageEvent.AfterParticles(this, this.levelRenderState, null, modelViewMatrix, this.getRenderableSections())); ++ Profiler.get().pop(); + profiler.popPush("solidFeatures"); + this.featureRenderDispatcher.renderSolidFeatures(); + bufferSource.endBatch(); +@@ -706,6 +_,8 @@ + crumblingBufferSource.endBatch(); + profiler.pop(); this.renderBuffers.outlineBufferSource().endOutlineBatch(); + profiler.popPush("neoforge_render_after_entities"); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLevelStageEvent.AfterEntities(this, this.levelRenderState, poseStack, modelViewMatrix, this.getRenderableSections())); if (renderOutline) { this.renderBlockOutline(bufferSource, poseStack, false, levelRenderState); - } -@@ -711,8 +_,12 @@ - - profiler.push("translucent"); + bufferSource.endBatch(); +@@ -717,6 +_,8 @@ + this.checkPoseStack(poseStack); + profiler.push("translucentTerrain"); chunkSectionsToRender.renderGroup(ChunkSectionLayerGroup.TRANSLUCENT, this.chunkLayerSampler); + profiler.popPush("neoforge_render_after_translucent_blocks"); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLevelStageEvent.AfterTranslucentBlocks(this, this.levelRenderState, null, modelViewMatrix, this.getRenderableSections())); - profiler.popPush("string"); - chunkSectionsToRender.renderGroup(ChunkSectionLayerGroup.TRIPWIRE, this.chunkLayerSampler); -+ profiler.popPush("neoforge_render_after_tripwire_blocks"); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLevelStageEvent.AfterTripwireBlocks(this, this.levelRenderState, null, modelViewMatrix, this.getRenderableSections())); if (renderOutline) { this.renderBlockOutline(bufferSource, poseStack, true, levelRenderState); } -@@ -723,7 +_,15 @@ +@@ -729,9 +_,18 @@ ); } -+ /** -+ * @deprecated Neo: use {@link #addParticlesPass(FrameGraphBuilder, GpuBufferSlice, Matrix4f)} instead -+ */ -+ @Deprecated - private void addParticlesPass(FrameGraphBuilder frame, GpuBufferSlice fog) { -+ addParticlesPass(frame, fog, RenderSystem.getModelViewMatrix()); -+ } -+ -+ private void addParticlesPass(FrameGraphBuilder frame, GpuBufferSlice fog, Matrix4f modelViewMatrix) { - FramePass pass = frame.addPass("particles"); - if (this.targets.particles != null) { - this.targets.particles = pass.readsAndWrites(this.targets.particles); -@@ -743,12 +_,24 @@ - this.particlesRenderState.submit(this.submitNodeStorage, this.levelRenderState.cameraRenderState); - this.featureRenderDispatcher.renderAllFeatures(); - this.particlesRenderState.reset(); -+ -+ Profiler.get().push("neoforge_render_after_particles"); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLevelStageEvent.AfterParticles(this, this.levelRenderState, null, modelViewMatrix, this.getRenderableSections())); -+ Profiler.get().pop(); - }); - } - + /** + * @deprecated Neo: use {@link #addCloudsPass(FrameGraphBuilder, CloudStatus, Vec3, long, float, int, float, Matrix4f)} instead + */ @@ -143,11 +118,12 @@ + addCloudsPass(frame, cloudsType, cameraPosition, gameTime, partialTicks, cloudColor, cloudHeight, RenderSystem.getModelViewMatrix()); + } + ++ // Neo: Add modelViewMatrix for use in our event + private void addCloudsPass(FrameGraphBuilder frame, CloudStatus cloudsType, Vec3 cameraPosition, long gameTime, float partialTicks, int cloudColor, float cloudHeight, Matrix4f modelViewMatrix) { FramePass pass = frame.addPass("clouds"); if (this.targets.clouds != null) { this.targets.clouds = pass.readsAndWrites(this.targets.clouds); -@@ -756,10 +_,22 @@ +@@ -739,10 +_,22 @@ this.targets.main = pass.readsAndWrites(this.targets.main); } @@ -171,17 +147,17 @@ int renderDistance = this.minecraft.options.getEffectiveRenderDistance() * 16; float depthFar = this.minecraft.gameRenderer.getDepthFar(); FramePass pass = frame.addPass("weather"); -@@ -773,6 +_,9 @@ +@@ -756,6 +_,9 @@ RenderSystem.setShaderFog(fog); - MultiBufferSource.BufferSource bufferSource = this.renderBuffers.bufferSource(); CameraRenderState cameraState = this.levelRenderState.cameraRenderState; + this.weatherEffectRenderer.render(cameraState.pos, this.levelRenderState.weatherRenderState); + Profiler.get().push("neoforge_render_after_weather"); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLevelStageEvent.AfterWeather(this, this.levelRenderState, null, modelViewMatrix, this.getRenderableSections())); + Profiler.get().pop(); - this.weatherEffectRenderer.render(bufferSource, cameraState.pos, this.levelRenderState.weatherRenderState); this.worldBorderRenderer.render(this.levelRenderState.worldBorderRenderState, cameraState.pos, renderDistance, depthFar); - bufferSource.endBatch(); -@@ -826,7 +_,7 @@ + }); + } +@@ -807,7 +_,7 @@ || camera.isDetached() || camera.entity() instanceof LivingEntity && ((LivingEntity)camera.entity()).isSleeping() ) @@ -190,7 +166,7 @@ if (entity.tickCount == 0) { entity.xOld = entity.getX(); entity.yOld = entity.getY(); -@@ -839,6 +_,9 @@ +@@ -820,6 +_,9 @@ if (state.appearsGlowing() && shouldShowEntityOutlines) { output.haveGlowingEntities = true; } @@ -200,7 +176,7 @@ } } } -@@ -859,12 +_,20 @@ +@@ -842,12 +_,20 @@ } } @@ -221,7 +197,7 @@ for (SectionRenderDispatcher.RenderSection section : this.visibleSections) { List renderableBlockEntities = section.getSectionMesh().getRenderableBlockEntities(); -@@ -882,9 +_,12 @@ +@@ -865,9 +_,12 @@ breakProgress = null; } @@ -235,7 +211,7 @@ } } } -@@ -897,9 +_,12 @@ +@@ -880,9 +_,12 @@ if (blockEntity.isRemoved()) { iterator.remove(); } else { @@ -249,7 +225,7 @@ } } } -@@ -963,19 +_,23 @@ +@@ -946,19 +_,23 @@ BlockPos pos = blockHitResult.getBlockPos(); BlockState state = this.level.getBlockState(pos); if (!state.isAir() && this.level.getWorldBorder().isWithinBounds(pos)) { @@ -276,7 +252,7 @@ } } } -@@ -987,6 +_,13 @@ +@@ -970,6 +_,13 @@ ) { BlockOutlineRenderState state = levelRenderState.blockOutlineRenderState; if (state != null) { @@ -290,7 +266,7 @@ if (state.isTranslucent() == onlyTranslucentBlocks) { Vec3 cameraPos = levelRenderState.cameraRenderState.pos; if (state.highContrast()) { -@@ -1168,7 +_,15 @@ +@@ -1151,7 +_,15 @@ } } @@ -306,7 +282,7 @@ FogType fogType = camera.getFluidInCamera(); if (fogType != FogType.POWDER_SNOW && fogType != FogType.LAVA && !this.doesMobEffectBlockSky(camera)) { SkyRenderState state = this.levelRenderState.skyRenderState; -@@ -1179,6 +_,7 @@ +@@ -1162,6 +_,7 @@ this.targets.main = pass.readsAndWrites(this.targets.main); pass.executes( () -> { @@ -314,7 +290,7 @@ RenderSystem.setShaderFog(skyFog); if (state.skybox == DimensionType.Skybox.END) { skyRenderer.renderEndSky(); -@@ -1197,6 +_,10 @@ +@@ -1180,6 +_,10 @@ skyRenderer.renderDarkDisc(); } } @@ -325,16 +301,16 @@ } ); } -@@ -1419,7 +_,7 @@ +@@ -1402,7 +_,7 @@ } else { int packedBrightness = brightnessGetter.packedBrightness(level, pos); - int block = LightTexture.block(packedBrightness); + int block = LightCoordsUtil.block(packedBrightness); - int blockSelfEmission = state.getLightEmission(); + int blockSelfEmission = state.getLightEmission(level, pos); - if (block < blockSelfEmission) { - int sky = LightTexture.sky(packedBrightness); - return LightTexture.pack(blockSelfEmission, sky); -@@ -1476,6 +_,22 @@ + return block < blockSelfEmission ? LightCoordsUtil.withBlock(packedBrightness, blockSelfEmission) : packedBrightness; + } + } +@@ -1454,6 +_,22 @@ public CloudRenderer getCloudRenderer() { return this.cloudRenderer; diff --git a/patches/net/minecraft/client/renderer/LightTexture.java.patch b/patches/net/minecraft/client/renderer/LightTexture.java.patch deleted file mode 100644 index 669783bbe16..00000000000 --- a/patches/net/minecraft/client/renderer/LightTexture.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/net/minecraft/client/renderer/LightTexture.java -+++ b/net/minecraft/client/renderer/LightTexture.java -@@ -187,4 +_,20 @@ - return pack(block, sky); - } - } -+ -+ // Neo: block and sky only return the integer part. So we add these methods that work with fractional parts too. -+ // A full block or sky value is encoded as `0xij` where i is the integer part and j is the fractional part. -+ // Shifting by 4 then masking with 15 (= 0xF) only returns the integer part. -+ -+ public static int packWithFraction(int block, int sky) { -+ return block | sky << 16; -+ } -+ -+ public static int blockWithFraction(int light) { -+ return light & 0xFF; -+ } -+ -+ public static int skyWithFraction(int light) { -+ return light >>> 16 & 0xFF; -+ } - } diff --git a/patches/net/minecraft/client/renderer/MapRenderer.java.patch b/patches/net/minecraft/client/renderer/MapRenderer.java.patch index 54786305aec..8a098e3d9f1 100644 --- a/patches/net/minecraft/client/renderer/MapRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/MapRenderer.java.patch @@ -11,7 +11,7 @@ poseStack.pushPose(); poseStack.translate(decoration.x / 2.0F + 64.0F, decoration.y / 2.0F + 64.0F, -0.02F); poseStack.mulPose(Axis.ZP.rotationDegrees(decoration.rot * 360 / 16.0F)); -@@ -84,8 +_,9 @@ +@@ -84,13 +_,15 @@ mapRenderState.texture = this.mapTextureManager.prepareMapTexture(mapId, mapData); mapRenderState.decorations.clear(); @@ -22,3 +22,9 @@ } } + private MapRenderState.MapDecorationRenderState extractDecorationRenderState(MapDecoration decoration) { + MapRenderState.MapDecorationRenderState state = new MapRenderState.MapDecorationRenderState(); ++ state.type = decoration.type(); + state.atlasSprite = this.decorationSprites.getSprite(decoration.getSpriteLocation()); + state.x = decoration.x(); + state.y = decoration.y(); diff --git a/patches/net/minecraft/client/renderer/RenderPipelines.java.patch b/patches/net/minecraft/client/renderer/RenderPipelines.java.patch index 02d2b0b8dc5..98da87e4ea2 100644 --- a/patches/net/minecraft/client/renderer/RenderPipelines.java.patch +++ b/patches/net/minecraft/client/renderer/RenderPipelines.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/RenderPipelines.java +++ b/net/minecraft/client/renderer/RenderPipelines.java -@@ -779,4 +_,14 @@ +@@ -769,4 +_,14 @@ public static List getStaticPipelines() { return PIPELINES_BY_LOCATION.values().stream().toList(); } diff --git a/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch b/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch index 3dcda5841cb..df39c4254b2 100644 --- a/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch @@ -55,7 +55,7 @@ + + public static void renderFluid(Minecraft minecraft, PoseStack poseStack, MultiBufferSource bufferSource, Identifier texture) { BlockPos pos = BlockPos.containing(minecraft.player.getX(), minecraft.player.getEyeY(), minecraft.player.getZ()); - float br = LightTexture.getBrightness(minecraft.player.level().dimensionType(), minecraft.player.level().getMaxLocalRawBrightness(pos)); + float br = Lightmap.getBrightness(minecraft.player.level().dimensionType(), minecraft.player.level().getMaxLocalRawBrightness(pos)); int color = ARGB.colorFromFloat(0.1F, br, br, br); @@ -169,7 +_,7 @@ float uo = -minecraft.player.getYRot() / 64.0F; diff --git a/patches/net/minecraft/client/renderer/UiLightmap.java.patch b/patches/net/minecraft/client/renderer/UiLightmap.java.patch new file mode 100644 index 00000000000..cf4a9854647 --- /dev/null +++ b/patches/net/minecraft/client/renderer/UiLightmap.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/client/renderer/UiLightmap.java ++++ b/net/minecraft/client/renderer/UiLightmap.java +@@ -8,11 +_,18 @@ + + @OnlyIn(Dist.CLIENT) + public class UiLightmap implements AutoCloseable { +- private final DynamicTexture texture = new DynamicTexture("UI Lightmap", 1, 1, false); ++ // Neo: change the UI lightmap to match the level lightmap such that special item models and PiP renderers can use ++ // the same light coordinates in level and in UI rendering. (An OOB read will make the vertex transparent). ++ private static final int TEXTURE_SIZE = Lightmap.TEXTURE_SIZE; ++ private final DynamicTexture texture = new DynamicTexture("UI Lightmap", TEXTURE_SIZE, TEXTURE_SIZE, false); + + public UiLightmap() { + NativeImage pixels = this.texture.getPixels(); +- pixels.setPixel(0, 0, -1); ++ for (int i = 0; i < TEXTURE_SIZE; ++i) { ++ for (int j = 0; j < TEXTURE_SIZE; ++j) { ++ pixels.setPixel(i, j, -1); ++ } ++ } + this.texture.upload(); + } + diff --git a/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch b/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch index 6ee0666e0f4..edb62eff855 100644 --- a/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch @@ -1,26 +1,26 @@ --- a/net/minecraft/client/renderer/WeatherEffectRenderer.java +++ b/net/minecraft/client/renderer/WeatherEffectRenderer.java -@@ -91,7 +_,19 @@ - } +@@ -117,7 +_,19 @@ + renderPass.drawIndexed(0, startColumn * 6, columnCount * 6, 1); } + /** -+ * @deprecated Neo: use {@link #render(MultiBufferSource, Vec3, WeatherRenderState, net.minecraft.client.renderer.state.LevelRenderState)} instead ++ * @deprecated Neo: use {@link #render(Vec3, WeatherRenderState, net.minecraft.client.renderer.state.LevelRenderState)} instead + */ + @Deprecated - public void render(MultiBufferSource bufferSource, Vec3 cameraPos, WeatherRenderState renderState) { -+ this.render(bufferSource, cameraPos, renderState, null); + public void render(Vec3 cameraPos, WeatherRenderState renderState) { ++ this.render(cameraPos, renderState, null); + } + -+ public void render(MultiBufferSource bufferSource, Vec3 cameraPos, WeatherRenderState renderState, net.minecraft.client.renderer.state.@org.jspecify.annotations.Nullable LevelRenderState levelRenderState) { -+ if (levelRenderState != null && levelRenderState.customWeatherEffectRenderer != null && levelRenderState.customWeatherEffectRenderer.renderSnowAndRain(levelRenderState, renderState, bufferSource, cameraPos)) { ++ public void render(Vec3 cameraPos, WeatherRenderState renderState, net.minecraft.client.renderer.state.@org.jspecify.annotations.Nullable LevelRenderState levelRenderState) { ++ if (levelRenderState != null && levelRenderState.customWeatherEffectRenderer != null && levelRenderState.customWeatherEffectRenderer.renderSnowAndRain(levelRenderState, renderState, Minecraft.getInstance().renderBuffers().bufferSource(), cameraPos)) { + return; + } + - if (!renderState.rainColumns.isEmpty()) { - RenderType renderType = RenderTypes.weather(RAIN_LOCATION, Minecraft.useShaderTransparency()); - this.renderInstances(bufferSource.getBuffer(renderType), renderState.rainColumns, cameraPos, 1.0F, renderState.radius, renderState.intensity); -@@ -157,6 +_,10 @@ + int columnCount = renderState.rainColumns.size() + renderState.snowColumns.size(); + if (columnCount != 0) { + TextureManager textureManager = Minecraft.getInstance().getTextureManager(); +@@ -220,6 +_,10 @@ } public void tickRainParticles(ClientLevel level, Camera camera, int ticks, ParticleStatus particleStatus, int weatherRadius) { diff --git a/patches/net/minecraft/client/renderer/block/LiquidBlockRenderer.java.patch b/patches/net/minecraft/client/renderer/block/LiquidBlockRenderer.java.patch index 68605103029..83ed7b9b7a4 100644 --- a/patches/net/minecraft/client/renderer/block/LiquidBlockRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/block/LiquidBlockRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/LiquidBlockRenderer.java +++ b/net/minecraft/client/renderer/block/LiquidBlockRenderer.java -@@ -38,12 +_,17 @@ +@@ -39,12 +_,17 @@ this.waterStill = materials.get(ModelBakery.WATER_STILL); this.waterFlowing = materials.get(ModelBakery.WATER_FLOW); this.waterOverlay = materials.get(ModelBakery.WATER_OVERLAY); @@ -18,7 +18,7 @@ private static boolean isFaceOccludedByState(Direction direction, float height, BlockState state) { VoxelShape occluder = state.getFaceOcclusionShape(direction.getOpposite()); if (occluder == Shapes.empty()) { -@@ -65,15 +_,22 @@ +@@ -66,15 +_,22 @@ return isFaceOccludedByState(direction.getOpposite(), 1.0F, state); } @@ -45,7 +45,7 @@ float r = (col >> 16 & 0xFF) / 255.0F; float g = (col >> 8 & 0xFF) / 255.0F; float b = (col & 0xFF) / 255.0F; -@@ -89,13 +_,13 @@ +@@ -90,13 +_,13 @@ FluidState fluidStateWest = blockStateWest.getFluidState(); BlockState blockStateEast = level.getBlockState(pos.relative(Direction.EAST)); FluidState fluidStateEast = blockStateEast.getFluidState(); @@ -65,46 +65,46 @@ if (renderUp || renderDown || renderEast || renderWest || renderNorth || renderSouth) { float c10 = level.getShade(Direction.DOWN, true); float c11 = level.getShade(Direction.UP, true); -@@ -181,15 +_,15 @@ +@@ -182,15 +_,15 @@ float topRed = c11 * r; float topGreen = c11 * g; float topBlue = c11 * b; -- this.vertex(builder, x + 0.0F, y + heightNorthWest, z + 0.0F, topRed, topGreen, topBlue, u00, v00, topColor); -- this.vertex(builder, x + 0.0F, y + heightSouthWest, z + 1.0F, topRed, topGreen, topBlue, u01, v01, topColor); -- this.vertex(builder, x + 1.0F, y + heightSouthEast, z + 1.0F, topRed, topGreen, topBlue, u10, v10, topColor); -- this.vertex(builder, x + 1.0F, y + heightNorthEast, z + 0.0F, topRed, topGreen, topBlue, u11, v11, topColor); -+ this.vertex(builder, x + 0.0F, y + heightNorthWest, z + 0.0F, topRed, topGreen, topBlue, alpha, u00, v00, topColor); -+ this.vertex(builder, x + 0.0F, y + heightSouthWest, z + 1.0F, topRed, topGreen, topBlue, alpha, u01, v01, topColor); -+ this.vertex(builder, x + 1.0F, y + heightSouthEast, z + 1.0F, topRed, topGreen, topBlue, alpha, u10, v10, topColor); -+ this.vertex(builder, x + 1.0F, y + heightNorthEast, z + 0.0F, topRed, topGreen, topBlue, alpha, u11, v11, topColor); +- this.vertex(builder, x + 0.0F, y + heightNorthWest, z + 0.0F, topRed, topGreen, topBlue, u00, v00, topLightCoords); +- this.vertex(builder, x + 0.0F, y + heightSouthWest, z + 1.0F, topRed, topGreen, topBlue, u01, v01, topLightCoords); +- this.vertex(builder, x + 1.0F, y + heightSouthEast, z + 1.0F, topRed, topGreen, topBlue, u10, v10, topLightCoords); +- this.vertex(builder, x + 1.0F, y + heightNorthEast, z + 0.0F, topRed, topGreen, topBlue, u11, v11, topLightCoords); ++ this.vertex(builder, x + 0.0F, y + heightNorthWest, z + 0.0F, topRed, topGreen, topBlue, alpha, u00, v00, topLightCoords); ++ this.vertex(builder, x + 0.0F, y + heightSouthWest, z + 1.0F, topRed, topGreen, topBlue, alpha, u01, v01, topLightCoords); ++ this.vertex(builder, x + 1.0F, y + heightSouthEast, z + 1.0F, topRed, topGreen, topBlue, alpha, u10, v10, topLightCoords); ++ this.vertex(builder, x + 1.0F, y + heightNorthEast, z + 0.0F, topRed, topGreen, topBlue, alpha, u11, v11, topLightCoords); if (fluidState.shouldRenderBackwardUpFace(level, pos.above())) { -- this.vertex(builder, x + 0.0F, y + heightNorthWest, z + 0.0F, topRed, topGreen, topBlue, u00, v00, topColor); -- this.vertex(builder, x + 1.0F, y + heightNorthEast, z + 0.0F, topRed, topGreen, topBlue, u11, v11, topColor); -- this.vertex(builder, x + 1.0F, y + heightSouthEast, z + 1.0F, topRed, topGreen, topBlue, u10, v10, topColor); -- this.vertex(builder, x + 0.0F, y + heightSouthWest, z + 1.0F, topRed, topGreen, topBlue, u01, v01, topColor); -+ this.vertex(builder, x + 0.0F, y + heightNorthWest, z + 0.0F, topRed, topGreen, topBlue, alpha, u00, v00, topColor); -+ this.vertex(builder, x + 1.0F, y + heightNorthEast, z + 0.0F, topRed, topGreen, topBlue, alpha, u11, v11, topColor); -+ this.vertex(builder, x + 1.0F, y + heightSouthEast, z + 1.0F, topRed, topGreen, topBlue, alpha, u10, v10, topColor); -+ this.vertex(builder, x + 0.0F, y + heightSouthWest, z + 1.0F, topRed, topGreen, topBlue, alpha, u01, v01, topColor); +- this.vertex(builder, x + 0.0F, y + heightNorthWest, z + 0.0F, topRed, topGreen, topBlue, u00, v00, topLightCoords); +- this.vertex(builder, x + 1.0F, y + heightNorthEast, z + 0.0F, topRed, topGreen, topBlue, u11, v11, topLightCoords); +- this.vertex(builder, x + 1.0F, y + heightSouthEast, z + 1.0F, topRed, topGreen, topBlue, u10, v10, topLightCoords); +- this.vertex(builder, x + 0.0F, y + heightSouthWest, z + 1.0F, topRed, topGreen, topBlue, u01, v01, topLightCoords); ++ this.vertex(builder, x + 0.0F, y + heightNorthWest, z + 0.0F, topRed, topGreen, topBlue, alpha, u00, v00, topLightCoords); ++ this.vertex(builder, x + 1.0F, y + heightNorthEast, z + 0.0F, topRed, topGreen, topBlue, alpha, u11, v11, topLightCoords); ++ this.vertex(builder, x + 1.0F, y + heightSouthEast, z + 1.0F, topRed, topGreen, topBlue, alpha, u10, v10, topLightCoords); ++ this.vertex(builder, x + 0.0F, y + heightSouthWest, z + 1.0F, topRed, topGreen, topBlue, alpha, u01, v01, topLightCoords); } } -@@ -202,10 +_,10 @@ +@@ -203,10 +_,10 @@ float belowRed = c10 * r; float belowGreen = c10 * g; float belowBlue = c10 * b; -- this.vertex(builder, x, y + bottomOffs, z + 1.0F, belowRed, belowGreen, belowBlue, u0, v1, belowColor); -- this.vertex(builder, x, y + bottomOffs, z, belowRed, belowGreen, belowBlue, u0, v0, belowColor); -- this.vertex(builder, x + 1.0F, y + bottomOffs, z, belowRed, belowGreen, belowBlue, u1, v0, belowColor); -- this.vertex(builder, x + 1.0F, y + bottomOffs, z + 1.0F, belowRed, belowGreen, belowBlue, u1, v1, belowColor); -+ this.vertex(builder, x, y + bottomOffs, z + 1.0F, belowRed, belowGreen, belowBlue, alpha, u0, v1, belowColor); -+ this.vertex(builder, x, y + bottomOffs, z, belowRed, belowGreen, belowBlue, alpha, u0, v0, belowColor); -+ this.vertex(builder, x + 1.0F, y + bottomOffs, z, belowRed, belowGreen, belowBlue, alpha, u1, v0, belowColor); -+ this.vertex(builder, x + 1.0F, y + bottomOffs, z + 1.0F, belowRed, belowGreen, belowBlue, alpha, u1, v1, belowColor); +- this.vertex(builder, x, y + bottomOffs, z + 1.0F, belowRed, belowGreen, belowBlue, u0, v1, belowLightCoords); +- this.vertex(builder, x, y + bottomOffs, z, belowRed, belowGreen, belowBlue, u0, v0, belowLightCoords); +- this.vertex(builder, x + 1.0F, y + bottomOffs, z, belowRed, belowGreen, belowBlue, u1, v0, belowLightCoords); +- this.vertex(builder, x + 1.0F, y + bottomOffs, z + 1.0F, belowRed, belowGreen, belowBlue, u1, v1, belowLightCoords); ++ this.vertex(builder, x, y + bottomOffs, z + 1.0F, belowRed, belowGreen, belowBlue, alpha, u0, v1, belowLightCoords); ++ this.vertex(builder, x, y + bottomOffs, z, belowRed, belowGreen, belowBlue, alpha, u0, v0, belowLightCoords); ++ this.vertex(builder, x + 1.0F, y + bottomOffs, z, belowRed, belowGreen, belowBlue, alpha, u1, v0, belowLightCoords); ++ this.vertex(builder, x + 1.0F, y + bottomOffs, z + 1.0F, belowRed, belowGreen, belowBlue, alpha, u1, v1, belowLightCoords); } - int sideColor = this.getLightColor(level, pos); -@@ -259,10 +_,9 @@ + int sideLightCoords = this.getLightCoords(level, pos); +@@ -260,10 +_,9 @@ if (renderCondition && !isFaceOccludedByNeighbor(faceDir, Math.max(hh0, hh1), level.getBlockState(pos.relative(faceDir)))) { BlockPos tPos = pos.relative(faceDir); TextureAtlasSprite sprite = flowingSprite; @@ -118,31 +118,31 @@ } } -@@ -275,15 +_,15 @@ +@@ -276,15 +_,15 @@ float red = c11 * br * r; float green = c11 * br * g; float blue = c11 * br * b; -- this.vertex(builder, x0, y + hh0, z0, red, green, blue, u0, v01x, sideColor); -- this.vertex(builder, x1, y + hh1, z1, red, green, blue, u1, v02, sideColor); -- this.vertex(builder, x1, y + bottomOffs, z1, red, green, blue, u1, v1, sideColor); -- this.vertex(builder, x0, y + bottomOffs, z0, red, green, blue, u0, v1, sideColor); -+ this.vertex(builder, x0, y + hh0, z0, red, green, blue, alpha, u0, v01x, sideColor); -+ this.vertex(builder, x1, y + hh1, z1, red, green, blue, alpha, u1, v02, sideColor); -+ this.vertex(builder, x1, y + bottomOffs, z1, red, green, blue, alpha, u1, v1, sideColor); -+ this.vertex(builder, x0, y + bottomOffs, z0, red, green, blue, alpha, u0, v1, sideColor); +- this.vertex(builder, x0, y + hh0, z0, red, green, blue, u0, v01x, sideLightCoords); +- this.vertex(builder, x1, y + hh1, z1, red, green, blue, u1, v02, sideLightCoords); +- this.vertex(builder, x1, y + bottomOffs, z1, red, green, blue, u1, v1, sideLightCoords); +- this.vertex(builder, x0, y + bottomOffs, z0, red, green, blue, u0, v1, sideLightCoords); ++ this.vertex(builder, x0, y + hh0, z0, red, green, blue, alpha, u0, v01x, sideLightCoords); ++ this.vertex(builder, x1, y + hh1, z1, red, green, blue, alpha, u1, v02, sideLightCoords); ++ this.vertex(builder, x1, y + bottomOffs, z1, red, green, blue, alpha, u1, v1, sideLightCoords); ++ this.vertex(builder, x0, y + bottomOffs, z0, red, green, blue, alpha, u0, v1, sideLightCoords); if (sprite != this.waterOverlay) { -- this.vertex(builder, x0, y + bottomOffs, z0, red, green, blue, u0, v1, sideColor); -- this.vertex(builder, x1, y + bottomOffs, z1, red, green, blue, u1, v1, sideColor); -- this.vertex(builder, x1, y + hh1, z1, red, green, blue, u1, v02, sideColor); -- this.vertex(builder, x0, y + hh0, z0, red, green, blue, u0, v01x, sideColor); -+ this.vertex(builder, x0, y + bottomOffs, z0, red, green, blue, alpha, u0, v1, sideColor); -+ this.vertex(builder, x1, y + bottomOffs, z1, red, green, blue, alpha, u1, v1, sideColor); -+ this.vertex(builder, x1, y + hh1, z1, red, green, blue, alpha, u1, v02, sideColor); -+ this.vertex(builder, x0, y + hh0, z0, red, green, blue, alpha, u0, v01x, sideColor); +- this.vertex(builder, x0, y + bottomOffs, z0, red, green, blue, u0, v1, sideLightCoords); +- this.vertex(builder, x1, y + bottomOffs, z1, red, green, blue, u1, v1, sideLightCoords); +- this.vertex(builder, x1, y + hh1, z1, red, green, blue, u1, v02, sideLightCoords); +- this.vertex(builder, x0, y + hh0, z0, red, green, blue, u0, v01x, sideLightCoords); ++ this.vertex(builder, x0, y + bottomOffs, z0, red, green, blue, alpha, u0, v1, sideLightCoords); ++ this.vertex(builder, x1, y + bottomOffs, z1, red, green, blue, alpha, u1, v1, sideLightCoords); ++ this.vertex(builder, x1, y + hh1, z1, red, green, blue, alpha, u1, v02, sideLightCoords); ++ this.vertex(builder, x0, y + hh0, z0, red, green, blue, alpha, u0, v01x, sideLightCoords); } } } -@@ -324,6 +_,26 @@ +@@ -325,6 +_,26 @@ private float getHeight(BlockAndTintGetter level, Fluid fluidType, BlockPos pos) { BlockState state = level.getBlockState(pos); return this.getHeight(level, fluidType, pos, state, state.getFluidState()); diff --git a/patches/net/minecraft/client/renderer/block/ModelBlockRenderer.java.patch b/patches/net/minecraft/client/renderer/block/ModelBlockRenderer.java.patch index 38a5f3a3a2b..d355d927659 100644 --- a/patches/net/minecraft/client/renderer/block/ModelBlockRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/block/ModelBlockRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/ModelBlockRenderer.java +++ b/net/minecraft/client/renderer/block/ModelBlockRenderer.java -@@ -38,6 +_,7 @@ +@@ -40,6 +_,7 @@ this.blockColors = blockColors; } @@ -8,7 +8,7 @@ public void tesselateBlock( BlockAndTintGetter level, List parts, -@@ -45,18 +_,36 @@ +@@ -47,18 +_,36 @@ BlockPos pos, PoseStack poseStack, VertexConsumer builder, @@ -48,7 +48,7 @@ } } catch (Throwable var13) { CrashReport report = CrashReport.forThrowable(var13, "Tesselating block model"); -@@ -68,6 +_,8 @@ +@@ -70,6 +_,8 @@ } } @@ -57,7 +57,7 @@ private static boolean shouldRenderFace(BlockAndTintGetter level, BlockState state, boolean cullEnabled, Direction direction, BlockPos neighborPos) { if (!cullEnabled) { return true; -@@ -77,6 +_,16 @@ +@@ -79,6 +_,16 @@ } } @@ -74,7 +74,7 @@ public void tesselateWithAO( BlockAndTintGetter level, List parts, -@@ -87,11 +_,39 @@ +@@ -89,11 +_,39 @@ boolean cull, int overlayCoords ) { @@ -115,7 +115,7 @@ for (Direction direction : DIRECTIONS) { int cacheMask = 1 << direction.ordinal(); boolean validCacheForDirection = (cacheValid & cacheMask) == 1; -@@ -100,7 +_,7 @@ +@@ -102,7 +_,7 @@ List culledQuads = part.getQuads(direction); if (!culledQuads.isEmpty()) { if (!validCacheForDirection) { @@ -124,12 +124,12 @@ cacheValid |= cacheMask; if (shouldRenderFace) { shouldRenderFaceCache |= cacheMask; -@@ -108,6 +_,12 @@ +@@ -110,6 +_,12 @@ } if (shouldRenderFace) { + if (!ao) { -+ int light = scratch.cache.getLightColor(state, level, scratch.scratchPos.setWithOffset(pos, direction)); ++ int light = scratch.cache.getLightCoords(state, level, scratch.scratchPos.setWithOffset(pos, direction)); + this.renderModelFaceFlat( + level, state, pos, light, overlayCoords, false, poseStack, builder, culledQuads, scratch + ); @@ -137,7 +137,7 @@ this.renderModelFaceAO(level, state, pos, poseStack, builder, culledQuads, scratch, overlayCoords); } } -@@ -116,11 +_,17 @@ +@@ -118,11 +_,17 @@ List unculledQuads = part.getQuads(null); if (!unculledQuads.isEmpty()) { @@ -155,7 +155,7 @@ public void tesselateWithoutAO( BlockAndTintGetter level, List parts, -@@ -128,6 +_,19 @@ +@@ -130,6 +_,19 @@ BlockPos pos, PoseStack poseStack, VertexConsumer builder, @@ -175,7 +175,7 @@ boolean cull, int overlayCoords ) { -@@ -136,6 +_,7 @@ +@@ -138,6 +_,7 @@ int shouldRenderFaceCache = 0; for (BlockModelPart part : parts) { @@ -183,7 +183,7 @@ for (Direction direction : DIRECTIONS) { int cacheMask = 1 << direction.ordinal(); boolean validCacheForDirection = (cacheValid & cacheMask) == 1; -@@ -145,7 +_,7 @@ +@@ -147,7 +_,7 @@ if (!culledQuads.isEmpty()) { BlockPos relativePos = scratch.scratchPos.setWithOffset(pos, direction); if (!validCacheForDirection) { @@ -192,7 +192,7 @@ cacheValid |= cacheMask; if (shouldRenderFace) { shouldRenderFaceCache |= cacheMask; -@@ -178,7 +_,12 @@ +@@ -180,7 +_,12 @@ int overlayCoords ) { for (BakedQuad quad : quads) { @@ -205,11 +205,11 @@ storage.calculate(level, state, pos, quad.direction(), quad.shade()); this.putQuadData(level, state, pos, builder, poseStack.last(), quad, storage, overlayCoords); } -@@ -288,17 +_,30 @@ +@@ -290,17 +_,30 @@ ModelBlockRenderer.CommonRenderStorage shapeState ) { for (BakedQuad quad : quads) { -+ renderModelQuadFlat(level, state, pos, lightColor, overlayCoords, checkLight, poseStack, builder, quad, shapeState); ++ renderModelQuadFlat(level, state, pos, lightCoords, overlayCoords, checkLight, poseStack, builder, quad, shapeState); + } + } + @@ -217,7 +217,7 @@ + BlockAndTintGetter level, + BlockState state, + BlockPos pos, -+ int lightColor, ++ int lightCoords, + int overlayCoords, + boolean checkLight, + PoseStack poseStack, @@ -229,7 +229,7 @@ if (checkLight) { calculateShape(level, state, pos, quad, shapeState); BlockPos lightPos = (BlockPos)(shapeState.faceCubic ? shapeState.scratchPos.setWithOffset(pos, quad.direction()) : pos); - lightColor = shapeState.cache.getLightColor(state, level, lightPos); + lightCoords = shapeState.cache.getLightCoords(state, level, lightPos); } - float directionalBrightness = level.getShade(quad.direction(), quad.shade()); @@ -238,10 +238,10 @@ - shapeState.brightness[2] = directionalBrightness; - shapeState.brightness[3] = directionalBrightness; + net.neoforged.neoforge.client.model.ao.EnhancedAoRenderStorage.applyFlatQuadBrightness(level, quad, shapeState); - shapeState.lightmap[0] = lightColor; - shapeState.lightmap[1] = lightColor; - shapeState.lightmap[2] = lightColor; -@@ -307,10 +_,18 @@ + shapeState.lightmap[0] = lightCoords; + shapeState.lightmap[1] = lightCoords; + shapeState.lightmap[2] = lightCoords; +@@ -309,10 +_,18 @@ } } @@ -261,7 +261,7 @@ for (Direction direction : DIRECTIONS) { renderQuadList(pose, builder, r, g, b, part.getQuads(direction), lightCoords, overlayCoords); } -@@ -664,6 +_,9 @@ +@@ -666,6 +_,9 @@ public AmbientOcclusionRenderStorage() { } 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 ec33c180394..8775eea8569 100644 --- a/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/model/BlockModel.java +++ b/net/minecraft/client/renderer/block/model/BlockModel.java -@@ -27,21 +_,48 @@ +@@ -27,22 +_,49 @@ @Nullable Boolean ambientOcclusion, @Nullable ItemTransforms transforms, TextureSlots.Data textureSlots, @@ -29,6 +29,7 @@ return GsonHelper.fromJson(GSON, reader, BlockModel.class); } + @OnlyIn(Dist.CLIENT) + public BlockModel( + @Nullable UnbakedGeometry geometry, + UnbakedModel.@Nullable GuiLight guiLight, @@ -47,9 +48,9 @@ + net.neoforged.neoforge.client.model.NeoForgeModelProperties.fillPartVisibilityProperty(propertiesBuilder, this.partVisibility); + } + - @OnlyIn(Dist.CLIENT) public static class Deserializer implements JsonDeserializer { public BlockModel deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + JsonObject object = json.getAsJsonObject(); @@ -62,7 +_,12 @@ } diff --git a/patches/net/minecraft/client/renderer/block/model/BlockStateModel.java.patch b/patches/net/minecraft/client/renderer/block/model/BlockStateModel.java.patch index f7eeb1442fd..1664ddc00df 100644 --- a/patches/net/minecraft/client/renderer/block/model/BlockStateModel.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/BlockStateModel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/model/BlockStateModel.java +++ b/net/minecraft/client/renderer/block/model/BlockStateModel.java -@@ -22,14 +_,20 @@ +@@ -23,14 +_,20 @@ @OnlyIn(Dist.CLIENT) public interface BlockStateModel extends net.neoforged.neoforge.client.extensions.BlockStateModelExtension { @@ -21,7 +21,7 @@ TextureAtlasSprite particleIcon(); @OnlyIn(Dist.CLIENT) -@@ -67,30 +_,41 @@ +@@ -72,30 +_,41 @@ i -> i.group(Variant.MAP_CODEC.forGetter(Weighted::value), ExtraCodecs.POSITIVE_INT.optionalFieldOf("weight", 1).forGetter(Weighted::weight)) .apply(i, Weighted::new) ); 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 1a4e0d38204..202ea9461b5 100644 --- a/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch @@ -21,3 +21,42 @@ ); } +@@ -179,6 +_,11 @@ + } + + public static void recalculateWinding(Vector3fc[] positions, long[] uvs, Direction direction) { ++ recalculateWinding(positions, uvs, direction, null, null); ++ } ++ ++ // Neo: Allow swapping colors and normals alongside the positions/uvs ++ public static void recalculateWinding(Vector3fc[] positions, long[] uvs, Direction direction, int @Nullable [] colors, int @Nullable [] normals) { + float minX = 999.0F; + float minY = 999.0F; + float minZ = 999.0F; +@@ -231,6 +_,12 @@ + if (vertexToSwap != vertex) { + swap(positions, vertexToSwap, vertex); + swap(uvs, vertexToSwap, vertex); ++ if (colors != null) { ++ swap(colors, vertexToSwap, vertex); ++ } ++ if (normals != null) { ++ swap(normals, vertexToSwap, vertex); ++ } + } + } + } +@@ -254,6 +_,13 @@ + + private static void swap(long[] array, int indexA, int indexB) { + long tmp = array[indexA]; ++ array[indexA] = array[indexB]; ++ array[indexB] = tmp; ++ } ++ ++ // Neo: Used by the winding patch to swap colors/normals ++ private static void swap(int[] array, int indexA, int indexB) { ++ int tmp = array[indexA]; + array[indexA] = array[indexB]; + array[indexB] = tmp; + } diff --git a/patches/net/minecraft/client/renderer/block/model/multipart/MultiPartModel.java.patch b/patches/net/minecraft/client/renderer/block/model/multipart/MultiPartModel.java.patch index 089a1e2e9fd..14e8171d3b9 100644 --- a/patches/net/minecraft/client/renderer/block/model/multipart/MultiPartModel.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/multipart/MultiPartModel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/model/multipart/MultiPartModel.java +++ b/net/minecraft/client/renderer/block/model/multipart/MultiPartModel.java -@@ -36,8 +_,9 @@ +@@ -37,8 +_,9 @@ return this.shared.particleIcon; } @@ -11,7 +11,7 @@ if (this.models == null) { this.models = this.shared.selectModels(this.blockState); } -@@ -46,9 +_,36 @@ +@@ -47,9 +_,36 @@ for (BlockStateModel model : this.models) { random.setSeed(seed); @@ -51,7 +51,7 @@ @OnlyIn(Dist.CLIENT) public record Selector(Predicate condition, T model) { -@@ -85,7 +_,6 @@ +@@ -86,7 +_,6 @@ selectedModels.set(i); } } diff --git a/patches/net/minecraft/client/renderer/blockentity/ChestRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/ChestRenderer.java.patch index a29aa773418..c7c8728a7a4 100644 --- a/patches/net/minecraft/client/renderer/blockentity/ChestRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/ChestRenderer.java.patch @@ -18,9 +18,9 @@ RenderType renderType = material.renderType(RenderTypes::entityCutout); TextureAtlasSprite sprite = this.materials.get(material); if (state.type != ChestType.SINGLE) { -@@ -126,5 +_,20 @@ +@@ -124,5 +_,20 @@ } else { - return ChestRenderState.ChestMaterialType.REGULAR; + return entity instanceof TrappedChestBlockEntity ? ChestRenderState.ChestMaterialType.TRAPPED : ChestRenderState.ChestMaterialType.REGULAR; } + } + diff --git a/patches/net/minecraft/client/renderer/chunk/RenderSectionRegion.java.patch b/patches/net/minecraft/client/renderer/chunk/RenderSectionRegion.java.patch index ed6f4048e5a..7d2779332b3 100644 --- a/patches/net/minecraft/client/renderer/chunk/RenderSectionRegion.java.patch +++ b/patches/net/minecraft/client/renderer/chunk/RenderSectionRegion.java.patch @@ -40,7 +40,7 @@ + + @Override + public net.neoforged.neoforge.common.world.AuxiliaryLightManager getAuxLightManager(net.minecraft.world.level.ChunkPos pos) { -+ return this.getSection(pos.x, this.minSectionY, pos.z).wrapped.getAuxLightManager(pos); ++ return this.getSection(pos.x(), this.minSectionY, pos.z()).wrapped.getAuxLightManager(pos); } public static int index(int minSectionX, int minSectionY, int minSectionZ, int sectionX, int sectionY, int sectionZ) { diff --git a/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch b/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch index 295364235b3..1cb697fbb0d 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 -@@ -347,9 +_,10 @@ +@@ -353,9 +_,10 @@ public SectionRenderDispatcher.RenderSection.CompileTask createCompileTask(RenderRegionCache cache) { this.cancelTasks(); @@ -12,7 +12,7 @@ return this.lastRebuildTask; } -@@ -376,6 +_,15 @@ +@@ -382,6 +_,15 @@ ); } @@ -27,8 +27,8 @@ + @OnlyIn(Dist.CLIENT) public abstract class CompileTask { - protected final AtomicBoolean isCancelled = new AtomicBoolean(false); -@@ -404,10 +_,18 @@ + protected final AtomicBoolean isCancelled; +@@ -414,11 +_,19 @@ @OnlyIn(Dist.CLIENT) private class RebuildTask extends SectionRenderDispatcher.RenderSection.CompileTask { protected final RenderSectionRegion region; @@ -41,13 +41,14 @@ + } + + public RebuildTask(RenderSectionRegion region, boolean isRecompile, java.util.List additionalRenderers) { + Objects.requireNonNull(RenderSection.this); super(isRecompile); this.region = region; + this.additionalRenderers = additionalRenderers; } @Override -@@ -428,7 +_,7 @@ +@@ -439,7 +_,7 @@ SectionCompiler.Results results; try (Zone ignored = Profiler.get().zone("Compile Section")) { results = SectionRenderDispatcher.this.sectionCompiler diff --git a/patches/net/minecraft/client/renderer/debug/DebugRenderer.java.patch b/patches/net/minecraft/client/renderer/debug/DebugRenderer.java.patch new file mode 100644 index 00000000000..580ea21a518 --- /dev/null +++ b/patches/net/minecraft/client/renderer/debug/DebugRenderer.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/client/renderer/debug/DebugRenderer.java ++++ b/net/minecraft/client/renderer/debug/DebugRenderer.java +@@ -137,6 +_,9 @@ + } + + this.renderers.add(new ChunkCullingDebugRenderer(minecraft)); ++ ++ // Neo: Allow registering custom debug renderers ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterDebugRenderersEvent(factory -> renderers.add(factory.apply(minecraft)))); + } + + public void emitGizmos(Frustum frustum, double camX, double camY, double camZ, float partialTicks) { diff --git a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch index 8d7b277f15d..bd54ed0d5fa 100644 --- a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/entity/EntityRenderer.java +++ b/net/minecraft/client/renderer/entity/EntityRenderer.java -@@ -121,6 +_,8 @@ +@@ -122,6 +_,8 @@ protected void submitNameTag(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { if (state.nameTag != null) { @@ -9,7 +9,15 @@ submitNodeCollector.submitNameTag( poseStack, state.nameTagAttachment, 0, state.nameTag, !state.isDiscrete, state.lightCoords, state.distanceToCameraSq, camera ); -@@ -154,6 +_,7 @@ +@@ -146,6 +_,7 @@ + S state = this.createRenderState(); + this.extractRenderState(entity, state, partialTicks); + this.finalizeRenderState(entity, state); ++ net.neoforged.neoforge.client.renderstate.RenderStateExtensions.onUpdateEntityRenderState(this, entity, state); + return state; + } + +@@ -155,6 +_,7 @@ state.y = Mth.lerp((double)partialTicks, entity.yOld, entity.getY()); state.z = Mth.lerp((double)partialTicks, entity.zOld, entity.getZ()); state.isInvisible = entity.isInvisible(); @@ -17,12 +25,13 @@ state.ageInTicks = entity.tickCount + partialTicks; state.boundingBoxWidth = entity.getBbWidth(); state.boundingBoxHeight = entity.getBbHeight(); -@@ -172,9 +_,10 @@ +@@ -173,9 +_,11 @@ if (this.entityRenderDispatcher.camera != null) { state.distanceToCameraSq = this.entityRenderDispatcher.distanceToSqr(entity); - boolean shouldShowName = state.distanceToCameraSq < 4096.0 && this.shouldShowName(entity, state.distanceToCameraSq); + var event = new net.neoforged.neoforge.client.event.RenderNameTagEvent.CanRender(entity, state, this.getNameTag(entity), this, partialTicks); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event); + boolean shouldShowName = event.canRender().isTrue() || (event.canRender().isDefault() && state.distanceToCameraSq < 4096.0 && this.shouldShowName(entity, state.distanceToCameraSq)); if (shouldShowName) { - state.nameTag = this.getNameTag(entity); diff --git a/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch index 9608ac0e0a8..4ab8489e1b5 100644 --- a/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/entity/ItemFrameRenderer.java +++ b/net/minecraft/client/renderer/entity/ItemFrameRenderer.java -@@ -94,6 +_,7 @@ +@@ -92,6 +_,7 @@ poseStack.translate(0.0F, 0.0F, 0.4375F); } @@ -8,7 +8,7 @@ if (state.mapId != null) { int rotation = state.rotation % 4 * 2; poseStack.mulPose(Axis.ZP.rotationDegrees(rotation * 360.0F / 8.0F)); -@@ -110,6 +_,7 @@ +@@ -108,6 +_,7 @@ poseStack.scale(0.5F, 0.5F, 0.5F); state.item.submit(poseStack, submitNodeCollector, lightVal, OverlayTexture.NO_OVERLAY, state.outlineColor); } @@ -16,7 +16,7 @@ poseStack.popPose(); } -@@ -145,7 +_,7 @@ +@@ -143,7 +_,7 @@ if (!itemStack.isEmpty()) { MapId framedMapId = entity.getFramedMapId(itemStack); if (framedMapId != null) { diff --git a/patches/net/minecraft/client/renderer/feature/BlockFeatureRenderer.java.patch b/patches/net/minecraft/client/renderer/feature/BlockFeatureRenderer.java.patch index 5eb7a7a5bdf..39ae1e17d76 100644 --- a/patches/net/minecraft/client/renderer/feature/BlockFeatureRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/feature/BlockFeatureRenderer.java.patch @@ -1,21 +1,21 @@ --- a/net/minecraft/client/renderer/feature/BlockFeatureRenderer.java +++ b/net/minecraft/client/renderer/feature/BlockFeatureRenderer.java -@@ -31,7 +_,7 @@ - MovingBlockRenderState movingBlockRenderState = submit.movingBlockRenderState(); - BlockState blockState = movingBlockRenderState.blockState; - List parts = blockRenderDispatcher.getBlockModel(blockState) -- .collectParts(RandomSource.create(blockState.getSeed(movingBlockRenderState.randomSeedPos))); -+ .collectParts(movingBlockRenderState.level, movingBlockRenderState.blockPos, movingBlockRenderState.blockState, RandomSource.create(blockState.getSeed(movingBlockRenderState.randomSeedPos))); - PoseStack poseStack = new PoseStack(); - poseStack.mulPose(submit.pose()); - blockRenderDispatcher.getModelRenderer() -@@ -41,7 +_,8 @@ - blockState, - movingBlockRenderState.blockPos, - poseStack, -- bufferSource.getBuffer(ItemBlockRenderTypes.getMovingBlockRenderType(blockState)), -+ // TODO: this needs further thought as it violates the "one submit == one rendertype" contract -+ renderType -> bufferSource.getBuffer(net.neoforged.neoforge.client.RenderTypeHelper.getMovingBlockRenderType(renderType)), - false, - OverlayTexture.NO_OVERLAY - ); +@@ -53,7 +_,7 @@ + RenderType renderType = ItemBlockRenderTypes.getMovingBlockRenderType(blockState); + if (renderType.hasBlending() == translucent) { + List parts = blockRenderDispatcher.getBlockModel(blockState) +- .collectParts(RandomSource.create(blockState.getSeed(movingBlockRenderState.randomSeedPos))); ++ .collectParts(movingBlockRenderState.level, movingBlockRenderState.blockPos, movingBlockRenderState.blockState, RandomSource.create(blockState.getSeed(movingBlockRenderState.randomSeedPos))); + PoseStack poseStack = new PoseStack(); + poseStack.mulPose(submit.pose()); + blockRenderDispatcher.getModelRenderer() +@@ -63,7 +_,8 @@ + blockState, + movingBlockRenderState.blockPos, + poseStack, +- bufferSource.getBuffer(renderType), ++ // TODO: this needs further thought as it violates the "one submit == one rendertype" contract ++ partRenderType -> bufferSource.getBuffer(net.neoforged.neoforge.client.RenderTypeHelper.getMovingBlockRenderType(partRenderType)), + false, + OverlayTexture.NO_OVERLAY + ); diff --git a/patches/net/minecraft/client/renderer/state/LevelRenderState.java.patch b/patches/net/minecraft/client/renderer/state/LevelRenderState.java.patch index fd1000b1771..1c884107021 100644 --- a/patches/net/minecraft/client/renderer/state/LevelRenderState.java.patch +++ b/patches/net/minecraft/client/renderer/state/LevelRenderState.java.patch @@ -9,17 +9,17 @@ public CameraRenderState cameraRenderState = new CameraRenderState(); public final List entityRenderStates = new ArrayList<>(); public final List blockEntityRenderStates = new ArrayList<>(); -@@ -20,6 +_,9 @@ - public final WorldBorderRenderState worldBorderRenderState = new WorldBorderRenderState(); +@@ -21,6 +_,9 @@ public final SkyRenderState skyRenderState = new SkyRenderState(); public long gameTime; + public int lastEntityRenderStateCount; + public net.neoforged.neoforge.client.@Nullable CustomSkyboxRenderer customSkyboxRenderer; + public net.neoforged.neoforge.client.@Nullable CustomCloudsRenderer customCloudsRenderer; + public net.neoforged.neoforge.client.@Nullable CustomWeatherEffectRenderer customWeatherEffectRenderer; public void reset() { this.entityRenderStates.clear(); -@@ -31,5 +_,9 @@ +@@ -32,5 +_,9 @@ this.worldBorderRenderState.reset(); this.skyRenderState.reset(); this.gameTime = 0L; diff --git a/patches/net/minecraft/client/renderer/texture/MipmapGenerator.java.patch b/patches/net/minecraft/client/renderer/texture/MipmapGenerator.java.patch deleted file mode 100644 index aabff38209e..00000000000 --- a/patches/net/minecraft/client/renderer/texture/MipmapGenerator.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/net/minecraft/client/renderer/texture/MipmapGenerator.java -+++ b/net/minecraft/client/renderer/texture/MipmapGenerator.java -@@ -116,12 +_,15 @@ - float cutoutRef = mipmapStrategy == MipmapStrategy.STRICT_CUTOUT ? 0.3F : 0.5F; - float originalCoverage = isCutoutMip ? alphaTestCoverage(currentMips[0], cutoutRef, 1.0F) : 0.0F; - -+ int maxMipmapLevel = net.neoforged.neoforge.client.ClientHooks.getMaxMipmapLevel(result[0].getWidth(), result[0].getHeight()); - for (int level = 1; level <= newMipLevel; level++) { - if (level < currentMips.length) { - result[level] = currentMips[level]; - } else { - NativeImage lastData = result[level - 1]; -- NativeImage data = new NativeImage(lastData.getWidth() >> 1, lastData.getHeight() >> 1, false); -+ // Forge: Guard against invalid texture size, because we allow generating mipmaps regardless of texture sizes -+ NativeImage data = new NativeImage(Math.max(1, lastData.getWidth() >> 1), Math.max(1, lastData.getHeight() >> 1), false); -+ if (level <= maxMipmapLevel) { - int width = data.getWidth(); - int height = data.getHeight(); - -@@ -140,6 +_,7 @@ - - data.setPixel(x, y, color); - } -+ } - } - - result[level] = data; diff --git a/patches/net/minecraft/client/renderer/texture/SpriteContents.java.patch b/patches/net/minecraft/client/renderer/texture/SpriteContents.java.patch index 181961fac68..001b57a975b 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 -@@ -78,6 +_,10 @@ +@@ -79,6 +_,10 @@ this.alphaCutoffBias = textureInfo.map(TextureMetadataSection::alphaCutoffBias).orElse(0.0F); } diff --git a/patches/net/minecraft/client/renderer/texture/SpriteLoader.java.patch b/patches/net/minecraft/client/renderer/texture/SpriteLoader.java.patch index 27e23a2a172..fc8f64b45ae 100644 --- a/patches/net/minecraft/client/renderer/texture/SpriteLoader.java.patch +++ b/patches/net/minecraft/client/renderer/texture/SpriteLoader.java.patch @@ -1,14 +1,5 @@ --- a/net/minecraft/client/renderer/texture/SpriteLoader.java +++ b/net/minecraft/client/renderer/texture/SpriteLoader.java -@@ -72,7 +_,7 @@ - int minSize = Math.min(minTexelSize, lowestOneBit); - int minPowerOfTwo = Mth.log2(minSize); - int mipLevel; -- if (minPowerOfTwo < maxMipmapLevels) { -+ if (false) { // Forge: Do not lower the mipmap level - LOGGER.warn("{}: dropping miplevel from {} to {}, because of minimum power of two: {}", this.location, maxMipmapLevels, minPowerOfTwo, minSize); - mipLevel = minPowerOfTwo; - } else { @@ -129,7 +_,7 @@ ResourceManager manager, Identifier atlasInfoLocation, int maxMipmapLevels, Executor taskExecutor, Set> additionalMetadata ) { diff --git a/patches/net/minecraft/client/renderer/texture/atlas/SpriteSourceList.java.patch b/patches/net/minecraft/client/renderer/texture/atlas/SpriteSourceList.java.patch index f68cc3c4521..8ee53d81f4f 100644 --- a/patches/net/minecraft/client/renderer/texture/atlas/SpriteSourceList.java.patch +++ b/patches/net/minecraft/client/renderer/texture/atlas/SpriteSourceList.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/texture/atlas/SpriteSourceList.java +++ b/net/minecraft/client/renderer/texture/atlas/SpriteSourceList.java -@@ -34,7 +_,15 @@ +@@ -35,7 +_,15 @@ this.sources = sources; } @@ -15,8 +15,8 @@ + public List list(ResourceManager resourceManager, java.util.Set> additionalMetadata) { final Map sprites = new HashMap<>(); SpriteSource.Output output = new SpriteSource.Output() { - @Override -@@ -58,7 +_,7 @@ + { +@@ -63,7 +_,7 @@ } } }; diff --git a/patches/net/minecraft/client/resources/language/LanguageManager.java.patch b/patches/net/minecraft/client/resources/language/LanguageManager.java.patch index 91d0fcdf1f0..4a480e8bc09 100644 --- a/patches/net/minecraft/client/resources/language/LanguageManager.java.patch +++ b/patches/net/minecraft/client/resources/language/LanguageManager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/resources/language/LanguageManager.java +++ b/net/minecraft/client/resources/language/LanguageManager.java -@@ -30,7 +_,7 @@ +@@ -29,7 +_,7 @@ private final Consumer reloadCallback; public LanguageManager(String languageCode, Consumer reloadCallback) { @@ -9,7 +9,7 @@ this.reloadCallback = reloadCallback; } -@@ -69,8 +_,12 @@ +@@ -68,8 +_,12 @@ this.reloadCallback.accept(locale); } diff --git a/patches/net/minecraft/client/resources/model/ModelBakery.java.patch b/patches/net/minecraft/client/resources/model/ModelBakery.java.patch index 9a7eaed6ba1..c665f7ab651 100644 --- a/patches/net/minecraft/client/resources/model/ModelBakery.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelBakery.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/resources/model/ModelBakery.java +++ b/net/minecraft/client/resources/model/ModelBakery.java -@@ -64,7 +_,13 @@ +@@ -65,7 +_,13 @@ private final Map clientInfos; private final Map resolvedModels; private final ResolvedModel missingModel; @@ -14,7 +14,7 @@ public ModelBakery( EntityModelSet entityModelSet, MaterialSet materials, -@@ -74,6 +_,20 @@ +@@ -75,6 +_,20 @@ Map resolvedModels, ResolvedModel missingModel ) { @@ -35,7 +35,7 @@ this.entityModelSet = entityModelSet; this.materials = materials; this.playerSkinRenderCache = playerSkinRenderCache; -@@ -81,6 +_,8 @@ +@@ -82,6 +_,8 @@ this.clientInfos = clientInfos; this.resolvedModels = resolvedModels; this.missingModel = missingModel; @@ -44,7 +44,7 @@ } public CompletableFuture bakeModels(SpriteGetter sprites, Executor taskExecutor) { -@@ -104,7 +_,7 @@ +@@ -105,7 +_,7 @@ return clientInfo.model() .bake( new ItemModel.BakingContext( @@ -53,7 +53,7 @@ ) ); } catch (Exception var6x) { -@@ -114,6 +_,8 @@ +@@ -115,6 +_,8 @@ }, taskExecutor ); @@ -62,7 +62,7 @@ Map itemStackModelProperties = new HashMap<>(this.clientInfos.size()); this.clientInfos.forEach((id, clientInfo) -> { ClientItem.Properties properties = clientInfo.properties(); -@@ -121,13 +_,15 @@ +@@ -122,13 +_,15 @@ itemStackModelProperties.put(id, properties); } }); @@ -79,7 +79,7 @@ ) ); } -@@ -138,7 +_,20 @@ +@@ -139,7 +_,20 @@ Map blockStateModels, Map itemStackModels, Map itemProperties @@ -100,7 +100,7 @@ } @OnlyIn(Dist.CLIENT) -@@ -232,10 +_,22 @@ +@@ -237,10 +_,22 @@ @OnlyIn(Dist.CLIENT) private static class PartCacheImpl implements ModelBaker.PartCache { private final Interner vectors = Interners.newStrongInterner(); diff --git a/patches/net/minecraft/client/resources/model/ModelManager.java.patch b/patches/net/minecraft/client/resources/model/ModelManager.java.patch index ba94d26b9e2..bf047b2e34e 100644 --- a/patches/net/minecraft/client/resources/model/ModelManager.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelManager.java.patch @@ -84,13 +84,13 @@ result.add(CompletableFuture.supplyAsync(() -> { @@ -173,7 +_,7 @@ try { - Pair var3; + Pair t$; try (Reader reader = resource.getValue().openAsReader()) { -- var3 = Pair.of(modelId, BlockModel.fromStream(reader)); -+ var3 = Pair.of(modelId, net.neoforged.neoforge.client.model.UnbakedModelParser.parse(reader)); +- t$ = Pair.of(modelId, BlockModel.fromStream(reader)); ++ t$ = Pair.of(modelId, net.neoforged.neoforge.client.model.UnbakedModelParser.parse(reader)); } - return var3; + return t$; @@ -190,15 +_,26 @@ ); } @@ -128,20 +128,13 @@ Map modelByStateCache = createBlockStateToModelDispatch( bakingResult.blockStateModels(), bakingResult.missingModels().block() ); -@@ -313,6 +_,16 @@ +@@ -313,6 +_,9 @@ this.itemProperties = bakedModels.itemProperties(); this.modelGroups = preparations.modelGroups; this.missingModels = bakedModels.missingModels(); + this.bakedStandaloneModels = bakedModels.standaloneModels(); + net.neoforged.neoforge.client.ClientHooks.onModelBake(this, bakedModels, this.modelBakery.get()); + this.reportedMissingItemModels = new java.util.HashSet<>(); -+ for (net.minecraft.world.item.Item item : BuiltInRegistries.ITEM) { -+ Identifier modelId = item.components().get(net.minecraft.core.component.DataComponents.ITEM_MODEL); -+ if (modelId != null && !this.bakedItemStackModels.containsKey(modelId)) { -+ this.reportedMissingItemModels.add(modelId); -+ LOGGER.warn("No model loaded for default item model ID {} of {}", modelId, item); -+ } -+ } this.blockModelShaper.replaceCache(preparations.modelCache); this.specialBlockModelRenderer = preparations.specialBlockModelRenderer; this.entityModelSet = preparations.entityModelSet; diff --git a/patches/net/minecraft/commands/Commands.java.patch b/patches/net/minecraft/commands/Commands.java.patch index 5e5c8c48781..c6648afddd1 100644 --- a/patches/net/minecraft/commands/Commands.java.patch +++ b/patches/net/minecraft/commands/Commands.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -295,6 +_,7 @@ +@@ -298,6 +_,7 @@ if (commandSelection.includeIntegrated) { PublishCommand.register(this.dispatcher); } @@ -8,7 +8,7 @@ this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer()); } -@@ -316,6 +_,16 @@ +@@ -319,6 +_,16 @@ public void performCommand(ParseResults command, String commandString) { CommandSourceStack sender = command.getContext().getSource(); @@ -25,7 +25,7 @@ Profiler.get().push(() -> "/" + commandString); ContextChain commandChain = finishParsing(command, commandString, sender); -@@ -410,10 +_,12 @@ +@@ -413,10 +_,12 @@ Map, CommandNode> playerCommands = new HashMap<>(); RootCommandNode root = new RootCommandNode<>(); playerCommands.put(this.dispatcher.getRoot(), root); diff --git a/patches/net/minecraft/commands/arguments/EntityArgument.java.patch b/patches/net/minecraft/commands/arguments/EntityArgument.java.patch index f6c6563fa1d..8d9805a91ca 100644 --- a/patches/net/minecraft/commands/arguments/EntityArgument.java.patch +++ b/patches/net/minecraft/commands/arguments/EntityArgument.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/arguments/EntityArgument.java +++ b/net/minecraft/commands/arguments/EntityArgument.java -@@ -128,7 +_,7 @@ +@@ -129,7 +_,7 @@ if (contextBuilder.getSource() instanceof SharedSuggestionProvider source) { StringReader reader = new StringReader(builder.getInput()); reader.setCursor(builder.getStart()); diff --git a/patches/net/minecraft/commands/arguments/ResourceKeyArgument.java.patch b/patches/net/minecraft/commands/arguments/ResourceKeyArgument.java.patch index 3204d67bc0b..d402d3d1093 100644 --- a/patches/net/minecraft/commands/arguments/ResourceKeyArgument.java.patch +++ b/patches/net/minecraft/commands/arguments/ResourceKeyArgument.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/arguments/ResourceKeyArgument.java +++ b/net/minecraft/commands/arguments/ResourceKeyArgument.java -@@ -49,6 +_,9 @@ +@@ -50,6 +_,9 @@ private static final DynamicCommandExceptionType ERROR_INVALID_ADVANCEMENT = new DynamicCommandExceptionType( value -> Component.translatableEscape("advancement.advancementNotFound", value) ); @@ -10,7 +10,7 @@ private final ResourceKey> registryKey; public ResourceKeyArgument(ResourceKey> registryKey) { -@@ -91,6 +_,9 @@ +@@ -92,6 +_,9 @@ } public static RecipeHolder getRecipe(CommandContext context, String name) throws CommandSyntaxException { @@ -20,7 +20,7 @@ RecipeManager recipeManager = context.getSource().getServer().getRecipeManager(); ResourceKey> key = getRegistryKey(context, name, Registries.RECIPE, ERROR_INVALID_RECIPE); return recipeManager.byKey(key).orElseThrow(() -> ERROR_INVALID_RECIPE.create(key.identifier())); -@@ -98,7 +_,7 @@ +@@ -99,7 +_,7 @@ public static AdvancementHolder getAdvancement(CommandContext context, String name) throws CommandSyntaxException { ResourceKey key = getRegistryKey(context, name, Registries.ADVANCEMENT, ERROR_INVALID_ADVANCEMENT); diff --git a/patches/net/minecraft/core/Holder.java.patch b/patches/net/minecraft/core/Holder.java.patch index ef2a6d6651c..d1219eacc65 100644 --- a/patches/net/minecraft/core/Holder.java.patch +++ b/patches/net/minecraft/core/Holder.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/Holder.java +++ b/net/minecraft/core/Holder.java -@@ -226,6 +_,14 @@ +@@ -247,6 +_,14 @@ } } @@ -15,7 +15,7 @@ void bindTags(Collection> tags) { this.tags = Set.copyOf(tags); } -@@ -238,6 +_,32 @@ +@@ -268,6 +_,32 @@ @Override public String toString() { return "Reference{" + this.key + "=" + this.value + "}"; diff --git a/patches/net/minecraft/core/HolderLookup.java.patch b/patches/net/minecraft/core/HolderLookup.java.patch index 39aad15ead5..11c83a9d502 100644 --- a/patches/net/minecraft/core/HolderLookup.java.patch +++ b/patches/net/minecraft/core/HolderLookup.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/HolderLookup.java +++ b/net/minecraft/core/HolderLookup.java -@@ -94,6 +_,18 @@ +@@ -99,6 +_,18 @@ }; } @@ -19,7 +19,7 @@ public interface Delegate extends HolderLookup.RegistryLookup { HolderLookup.RegistryLookup parent(); -@@ -125,6 +_,12 @@ +@@ -130,6 +_,12 @@ @Override default Stream> listTags() { return this.parent().listTags(); diff --git a/patches/net/minecraft/core/MappedRegistry.java.patch b/patches/net/minecraft/core/MappedRegistry.java.patch index 6eb7d15ff31..7ec74ae7c4b 100644 --- a/patches/net/minecraft/core/MappedRegistry.java.patch +++ b/patches/net/minecraft/core/MappedRegistry.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java -@@ -29,7 +_,7 @@ +@@ -30,7 +_,7 @@ import net.minecraft.util.Util; import org.jspecify.annotations.Nullable; @@ -9,7 +9,7 @@ private final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(), t -> t.defaultReturnValue(-1)); -@@ -84,9 +_,17 @@ +@@ -86,9 +_,17 @@ @Override public Holder.Reference register(ResourceKey key, T value, RegistrationInfo registrationInfo) { @@ -27,7 +27,7 @@ if (this.byLocation.containsKey(key.identifier())) { throw (IllegalStateException)Util.pauseInIde(new IllegalStateException("Adding duplicate key '" + key + "' to registry")); } else if (this.byValue.containsKey(value)) { -@@ -102,16 +_,18 @@ +@@ -104,16 +_,18 @@ holder.bindKey(key); } else { holder = this.byKey.computeIfAbsent(key, k -> Holder.Reference.createStandAlone(this, (ResourceKey)k)); @@ -47,7 +47,7 @@ return holder; } } -@@ -134,7 +_,7 @@ +@@ -136,7 +_,7 @@ @Override public @Nullable T getValue(@Nullable ResourceKey key) { @@ -56,7 +56,7 @@ } @Override -@@ -149,12 +_,12 @@ +@@ -151,12 +_,12 @@ @Override public Optional> get(Identifier id) { @@ -71,7 +71,7 @@ } @Override -@@ -169,12 +_,12 @@ +@@ -171,12 +_,12 @@ } private Holder.Reference getOrCreateHolderOrThrow(ResourceKey key) { @@ -87,7 +87,7 @@ } }); } -@@ -201,7 +_,7 @@ +@@ -203,7 +_,7 @@ @Override public @Nullable T getValue(@Nullable Identifier key) { @@ -96,8 +96,8 @@ return getValueFromNullable(result); } -@@ -262,13 +_,23 @@ - return this.byKey.containsKey(key); +@@ -269,13 +_,23 @@ + return Objects.requireNonNull(this.componentLookup, "Registry not frozen yet"); } + /** @deprecated Forge: For internal use only. Use the Register events when registering values. */ @@ -121,7 +121,7 @@ List unboundEntries = this.byKey .entrySet() .stream() -@@ -284,11 +_,15 @@ +@@ -291,11 +_,15 @@ throw new IllegalStateException("Some intrusive holders were not registered: " + this.unregisteredIntrusiveHolders.values()); } @@ -139,7 +139,7 @@ } else { List unboundTags = this.frozenTags .entrySet() -@@ -443,6 +_,55 @@ +@@ -463,6 +_,55 @@ } }; } diff --git a/patches/net/minecraft/core/Registry.java.patch b/patches/net/minecraft/core/Registry.java.patch index 34e2aa52504..15fe34daa7f 100644 --- a/patches/net/minecraft/core/Registry.java.patch +++ b/patches/net/minecraft/core/Registry.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/Registry.java +++ b/net/minecraft/core/Registry.java -@@ -45,7 +_,7 @@ +@@ -47,7 +_,7 @@ } private DataResult> safeCastToReference(Holder holder) { diff --git a/patches/net/minecraft/core/RegistrySetBuilder.java.patch b/patches/net/minecraft/core/RegistrySetBuilder.java.patch index 9be3b67929c..a5780cbe45c 100644 --- a/patches/net/minecraft/core/RegistrySetBuilder.java.patch +++ b/patches/net/minecraft/core/RegistrySetBuilder.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/RegistrySetBuilder.java +++ b/net/minecraft/core/RegistrySetBuilder.java -@@ -69,6 +_,10 @@ +@@ -70,6 +_,10 @@ return this.add(key, Lifecycle.stable(), bootstrap); } @@ -11,7 +11,7 @@ private RegistrySetBuilder.BuildState createState(RegistryAccess context) { RegistrySetBuilder.BuildState state = RegistrySetBuilder.BuildState.create(context, this.entries.stream().map(RegistrySetBuilder.RegistryStub::key)); this.entries.forEach(e -> e.apply(state)); -@@ -182,16 +_,22 @@ +@@ -187,16 +_,22 @@ holder.supplier = () -> cloner.clone((T)elementHolder.value(), patchProvider, targetProvider.get()); entries.put(elementKey, holder); }); @@ -43,7 +43,7 @@ return lookupFromMap(registryKey, lifecycle, owner, entries); } } -@@ -237,7 +_,7 @@ +@@ -242,7 +_,7 @@ RegistrySetBuilder.UniversalLookup lookup = new RegistrySetBuilder.UniversalLookup(owner); Builder> registries = ImmutableMap.builder(); context.registries() @@ -52,7 +52,7 @@ newRegistries.forEach(newRegistry -> registries.put(newRegistry.identifier(), lookup)); return new RegistrySetBuilder.BuildState(owner, lookup, registries.build(), new HashMap<>(), errors); } -@@ -260,6 +_,11 @@ +@@ -269,6 +_,11 @@ public HolderGetter lookup(ResourceKey> key) { return (HolderGetter)BuildState.this.registries.getOrDefault(key.identifier(), BuildState.this.lookup); } @@ -64,7 +64,7 @@ }; } -@@ -410,6 +_,26 @@ +@@ -419,6 +_,26 @@ @Override public Optional> get(ResourceKey id) { return Optional.of(this.getOrCreate(id)); diff --git a/patches/net/minecraft/core/TypedInstance.java.patch b/patches/net/minecraft/core/TypedInstance.java.patch new file mode 100644 index 00000000000..5ff4f0fccdd --- /dev/null +++ b/patches/net/minecraft/core/TypedInstance.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/core/TypedInstance.java ++++ b/net/minecraft/core/TypedInstance.java +@@ -24,7 +_,8 @@ + } + + default boolean is(Holder type) { +- return this.typeHolder() == type; ++ // Neo: Fix comparing for custom holders such as DeferredHolders ++ return is(type.value()); + } + + default boolean is(ResourceKey type) { diff --git a/patches/net/minecraft/core/component/DataComponentInitializers.java.patch b/patches/net/minecraft/core/component/DataComponentInitializers.java.patch new file mode 100644 index 00000000000..50034db9427 --- /dev/null +++ b/patches/net/minecraft/core/component/DataComponentInitializers.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/core/component/DataComponentInitializers.java ++++ b/net/minecraft/core/component/DataComponentInitializers.java +@@ -68,6 +_,21 @@ + Set> elementsWithComponents = Sets.newIdentityHashSet(); + elementBuilders.builders.forEach((elementKey, elementBuilder) -> { + Holder.Reference element = registry.getOrThrow((ResourceKey)elementKey); ++ ++ // Neo: Support programmatic customization of the default components for items ++ if (elementKey.isFor(net.minecraft.core.registries.Registries.ITEM)) { ++ var item = (net.minecraft.world.item.Item) element.value(); ++ var modifier = net.neoforged.neoforge.internal.RegistrationEvents.componentModifiersByItem.get(item); ++ if (modifier != null) { ++ modifier.accept(elementBuilder); ++ } ++ for (var pair : net.neoforged.neoforge.internal.RegistrationEvents.componentModifiersByPredicate) { ++ if (pair.getFirst().test(item)) { ++ pair.getSecond().accept(elementBuilder); ++ } ++ } ++ } ++ + DataComponentMap components = elementBuilder.build(); + entries.add(new DataComponentInitializers.BakedEntry<>(element, components)); + elementsWithComponents.add(element); +@@ -115,6 +_,7 @@ + } + + default DataComponentInitializers.Initializer add(DataComponentType type, C value) { ++ net.neoforged.neoforge.common.CommonHooks.validateComponent(value); + return this.andThen((components, context, key) -> components.set(type, value)); + } + } +@@ -141,7 +_,11 @@ + C create(HolderLookup.Provider context); + + default DataComponentInitializers.Initializer asInitializer(DataComponentType type) { +- return (components, context, key) -> components.set(type, this.create(context)); ++ return (components, context, key) -> { ++ var value = this.create(context); ++ net.neoforged.neoforge.common.CommonHooks.validateComponent(value); ++ components.set(type, value); ++ }; + } + } + } diff --git a/patches/net/minecraft/core/component/DataComponentPatch.java.patch b/patches/net/minecraft/core/component/DataComponentPatch.java.patch index ef6abec213c..98de7f39f08 100644 --- a/patches/net/minecraft/core/component/DataComponentPatch.java.patch +++ b/patches/net/minecraft/core/component/DataComponentPatch.java.patch @@ -1,6 +1,21 @@ --- a/net/minecraft/core/component/DataComponentPatch.java +++ b/net/minecraft/core/component/DataComponentPatch.java -@@ -248,6 +_,7 @@ +@@ -156,6 +_,14 @@ + return new DataComponentPatch.Builder(); + } + ++ /** ++ * {@return the patch stored for the given component type, null if no patch is stored} ++ */ ++ @SuppressWarnings("unchecked") ++ public @Nullable Optional getPatch(DataComponentType type) { ++ return (Optional) this.map.get(type); ++ } ++ + public @Nullable T get(DataComponentGetter prototype, DataComponentType type) { + return getFromPatchAndPrototype(this.map, prototype, type); + } +@@ -255,6 +_,7 @@ } public DataComponentPatch.Builder set(DataComponentType type, T value) { diff --git a/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch b/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch index 62d47d0c068..90643ed8c52 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 -@@ -66,6 +_,7 @@ +@@ -65,6 +_,7 @@ } public @Nullable T set(DataComponentType type, @Nullable T value) { @@ -8,7 +8,7 @@ this.ensureMapOwnership(); T defaultValue = this.prototype.get(type); Optional lastValue; -@@ -204,6 +_,10 @@ +@@ -203,6 +_,10 @@ return size; } @@ -19,7 +19,21 @@ public DataComponentPatch asPatch() { if (this.patch.isEmpty()) { return DataComponentPatch.EMPTY; -@@ -231,7 +_,23 @@ +@@ -221,6 +_,13 @@ + return (DataComponentMap)(this.patch.isEmpty() ? this.prototype : this.copy()); + } + ++ /** ++ * {@return true if the contained patch equals the given patch.} ++ */ ++ public boolean patchEquals(DataComponentPatch patch) { ++ return this.patch.equals(patch.map); ++ } ++ + @Override + public boolean equals(Object obj) { + return this == obj +@@ -230,7 +_,24 @@ @Override public int hashCode() { @@ -29,7 +43,7 @@ + + // Neo: Change implementation of hashCode to reduce collisions. + // For a map, hashCode is specified as the sum of the hash codes of its entries. -+ // We do that, but change the entry hash code to 31^ * , ++ // We do that, but change the entry hash code to 8191^ * , + // where is the lower bits of the identity hash code of the key. + private static int hashPatch(Reference2ObjectMap, Optional> patch) { + int h = 0, n = patch.size(); @@ -37,7 +51,8 @@ + while (n-- != 0) { + var entry = iterator.next(); + int exponent = System.identityHashCode(entry.getKey()) & 0xff; -+ int entryHash = com.google.common.math.IntMath.pow(31, exponent) * entry.getValue().hashCode(); ++ // Use 8191 instead of the usual 31, as 31 can produce many collisions with typical integer component ranges (0-255) if the exponent difference is only 1 ++ int entryHash = com.google.common.math.IntMath.pow(8191, exponent) * entry.getValue().hashCode(); + h += entryHash; + } + return h; diff --git a/patches/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch b/patches/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch index 7f0d38d6c6a..e2ba255bfbc 100644 --- a/patches/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch +++ b/patches/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -177,7 +_,7 @@ +@@ -149,7 +_,7 @@ DispensibleContainerItem bucket = (DispensibleContainerItem)dispensed.getItem(); BlockPos target = source.pos().relative(source.state().getValue(DispenserBlock.FACING)); Level level = source.level(); @@ -9,7 +9,7 @@ bucket.checkExtraContent(null, level, dispensed, target); return this.consumeWithRemainder(source, dispensed, new ItemStack(Items.BUCKET)); } else { -@@ -225,11 +_,12 @@ +@@ -197,11 +_,12 @@ if (BaseFireBlock.canBePlacedAt(level, targetPos, facing)) { level.setBlockAndUpdate(targetPos, BaseFireBlock.getState(level, targetPos)); level.gameEvent(null, GameEvent.BLOCK_PLACE, targetPos); diff --git a/patches/net/minecraft/core/particles/ItemParticleOption.java.patch b/patches/net/minecraft/core/particles/ItemParticleOption.java.patch deleted file mode 100644 index c96ef84bdf2..00000000000 --- a/patches/net/minecraft/core/particles/ItemParticleOption.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/core/particles/ItemParticleOption.java -+++ b/net/minecraft/core/particles/ItemParticleOption.java -@@ -25,7 +_,7 @@ - throw new IllegalArgumentException("Empty stacks are not allowed"); - } else { - this.type = type; -- this.itemStack = itemStack; -+ this.itemStack = itemStack.copy(); //Forge: Fix stack updating after the fact causing particle changes. - } - } - diff --git a/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch b/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch index 249506676be..dc5472faee9 100644 --- a/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch +++ b/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/registries/BuiltInRegistries.java +++ b/net/minecraft/core/registries/BuiltInRegistries.java -@@ -431,6 +_,10 @@ +@@ -435,6 +_,10 @@ ((MappedRegistry)registry).bindAllTagsToEmpty(); } diff --git a/patches/net/minecraft/core/registries/Registries.java.patch b/patches/net/minecraft/core/registries/Registries.java.patch index 919c38a2977..33651d63b65 100644 --- a/patches/net/minecraft/core/registries/Registries.java.patch +++ b/patches/net/minecraft/core/registries/Registries.java.patch @@ -1,15 +1,11 @@ --- a/net/minecraft/core/registries/Registries.java +++ b/net/minecraft/core/registries/Registries.java -@@ -309,10 +_,10 @@ +@@ -315,7 +_,7 @@ } - public static String elementsDirPath(ResourceKey> registryKey) { + private static String registryDirPath(ResourceKey> registryKey) { - return registryKey.identifier().getPath(); + return net.neoforged.neoforge.common.CommonHooks.prefixNamespace(registryKey.identifier()); } - public static String tagsDirPath(ResourceKey> registryKey) { -- return "tags/" + registryKey.identifier().getPath(); -+ return "tags/" + net.neoforged.neoforge.common.CommonHooks.prefixNamespace(registryKey.identifier()); - } - } + public static String elementsDirPath(ResourceKey> registryKey) { diff --git a/patches/net/minecraft/data/DataGenerator.java.patch b/patches/net/minecraft/data/DataGenerator.java.patch index 8feff41bb6b..9046d54cc4f 100644 --- a/patches/net/minecraft/data/DataGenerator.java.patch +++ b/patches/net/minecraft/data/DataGenerator.java.patch @@ -1,27 +1,17 @@ --- a/net/minecraft/data/DataGenerator.java +++ b/net/minecraft/data/DataGenerator.java -@@ -21,6 +_,7 @@ - private final Map providersToRun = new LinkedHashMap<>(); - private final WorldVersion version; - private final boolean alwaysGenerate; +@@ -19,6 +_,7 @@ + protected final PackOutput vanillaPackOutput; + protected final Set allProviderIds = new HashSet<>(); + protected final Map providersToRun = new LinkedHashMap<>(); + private final Map providersView = java.util.Collections.unmodifiableMap(this.providersToRun); - public DataGenerator(Path output, WorldVersion version, boolean alwaysGenerate) { - this.rootOutputFolder = output; -@@ -38,6 +_,7 @@ - LOGGER.debug("Generator {} already run for version {}", providerId, this.version.name()); - } else { - LOGGER.info("Starting provider: {}", providerId); -+ net.neoforged.fml.loading.progress.StartupNotificationManager.addModMessage("Generating: " + providerId); - stopwatch.start(); - cache.applyUpdate(cache.generateUpdate(providerId, provider::run).join()); - stopwatch.stop(); -@@ -56,6 +_,55 @@ - public DataGenerator.PackGenerator getBuiltinDatapack(boolean toRun, String packId) { - Path packOutputDir = this.vanillaPackOutput.getOutputFolder(PackOutput.Target.DATA_PACK).resolve("minecraft").resolve("datapacks").resolve(packId); + public DataGenerator(Path output) { + this.vanillaPackOutput = new PackOutput(output); +@@ -35,6 +_,55 @@ return new DataGenerator.PackGenerator(toRun, packId, new PackOutput(packOutputDir)); -+ } -+ + } + + public PackGenerator getBuiltinDatapack(boolean run, String namespace, String path) { + var packPath = vanillaPackOutput.getOutputFolder(PackOutput.Target.DATA_PACK).resolve(namespace).resolve("datapacks").resolve(path); + return new PackGenerator(run, namespace + '_' + path, new PackOutput(packPath)); @@ -36,7 +26,7 @@ + } + + public PackOutput getPackOutput(String path) { -+ return new PackOutput(rootOutputFolder.resolve(path)); ++ return new PackOutput(vanillaPackOutput.getOutputFolder().resolve(path)); + } + + public PackGenerator getPackGenerator(boolean run, String providerPrefix, String path) { @@ -69,6 +59,24 @@ + + other.providersToRun.clear(); + other.allProviderIds.clear(); - } - ++ } ++ static { + Bootstrap.bootStrap(); + } +@@ -61,6 +_,7 @@ + DataGenerator.LOGGER.debug("Generator {} already run for version {}", providerId, this.version.name()); + } else { + DataGenerator.LOGGER.info("Starting provider: {}", providerId); ++ net.neoforged.fml.loading.progress.StartupNotificationManager.addModMessage("Generating: " + providerId); + stopwatch.start(); + cache.applyUpdate(cache.generateUpdate(providerId, provider::run).join()); + stopwatch.stop(); +@@ -112,6 +_,7 @@ + Stopwatch stopwatch = Stopwatch.createUnstarted(); + this.providersToRun.forEach((providerId, provider) -> { + DataGenerator.LOGGER.info("Starting uncached provider: {}", providerId); ++ net.neoforged.fml.loading.progress.StartupNotificationManager.addModMessage("Generating: " + providerId); + stopwatch.start(); + provider.run(CachedOutput.NO_CACHE).join(); + stopwatch.stop(); diff --git a/patches/net/minecraft/data/HashCache.java.patch b/patches/net/minecraft/data/HashCache.java.patch index 5e1d5ff4dca..fd14aa78d80 100644 --- a/patches/net/minecraft/data/HashCache.java.patch +++ b/patches/net/minecraft/data/HashCache.java.patch @@ -25,7 +25,7 @@ cache.save(this.rootDir, cachePath, DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(ZonedDateTime.now()) + "\t" + providerId); } -@@ -221,10 +_,11 @@ +@@ -225,10 +_,11 @@ output.write(extraHeaderInfo); output.newLine(); diff --git a/patches/net/minecraft/data/Main.java.patch b/patches/net/minecraft/data/Main.java.patch index 4e5e7ac34bc..aa6b091aede 100644 --- a/patches/net/minecraft/data/Main.java.patch +++ b/patches/net/minecraft/data/Main.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/Main.java +++ b/net/minecraft/data/Main.java -@@ -70,10 +_,13 @@ +@@ -73,10 +_,13 @@ OptionSpec serverOption = parser.accepts("server", "Include server generators"); OptionSpec devOption = parser.accepts("dev", "Include development tools"); OptionSpec reportsOption = parser.accepts("reports", "Include data reports"); @@ -15,18 +15,19 @@ OptionSet optionSet = parser.parse(args); if (!optionSet.has(helpOption) && optionSet.hasOptions()) { Path output = Paths.get(outputOption.value(optionSet)); -@@ -82,10 +_,17 @@ +@@ -85,11 +_,18 @@ boolean dev = allOptions || optionSet.has(devOption); boolean reports = allOptions || optionSet.has(reportsOption); Collection input = optionSet.valuesOf(inputOption).stream().map(x$0 -> Paths.get(x$0)).toList(); -- DataGenerator generator = new DataGenerator(output, SharedConstants.getCurrentVersion(), true); +- DataGenerator generator = new DataGenerator.Cached(output, SharedConstants.getCurrentVersion(), true); + java.util.Set mods = new java.util.HashSet<>(optionSet.valuesOf(mod)); + boolean isFlat = mods.isEmpty() || optionSet.has(flat); + boolean validate = optionSet.has(validateSpec); -+ DataGenerator generator = new DataGenerator(isFlat ? output : output.resolve("minecraft"), SharedConstants.getCurrentVersion(), true); ++ DataGenerator generator = new DataGenerator.Cached(isFlat ? output : output.resolve("minecraft"), SharedConstants.getCurrentVersion(), true); + java.util.Collection existingPacks = optionSet.valuesOf(existing).stream().map(Paths::get).toList(); + if (mods.contains("minecraft") || mods.isEmpty()) { - addServerProviders(generator, input, server, dev, reports); + addServerDefinitionProviders(generator, server, reports); + addServerConverters(generator, input, server, dev); - generator.run(); Util.shutdownExecutors(); + } diff --git a/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch b/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch index 578d6fc7235..b024d99a580 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 -@@ -724,12 +_,16 @@ +@@ -717,12 +_,16 @@ protected abstract void generate(); diff --git a/patches/net/minecraft/data/loot/LootTableProvider.java.patch b/patches/net/minecraft/data/loot/LootTableProvider.java.patch index 2552d1274e5..8dbe4e50455 100644 --- a/patches/net/minecraft/data/loot/LootTableProvider.java.patch +++ b/patches/net/minecraft/data/loot/LootTableProvider.java.patch @@ -10,7 +10,7 @@ Identifier sequenceId = sequenceIdForLootTable(id); Identifier previous = randomSequenceSeeds.put(RandomSequence.seedForKey(sequenceId), sequenceId); if (previous != null) { -@@ -69,24 +_,18 @@ +@@ -69,17 +_,18 @@ lootTable.setRandomSequence(sequenceId); LootTable table = lootTable.setParamSet(subProvider.paramSet).build(); tables.register(id, table, RegistrationInfo.BUILT_IN); @@ -22,25 +22,18 @@ tables.freeze(); ProblemReporter.Collector problems = new ProblemReporter.Collector(); HolderGetter.Provider validationProvider = new RegistryAccess.ImmutableRegistryAccess(List.of(tables)).freeze(); - ValidationContext validationContext = new ValidationContext(problems, LootContextParamSets.ALL_PARAMS, validationProvider); + ValidationContextSource validationContext = new ValidationContextSource(problems, validationProvider); - for (ResourceKey missingTable : Sets.difference(this.requiredTables, tables.registryKeySet())) { - problems.report(new LootTableProvider.MissingTableProblem(missingTable)); - } + validate(tables, validationContext, problems); -- tables.listElements() -- .forEach( -- tableHolder -> tableHolder.value() -- .validate( -- validationContext.setContextKeySet(tableHolder.value().getParamSet()) -- .enterElement(new ProblemReporter.RootElementPathElement(tableHolder.key()), tableHolder.key()) -- ) -- ); +- LootDataType.TABLE.runValidation(validationContext, tables); if (!problems.isEmpty()) { problems.forEach((id, problem) -> LOGGER.warn("Found validation problem in {}: {}", id, problem.description())); throw new IllegalStateException("Failed to validate loot tables, see logs"); -@@ -95,9 +_,29 @@ +@@ -88,9 +_,29 @@ ResourceKey id = entry.getKey(); LootTable table = entry.getValue(); Path path = this.pathProvider.json(id.identifier()); @@ -55,7 +48,7 @@ + return this.subProviders; + } + -+ protected void validate(WritableRegistry tables, ValidationContext validationContext, ProblemReporter.Collector problems) { ++ protected void validate(WritableRegistry tables, ValidationContextSource validationContext, ProblemReporter.Collector problems) { + for (ResourceKey missingTable : Sets.difference(this.requiredTables, tables.registryKeySet())) { + problems.report(new LootTableProvider.MissingTableProblem(missingTable)); + } @@ -64,7 +57,7 @@ + .forEach( + tableHolder -> tableHolder.value() + .validate( -+ validationContext.setContextKeySet(tableHolder.value().getParamSet()) ++ validationContext.context(tableHolder.value().getParamSet()) + .enterElement(new ProblemReporter.RootElementPathElement(tableHolder.key()), tableHolder.key()) + ) + ); diff --git a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch index 4eb6d2fc14f..203b5943ebb 100644 --- a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch +++ b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/recipes/RecipeProvider.java +++ b/net/minecraft/data/recipes/RecipeProvider.java -@@ -574,8 +_,7 @@ +@@ -599,8 +_,7 @@ } protected void waxRecipes(FeatureFlagSet flagSet) { @@ -10,20 +10,25 @@ .forEach( (block, waxedBlock) -> { if (waxedBlock.requiredFeatures().isSubsetOf(flagSet)) { -@@ -735,6 +_,10 @@ +@@ -758,6 +_,10 @@ return Ingredient.of(this.items.getOrThrow(id)); } -+ protected ShapedRecipeBuilder shaped(RecipeCategory category, ItemStack stack) { ++ protected ShapedRecipeBuilder shaped(RecipeCategory category, ItemStackTemplate stack) { + return ShapedRecipeBuilder.shaped(this.items, category, stack); + } + protected ShapedRecipeBuilder shaped(RecipeCategory category, ItemLike item) { return ShapedRecipeBuilder.shaped(this.items, category, item); } -@@ -780,13 +_,13 @@ +@@ -802,18 +_,14 @@ + final Set>> allRecipes = Sets.newHashSet(); final List> tasks = new ArrayList<>(); RecipeOutput recipeOutput = new RecipeOutput() { +- { +- Objects.requireNonNull(Runner.this); +- } +- @Override - public void accept(ResourceKey> id, Recipe recipe, @Nullable AdvancementHolder advancementHolder) { + public void accept(ResourceKey> id, Recipe recipe, @Nullable AdvancementHolder advancementHolder, net.neoforged.neoforge.common.conditions.ICondition... conditions) { @@ -38,7 +43,7 @@ } } } -@@ -805,13 +_,19 @@ +@@ -832,13 +_,19 @@ } private void saveRecipe(ResourceKey> id, Recipe recipe) { diff --git a/patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch b/patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch index 914dce122b5..f353ccba666 100644 --- a/patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch +++ b/patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch @@ -1,48 +1,13 @@ --- a/net/minecraft/data/recipes/ShapedRecipeBuilder.java +++ b/net/minecraft/data/recipes/ShapedRecipeBuilder.java -@@ -28,6 +_,7 @@ - private final RecipeCategory category; - private final Item result; - private final int count; -+ private final ItemStack resultStack; // Neo: add stack result support - private final List rows = Lists.newArrayList(); - private final Map key = Maps.newLinkedHashMap(); - private final Map> criteria = new LinkedHashMap<>(); -@@ -35,10 +_,15 @@ - private boolean showNotification = true; - - private ShapedRecipeBuilder(HolderGetter items, RecipeCategory category, ItemLike result, int count) { -+ this(items, category, new ItemStack(result, count)); -+ } -+ -+ private ShapedRecipeBuilder(HolderGetter items, RecipeCategory category, ItemStack result) { - this.items = items; - this.category = category; -- this.result = result.asItem(); -- this.count = count; -+ this.result = result.getItem(); -+ this.count = result.getCount(); -+ this.resultStack = result; - } - - public static ShapedRecipeBuilder shaped(HolderGetter items, RecipeCategory category, ItemLike item) { -@@ -49,6 +_,10 @@ +@@ -51,6 +_,10 @@ return new ShapedRecipeBuilder(items, category, item, count); } -+ public static ShapedRecipeBuilder shaped(HolderGetter items, RecipeCategory category, ItemStack result) { ++ public static ShapedRecipeBuilder shaped(HolderGetter items, RecipeCategory category, ItemStackTemplate result) { + return new ShapedRecipeBuilder(items, category, result); + } + public ShapedRecipeBuilder define(Character symbol, TagKey tag) { return this.define(symbol, Ingredient.of(this.items.getOrThrow(tag))); } -@@ -109,7 +_,7 @@ - Objects.requireNonNullElse(this.group, ""), - RecipeBuilder.determineBookCategory(this.category), - pattern, -- new ItemStack(this.result, this.count), -+ this.resultStack, - this.showNotification - ); - output.accept(id, recipe, advancement.build(id.identifier().withPrefix("recipes/" + this.category.getFolderName() + "/"))); diff --git a/patches/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java.patch b/patches/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java.patch index 75854d6b0d1..749cfb29e28 100644 --- a/patches/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java.patch +++ b/patches/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java.patch @@ -1,82 +1,41 @@ --- a/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java +++ b/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java -@@ -29,6 +_,7 @@ - private final RecipeCategory category; - private final CookingBookCategory bookCategory; - private final Item result; -+ private final ItemStack stackResult; // Neo: add stack result support - private final Ingredient ingredient; - private final float experience; - private final int cookingTime; -@@ -45,9 +_,22 @@ - int cookingTime, - AbstractCookingRecipe.Factory factory - ) { -+ this(category, bookCategory, new ItemStack(result), ingredient, experience, cookingTime, factory); -+ } -+ -+ private SimpleCookingRecipeBuilder( -+ RecipeCategory category, -+ CookingBookCategory bookCategory, -+ ItemStack result, -+ Ingredient ingredient, -+ float experience, -+ int cookingTime, -+ AbstractCookingRecipe.Factory factory -+ ) { - this.category = category; - this.bookCategory = bookCategory; -- this.result = result.asItem(); -+ this.result = result.getItem(); -+ this.stackResult = result; - this.ingredient = ingredient; - this.experience = experience; - this.cookingTime = cookingTime; -@@ -86,6 +_,38 @@ - return new SimpleCookingRecipeBuilder(category, CookingBookCategory.FOOD, result, ingredient, experience, cookingTime, SmokingRecipe::new); +@@ -98,6 +_,38 @@ + return new SimpleCookingRecipeBuilder(craftingCategory, CookingBookCategory.FOOD, result, ingredient, experience, cookingTime, SmokingRecipe::new); } + public static SimpleCookingRecipeBuilder generic( + Ingredient ingredient, -+ RecipeCategory category, -+ ItemStack result, ++ RecipeCategory craftingCategory, ++ CookingBookCategory cookingCategory, ++ net.minecraft.world.item.ItemStack result, + float experience, + int cookingTime, -+ RecipeSerializer serializer, + AbstractCookingRecipe.Factory factory + ) { -+ return new SimpleCookingRecipeBuilder(category, determineSmeltingRecipeCategory(result.getItem()), result, ingredient, experience, cookingTime, factory); ++ return new SimpleCookingRecipeBuilder(craftingCategory, cookingCategory, ItemStackTemplate.fromNonEmptyStack(result), ingredient, experience, cookingTime, factory); + } + -+ public static SimpleCookingRecipeBuilder campfireCooking(Ingredient ingredient, RecipeCategory category, ItemStack result, float experience, int cookingTime) { -+ return new SimpleCookingRecipeBuilder(category, CookingBookCategory.FOOD, result, ingredient, experience, cookingTime, CampfireCookingRecipe::new); ++ public static SimpleCookingRecipeBuilder campfireCooking(Ingredient ingredient, RecipeCategory craftingCategory, net.minecraft.world.item.ItemStack result, float experience, int cookingTime) { ++ return new SimpleCookingRecipeBuilder(craftingCategory, CookingBookCategory.FOOD, ItemStackTemplate.fromNonEmptyStack(result), ingredient, experience, cookingTime, CampfireCookingRecipe::new); + } + -+ public static SimpleCookingRecipeBuilder blasting(Ingredient ingredient, RecipeCategory category, ItemStack result, float experience, int cookingTime) { ++ public static SimpleCookingRecipeBuilder blasting(Ingredient ingredient, RecipeCategory craftingCategory, CookingBookCategory cookingCategory, net.minecraft.world.item.ItemStack result, float experience, int cookingTime) { + return new SimpleCookingRecipeBuilder( -+ category, determineBlastingRecipeCategory(result.getItem()), result, ingredient, experience, cookingTime, BlastingRecipe::new ++ craftingCategory, cookingCategory, ItemStackTemplate.fromNonEmptyStack(result), ingredient, experience, cookingTime, BlastingRecipe::new + ); + } + -+ public static SimpleCookingRecipeBuilder smelting(Ingredient ingredient, RecipeCategory category, ItemStack result, float experience, int cookingTime) { ++ public static SimpleCookingRecipeBuilder smelting(Ingredient ingredient, RecipeCategory craftingCategory, CookingBookCategory cookingCategory, net.minecraft.world.item.ItemStack result, float experience, int cookingTime) { + return new SimpleCookingRecipeBuilder( -+ category, determineSmeltingRecipeCategory(result.getItem()), result, ingredient, experience, cookingTime, SmeltingRecipe::new ++ craftingCategory, cookingCategory, ItemStackTemplate.fromNonEmptyStack(result), ingredient, experience, cookingTime, SmeltingRecipe::new + ); + } + -+ public static SimpleCookingRecipeBuilder smoking(Ingredient ingredient, RecipeCategory category, ItemStack result, float experience, int cookingTime) { -+ return new SimpleCookingRecipeBuilder(category, CookingBookCategory.FOOD, result, ingredient, experience, cookingTime, SmokingRecipe::new); ++ public static SimpleCookingRecipeBuilder smoking(Ingredient ingredient, RecipeCategory craftingCategory, net.minecraft.world.item.ItemStack result, float experience, int cookingTime) { ++ return new SimpleCookingRecipeBuilder(craftingCategory, CookingBookCategory.FOOD, ItemStackTemplate.fromNonEmptyStack(result), ingredient, experience, cookingTime, SmokingRecipe::new); + } + public SimpleCookingRecipeBuilder unlockedBy(String name, Criterion criterion) { this.criteria.put(name, criterion); return this; -@@ -111,7 +_,7 @@ - this.criteria.forEach(advancement::addCriterion); - AbstractCookingRecipe recipe = this.factory - .create( -- Objects.requireNonNullElse(this.group, ""), this.bookCategory, this.ingredient, new ItemStack(this.result), this.experience, this.cookingTime -+ Objects.requireNonNullElse(this.group, ""), this.bookCategory, this.ingredient, this.stackResult, this.experience, this.cookingTime - ); - output.accept(id, recipe, advancement.build(id.identifier().withPrefix("recipes/" + this.category.getFolderName() + "/"))); - } diff --git a/patches/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch b/patches/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch index ddcf0498f41..9fbce3cda1d 100644 --- a/patches/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch +++ b/patches/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch @@ -52,7 +52,7 @@ PackOutput.PathProvider pathProvider = this.output.createRegistryElementsPathProvider(registryKey); return CompletableFuture.allOf( registry.listElements() -- .map(e -> dumpValue(pathProvider.json(e.key().identifier()), cache, writeOps, v.elementCodec(), e.value())) +- .>map(e -> dumpValue(pathProvider.json(e.key().identifier()), cache, writeOps, v.elementCodec(), e.value())) + .filter(holder -> this.namespacePredicate.test(holder.key().identifier().getNamespace())) + .map(e -> dumpValue(pathProvider.json(e.key().identifier()), cache, writeOps, conditionalCodec, Optional.of(new net.neoforged.neoforge.common.conditions.WithConditions<>(conditions.getOrDefault(e.key(), java.util.List.of()), e.value())))) .toArray(CompletableFuture[]::new) diff --git a/patches/net/minecraft/data/registries/VanillaRegistries.java.patch b/patches/net/minecraft/data/registries/VanillaRegistries.java.patch index 01668990b4c..9427239a08d 100644 --- a/patches/net/minecraft/data/registries/VanillaRegistries.java.patch +++ b/patches/net/minecraft/data/registries/VanillaRegistries.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/data/registries/VanillaRegistries.java +++ b/net/minecraft/data/registries/VanillaRegistries.java -@@ -95,6 +_,9 @@ - .add(Registries.DIALOG, Dialogs::bootstrap) - .add(Registries.TIMELINE, Timelines::bootstrap); +@@ -101,6 +_,9 @@ + .add(Registries.VILLAGER_TRADE, VillagerTrades::bootstrap) + .add(Registries.TRADE_SET, TradeSets::bootstrap); + // Neo: Keep a set of all actual vanilla registries to allow filtering out registries that are added by mods for Vanilla clients. + public static final List>> DATAPACK_REGISTRY_KEYS = BUILDER.getEntryKeys(); diff --git a/patches/net/minecraft/data/tags/TagAppender.java.patch b/patches/net/minecraft/data/tags/TagAppender.java.patch index 29c5abdef91..bffff0a4c38 100644 --- a/patches/net/minecraft/data/tags/TagAppender.java.patch +++ b/patches/net/minecraft/data/tags/TagAppender.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/tags/TagAppender.java +++ b/net/minecraft/data/tags/TagAppender.java -@@ -54,6 +_,30 @@ +@@ -55,6 +_,30 @@ builder.addOptionalTag(tag.location()); return this; } @@ -31,7 +31,7 @@ }; } -@@ -68,7 +_,7 @@ +@@ -73,7 +_,7 @@ @Override public TagAppender addOptional(U element) { @@ -40,7 +40,7 @@ return this; } -@@ -81,6 +_,30 @@ +@@ -86,6 +_,30 @@ @Override public TagAppender addOptionalTag(TagKey tag) { original.addOptionalTag(tag); diff --git a/patches/net/minecraft/data/tags/TagsProvider.java.patch b/patches/net/minecraft/data/tags/TagsProvider.java.patch index b16599971aa..4aa39986271 100644 --- a/patches/net/minecraft/data/tags/TagsProvider.java.patch +++ b/patches/net/minecraft/data/tags/TagsProvider.java.patch @@ -69,7 +69,7 @@ ); } else { - Path path = this.pathProvider.json(id); -- return DataProvider.saveStable(cache, c.contents, TagFile.CODEC, new TagFile(entries, false), path); +- return DataProvider.saveStable(cache, c.contents, TagFile.CODEC, new TagFile(entries, builder.shouldReplace()), path); + Path path = this.getPath(id); + if (path == null) return CompletableFuture.completedFuture(null); // Neo: Allow running this data provider without writing it. Recipe provider needs valid tags. + var removed = builder.getRemoveEntries().toList(); diff --git a/patches/net/minecraft/data/tags/VanillaItemTagsProvider.java.patch b/patches/net/minecraft/data/tags/VanillaItemTagsProvider.java.patch index 011699f1b6c..cdb6b1e16a9 100644 --- a/patches/net/minecraft/data/tags/VanillaItemTagsProvider.java.patch +++ b/patches/net/minecraft/data/tags/VanillaItemTagsProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/tags/VanillaItemTagsProvider.java +++ b/net/minecraft/data/tags/VanillaItemTagsProvider.java -@@ -536,5 +_,29 @@ +@@ -544,5 +_,29 @@ this.itemAppender.addOptionalTag(blockTagToItemTag(tag)); return this; } diff --git a/patches/net/minecraft/gametest/framework/GameTestMainUtil.java.patch b/patches/net/minecraft/gametest/framework/GameTestMainUtil.java.patch index 462a53dfcac..74c2bbf30c2 100644 --- a/patches/net/minecraft/gametest/framework/GameTestMainUtil.java.patch +++ b/patches/net/minecraft/gametest/framework/GameTestMainUtil.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/gametest/framework/GameTestMainUtil.java +++ b/net/minecraft/gametest/framework/GameTestMainUtil.java -@@ -67,6 +_,7 @@ +@@ -75,6 +_,7 @@ Bootstrap.bootStrap(); Util.startTimerHackThread(); diff --git a/patches/net/minecraft/gametest/framework/GameTestServer.java.patch b/patches/net/minecraft/gametest/framework/GameTestServer.java.patch index e70b5512e53..978e975802f 100644 --- a/patches/net/minecraft/gametest/framework/GameTestServer.java.patch +++ b/patches/net/minecraft/gametest/framework/GameTestServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/gametest/framework/GameTestServer.java +++ b/net/minecraft/gametest/framework/GameTestServer.java -@@ -87,6 +_,11 @@ +@@ -90,6 +_,11 @@ private final Stopwatch stopwatch = Stopwatch.createUnstarted(); private static final WorldOptions WORLD_OPTIONS = new WorldOptions(0L, false, false); private @Nullable MultipleTestTracker testTracker; @@ -12,7 +12,7 @@ public static GameTestServer create( Thread serverThread, -@@ -101,7 +_,7 @@ +@@ -105,7 +_,7 @@ enabledPacks.addFirst("vanilla"); WorldDataConfiguration defaultTestConfig = new WorldDataConfiguration(new DataPackConfig(enabledPacks, List.of()), ENABLED_FEATURES); LevelSettings testSettings = new LevelSettings( @@ -21,9 +21,9 @@ ); WorldLoader.PackConfig packConfig = new WorldLoader.PackConfig(packRepository, defaultTestConfig, false, true); WorldLoader.InitConfig initConfig = new WorldLoader.InitConfig(packConfig, Commands.CommandSelection.DEDICATED, LevelBasedPermissionSet.OWNER); -@@ -167,10 +_,12 @@ - protected boolean initServer() { - this.setPlayerList(new PlayerList(this, this.registries(), this.playerDataStorage, new EmptyNotificationService()) {}); +@@ -177,10 +_,12 @@ + } + }); Gizmos.withCollector(GizmoCollector.NOOP); + net.neoforged.neoforge.server.ServerLifecycleHooks.handleServerAboutToStart(this); this.loadLevel(); @@ -34,7 +34,7 @@ return true; } -@@ -229,8 +_,14 @@ +@@ -259,8 +_,14 @@ GlobalTestReporter.finish(); LOGGER.info("========= {} GAME TESTS COMPLETE IN {} ======================", this.testTracker.getTotalCount(), this.stopwatch.stop()); if (this.testTracker.hasFailedRequired()) { @@ -50,7 +50,7 @@ } else { LOGGER.info("All {} required tests passed :)", this.testTracker.getTotalCount()); } -@@ -246,11 +_,11 @@ +@@ -276,11 +_,11 @@ private static void logFailedTest(GameTestInfo testInfo) { if (testInfo.getRotation() != Rotation.NONE) { diff --git a/patches/net/minecraft/locale/Language.java.patch b/patches/net/minecraft/locale/Language.java.patch index 2614c174b1d..4a9b4827ba5 100644 --- a/patches/net/minecraft/locale/Language.java.patch +++ b/patches/net/minecraft/locale/Language.java.patch @@ -53,7 +53,7 @@ JsonObject entries = GSON.fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), JsonObject.class); for (Entry entry : entries.entrySet()) { -+ if (entry.getValue().isJsonArray()) { ++ if (entry.getValue().isJsonArray() || entry.getValue().isJsonObject()) { + var component = net.minecraft.network.chat.ComponentSerialization.CODEC + .parse(com.mojang.serialization.JsonOps.INSTANCE, entry.getValue()) + .getOrThrow(msg -> new com.google.gson.JsonParseException("Error parsing translation for " + entry.getKey() + ": " + msg)); diff --git a/patches/net/minecraft/network/Connection.java.patch b/patches/net/minecraft/network/Connection.java.patch index c234a45ecf9..3a26a2652e8 100644 --- a/patches/net/minecraft/network/Connection.java.patch +++ b/patches/net/minecraft/network/Connection.java.patch @@ -76,7 +76,7 @@ return new Bootstrap().group(eventLoopGroupHolder.eventLoopGroup()).handler(new ChannelInitializer() { @Override protected void initChannel(Channel channel) { -@@ -586,5 +_,17 @@ +@@ -590,5 +_,17 @@ public void setBandwidthLogger(LocalSampleLogger bandwidthLogger) { this.bandwidthDebugMonitor = new BandwidthDebugMonitor(bandwidthLogger); diff --git a/patches/net/minecraft/network/FriendlyByteBuf.java.patch b/patches/net/minecraft/network/FriendlyByteBuf.java.patch index fa56f2cd141..88071886f12 100644 --- a/patches/net/minecraft/network/FriendlyByteBuf.java.patch +++ b/patches/net/minecraft/network/FriendlyByteBuf.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/network/FriendlyByteBuf.java +++ b/net/minecraft/network/FriendlyByteBuf.java -@@ -1637,4 +_,9 @@ +@@ -1611,4 +_,9 @@ public boolean release(int decrement) { return this.source.release(decrement); } diff --git a/patches/net/minecraft/network/protocol/BundlerInfo.java.patch b/patches/net/minecraft/network/protocol/BundlerInfo.java.patch index 6fa11fb62eb..c776f82a473 100644 --- a/patches/net/minecraft/network/protocol/BundlerInfo.java.patch +++ b/patches/net/minecraft/network/protocol/BundlerInfo.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/network/protocol/BundlerInfo.java +++ b/net/minecraft/network/protocol/BundlerInfo.java -@@ -27,6 +_,26 @@ +@@ -28,6 +_,26 @@ } @Override @@ -26,8 +26,8 @@ + @Override public BundlerInfo.@Nullable Bundler startPacketBundling(Packet packet) { return packet == delimiterPacket ? new BundlerInfo.Bundler() { - private final List> bundlePackets = new ArrayList<>(); -@@ -47,7 +_,24 @@ + private final List> bundlePackets; +@@ -53,7 +_,24 @@ }; } diff --git a/patches/net/minecraft/resources/RegistryDataLoader.java.patch b/patches/net/minecraft/resources/RegistryDataLoader.java.patch index 24b5271b2f7..3cb2659200f 100644 --- a/patches/net/minecraft/resources/RegistryDataLoader.java.patch +++ b/patches/net/minecraft/resources/RegistryDataLoader.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/resources/RegistryDataLoader.java +++ b/net/minecraft/resources/RegistryDataLoader.java -@@ -134,7 +_,7 @@ +@@ -122,7 +_,7 @@ public static final List> DIMENSION_REGISTRIES = List.of( new RegistryDataLoader.RegistryData<>(Registries.LEVEL_STEM, LevelStem.CODEC) ); @@ -9,111 +9,69 @@ new RegistryDataLoader.RegistryData<>(Registries.BIOME, Biome.NETWORK_CODEC), new RegistryDataLoader.RegistryData<>(Registries.CHAT_TYPE, ChatType.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.TRIM_PATTERN, TrimPattern.DIRECT_CODEC), -@@ -158,12 +_,12 @@ - new RegistryDataLoader.RegistryData<>(Registries.TEST_INSTANCE, GameTestInstance.DIRECT_CODEC), +@@ -147,7 +_,7 @@ new RegistryDataLoader.RegistryData<>(Registries.DIALOG, Dialog.DIRECT_CODEC), + new RegistryDataLoader.RegistryData<>(Registries.WORLD_CLOCK, WorldClock.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.TIMELINE, Timeline.NETWORK_CODEC) - ); + )); // Neo: Keep the list so custom registries can be added later - public static RegistryAccess.Frozen load( - ResourceManager resourceManager, List> contextRegistries, List> registriesToLoad - ) { -- return load((loader, context) -> loader.loadFromResources(resourceManager, context), contextRegistries, registriesToLoad); -+ return load((loader, context) -> loader.loadFromResources(resourceManager, context), contextRegistries, registriesToLoad, true); + public static CompletableFuture load( + ResourceManager resourceManager, +@@ -161,7 +_,7 @@ + return new ResourceManagerRegistryLoadTask<>(data, Lifecycle.stable(), loadingErrors, resourceManager); + } + }; +- return load(loaderFactory, contextRegistries, registriesToLoad, executor); ++ return load(loaderFactory, contextRegistries, registriesToLoad, executor, true); } - public static RegistryAccess.Frozen load( -@@ -172,13 +_,25 @@ - List> contextRegistries, - List> registriesToLoad - ) { -- return load((loader, context) -> loader.loadFromNetwork(entries, knownDataSource, context), contextRegistries, registriesToLoad); -+ return load((loader, context) -> loader.loadFromNetwork(entries, knownDataSource, context), contextRegistries, registriesToLoad, false); + public static CompletableFuture load( +@@ -177,14 +_,16 @@ + return new NetworkRegistryLoadTask<>(data, Lifecycle.stable(), loadingErrors, entries, knownDataSource); + } + }; +- return load(loaderFactory, contextRegistries, registriesToLoad, executor); ++ return load(loaderFactory, contextRegistries, registriesToLoad, executor, false); } -+ /** -+ * @deprecated Neo: use {@link #load(LoadingFunction, List, List, boolean) the source-aware variant} -+ */ -+ @Deprecated - private static RegistryAccess.Frozen load( - RegistryDataLoader.LoadingFunction loadingFunction, ++ // Neo: Added parameter to know we are loading server-side from resources + private static CompletableFuture load( + RegistryDataLoader.LoaderFactory loaderFactory, List> contextRegistries, - List> registriesToLoad -+ ) { -+ return load(loadingFunction, contextRegistries, registriesToLoad, false); -+ } -+ private static RegistryAccess.Frozen load( -+ RegistryDataLoader.LoadingFunction loadingFunction, -+ List> contextRegistries, -+ List> registriesToLoad, + List> registriesToLoad, +- Executor executor ++ Executor executor, + boolean fromResources ) { - Map, Exception> loadingErrors = new HashMap<>(); - List> newRegistriesAndLoaders = registriesToLoad.stream() -@@ -186,6 +_,14 @@ - .collect(Collectors.toUnmodifiableList()); - RegistryOps.RegistryInfoLookup contextAndNewRegistries = createContext(contextRegistries, newRegistriesAndLoaders); - newRegistriesAndLoaders.forEach(loader -> loadingFunction.apply((RegistryDataLoader.Loader)loader, contextAndNewRegistries)); -+ if (fromResources && net.neoforged.neoforge.gametest.GameTestHooks.isGametestEnabled()) { -+ var byKeyMap = newRegistriesAndLoaders.stream().collect(java.util.stream.Collectors.toMap(d -> d.registry().key(), d -> d.registry)); -+ var envRegistry = (WritableRegistry) byKeyMap.get(Registries.TEST_ENVIRONMENT); -+ var testsRegistry = (WritableRegistry) byKeyMap.get(Registries.TEST_INSTANCE); -+ if (envRegistry != null && testsRegistry != null) { -+ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.event.RegisterGameTestsEvent(envRegistry, testsRegistry)); -+ } -+ } - newRegistriesAndLoaders.forEach(p -> { - Registry registry = p.registry(); - -@@ -282,11 +_,16 @@ - Resource thunk, - RegistrationInfo registrationInfo - ) throws IOException { -+ Decoder> decoder = net.neoforged.neoforge.common.conditions.ConditionalOps.createConditionalCodec(net.neoforged.neoforge.common.util.NeoForgeExtraCodecs.decodeOnly(elementDecoder)); - try (Reader reader = thunk.openAsReader()) { - JsonElement json = StrictJsonParser.parse(reader); -- DataResult parseResult = elementDecoder.parse(ops, json); -- E parsedElement = parseResult.getOrThrow(); -+ DataResult> dataresult = decoder.parse(ops, json); -+ Optional candidate = dataresult.getOrThrow(); -+ candidate.ifPresentOrElse(parsedElement -> { - output.register(elementKey, parsedElement, registrationInfo); -+ }, () -> { -+ LOGGER.debug("Skipping loading registry entry {} as its conditions were not met", elementKey); -+ }); - } - } - -@@ -298,7 +_,7 @@ - Map, Exception> loadingErrors - ) { - FileToIdConverter lister = FileToIdConverter.registry(registry.key()); -- RegistryOps ops = RegistryOps.create(JsonOps.INSTANCE, lookup); -+ RegistryOps ops = new net.neoforged.neoforge.common.conditions.ConditionalOps<>(RegistryOps.create(JsonOps.INSTANCE, lookup), net.neoforged.neoforge.common.conditions.ICondition.IContext.TAGS_INVALID); - - for (Entry resourceEntry : lister.listMatchingResources(resourceManager).entrySet()) { - Identifier resourceId = resourceEntry.getKey(); -@@ -384,13 +_,20 @@ + return CompletableFuture.>supplyAsync( + () -> { +@@ -203,6 +_,15 @@ + return CompletableFuture.allOf(loadCompletions) + .thenApplyAsync( + ignored -> { ++ if (fromResources && net.neoforged.neoforge.gametest.GameTestHooks.isGametestEnabled()) { ++ var byKeyMap = loadTasks.stream().collect(java.util.stream.Collectors.toMap(d -> d.registryKey(), d -> d.readOnlyRegistry())); ++ var envRegistry = (net.minecraft.core.WritableRegistry) byKeyMap.get(Registries.TEST_ENVIRONMENT); ++ var testsRegistry = (net.minecraft.core.WritableRegistry) byKeyMap.get(Registries.TEST_INSTANCE); ++ if (envRegistry != null && testsRegistry != null) { ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.event.RegisterGameTestsEvent(envRegistry, testsRegistry)); ++ } ++ } ++ + List> frozenRegistries = loadTasks.stream().filter(task -> task.freezeRegistry(loadingErrors)).toList(); + if (!loadingErrors.isEmpty()) { + throw logErrors(loadingErrors); +@@ -297,7 +_,11 @@ public record NetworkedRegistryData(List elements, TagNetworkSerialization.NetworkPayload tags) { } -- public record RegistryData(ResourceKey> key, Codec elementCodec, boolean requiredNonEmpty) { -+ public record RegistryData(ResourceKey> key, Codec elementCodec, boolean requiredNonEmpty, java.util.function.Consumer> registryBuilderConsumer) { -+ public RegistryData(ResourceKey> key, Codec elementCodec, boolean requiredNonEmpty) { -+ this(key, elementCodec, requiredNonEmpty, registryBuilder -> {}); +- public record RegistryData(ResourceKey> key, Codec elementCodec, RegistryValidator validator) { ++ public record RegistryData(ResourceKey> key, Codec elementCodec, RegistryValidator validator, java.util.function.Consumer> registryBuilderConsumer) { ++ public RegistryData(ResourceKey> key, Codec elementCodec, RegistryValidator validator) { ++ this(key, elementCodec, validator, _ -> {}); + } + private RegistryData(ResourceKey> key, Codec elementCodec) { - this(key, elementCodec, false); + this(key, elementCodec, RegistryValidator.none()); } - - private RegistryDataLoader.Loader create(Lifecycle lifecycle, Map, Exception> loadingErrors) { -- WritableRegistry result = new MappedRegistry<>(this.key, lifecycle); -+ net.neoforged.neoforge.registries.RegistryBuilder registryBuilder = new net.neoforged.neoforge.registries.RegistryBuilder<>(key); -+ registryBuilderConsumer.accept(registryBuilder); -+ -+ WritableRegistry result = (WritableRegistry) registryBuilder.disableRegistrationCheck().create(); - return new RegistryDataLoader.Loader<>(this, result, loadingErrors); - } - diff --git a/patches/net/minecraft/resources/RegistryLoadTask.java.patch b/patches/net/minecraft/resources/RegistryLoadTask.java.patch new file mode 100644 index 00000000000..b16e1270bef --- /dev/null +++ b/patches/net/minecraft/resources/RegistryLoadTask.java.patch @@ -0,0 +1,57 @@ +--- a/net/minecraft/resources/RegistryLoadTask.java ++++ b/net/minecraft/resources/RegistryLoadTask.java +@@ -27,6 +_,9 @@ + import net.minecraft.util.StrictJsonParser; + + public abstract class RegistryLoadTask { ++ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); ++ // Neo: Used as a marker to skip registration elements that were disabled due to conditions ++ private static final Exception SKIPPED_ELEMENT_MARKER = new Exception(); + private final Object registryWriteLock = new Object(); + protected final RegistryDataLoader.RegistryData data; + private final WritableRegistry registry; +@@ -35,8 +_,11 @@ + private volatile boolean elementsRegistered; + + protected RegistryLoadTask(RegistryDataLoader.RegistryData data, Lifecycle lifecycle, Map, Exception> loadingErrors) { ++ var registryBuilder = new net.neoforged.neoforge.registries.RegistryBuilder<>(data.key()); ++ data.registryBuilderConsumer().accept(registryBuilder); ++ + this.data = data; +- this.registry = new MappedRegistry<>(data.key(), lifecycle); ++ this.registry = (WritableRegistry) registryBuilder.disableRegistrationCheck().create(); + this.loadingErrors = loadingErrors; + this.concurrentRegistrationGetter = new ConcurrentHolderGetter<>(this.registryWriteLock, this.registry.createRegistrationLookup()); + } +@@ -64,7 +_,13 @@ + elements.forEach( + element -> element.value + .ifLeft(value -> this.registry.register(element.key, (T)value, element.registrationInfo)) +- .ifRight(error -> this.loadingErrors.put(element.key, error)) ++ .ifRight(error -> { ++ if (error == SKIPPED_ELEMENT_MARKER) { ++ LOGGER.debug("Skipping loading registry entry {} as its conditions were not met", element.key); ++ } else { ++ this.loadingErrors.put(element.key, error); ++ } ++ }) + ); + this.elementsRegistered = true; + } +@@ -105,7 +_,15 @@ + Either var6; + try (Reader reader = thunk.openAsReader()) { + JsonElement json = StrictJsonParser.parse(reader); +- var6 = Either.left(elementDecoder.parse(ops, json).getOrThrow()); ++ ++ // Neo: Allow a condition to skip the entire element, in which case we return a special marker error to skip it in the loader. Look for uses of SKIPPED_ELEMENT_MARKER ++ var conditionalDecoder = net.neoforged.neoforge.common.conditions.ConditionalOps.createConditionalCodec(net.neoforged.neoforge.common.util.NeoForgeExtraCodecs.decodeOnly(elementDecoder)); ++ var candidate = conditionalDecoder.parse(ops, json).getOrThrow(); ++ if (candidate.isPresent()) { ++ var6 = Either.left(candidate.get()); ++ } else { ++ var6 = Either.right(SKIPPED_ELEMENT_MARKER); ++ } + } + + return var6; diff --git a/patches/net/minecraft/resources/ResourceManagerRegistryLoadTask.java.patch b/patches/net/minecraft/resources/ResourceManagerRegistryLoadTask.java.patch new file mode 100644 index 00000000000..ee22909c0ed --- /dev/null +++ b/patches/net/minecraft/resources/ResourceManagerRegistryLoadTask.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/resources/ResourceManagerRegistryLoadTask.java ++++ b/net/minecraft/resources/ResourceManagerRegistryLoadTask.java +@@ -40,7 +_,7 @@ + return CompletableFuture.>supplyAsync(() -> lister.listMatchingResources(this.resourceManager), executor) + .thenCompose( + registryResources -> { +- RegistryOps ops = RegistryOps.create(JsonOps.INSTANCE, context); ++ RegistryOps ops = new net.neoforged.neoforge.common.conditions.ConditionalOps<>(RegistryOps.create(JsonOps.INSTANCE, context), net.neoforged.neoforge.common.conditions.ICondition.IContext.TAGS_INVALID); + return ParallelMapTransform.schedule( + (Map)registryResources, + (resourceId, thunk) -> { diff --git a/patches/net/minecraft/server/MinecraftServer.java.patch b/patches/net/minecraft/server/MinecraftServer.java.patch index 047442b22b8..1bec48dbb8f 100644 --- a/patches/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/net/minecraft/server/MinecraftServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -282,7 +_,7 @@ +@@ -286,7 +_,7 @@ public static S spin(Function factory) { AtomicReference serverReference = new AtomicReference<>(); @@ -9,7 +9,7 @@ thread.setUncaughtExceptionHandler((t, e) -> LOGGER.error("Uncaught exception in server thread", e)); if (Runtime.getRuntime().availableProcessors() > 4) { thread.setPriority(8); -@@ -328,9 +_,9 @@ +@@ -332,9 +_,9 @@ this.structureTemplateManager = new StructureTemplateManager(worldStem.resourceManager(), storageSource, fixerUpper, blockLookup); this.serverThread = serverThread; this.executor = Util.backgroundExecutor(); @@ -21,7 +21,7 @@ this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick"); this.notificationManager = new NotificationManager(); this.serverActivityMonitor = new ServerActivityMonitor(this.notificationManager, 30); -@@ -412,6 +_,7 @@ +@@ -422,6 +_,7 @@ this.scoreboard.load(overworldDataStorage.computeIfAbsent(ScoreboardSaveData.TYPE).getData()); this.commandStorage = new CommandStorage(overworldDataStorage); this.stopwatches = overworldDataStorage.computeIfAbsent(Stopwatches.TYPE); @@ -29,7 +29,7 @@ if (!levelData.isInitialized()) { try { setInitialSpawn(overworld, levelData, worldOptions.generateBonusChest(), isDebug, this.levelLoadListener); -@@ -462,6 +_,7 @@ +@@ -472,6 +_,7 @@ randomSequences ); this.levels.put(dimension, level); @@ -37,15 +37,15 @@ } else { level = overworld; } -@@ -509,6 +_,7 @@ +@@ -519,6 +_,7 @@ levelData.setSpawn(LevelData.RespawnData.of(level.dimension(), BlockPos.ZERO.above(80), 0.0F, 0.0F)); } else { ServerChunkCache chunkSource = level.getChunkSource(); + if (net.neoforged.neoforge.event.EventHooks.onCreateWorldSpawn(level, levelData)) return; - ChunkPos spawnChunk = new ChunkPos(chunkSource.randomState().sampler().findSpawnPosition()); + ChunkPos spawnChunk = ChunkPos.containing(chunkSource.randomState().sampler().findSpawnPosition()); levelLoadListener.start(LevelLoadListener.Stage.PREPARE_GLOBAL_SPAWN, 0); levelLoadListener.updateFocus(level.dimension(), spawnChunk); -@@ -573,6 +_,7 @@ +@@ -583,6 +_,7 @@ TicketStorage savedTickets = level.getDataStorage().get(TicketStorage.TYPE); if (savedTickets != null) { savedTickets.activateAllDeactivatedTickets(); @@ -53,7 +53,7 @@ } }); } -@@ -691,6 +_,7 @@ +@@ -705,6 +_,7 @@ for (ServerLevel levelx : this.getAllLevels()) { if (levelx != null) { try { @@ -61,7 +61,7 @@ levelx.close(); } catch (IOException var5) { LOGGER.error("Exception closing the level", (Throwable)var5); -@@ -737,9 +_,11 @@ +@@ -751,9 +_,11 @@ throw new IllegalStateException("Failed to initialize server"); } @@ -73,7 +73,7 @@ while (this.running) { long thisTickNanos; -@@ -793,6 +_,8 @@ +@@ -807,6 +_,8 @@ this.isReady = true; JvmProfiler.INSTANCE.onServerTick(this.smoothedTickTimeMillis); } @@ -82,7 +82,7 @@ } catch (Throwable var69) { LOGGER.error("Encountered an unexpected exception", var69); CrashReport report = constructOrExtractCrashReport(var69); -@@ -804,6 +_,7 @@ +@@ -818,6 +_,7 @@ LOGGER.error("We were unable to save this crash report to disk."); } @@ -90,7 +90,7 @@ this.onServerCrash(report); } finally { try { -@@ -812,6 +_,7 @@ +@@ -826,6 +_,7 @@ } catch (Throwable var64) { LOGGER.error("Exception stopping the server", var64); } finally { @@ -98,7 +98,7 @@ this.onServerExit(); } } -@@ -1011,11 +_,13 @@ +@@ -1025,11 +_,13 @@ } this.tickCount++; @@ -112,7 +112,7 @@ } this.ticksUntilAutosave--; -@@ -1033,6 +_,7 @@ +@@ -1047,6 +_,7 @@ this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)tickTime / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F; this.logTickMethodTime(nano); profiler.pop(); @@ -120,7 +120,7 @@ } protected void processPacketsAndTick(boolean sprinting) { -@@ -1063,6 +_,16 @@ +@@ -1077,6 +_,16 @@ } } @@ -137,7 +137,7 @@ private int computeNextAutosaveInterval() { float ticksPerSecond; if (this.tickRateManager.isSprinting()) { -@@ -1094,7 +_,8 @@ +@@ -1108,7 +_,8 @@ Optional.of(players), Optional.of(ServerStatus.Version.current()), Optional.ofNullable(this.statusIcon), @@ -147,25 +147,20 @@ ); } -@@ -1126,7 +_,8 @@ - profiler.popPush("levels"); +@@ -1153,9 +_,11 @@ + profiler.push("levels"); this.updateEffectiveRespawnData(); - for (ServerLevel level : this.getAllLevels()) { + for (ServerLevel level : this.getWorldArray()) { + long tickStart = Util.getNanos(); profiler.push(() -> level + " " + level.dimension().identifier()); - if (this.tickCount % 20 == 0) { - profiler.push("timeSync"); -@@ -1135,6 +_,7 @@ - } - profiler.push("tick"); + net.neoforged.neoforge.event.EventHooks.fireLevelTickPre(level, haveTime); try { level.tick(haveTime); -@@ -1143,9 +_,11 @@ +@@ -1164,9 +_,11 @@ level.fillReportDetails(report); throw new ReportedException(report); } @@ -177,7 +172,7 @@ } profiler.popPush("connection"); -@@ -1154,8 +_,8 @@ +@@ -1175,8 +_,8 @@ this.playerList.tick(); profiler.popPush("debugSubscribers"); this.debugSubscribers.tick(); @@ -187,29 +182,17 @@ GameTestTicker.SINGLETON.tick(); } -@@ -1187,10 +_,17 @@ +@@ -1208,6 +_,9 @@ } - private void synchronizeTime(ServerLevel level) { -- this.playerList -- .broadcastAll( -- new ClientboundSetTimePacket(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME)), level.dimension() -- ); -+ ClientboundSetTimePacket vanillaPacket = new ClientboundSetTimePacket(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME)); -+ net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload neoPacket = new net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME), level.getDayTimeFraction(), level.getDayTimePerTick()); -+ for (ServerPlayer serverplayer : playerList.getPlayers()) { -+ if (serverplayer.level().dimension() == level.dimension()) { -+ if (serverplayer.connection.hasChannel(net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload.TYPE)) { -+ serverplayer.connection.send(neoPacket); -+ } else { -+ serverplayer.connection.send(vanillaPacket); -+ } -+ } + public void forceGameTimeSynchronization() { ++ if (this.overworld() == null) { ++ return; // Neo: Our ephemeral JUnit server has no overworld + } - } - - public void forceTimeSynchronization() { -@@ -1251,7 +_,7 @@ + ProfilerFiller profiler = Profiler.get(); + profiler.push("timeSync"); + this.playerList.broadcastAll(new ClientboundSetTimePacket(this.overworld().getGameTime(), Map.of())); +@@ -1261,7 +_,7 @@ } public String getServerModName() { @@ -217,8 +200,8 @@ + return net.neoforged.neoforge.internal.BrandingControl.getServerBranding(); } - public SystemReport fillSystemReport(SystemReport systemReport) { -@@ -1541,9 +_,9 @@ + public ServerClockManager clockManager() { +@@ -1555,9 +_,9 @@ public CompletableFuture reloadResources(Collection packsToEnable) { CompletableFuture result = CompletableFuture.supplyAsync( @@ -231,7 +214,7 @@ .map(Pack::open) .collect(ImmutableList.toImmutableList()), this -@@ -1582,7 +_,8 @@ +@@ -1596,7 +_,8 @@ this.getPlayerList().reloadResources(); this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary()); this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager); @@ -241,7 +224,7 @@ }, this); if (this.isSameThread()) { this.managedBlock(result::isDone); -@@ -1598,8 +_,10 @@ +@@ -1612,8 +_,10 @@ FeatureFlagSet forcedFeatures = initMode ? FeatureFlagSet.of() : initialDataConfig.enabledFeatures(); FeatureFlagSet allowedFeatures = initMode ? FeatureFlags.REGISTRY.allFlags() : initialDataConfig.enabledFeatures(); packRepository.reload(); @@ -253,7 +236,7 @@ } else { Set selected = Sets.newLinkedHashSet(); -@@ -1645,6 +_,8 @@ +@@ -1659,6 +_,8 @@ selected.add("vanilla"); } @@ -262,7 +245,7 @@ return configureRepositoryWithSelection(packRepository, selected, forcedFeatures, true); } } -@@ -1844,6 +_,31 @@ +@@ -1858,6 +_,31 @@ public abstract boolean isSingleplayerOwner(NameAndId nameAndId); @@ -294,14 +277,24 @@ public void dumpServerProperties(Path path) throws IOException { } -@@ -2002,6 +_,10 @@ - - public WorldData getWorldData() { +@@ -2022,6 +_,10 @@ return this.worldData; -+ } -+ + } + + public MinecraftServer.ReloadableResources getServerResources() { + return resources; ++ } ++ + public RegistryAccess.Frozen registryAccess() { + return this.registries.compositeAccess(); + } +@@ -2152,6 +_,9 @@ + } else if (rule == GameRules.ADVANCE_TIME) { + this.getPlayerList().broadcastAll(this.clockManager().createFullSyncPacket()); + } ++ ++ // Neo: Allow mods to react to game rule state changes ++ net.neoforged.neoforge.event.EventHooks.onGameRuleChanged(this, rule, value); } - public RegistryAccess.Frozen registryAccess() { + @Deprecated diff --git a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch index c35fb70b74c..f10865603a7 100644 --- a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch +++ b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -1,9 +1,10 @@ --- a/net/minecraft/server/ReloadableServerRegistries.java +++ b/net/minecraft/server/ReloadableServerRegistries.java -@@ -61,6 +_,16 @@ +@@ -60,7 +_,16 @@ + return CompletableFuture.supplyAsync(() -> { WritableRegistry registry = new MappedRegistry<>(type.registryKey(), Lifecycle.experimental()); Map elements = new HashMap<>(); - SimpleJsonResourceReloadListener.scanDirectory(manager, type.registryKey(), ops, type.codec(), elements); +- SimpleJsonResourceReloadListener.scanDirectory(manager, type.registryKey(), ops, type.codec(), elements); + var provider = net.neoforged.neoforge.common.CommonHooks.extractLookupProvider(ops); + Map> optionalMap = new HashMap<>(); + SimpleJsonResourceReloadListener.scanDirectoryWithOptionalValues(manager, type.registryKey(), ops, type.conditionalCodec(), optionalMap); diff --git a/patches/net/minecraft/server/ReloadableServerResources.java.patch b/patches/net/minecraft/server/ReloadableServerResources.java.patch index 25cac05b9ca..a9a537b8256 100644 --- a/patches/net/minecraft/server/ReloadableServerResources.java.patch +++ b/patches/net/minecraft/server/ReloadableServerResources.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/ReloadableServerResources.java +++ b/net/minecraft/server/ReloadableServerResources.java -@@ -42,6 +_,9 @@ +@@ -47,6 +_,9 @@ this.commands = new Commands(commandSelection, CommandBuildContext.simple(loadingContext, enabledFeatures)); this.advancements = new ServerAdvancementManager(loadingContext); this.functionLibrary = new ServerFunctionLibrary(functionCompilationPermissions, this.commands.getDispatcher()); @@ -10,7 +10,7 @@ } public ServerFunctionLibrary getFunctionLibrary() { -@@ -68,6 +_,25 @@ +@@ -73,6 +_,25 @@ return List.of(this.recipes, this.functionLibrary, this.advancements); } @@ -36,42 +36,49 @@ public static CompletableFuture loadResources( ResourceManager resourceManager, LayeredRegistryAccess contextLayers, -@@ -89,10 +_,30 @@ - updatedContextTags, - functionCompilationPermissions - ); +@@ -99,15 +_,35 @@ + functionCompilationPermissions, + (List>)pendingComponents + ); + -+ // Neo: Fire the AddServerReloadListenersEvent and use the resulting listeners instead of the vanilla listener list. -+ List listeners = net.neoforged.neoforge.event.EventHooks.onResourceReload(result, fullRegistries.layers().compositeAccess()); ++ // Neo: Fire the AddServerReloadListenersEvent and use the resulting listeners instead of the vanilla listener list. ++ List listeners = net.neoforged.neoforge.event.EventHooks.onResourceReload(result, fullRegistries.layers().compositeAccess()); + -+ // Neo: Inject the ConditionContext and RegistryLookup to any resource listener that requests it. -+ for (PreparableReloadListener rl : listeners) { -+ if (rl instanceof net.neoforged.neoforge.resource.ContextAwareReloadListener carl) { -+ carl.injectContext(result.context, result.registryLookup); -+ } -+ } -+ - return SimpleReloadInstance.create( -- resourceManager, result.listeners(), backgroundExecutor, mainThreadExecutor, DATA_RELOAD_INITIAL_TASK, LOGGER.isDebugEnabled() -+ resourceManager, listeners, backgroundExecutor, mainThreadExecutor, DATA_RELOAD_INITIAL_TASK, LOGGER.isDebugEnabled() - ) - .done() -+ .thenRun(() -> { -+ // Neo: Clear context after reload completes -+ result.context.clear(); -+ listeners.forEach(rl -> { -+ if (rl instanceof net.neoforged.neoforge.resource.ContextAwareReloadListener srl) { -+ srl.injectContext(net.neoforged.neoforge.common.conditions.ICondition.IContext.EMPTY, net.minecraft.core.RegistryAccess.EMPTY); ++ // Neo: Inject the ConditionContext and RegistryLookup to any resource listener that requests it. ++ for (PreparableReloadListener rl : listeners) { ++ if (rl instanceof net.neoforged.neoforge.resource.ContextAwareReloadListener carl) { ++ carl.injectContext(result.context, result.registryLookup); + } -+ }); -+ }) - .thenApply(ignore -> result); - } - ); -@@ -100,5 +_,6 @@ ++ } ++ + return SimpleReloadInstance.create( + resourceManager, +- result.listeners(), ++ listeners, + backgroundExecutor, + mainThreadExecutor, + DATA_RELOAD_INITIAL_TASK, + LOGGER.isDebugEnabled() + ) + .done() ++ .thenRun(() -> { ++ // Neo: Clear context after reload completes ++ result.context.clear(); ++ listeners.forEach(rl -> { ++ if (rl instanceof net.neoforged.neoforge.resource.ContextAwareReloadListener srl) { ++ srl.injectContext(net.neoforged.neoforge.common.conditions.ICondition.IContext.EMPTY, net.minecraft.core.RegistryAccess.EMPTY); ++ } ++ }); ++ }) + .thenApply(ignore -> result); + } + ) +@@ -116,6 +_,8 @@ - public void updateStaticRegistryTags() { + public void updateComponentsAndStaticRegistryTags() { this.postponedTags.forEach(Registry.PendingTags::apply); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.TagsUpdatedEvent(registryLookup, false, false)); + this.newComponents.forEach(DataComponentInitializers.PendingComponents::apply); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.DefaultDataComponentsBoundEvent(false, false)); } } diff --git a/patches/net/minecraft/server/WorldLoader.java.patch b/patches/net/minecraft/server/WorldLoader.java.patch index 23e864dfc81..bcdd09e08d3 100644 --- a/patches/net/minecraft/server/WorldLoader.java.patch +++ b/patches/net/minecraft/server/WorldLoader.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/server/WorldLoader.java +++ b/net/minecraft/server/WorldLoader.java -@@ -41,7 +_,7 @@ - RegistryAccess.Frozen worldgenLoadContext = initialLayers.getAccessForLoading(RegistryLayer.WORLDGEN); - List> worldgenContextRegistries = TagLoader.buildUpdatedLookups(worldgenLoadContext, staticLayerTags); - RegistryAccess.Frozen loadedWorldgenRegistries = RegistryDataLoader.load( -- resources, worldgenContextRegistries, RegistryDataLoader.WORLDGEN_REGISTRIES -+ resources, worldgenContextRegistries, net.neoforged.neoforge.registries.DataPackRegistriesHooks.getDataPackRegistries() - ); - List> dimensionContextRegistries = Stream.concat( - worldgenContextRegistries.stream(), loadedWorldgenRegistries.listRegistries() +@@ -39,7 +_,7 @@ + ); + RegistryAccess.Frozen worldgenLoadContext = initialLayers.getAccessForLoading(RegistryLayer.WORLDGEN); + List> worldgenContextRegistries = TagLoader.buildUpdatedLookups(worldgenLoadContext, staticLayerTags); +- return RegistryDataLoader.load(resources, worldgenContextRegistries, RegistryDataLoader.WORLDGEN_REGISTRIES, backgroundExecutor) ++ return RegistryDataLoader.load(resources, worldgenContextRegistries, net.neoforged.neoforge.registries.DataPackRegistriesHooks.getDataPackRegistries(), backgroundExecutor) + .thenComposeAsync( + loadedWorldgenRegistries -> { + List> dimensionContextRegistries = Stream.concat( diff --git a/patches/net/minecraft/server/commands/ForceLoadCommand.java.patch b/patches/net/minecraft/server/commands/ForceLoadCommand.java.patch index dd277d9ce7a..143ca717581 100644 --- a/patches/net/minecraft/server/commands/ForceLoadCommand.java.patch +++ b/patches/net/minecraft/server/commands/ForceLoadCommand.java.patch @@ -17,7 +17,7 @@ } @@ -112,16 +_,16 @@ - String chunkList = Joiner.on(", ").join(forcedChunks.stream().sorted().map(ChunkPos::new).map(ChunkPos::toString).iterator()); + String chunkList = Joiner.on(", ").join(forcedChunks.stream().sorted().map(ChunkPos::unpack).map(ChunkPos::toString).iterator()); if (chunkCount == 1) { source.sendSuccess( - () -> Component.translatable("commands.forceload.list.single", Component.translationArg(dimension.identifier()), chunkList), false diff --git a/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch b/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch index 94e21a9ac4a..dde04482ca0 100644 --- a/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -93,6 +_,7 @@ +@@ -97,6 +_,7 @@ private final Map codeOfConductTexts; private @Nullable ManagementServer jsonRpcServer; private long lastHeartbeat; @@ -8,15 +8,15 @@ public DedicatedServer( Thread serverThread, -@@ -191,6 +_,7 @@ - Thread consoleThread = new Thread("Server console handler") { +@@ -199,6 +_,7 @@ + @Override public void run() { + if (net.neoforged.neoforge.server.console.TerminalHandler.handleCommands(DedicatedServer.this)) return; BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); String line; -@@ -264,11 +_,13 @@ +@@ -272,11 +_,13 @@ this.tickTimeLogger = new RemoteSampleLogger(TpsDebugDimensions.values().length, this.debugSubscribers(), RemoteDebugSampleType.TICK_TIME); long levelNanoTime = Util.getNanos(); this.services.nameToIdCache().resolveOfflineUsers(!this.usesAuthentication()); @@ -30,7 +30,7 @@ if (properties.announcePlayerAchievements != null) { this.worldData.getGameRules().set(GameRules.SHOW_ADVANCEMENT_MESSAGES, properties.announcePlayerAchievements, this); } -@@ -297,6 +_,12 @@ +@@ -305,6 +_,12 @@ } this.notificationManager().serverStarted(); @@ -43,7 +43,7 @@ return true; } } -@@ -431,6 +_,11 @@ +@@ -450,6 +_,11 @@ this.queryThreadGs4.stop(); } @@ -55,7 +55,7 @@ if (this.jsonRpcServer != null) { try { this.jsonRpcServer.stop(true); -@@ -720,7 +_,12 @@ +@@ -739,7 +_,12 @@ @Override protected void stopServer() { this.notificationManager().serverShuttingDown(); diff --git a/patches/net/minecraft/server/dedicated/ServerWatchdog.java.patch b/patches/net/minecraft/server/dedicated/ServerWatchdog.java.patch index 9e506ee1463..4f4e51bc126 100644 --- a/patches/net/minecraft/server/dedicated/ServerWatchdog.java.patch +++ b/patches/net/minecraft/server/dedicated/ServerWatchdog.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/dedicated/ServerWatchdog.java +++ b/net/minecraft/server/dedicated/ServerWatchdog.java -@@ -45,7 +_,13 @@ +@@ -46,7 +_,13 @@ String.format(Locale.ROOT, "%.2f", this.server.tickRateManager().millisecondsPerTick() / (float)TimeUtil.MILLISECONDS_PER_SECOND) ); LOGGER.error(LogUtils.FATAL_MARKER, "Considering it to be crashed, server will forcibly shutdown."); @@ -15,7 +15,7 @@ this.server.fillSystemReport(report.getSystemReport()); CrashReportCategory serverStats = report.addCategory("Performance stats"); serverStats.setDetail("Random tick rate", () -> this.server.getWorldData().getGameRules().getAsString(GameRules.RANDOM_TICK_SPEED)); -@@ -74,17 +_,21 @@ +@@ -75,17 +_,21 @@ } public static CrashReport createWatchdogCrashReport(String message, long mainThreadId) { diff --git a/patches/net/minecraft/server/gui/MinecraftServerGui.java.patch b/patches/net/minecraft/server/gui/MinecraftServerGui.java.patch index 6a3968ceb85..3ab260c1bec 100644 --- a/patches/net/minecraft/server/gui/MinecraftServerGui.java.patch +++ b/patches/net/minecraft/server/gui/MinecraftServerGui.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/gui/MinecraftServerGui.java +++ b/net/minecraft/server/gui/MinecraftServerGui.java -@@ -136,8 +_,10 @@ +@@ -141,8 +_,10 @@ return panel; } @@ -11,7 +11,7 @@ } public void close() { -@@ -151,6 +_,9 @@ +@@ -156,6 +_,9 @@ } public void print(JTextArea console, JScrollPane scrollPane, String line) { diff --git a/patches/net/minecraft/server/level/ChunkHolder.java.patch b/patches/net/minecraft/server/level/ChunkHolder.java.patch new file mode 100644 index 00000000000..166ff660052 --- /dev/null +++ b/patches/net/minecraft/server/level/ChunkHolder.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/level/ChunkHolder.java ++++ b/net/minecraft/server/level/ChunkHolder.java +@@ -230,6 +_,7 @@ + if (packet != null) { + this.broadcast(players, packet); + } ++ net.neoforged.neoforge.attachment.AttachmentSync.syncBlockEntityUpdates(blockEntity, players); + } + } + diff --git a/patches/net/minecraft/server/level/ChunkMap.java.patch b/patches/net/minecraft/server/level/ChunkMap.java.patch index 3ed1a6213f9..fab4c274254 100644 --- a/patches/net/minecraft/server/level/ChunkMap.java.patch +++ b/patches/net/minecraft/server/level/ChunkMap.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java -@@ -390,6 +_,7 @@ +@@ -391,6 +_,7 @@ this.modified = true; } @@ -8,12 +8,12 @@ return chunk; } } -@@ -519,12 +_,15 @@ +@@ -520,12 +_,15 @@ } else { ChunkAccess chunk = chunkHolder.getLatestChunk(); if (this.pendingUnloads.remove(pos, chunkHolder) && chunk != null) { + net.neoforged.neoforge.common.CommonHooks.onChunkUnload(this.poiManager, chunk); // Neo: Must be called for all chunk unloading. Not just LevelChunks. -+ this.chunkTypeCache.remove(chunk.getPos().toLong()); // Neo: Prevent chunk type cache from permanently retaining data for unloaded chunks ++ this.chunkTypeCache.remove(chunk.getPos().pack()); // Neo: Prevent chunk type cache from permanently retaining data for unloaded chunks if (chunk instanceof LevelChunk levelChunk) { levelChunk.setLoaded(false); } @@ -24,7 +24,7 @@ this.level.unload(levelChunk); } -@@ -567,6 +_,7 @@ +@@ -568,6 +_,7 @@ Profiler.get().incrementCounter("chunkLoad"); if (chunkData.isPresent()) { ChunkAccess chunk = chunkData.get().read(this.level, this.poiManager, this.storageInfo(), pos); @@ -32,7 +32,7 @@ this.markPosition(pos, chunk.getPersistedStatus().getChunkType()); return chunk; } else { -@@ -763,6 +_,7 @@ +@@ -761,6 +_,7 @@ Profiler.get().incrementCounter("chunkSave"); this.activeChunkWrites.incrementAndGet(); SerializableChunkData data = SerializableChunkData.copyOf(this.level, chunk); @@ -40,7 +40,7 @@ CompletableFuture encodedData = CompletableFuture.supplyAsync(data::write, Util.backgroundExecutor()); this.write(pos, encodedData::join).handle((ignored, throwable) -> { if (throwable != null) { -@@ -829,9 +_,11 @@ +@@ -827,9 +_,11 @@ private static void markChunkPendingToSend(ServerPlayer player, LevelChunk chunk) { player.connection.chunkSender.markChunkPendingToSend(chunk); @@ -52,7 +52,7 @@ player.connection.chunkSender.dropChunk(player, pos); } -@@ -934,7 +_,7 @@ +@@ -937,7 +_,7 @@ ChunkHolder holder = this.visibleChunkMap.get(spawnCandidateChunks.nextLong()); if (holder != null) { LevelChunk chunk = holder.getTickingChunk(); @@ -61,7 +61,7 @@ output.add(chunk); } } -@@ -958,6 +_,19 @@ +@@ -961,6 +_,19 @@ return triState == TriState.DEFAULT ? this.anyPlayerCloseEnoughForSpawningInternal(pos) : triState.toBoolean(true); } @@ -81,7 +81,7 @@ boolean anyPlayerCloseEnoughTo(BlockPos pos, int maxDistance) { Vec3 target = new Vec3(pos); -@@ -1087,6 +_,7 @@ +@@ -1090,6 +_,7 @@ this.playerMap.unIgnorePlayer(player); } @@ -89,7 +89,7 @@ this.updateChunkTracking(player); } } -@@ -1131,7 +_,7 @@ +@@ -1134,7 +_,7 @@ } protected void addEntity(Entity entity) { @@ -98,7 +98,7 @@ EntityType type = entity.getType(); int range = type.clientTrackingRange() * 16; if (range != 0) { -@@ -1290,6 +_,20 @@ +@@ -1293,6 +_,20 @@ } } @@ -118,8 +118,8 @@ + private class DistanceManager extends net.minecraft.server.level.DistanceManager { protected DistanceManager(TicketStorage ticketStorage, Executor executor, Executor mainThreadExecutor) { - super(ticketStorage, executor, mainThreadExecutor); -@@ -1421,5 +_,20 @@ + Objects.requireNonNull(ChunkMap.this); +@@ -1428,5 +_,20 @@ this.updatePlayer(player); } } diff --git a/patches/net/minecraft/server/level/ServerLevel.java.patch b/patches/net/minecraft/server/level/ServerLevel.java.patch index 70e407904ad..75bb7ca4e1c 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 -@@ -214,7 +_,7 @@ +@@ -216,7 +_,7 @@ private boolean handlingTick; private final List customSpawners; private @Nullable EndDragonFight dragonFight; @@ -9,7 +9,7 @@ private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; -@@ -237,7 +_,6 @@ +@@ -239,7 +_,6 @@ super(levelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates()); this.tickTime = tickTime; this.server = server; @@ -17,7 +17,7 @@ this.serverLevelData = levelData; ChunkGenerator generator = levelStem.generator(); boolean syncWrites = server.forceSynchronousWrites(); -@@ -304,6 +_,11 @@ +@@ -306,6 +_,11 @@ this.waypointManager = new ServerWaypointManager(); this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build(); this.updateSkyBrightness(); @@ -29,16 +29,20 @@ } @Deprecated -@@ -351,7 +_,7 @@ +@@ -357,7 +_,11 @@ if (this.sleepStatus.areEnoughSleeping(percentage) && this.sleepStatus.areEnoughDeepSleeping(percentage, this.players)) { - if (this.getGameRules().get(GameRules.ADVANCE_TIME)) { - long newTime = this.levelData.getDayTime() + 24000L; -- this.setDayTime(newTime - newTime % 24000L); -+ this.setDayTime(net.neoforged.neoforge.event.EventHooks.onSleepFinished(this, newTime - newTime % 24000L, this.getDayTime())); + Optional> defaultClock = this.dimensionType().defaultClock(); + if (this.getGameRules().get(GameRules.ADVANCE_TIME) && defaultClock.isPresent()) { +- this.server.clockManager().skipToTimeMarker(defaultClock.get(), ClockTimeMarkers.WAKE_UP_FROM_SLEEP); ++ // Neo: Allow mods to control how the clock is adjusted after sleep ++ var adjustment = net.neoforged.neoforge.event.EventHooks.onSleepFinished(this, new net.neoforged.neoforge.common.util.ClockAdjustment.Marker(ClockTimeMarkers.WAKE_UP_FROM_SLEEP)); ++ if (adjustment != null) { ++ adjustment.apply(this.server.clockManager(), defaultClock.get()); ++ } } this.wakeUpAllPlayers(); -@@ -389,7 +_,7 @@ +@@ -395,7 +_,7 @@ this.handlingTick = false; profiler.pop(); @@ -47,7 +51,7 @@ if (isActive) { this.resetEmptyTime(); } -@@ -426,7 +_,9 @@ +@@ -432,7 +_,9 @@ } profiler.push("tick"); @@ -58,16 +62,7 @@ profiler.pop(); } } -@@ -467,7 +_,7 @@ - this.serverLevelData.getScheduledEvents().tick(this.server, time); - Profiler.get().pop(); - if (this.getGameRules().get(GameRules.ADVANCE_TIME)) { -- this.setDayTime(this.levelData.getDayTime() + 1L); -+ this.setDayTime(this.levelData.getDayTime() + advanceDaytime()); - } - } - } -@@ -577,6 +_,7 @@ +@@ -572,6 +_,7 @@ BlockPos topPos = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos); BlockPos belowPos = topPos.below(); Biome biome = this.getBiome(topPos).value(); @@ -75,7 +70,7 @@ if (biome.shouldFreeze(this, belowPos)) { this.setBlockAndUpdate(belowPos, Blocks.ICE.defaultBlockState()); } -@@ -769,15 +_,19 @@ +@@ -764,15 +_,19 @@ .broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, this.thunderLevel), this.dimension()); } @@ -99,9 +94,9 @@ } } -@@ -814,7 +_,11 @@ +@@ -809,7 +_,11 @@ entity.tickCount++; - profiler.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString()); + profiler.push(entity.typeHolder()::getRegisteredName); profiler.incrementCounter("tickNonPassenger"); - entity.tick(); + // Neo: Permit cancellation of Entity#tick via EntityTickEvent.Pre @@ -112,7 +107,7 @@ profiler.pop(); for (Entity passenger : entity.getPassengers()) { -@@ -877,6 +_,7 @@ +@@ -872,6 +_,7 @@ } else { this.entityManager.autoSave(); } @@ -120,7 +115,7 @@ } } -@@ -970,6 +_,7 @@ +@@ -965,6 +_,7 @@ } private void addPlayer(ServerPlayer player) { @@ -128,7 +123,7 @@ Entity existing = this.getEntity(player.getUUID()); if (existing != null) { LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID()); -@@ -977,7 +_,8 @@ +@@ -972,7 +_,8 @@ this.removePlayerImmediately((ServerPlayer)existing, Entity.RemovalReason.DISCARDED); } @@ -138,8 +133,8 @@ } private boolean addEntity(Entity entity) { -@@ -985,7 +_,12 @@ - LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityType.getKey(entity.getType())); +@@ -980,7 +_,12 @@ + LOGGER.warn("Tried to add entity {} but it was marked as removed already", entity.typeHolder().getRegisteredName()); return false; } else { - return this.entityManager.addNewEntity(entity); @@ -152,7 +147,7 @@ } } -@@ -1026,6 +_,12 @@ +@@ -1021,6 +_,12 @@ public void playSeededSound( @Nullable Entity except, double x, double y, double z, Holder sound, SoundSource source, float volume, float pitch, long seed ) { @@ -165,7 +160,7 @@ this.server .getPlayerList() .broadcast( -@@ -1043,6 +_,12 @@ +@@ -1038,6 +_,12 @@ public void playSeededSound( @Nullable Entity except, Entity sourceEntity, Holder sound, SoundSource source, float volume, float pitch, long seed ) { @@ -178,7 +173,7 @@ this.server .getPlayerList() .broadcast( -@@ -1101,6 +_,7 @@ +@@ -1096,6 +_,7 @@ @Override public void gameEvent(Holder gameEvent, Vec3 position, GameEvent.Context context) { @@ -186,7 +181,7 @@ this.gameEventDispatcher.post(gameEvent, position, context); } -@@ -1139,6 +_,7 @@ +@@ -1134,6 +_,7 @@ @Override public void updateNeighborsAt(BlockPos pos, Block sourceBlock) { @@ -194,7 +189,7 @@ this.updateNeighborsAt(pos, sourceBlock, ExperimentalRedstoneUtils.initialOrientation(this, null, null)); } -@@ -1149,6 +_,10 @@ +@@ -1144,6 +_,10 @@ @Override public void updateNeighborsAtExceptFromFacing(BlockPos pos, Block blockObject, Direction skipDirection, @Nullable Orientation orientation) { @@ -205,7 +200,7 @@ this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, blockObject, skipDirection, orientation); } -@@ -1195,7 +_,7 @@ +@@ -1190,7 +_,7 @@ Explosion.BlockInteraction blockInteraction = switch (interactionType) { case NONE -> Explosion.BlockInteraction.KEEP; case BLOCK -> this.getDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY); @@ -214,7 +209,7 @@ ? this.getDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP; case TNT -> this.getDestroyType(GameRules.TNT_EXPLOSION_DROP_DECAY); -@@ -1203,6 +_,7 @@ +@@ -1198,6 +_,7 @@ }; Vec3 center = new Vec3(x, y, z); ServerExplosion explosion = new ServerExplosion(this, source, damageSource, damageCalculator, center, r, fire, blockInteraction); @@ -222,7 +217,7 @@ int blockCount = explosion.explode(); ParticleOptions explosionParticle = explosion.isSmall() ? smallExplosionParticles : largeExplosionParticles; -@@ -1380,7 +_,7 @@ +@@ -1375,7 +_,7 @@ } @Override @@ -231,7 +226,7 @@ return this.dragonParts.values(); } -@@ -1898,8 +_,8 @@ +@@ -1899,8 +_,8 @@ ServerLevel.this.navigatingMobs.add(mob); } @@ -242,7 +237,7 @@ ServerLevel.this.dragonParts.put(subEntity.getId(), subEntity); } } -@@ -1919,25 +_,107 @@ +@@ -1920,25 +_,62 @@ if (ServerLevel.this.isUpdatingNavigations) { String message = "onTrackingStart called during navigation iteration"; Util.logAndPauseIfInIde( @@ -272,7 +267,7 @@ public void onSectionChange(Entity entity) { entity.updateDynamicGameEventListener(DynamicGameEventListener::move); } - } ++ } + + @Override + public final void syncData(net.neoforged.neoforge.attachment.AttachmentType type) { @@ -306,50 +301,5 @@ + @org.jetbrains.annotations.ApiStatus.Internal + public void cleanCapabilityListenerReferences() { + capListenerHolder.clean(); -+ } -+ -+ // Neo: Variable day time code -+ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public void setDayTimeFraction(float dayTimeFraction) { -+ serverLevelData.setDayTimeFraction(dayTimeFraction); -+ } -+ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public float getDayTimeFraction() { -+ return serverLevelData.getDayTimeFraction(); -+ } -+ -+ /** -+ * Returns the current ratio between game ticks and clock ticks. If this value is negative, no -+ * speed has been set and those two are coupled 1:1 (i.e. vanilla mode). -+ */ -+ public float getDayTimePerTick() { -+ return serverLevelData.getDayTimePerTick(); -+ } -+ -+ /** -+ * This allows mods to set the rate time flows in a level. By default, each game tick the clock time -+ * also advances by one tick, with {@link Level#TICKS_PER_DAY} clock ticks (or 20 real-life minutes) -+ * forming a Minecraft day. -+ *

-+ * This can be sped up for shorter days by giving a higher number, or slowed down for longer days -+ * with a smaller number. A negative value will reset it back to vanilla logic. -+ *

-+ * This value can also be changed with the command /neoforge day, where you can set -+ * either the speed or a day length in minutes. -+ *

-+ * This has no effect when time progression is stopped. -+ *

-+ * While this still technically works when vanilla clients are connected, those will desync and -+ * experience a time jump once per second. -+ */ -+ @Override -+ public void setDayTimePerTick(float dayTimePerTick) { -+ if (dayTimePerTick != getDayTimePerTick() && dayTimePerTick != 0f) { -+ serverLevelData.setDayTimePerTick(dayTimePerTick); -+ server.forceTimeSynchronization(); -+ } -+ } -+ + } } diff --git a/patches/net/minecraft/server/level/ServerPlayer.java.patch b/patches/net/minecraft/server/level/ServerPlayer.java.patch index 2f924180c32..c65078e2637 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 -@@ -310,6 +_,10 @@ +@@ -321,6 +_,10 @@ } private void broadcastDataValue(AbstractContainerMenu container, int id, int value) { @@ -11,28 +11,44 @@ ServerPlayer.this.connection.send(new ClientboundContainerSetDataPacket(container.containerId, id, value)); } -@@ -359,6 +_,7 @@ +@@ -378,6 +_,8 @@ private Set> requestedDebugSubscriptions = Set.of(); private int containerCounter; public boolean wonGame; -+ private long lastDayTimeTick = -1L; // Neo: Used to limit TIME_SINCE_REST increases when day length is non-standard. No need to persist, at most Phantoms will spawn one tick too early for each save/load cycle. ++ // Neo: Used to track partial TIME_SINCE_REST increases for dimensions in which clocks move at different speeds. No need to persist, at most Phantoms will spawn one tick too early for each save/load cycle. ++ private float partialTimeSinceRestTick; public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) { super(level, gameProfile); -@@ -656,7 +_,11 @@ +@@ -675,7 +_,26 @@ } if (!this.isSleeping()) { - this.awardStat(Stats.TIME_SINCE_REST); + // Neo: Advance TIME_SINCE_REST if (a) vanilla daytime handling in effect, or (b) days are shorter, or (c) dayTime has ticked, or (d) dayTime advances are off and we need to ignore day length -+ if (level().getDayTimeFraction() < 0 || level().getDayTimeFraction() >= 1 || lastDayTimeTick != level().getDayTime() || !level().getGameRules().get(GameRules.ADVANCE_TIME)) { -+ lastDayTimeTick = level().getDayTime(); ++ var defaultClock = level().dimensionType().defaultClock(); ++ if (defaultClock.isEmpty() || !level().getGameRules().get(GameRules.ADVANCE_TIME)) { ++ // TODO 26.1: It's debatable whether this should advance in a dimension with no clock BUT in Vanilla it does! + this.awardStat(Stats.TIME_SINCE_REST); ++ } else { ++ var speed = level().clockManager().getSpeed(defaultClock.get()); ++ var fullTicks = (int) speed; ++ partialTimeSinceRestTick += speed; ++ if (partialTimeSinceRestTick >= 1) { ++ partialTimeSinceRestTick = 0; ++ fullTicks++; ++ } ++ ++ for (int i = 0; i < fullTicks; i++) { ++ this.awardStat(Stats.TIME_SINCE_REST); ++ } + } ++ } else { ++ partialTimeSinceRestTick = 0; } } -@@ -711,6 +_,11 @@ +@@ -730,6 +_,11 @@ this.connection.send(new ClientboundSetExperiencePacket(this.experienceProgress, this.totalExperience, this.experienceLevel)); } @@ -44,7 +60,7 @@ if (this.tickCount % 20 == 0) { CriteriaTriggers.LOCATION.trigger(this); } -@@ -724,7 +_,7 @@ +@@ -743,7 +_,7 @@ private void synchronizeSpecialItemUpdates(ItemStack itemStack) { MapId mapId = itemStack.get(DataComponents.MAP_ID); @@ -53,7 +69,7 @@ if (data != null) { Packet packet = data.getUpdatePacket(mapId, this); if (packet != null) { -@@ -871,6 +_,7 @@ +@@ -890,6 +_,7 @@ @Override public void die(DamageSource source) { this.gameEvent(GameEvent.ENTITY_DIE); @@ -61,7 +77,7 @@ boolean showDeathMessage = this.level().getGameRules().get(GameRules.SHOW_DEATH_MESSAGES); if (showDeathMessage) { Component deathMessage = this.getCombatTracker().getDeathMessage(); -@@ -1054,7 +_,7 @@ +@@ -1073,7 +_,7 @@ return BedBlock.findStandUpPosition(EntityType.PLAYER, level, pos, blockState.getValue(BedBlock.FACING), yaw) .map(p -> ServerPlayer.RespawnPosAngle.of(p, pos, 0.0F)); } else if (!forced) { @@ -70,7 +86,7 @@ } else { boolean freeBottom = block.isPossibleToRespawnInThis(blockState); BlockState topState = level.getBlockState(pos.above()); -@@ -1076,6 +_,7 @@ +@@ -1095,6 +_,7 @@ } public @Nullable ServerPlayer teleport(TeleportTransition transition) { @@ -78,7 +94,7 @@ if (this.isRemoved()) { return null; } else { -@@ -1103,7 +_,7 @@ +@@ -1122,7 +_,7 @@ PlayerList playerList = this.server.getPlayerList(); playerList.sendPlayerPermissionLevel(this); oldLevel.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); @@ -87,7 +103,7 @@ ProfilerFiller profiler = Profiler.get(); profiler.push("moving"); if (lastDimension == Level.OVERWORLD && newLevel.dimension() == Level.NETHER) { -@@ -1123,11 +_,15 @@ +@@ -1142,11 +_,15 @@ playerList.sendLevelInfo(this, newLevel); playerList.sendAllPlayerInfo(this); playerList.sendActivePlayerEffects(this); @@ -103,7 +119,7 @@ return this; } } -@@ -1169,8 +_,19 @@ +@@ -1188,8 +_,19 @@ @Override public Either startSleepInBed(BlockPos pos) { @@ -124,7 +140,7 @@ BedRule rule = this.level().environmentAttributes().getValue(EnvironmentAttributes.BED_RULE, pos); boolean canSleep = rule.canSleep(this.level()); boolean canSetSpawn = rule.canSetSpawn(this.level()); -@@ -1212,6 +_,23 @@ +@@ -1231,6 +_,23 @@ } } @@ -148,7 +164,7 @@ Either result = super.startSleepInBed(pos).ifRight(unit -> { this.awardStat(Stats.SLEEP_IN_BED); CriteriaTriggers.SLEPT_IN_BED.trigger(this); -@@ -1224,8 +_,6 @@ +@@ -1243,8 +_,6 @@ return result; } } @@ -157,7 +173,7 @@ } } -@@ -1236,6 +_,7 @@ +@@ -1255,6 +_,7 @@ } private boolean bedInRange(BlockPos pos, Direction direction) { @@ -165,7 +181,7 @@ return this.isReachableBedBlock(pos) || this.isReachableBedBlock(pos.relative(direction.getOpposite())); } -@@ -1320,11 +_,19 @@ +@@ -1338,11 +_,19 @@ @Override public OptionalInt openMenu(@Nullable MenuProvider provider) { @@ -185,7 +201,7 @@ } this.nextContainerCounter(); -@@ -1336,9 +_,31 @@ +@@ -1354,9 +_,31 @@ return OptionalInt.empty(); } else { @@ -217,7 +233,7 @@ return OptionalInt.of(this.containerCounter); } } -@@ -1360,6 +_,7 @@ +@@ -1378,6 +_,7 @@ this.connection.send(new ClientboundMountScreenOpenPacket(this.containerCounter, inventoryColumns, horse.getId())); this.containerMenu = new HorseInventoryMenu(this.containerCounter, this.getInventory(), container, horse, inventoryColumns); this.initMenu(this.containerMenu); @@ -225,7 +241,7 @@ } @Override -@@ -1401,6 +_,7 @@ +@@ -1419,6 +_,7 @@ public void doCloseContainer() { this.containerMenu.removed(this); this.inventoryMenu.transferState(this.containerMenu); @@ -233,7 +249,7 @@ this.containerMenu = this.inventoryMenu; } -@@ -1623,6 +_,15 @@ +@@ -1641,6 +_,15 @@ this.setShoulderEntityRight(oldPlayer.getShoulderEntityRight()); this.setLastDeathLocation(oldPlayer.getLastDeathLocation()); this.waypointIcon().copyFrom(oldPlayer.waypointIcon()); @@ -249,7 +265,7 @@ } private void transferInventoryXpAndScore(Player oldPlayer) { -@@ -1725,6 +_,8 @@ +@@ -1743,6 +_,8 @@ public boolean setGameMode(GameType mode) { boolean wasSpectator = this.isSpectator(); @@ -258,7 +274,7 @@ if (!this.gameMode.changeGameModeForPlayer(mode)) { return false; } else { -@@ -1894,6 +_,7 @@ +@@ -1912,6 +_,7 @@ public void setCamera(@Nullable Entity newCamera) { Entity oldCamera = this.getCamera(); this.camera = (Entity)(newCamera == null ? this : newCamera); @@ -266,7 +282,7 @@ if (oldCamera != this.camera) { if (this.camera.level() instanceof ServerLevel level) { this.teleportTo(level, this.camera.getX(), this.camera.getY(), this.camera.getZ(), Set.of(), this.getYRot(), this.getXRot(), false); -@@ -1929,7 +_,11 @@ +@@ -1938,7 +_,11 @@ } public @Nullable Component getTabListDisplayName() { @@ -279,7 +295,7 @@ } public int getTabListOrder() { -@@ -1963,6 +_,7 @@ +@@ -1972,6 +_,7 @@ } public void setRespawnPosition(ServerPlayer.@Nullable RespawnConfig respawnConfig, boolean showMessage) { @@ -287,7 +303,7 @@ if (showMessage && respawnConfig != null && !respawnConfig.isSamePosition(this.respawnConfig)) { this.sendSystemMessage(SPAWN_SET_MESSAGE); } -@@ -2000,6 +_,75 @@ +@@ -2009,6 +_,75 @@ return entity; } @@ -363,7 +379,7 @@ public TextFilter getTextFilter() { return this.textFilter; } -@@ -2014,6 +_,7 @@ +@@ -2023,6 +_,7 @@ } private GameType calculateGameModeForNewPlayer(@Nullable GameType loadedGameType) { @@ -371,7 +387,7 @@ GameType forcedGameType = this.server.getForcedGameType(); if (forcedGameType != null) { return forcedGameType; -@@ -2050,6 +_,8 @@ +@@ -2059,6 +_,8 @@ public void drop(boolean all) { Inventory inventory = this.getInventory(); @@ -380,7 +396,7 @@ ItemStack removed = inventory.removeFromSelected(all); this.containerMenu .findSlot(inventory, inventory.getSelectedSlot()) -@@ -2058,7 +_,7 @@ +@@ -2067,7 +_,7 @@ this.stopUsingItem(); } diff --git a/patches/net/minecraft/server/network/ServerConnectionListener.java.patch b/patches/net/minecraft/server/network/ServerConnectionListener.java.patch index 16a34c29072..243f1ab0889 100644 --- a/patches/net/minecraft/server/network/ServerConnectionListener.java.patch +++ b/patches/net/minecraft/server/network/ServerConnectionListener.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/ServerConnectionListener.java +++ b/net/minecraft/server/network/ServerConnectionListener.java -@@ -38,6 +_,7 @@ +@@ -39,6 +_,7 @@ public class ServerConnectionListener { private static final Logger LOGGER = LogUtils.getLogger(); @@ -8,7 +8,7 @@ private final MinecraftServer server; public volatile boolean running; private final List channels = Collections.synchronizedList(Lists.newArrayList()); -@@ -49,6 +_,8 @@ +@@ -50,6 +_,8 @@ } public void startTcpServerListener(@Nullable InetAddress address, int port) throws IOException { @@ -17,7 +17,7 @@ synchronized (this.channels) { EventLoopGroupHolder eventLoopGroupHolder = EventLoopGroupHolder.remote(this.server.useNativeTransport()); this.channels -@@ -64,7 +_,7 @@ +@@ -69,7 +_,7 @@ } catch (ChannelException var5) { } @@ -26,7 +26,7 @@ if (ServerConnectionListener.this.server.repliesToStatus()) { pipeline.addLast("legacy_query", new LegacyQueryHandler(ServerConnectionListener.this.getServer())); } -@@ -82,7 +_,7 @@ +@@ -87,7 +_,7 @@ } } ) @@ -35,7 +35,7 @@ .localAddress(address, port) .bind() .syncUninterruptibly() -@@ -117,7 +_,7 @@ +@@ -126,7 +_,7 @@ } } ) diff --git a/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 3d171d4ebe7..8e7f889992d 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 -@@ -484,18 +_,21 @@ +@@ -490,18 +_,21 @@ if (fail && level.noCollision(vehicle, oldAABB) || this.isEntityCollidingWithAnythingNew(level, vehicle, oldAABB, targetX, targetY, targetZ)) { vehicle.absSnapTo(oldX, oldY, oldZ, targetYRot, targetXRot); @@ -22,7 +22,7 @@ this.clientVehicleIsFloating = oyDist >= -0.03125 && !vehicleRestsOnSomething && !this.server.allowFlight() -@@ -509,6 +_,23 @@ +@@ -515,6 +_,23 @@ } } @@ -46,7 +46,7 @@ private boolean noBlocksAround(Entity entity) { return entity.level() .getBlockStates(entity.getBoundingBox().inflate(0.0625).expandTowards(0.0, -0.55, 0.0)) -@@ -692,7 +_,7 @@ +@@ -698,7 +_,7 @@ if (level.isLoaded(pos)) { BlockState blockState = level.getBlockState(pos); boolean includeData = this.player.hasInfiniteMaterials() && packet.includeData(); @@ -55,7 +55,7 @@ if (!itemStack.isEmpty()) { if (includeData) { addBlockDataToItem(blockState, level, pos, itemStack); -@@ -1113,7 +_,7 @@ +@@ -1151,7 +_,7 @@ && !playerStandsOnSomething && !this.player.isSpectator() && !this.server.allowFlight() @@ -64,7 +64,7 @@ && !this.player.hasEffect(MobEffects.LEVITATION) && !isFallFlying && !isAutoSpinAttack -@@ -1242,9 +_,10 @@ +@@ -1280,9 +_,10 @@ } case SWAP_ITEM_WITH_OFFHAND: if (!this.player.isSpectator()) { @@ -78,7 +78,7 @@ this.player.stopUsingItem(); } -@@ -1268,7 +_,7 @@ +@@ -1306,7 +_,7 @@ case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: this.player.gameMode.handleBlockBreakAction(pos, action, packet.getDirection(), this.player.level().getMaxY(), packet.getSequence()); @@ -87,7 +87,7 @@ return; default: throw new IllegalArgumentException("Invalid player action"); -@@ -1290,7 +_,7 @@ +@@ -1328,7 +_,7 @@ public void handleUseItemOn(ServerboundUseItemOnPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (this.hasClientLoaded()) { @@ -96,7 +96,7 @@ ServerLevel level = this.player.level(); InteractionHand hand = packet.getHand(); ItemStack itemStack = this.player.getItemInHand(hand); -@@ -1444,8 +_,9 @@ +@@ -1482,8 +_,9 @@ } CompletableFuture filteredFuture = this.filterTextPacket(signedMessage.signedContent()); @@ -107,20 +107,20 @@ PlayerChatMessage filteredMessage = signedMessage.withUnsignedContent(decorated).filter(filtered.mask()); this.broadcastChatMessage(filteredMessage); }); -@@ -1770,7 +_,11 @@ - - @Override - public void onInteraction(InteractionHand hand, Vec3 location) { -- this.performInteraction(hand, (player, targetxx, h) -> targetxx.interactAt(player, location, h)); -+ this.performInteraction(hand, (player, target, h) -> { -+ InteractionResult onInteractEntityAtResult = net.neoforged.neoforge.common.CommonHooks.onInteractEntityAt(player, target, location, hand); -+ if (onInteractEntityAtResult != null) return onInteractEntityAtResult; -+ return target.interactAt(player, location, h); -+ }); - } - - @Override -@@ -1971,14 +_,16 @@ +@@ -1814,7 +_,11 @@ + ItemStack tool = this.player.getItemInHand(hand); + if (tool.isItemEnabled(level.enabledFeatures())) { + ItemStack usedItemStack = tool.copy(); +- if (this.player.interactOn(target, hand, location) instanceof InteractionResult.Success success) { ++ var interactionResult = net.neoforged.neoforge.common.CommonHooks.onInteractEntityAt(player, target, location, hand); ++ if (interactionResult == null) { ++ interactionResult = this.player.interactOn(target, hand, location); ++ } ++ if (interactionResult instanceof InteractionResult.Success success) { + ItemStack awardedForStack = success.wasItemInteraction() ? usedItemStack : ItemStack.EMPTY; + CriteriaTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(this.player, awardedForStack, target); + if (success.swingSource() == InteractionResult.SwingSource.SERVER) { +@@ -2035,14 +_,16 @@ @Override public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); @@ -138,7 +138,7 @@ if (this.player.isModelPartShown(PlayerModelPart.HAT) != wasHatShown) { this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player)); } -@@ -2054,7 +_,7 @@ +@@ -2118,7 +_,7 @@ this.connection .setupInboundProtocol( ConfigurationProtocols.SERVERBOUND, @@ -147,7 +147,7 @@ ); } } -@@ -2089,6 +_,7 @@ +@@ -2153,6 +_,7 @@ @Override public void handleCustomPayload(ServerboundCustomPayloadPacket packet) { diff --git a/patches/net/minecraft/server/network/config/PrepareSpawnTask.java.patch b/patches/net/minecraft/server/network/config/PrepareSpawnTask.java.patch index 2a16cd9ee21..bbc3cc51c66 100644 --- a/patches/net/minecraft/server/network/config/PrepareSpawnTask.java.patch +++ b/patches/net/minecraft/server/network/config/PrepareSpawnTask.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/config/PrepareSpawnTask.java +++ b/net/minecraft/server/network/config/PrepareSpawnTask.java -@@ -181,6 +_,7 @@ +@@ -187,6 +_,7 @@ .loadPlayerData(PrepareSpawnTask.this.nameAndId) .map(tag -> TagValueInput.create(reporter, PrepareSpawnTask.this.server.registryAccess(), tag)); input.ifPresent(player::load); diff --git a/patches/net/minecraft/server/packs/AbstractPackResources.java.patch b/patches/net/minecraft/server/packs/AbstractPackResources.java.patch index 6cc102ac417..72d7887b7b8 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 -@@ -59,4 +_,9 @@ +@@ -42,4 +_,9 @@ public PackLocationInfo location() { return this.location; } diff --git a/patches/net/minecraft/server/packs/resources/MultiPackResourceManager.java.patch b/patches/net/minecraft/server/packs/resources/MultiPackResourceManager.java.patch index 77317d94af8..3d9e636c068 100644 --- a/patches/net/minecraft/server/packs/resources/MultiPackResourceManager.java.patch +++ b/patches/net/minecraft/server/packs/resources/MultiPackResourceManager.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/server/packs/resources/MultiPackResourceManager.java +++ b/net/minecraft/server/packs/resources/MultiPackResourceManager.java -@@ -59,6 +_,7 @@ +@@ -58,6 +_,7 @@ try { return pack.getMetadataSection(ResourceFilterSection.TYPE); - } catch (IOException var3) { + } catch (Exception var3) { + if (!net.neoforged.neoforge.data.loading.DatagenModLoader.isRunningDataGen())// Neo: Only warn about malformed pack filters outside of datagen in case modders are replacing variables with gradle LOGGER.error("Failed to get filter section from pack {}", pack.packId()); return null; diff --git a/patches/net/minecraft/server/players/PlayerList.java.patch b/patches/net/minecraft/server/players/PlayerList.java.patch index b347c262d12..9d866ba4b5b 100644 --- a/patches/net/minecraft/server/players/PlayerList.java.patch +++ b/patches/net/minecraft/server/players/PlayerList.java.patch @@ -40,7 +40,7 @@ } protected void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) { -@@ -288,6 +_,7 @@ +@@ -292,6 +_,7 @@ } protected void save(ServerPlayer player) { @@ -48,7 +48,7 @@ this.playerIo.save(player); ServerStatsCounter stats = this.stats.get(player.getUUID()); if (stats != null) { -@@ -301,6 +_,7 @@ +@@ -305,6 +_,7 @@ } public void remove(ServerPlayer player) { @@ -56,7 +56,7 @@ ServerLevel level = player.level(); player.awardStat(Stats.LEAVE_GAME); this.save(player); -@@ -386,13 +_,20 @@ +@@ -390,13 +_,20 @@ TeleportTransition respawnInfo = serverPlayer.findRespawnPositionAndUseSpawnBlock(!keepAllPlayerData, TeleportTransition.DO_NOTHING); this.players.remove(serverPlayer); serverPlayer.level().removePlayerImmediately(serverPlayer, removalReason); @@ -78,7 +78,7 @@ player.copyRespawnPosition(serverPlayer); } -@@ -422,6 +_,8 @@ +@@ -426,6 +_,8 @@ this.playersByUUID.put(player.getUUID(), player); player.initInventoryMenu(); player.setHealth(player.getHealth()); @@ -87,7 +87,7 @@ ServerPlayer.RespawnConfig respawnConfig = player.getRespawnConfig(); if (!keepAllPlayerData && respawnConfig != null) { LevelData.RespawnData respawnData = respawnConfig.respawnData(); -@@ -535,6 +_,7 @@ +@@ -539,6 +_,7 @@ } public void op(NameAndId nameAndId, Optional permissions, Optional canBypassPlayerLimit) { @@ -95,7 +95,7 @@ this.ops .add( new ServerOpListEntry( -@@ -548,6 +_,7 @@ +@@ -552,6 +_,7 @@ } public void deop(NameAndId nameAndId) { @@ -103,19 +103,7 @@ if (this.ops.remove(nameAndId)) { ServerPlayer player = this.getPlayer(nameAndId.id()); if (player != null) { -@@ -636,7 +_,11 @@ - public void sendLevelInfo(ServerPlayer player, ServerLevel level) { - WorldBorder worldBorder = level.getWorldBorder(); - player.connection.send(new ClientboundInitializeBorderPacket(worldBorder)); -+ if (player.connection.hasChannel(net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload.TYPE)) { -+ player.connection.send(new net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME), level.getDayTimeFraction(), level.getDayTimePerTick())); -+ } else { - player.connection.send(new ClientboundSetTimePacket(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME))); -+ } - player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getRespawnData())); - if (level.isRaining()) { - player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0.0F)); -@@ -646,6 +_,7 @@ +@@ -650,6 +_,7 @@ player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F)); this.server.tickRateManager().updateJoiningPlayer(player); @@ -123,7 +111,7 @@ } public void sendAllPlayerInfo(ServerPlayer player) { -@@ -790,6 +_,8 @@ +@@ -794,6 +_,8 @@ this.advancements.put(uuid, result); } @@ -132,7 +120,7 @@ result.setPlayer(player); return result; } -@@ -813,7 +_,7 @@ +@@ -817,7 +_,7 @@ } public List getPlayers() { @@ -141,7 +129,7 @@ } public @Nullable ServerPlayer getPlayer(UUID uuid) { -@@ -839,6 +_,7 @@ +@@ -843,6 +_,7 @@ advancements.reload(this.server.getAdvancements()); } @@ -149,7 +137,7 @@ this.broadcastAll(new ClientboundUpdateTagsPacket(TagNetworkSerialization.serializeTagsToNetwork(this.registries))); RecipeManager recipeManager = this.server.getRecipeManager(); ClientboundUpdateRecipesPacket recipes = new ClientboundUpdateRecipesPacket( -@@ -848,10 +_,15 @@ +@@ -852,10 +_,15 @@ for (ServerPlayer player : this.players) { player.connection.send(recipes); player.getRecipeBook().sendInitialRecipeBook(player); diff --git a/patches/net/minecraft/tags/BlockTags.java.patch b/patches/net/minecraft/tags/BlockTags.java.patch index c72580a074e..dd44dc9b658 100644 --- a/patches/net/minecraft/tags/BlockTags.java.patch +++ b/patches/net/minecraft/tags/BlockTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/BlockTags.java +++ b/net/minecraft/tags/BlockTags.java -@@ -216,4 +_,8 @@ +@@ -248,4 +_,8 @@ private static TagKey create(String name) { return TagKey.create(Registries.BLOCK, Identifier.withDefaultNamespace(name)); } diff --git a/patches/net/minecraft/tags/FluidTags.java.patch b/patches/net/minecraft/tags/FluidTags.java.patch index 6d394df1652..efaca351441 100644 --- a/patches/net/minecraft/tags/FluidTags.java.patch +++ b/patches/net/minecraft/tags/FluidTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/FluidTags.java +++ b/net/minecraft/tags/FluidTags.java -@@ -14,4 +_,8 @@ +@@ -18,4 +_,8 @@ private static TagKey create(String name) { return TagKey.create(Registries.FLUID, Identifier.withDefaultNamespace(name)); } diff --git a/patches/net/minecraft/tags/ItemTags.java.patch b/patches/net/minecraft/tags/ItemTags.java.patch index 376e2f95d7e..0536772ee64 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 -@@ -210,4 +_,8 @@ +@@ -211,4 +_,8 @@ private static TagKey bind(String name) { return TagKey.create(Registries.ITEM, Identifier.withDefaultNamespace(name)); } diff --git a/patches/net/minecraft/tags/TagBuilder.java.patch b/patches/net/minecraft/tags/TagBuilder.java.patch index 6bcc28f546a..2dfb393ef04 100644 --- a/patches/net/minecraft/tags/TagBuilder.java.patch +++ b/patches/net/minecraft/tags/TagBuilder.java.patch @@ -1,9 +1,10 @@ --- a/net/minecraft/tags/TagBuilder.java +++ b/net/minecraft/tags/TagBuilder.java -@@ -5,6 +_,16 @@ +@@ -5,8 +_,17 @@ import net.minecraft.resources.Identifier; public class TagBuilder implements net.neoforged.neoforge.common.extensions.ITagBuilderExtension { +- private final List entries = new ArrayList<>(); + // FORGE: Remove entries are used for datagen. + private final List removeEntries = new ArrayList<>(); + public java.util.stream.Stream getRemoveEntries() { return this.removeEntries.stream(); } @@ -13,11 +14,12 @@ + return this; + } + // FORGE: is this tag set to replace or not? -+ private boolean replace = false; - private final List entries = new ArrayList<>(); + private boolean replace = false; ++ private final List entries = new ArrayList<>(); public static TagBuilder create() { -@@ -34,5 +_,21 @@ + return new TagBuilder(); +@@ -44,5 +_,21 @@ public TagBuilder addOptionalTag(Identifier id) { return this.add(TagEntry.optionalTag(id)); diff --git a/patches/net/minecraft/tags/TagLoader.java.patch b/patches/net/minecraft/tags/TagLoader.java.patch index 2b617cbc083..cdc38830a58 100644 --- a/patches/net/minecraft/tags/TagLoader.java.patch +++ b/patches/net/minecraft/tags/TagLoader.java.patch @@ -18,7 +18,7 @@ missingElements.add(entry); } } -@@ -107,7 +_,7 @@ +@@ -111,7 +_,7 @@ missing -> LOGGER.error( "Couldn't load tag {} as it is missing following references: {}", id, @@ -27,7 +27,7 @@ ) ) .ifRight(tag -> newTags.put(id, (List)tag)) -@@ -174,7 +_,11 @@ +@@ -188,7 +_,11 @@ } } diff --git a/patches/net/minecraft/util/SpawnUtil.java.patch b/patches/net/minecraft/util/SpawnUtil.java.patch index dc62c0377e2..42fd4b9741e 100644 --- a/patches/net/minecraft/util/SpawnUtil.java.patch +++ b/patches/net/minecraft/util/SpawnUtil.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/SpawnUtil.java +++ b/net/minecraft/util/SpawnUtil.java -@@ -38,7 +_,7 @@ +@@ -39,7 +_,7 @@ && (!checkCollisions || level.noCollision(entityType.getSpawnAABB(searchPos.getX() + 0.5, searchPos.getY(), searchPos.getZ() + 0.5)))) { T mob = (T)entityType.create(level, null, searchPos, spawnReason, false, false); if (mob != null) { diff --git a/patches/net/minecraft/util/datafix/DataFixers.java.patch b/patches/net/minecraft/util/datafix/DataFixers.java.patch index 0939018e77e..c3321e4ca31 100644 --- a/patches/net/minecraft/util/datafix/DataFixers.java.patch +++ b/patches/net/minecraft/util/datafix/DataFixers.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/datafix/DataFixers.java +++ b/net/minecraft/util/datafix/DataFixers.java -@@ -1355,10 +_,35 @@ +@@ -1359,10 +_,35 @@ Schema v3800 = fixerUpper.addSchema(3800, SAME_NAMESPACED); UnaryOperator scuteRenamer = createRenamer(Map.of("minecraft:scute", "minecraft:turtle_scute")); fixerUpper.addFixer(ItemRenameFix.create(v3800, "Rename scute item to turtle_scute", scuteRenamer)); @@ -36,7 +36,7 @@ Schema v3807 = fixerUpper.addSchema(3807, V3807::new); fixerUpper.addFixer(new AddNewChoices(v3807, "Added Vault", References.BLOCK_ENTITY)); Schema v3807_1 = fixerUpper.addSchema(3807, 1, SAME_NAMESPACED); -@@ -1381,6 +_,18 @@ +@@ -1385,6 +_,18 @@ v3814, "Rename jump strength attribute", createRenamer("minecraft:horse.jump_strength", "minecraft:generic.jump_strength") ) ); diff --git a/patches/net/minecraft/util/worldupdate/WorldUpgrader.java.patch b/patches/net/minecraft/util/worldupdate/WorldUpgrader.java.patch index abd13c9fba7..b102ac7edef 100644 --- a/patches/net/minecraft/util/worldupdate/WorldUpgrader.java.patch +++ b/patches/net/minecraft/util/worldupdate/WorldUpgrader.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/worldupdate/WorldUpgrader.java +++ b/net/minecraft/util/worldupdate/WorldUpgrader.java -@@ -93,7 +_,7 @@ +@@ -52,7 +_,7 @@ this.eraseCache = eraseCache; this.dataFixer = dataFixer; this.levelStorage = levelSource; diff --git a/patches/net/minecraft/world/SimpleContainer.java.patch b/patches/net/minecraft/world/SimpleContainer.java.patch index fe240594b46..6eec0e35553 100644 --- a/patches/net/minecraft/world/SimpleContainer.java.patch +++ b/patches/net/minecraft/world/SimpleContainer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/SimpleContainer.java +++ b/net/minecraft/world/SimpleContainer.java -@@ -126,8 +_,14 @@ +@@ -109,8 +_,14 @@ @Override public void setItem(int slot, ItemStack itemStack) { diff --git a/patches/net/minecraft/world/clock/ClockManager.java.patch b/patches/net/minecraft/world/clock/ClockManager.java.patch new file mode 100644 index 00000000000..fb57c9f357b --- /dev/null +++ b/patches/net/minecraft/world/clock/ClockManager.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/clock/ClockManager.java ++++ b/net/minecraft/world/clock/ClockManager.java +@@ -4,4 +_,11 @@ + + public interface ClockManager { + long getTotalTicks(Holder definition); ++ ++ default float getFractionalTick(Holder definition) { ++ return 0; ++ } ++ ++ default void setSpeed(Holder definition, float speed) { ++ } + } diff --git a/patches/net/minecraft/world/clock/ClockState.java.patch b/patches/net/minecraft/world/clock/ClockState.java.patch new file mode 100644 index 00000000000..cf827ba1694 --- /dev/null +++ b/patches/net/minecraft/world/clock/ClockState.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/world/clock/ClockState.java ++++ b/net/minecraft/world/clock/ClockState.java +@@ -6,14 +_,34 @@ + import net.minecraft.network.codec.ByteBufCodecs; + import net.minecraft.network.codec.StreamCodec; + +-public record ClockState(long totalTicks, boolean paused) { ++// Neo: add state needed for variable speed clocks ++public record ClockState(long totalTicks, boolean paused, float fractionalTick, float speed) { ++ ++ // Neo: defaults to a standard-speed clock ++ public ClockState(long totalTicks, boolean paused) { ++ this(totalTicks, paused, 0, 1); ++ } ++ + public static final Codec CODEC = RecordCodecBuilder.create( + i -> i.group( +- Codec.LONG.fieldOf("total_ticks").forGetter(ClockState::totalTicks), Codec.BOOL.optionalFieldOf("paused", false).forGetter(ClockState::paused) ++ Codec.LONG.fieldOf("total_ticks").forGetter(ClockState::totalTicks), Codec.BOOL.optionalFieldOf("paused", false).forGetter(ClockState::paused), ++ Codec.FLOAT.optionalFieldOf("fractional_tick", 0f).forGetter(ClockState::fractionalTick), ++ Codec.FLOAT.optionalFieldOf("speed", 1.0f).forGetter(ClockState::speed) + ) + .apply(i, ClockState::new) + ); +- public static final StreamCodec STREAM_CODEC = StreamCodec.composite( +- ByteBufCodecs.VAR_LONG, ClockState::totalTicks, ByteBufCodecs.BOOL, ClockState::paused, ClockState::new ++ // Neo: sync the extended clock state only to NeoForge clients ++ public static final StreamCodec STREAM_CODEC = net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs.connectionAware( ++ StreamCodec.composite( ++ ByteBufCodecs.VAR_LONG, ClockState::totalTicks, ++ ByteBufCodecs.BOOL, ClockState::paused, ++ ByteBufCodecs.FLOAT, ClockState::fractionalTick, ++ ByteBufCodecs.FLOAT, ClockState::speed, ++ ClockState::new ++ ), ++ StreamCodec.composite( ++ ByteBufCodecs.VAR_LONG, ClockState::totalTicks, ++ ByteBufCodecs.BOOL, ClockState::paused, ClockState::new ++ ) + ); + } diff --git a/patches/net/minecraft/world/clock/ServerClockManager.java.patch b/patches/net/minecraft/world/clock/ServerClockManager.java.patch new file mode 100644 index 00000000000..a829a725463 --- /dev/null +++ b/patches/net/minecraft/world/clock/ServerClockManager.java.patch @@ -0,0 +1,99 @@ +--- a/net/minecraft/world/clock/ServerClockManager.java ++++ b/net/minecraft/world/clock/ServerClockManager.java +@@ -47,6 +_,9 @@ + } + + public void tick() { ++ if (this.server.overworld() == null) { ++ return; // Neo: Our JUnit ephemeral testserver has no overworld and getGlobalGameRules() would crash ++ } + boolean advanceTime = this.server.getGlobalGameRules().get(GameRules.ADVANCE_TIME); + if (advanceTime) { + this.clocks.values().forEach(ServerClockManager.ClockInstance::tick); +@@ -93,11 +_,45 @@ + this.server.getPlayerList().broadcastAll(new ClientboundSetTimePacket(this.getGameTime(), updates)); + } + ++ /** ++ * Returns the current ratio between game ticks and clock ticks. This value cannot be 0 or negative. ++ * The default is 1. ++ */ ++ public float getSpeed(Holder definition) { ++ return getInstance(definition).speed; ++ } ++ + @Override + public long getTotalTicks(Holder definition) { + return this.getInstance(definition).totalTicks; + } + ++ @Override ++ public float getFractionalTick(Holder definition) { ++ return this.getInstance(definition).fractionalTick; ++ } ++ ++ /** ++ * This allows mods to set the rate at which a specific clock advances relative to game time. ++ *

++ * This can be sped up for shorter days by giving a higher number, or slowed down for longer days ++ * with a smaller number. A negative value will reset it back to vanilla logic. ++ *

++ * This value can also be changed with the command /neoforge day, where you can set ++ * either the speed or a day length in minutes. ++ *

++ * This has no effect when time progression is stopped. ++ *

++ * While this still technically works when vanilla clients are connected, those will desync and ++ * experience a time jump once per second. ++ */ ++ @Override ++ public void setSpeed(Holder definition, float speed) { ++ if (speed > 0 && getInstance(definition).speed != speed) { ++ modifyClock(definition, instance -> instance.speed = speed); ++ } ++ } ++ + public ClientboundSetTimePacket createFullSyncPacket() { + return new ClientboundSetTimePacket(this.getGameTime(), Util.mapValues(this.clocks, clock -> clock.packNetworkState(this.server))); + } +@@ -119,26 +_,37 @@ + private static class ClockInstance { + private final Map, ClockTimeMarker> timeMarkers = new Reference2ObjectOpenHashMap<>(); + private long totalTicks; ++ private float fractionalTick; ++ private float speed = 1; + private boolean paused; + ++ // Neo: Replaced with ExtendedClockState + public void loadFrom(ClockState state) { + this.totalTicks = state.totalTicks(); ++ this.fractionalTick = state.fractionalTick(); ++ this.speed = state.speed(); + this.paused = state.paused(); + } + + public void tick() { + if (!this.paused) { +- this.totalTicks++; ++ // advances the fractional daytime, returns the integer part of it ++ float timeStep = fractionalTick + speed; ++ long result = (long)timeStep; ++ this.fractionalTick = (timeStep - result); ++ this.totalTicks += result; + } + } + ++ // Neo: Replaced with ExtendedClockState + public ClockState packState() { +- return new ClockState(this.totalTicks, this.paused); ++ return new ClockState(this.totalTicks, this.paused, this.fractionalTick, this.speed); + } + ++ // Neo: Replaced with ExtendedClockState + public ClockState packNetworkState(MinecraftServer server) { + boolean advanceTime = server.getGlobalGameRules().get(GameRules.ADVANCE_TIME); +- return new ClockState(this.totalTicks, this.paused || !advanceTime); ++ return new ClockState(this.totalTicks, this.paused || !advanceTime, this.fractionalTick, this.speed); + } + } + } diff --git a/patches/net/minecraft/world/entity/Entity.java.patch b/patches/net/minecraft/world/entity/Entity.java.patch index 2c6d7945005..f6d1042026f 100644 --- a/patches/net/minecraft/world/entity/Entity.java.patch +++ b/patches/net/minecraft/world/entity/Entity.java.patch @@ -1,15 +1,14 @@ --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -152,7 +_,7 @@ - import org.jspecify.annotations.Nullable; +@@ -157,6 +_,7 @@ import org.slf4j.Logger; --public abstract class Entity implements Nameable, EntityAccess, ScoreHolder, SyncedDataHolder, DataComponentGetter, ItemOwner, SlotProvider, DebugValueSource, net.neoforged.neoforge.common.extensions.IEntityExtension { -+public abstract class Entity extends net.neoforged.neoforge.attachment.AttachmentHolder implements Nameable, EntityAccess, ScoreHolder, SyncedDataHolder, DataComponentGetter, ItemOwner, SlotProvider, DebugValueSource, net.neoforged.neoforge.common.extensions.IEntityExtension { - private static final Logger LOGGER = LogUtils.getLogger(); - public static final String TAG_ID = "id"; - public static final String TAG_UUID = "UUID"; -@@ -190,6 +_,7 @@ + public abstract class Entity ++ extends net.neoforged.neoforge.attachment.AttachmentHolder + implements Nameable, + EntityAccess, + ScoreHolder, +@@ -203,6 +_,7 @@ private static final int MAX_BLOCK_ITERATIONS_ALONG_TRAVEL_PER_TICK = 16; private static final double MAX_MOVEMENT_RESETTING_TRACE_DISTANCE = 8.0; private static double viewScale = 1.0; @@ -17,18 +16,18 @@ private final EntityType type; private boolean requiresPrecisePosition; private int id = ENTITY_COUNTER.incrementAndGet(); -@@ -232,8 +_,10 @@ +@@ -245,8 +_,10 @@ public int tickCount; private int remainingFireTicks; protected boolean wasTouchingWater; + @Deprecated // Neo: Use forgeFluidTypeHeight instead - protected Object2DoubleMap> fluidHeight = new Object2DoubleArrayMap<>(2); + protected final Object2DoubleMap> fluidHeight = new Object2DoubleArrayMap<>(2); protected boolean wasEyeInWater; + @Deprecated // Neo: Use forgeFluidTypeOnEyes instead private final Set> fluidOnEyes = new HashSet<>(); public int invulnerableTime; protected boolean firstTick = true; -@@ -305,7 +_,10 @@ +@@ -318,7 +_,10 @@ this.defineSynchedData(entityDataBuilder); this.entityData = entityDataBuilder.build(); this.setPos(0.0, 0.0, 0.0); @@ -39,7 +38,7 @@ } public boolean isColliding(BlockPos pos, BlockState state) { -@@ -523,7 +_,7 @@ +@@ -541,7 +_,7 @@ } if (this.isInLava()) { @@ -48,7 +47,7 @@ } this.checkBelowWorld(); -@@ -973,9 +_,7 @@ +@@ -991,9 +_,7 @@ return getOnPos; } else { BlockState belowState = this.level().getBlockState(getOnPos); @@ -59,7 +58,7 @@ ? getOnPos.atY(Mth.floor(this.position.y - offset)) : getOnPos; } -@@ -1326,20 +_,20 @@ +@@ -1344,20 +_,20 @@ return !aboveState.is(BlockTags.INSIDE_STEP_SOUND_BLOCKS) && !aboveState.is(BlockTags.COMBINATION_STEP_SOUND_BLOCKS) ? affectingPos : abovePos; } @@ -89,7 +88,7 @@ } private boolean shouldPlayAmethystStepSound(BlockState affectingState) { -@@ -1491,7 +_,7 @@ +@@ -1509,7 +_,7 @@ } public boolean isInShallowWater() { @@ -98,7 +97,7 @@ } public boolean isInClouds() { -@@ -1510,26 +_,34 @@ +@@ -1528,26 +_,34 @@ public void updateSwimming() { if (this.isSwimming()) { @@ -139,7 +138,7 @@ if (!this.wasTouchingWater && !this.firstTick) { this.doWaterSplashEffect(); } -@@ -1544,6 +_,7 @@ +@@ -1562,6 +_,7 @@ private void updateFluidOnEyes() { this.wasEyeInWater = this.isEyeInFluid(FluidTags.WATER); this.fluidOnEyes.clear(); @@ -147,16 +146,16 @@ double eyeY = this.getEyeY(); if (!( this.getVehicle() instanceof AbstractBoat boat && !boat.isUnderWater() && boat.getBoundingBox().maxY >= eyeY && boat.getBoundingBox().minY <= eyeY -@@ -1552,7 +_,7 @@ +@@ -1570,7 +_,7 @@ FluidState fluidState = this.level().getFluidState(pos); double blockFluidHeight = pos.getY() + fluidState.getHeight(this.level(), pos); if (blockFluidHeight > eyeY) { -- fluidState.getTags().forEach(this.fluidOnEyes::add); +- fluidState.tags().forEach(this.fluidOnEyes::add); + this.forgeFluidTypeOnEyes = fluidState.getFluidType(); } } } -@@ -1600,12 +_,13 @@ +@@ -1618,12 +_,13 @@ } public boolean canSpawnSprintParticle() { @@ -171,7 +170,7 @@ if (blockState.getRenderShape() != RenderShape.INVISIBLE) { Vec3 movement = this.getDeltaMovement(); BlockPos entityPosition = this.blockPosition(); -@@ -1620,16 +_,19 @@ +@@ -1638,16 +_,19 @@ } this.level() @@ -193,7 +192,7 @@ } public void moveRelative(float speed, Vec3 input) { -@@ -2005,6 +_,11 @@ +@@ -2023,6 +_,11 @@ output.store("data", CustomData.CODEC, this.customData); } @@ -205,7 +204,7 @@ this.addAdditionalSaveData(output); if (this.isVehicle()) { ValueOutput.ValueOutputList passengersList = output.childrenList("Passengers"); -@@ -2067,6 +_,8 @@ +@@ -2085,6 +_,8 @@ this.setTicksFrozen(input.getIntOr("TicksFrozen", 0)); this.hasVisualFire = input.getBooleanOr("HasVisualFire", false); this.customData = input.read("data", CustomData.CODEC).orElse(CustomData.EMPTY); @@ -214,7 +213,7 @@ this.tags.clear(); input.read("Tags", TAG_LIST_CODEC).ifPresent(this.tags::addAll); this.readAdditionalSaveData(input); -@@ -2112,6 +_,8 @@ +@@ -2133,6 +_,8 @@ } else { ItemEntity entity = new ItemEntity(level, this.getX() + offset.x, this.getY() + offset.y, this.getZ() + offset.z, itemStack); entity.setDefaultPickUpDelay(); @@ -223,7 +222,7 @@ level.addFreshEntity(entity); return entity; } -@@ -2170,11 +_,11 @@ +@@ -2191,11 +_,11 @@ } ItemStack heldItem = player.getItemInHand(hand); @@ -237,7 +236,7 @@ && target.canShearEquipment(player) && !player.isSecondaryUseActive() && this.attemptToShearEquipment(player, hand, heldItem, target)) { -@@ -2282,7 +_,11 @@ +@@ -2303,7 +_,11 @@ public void rideTick() { this.setDeltaMovement(Vec3.ZERO); @@ -250,7 +249,7 @@ if (this.isPassenger()) { this.getVehicle().positionRider(this); } -@@ -2342,6 +_,7 @@ +@@ -2363,6 +_,7 @@ } } @@ -258,7 +257,7 @@ if (force || this.canRide(entityToRide) && entityToRide.canAddPassenger(this)) { if (this.isPassenger()) { this.stopRiding(); -@@ -2377,6 +_,7 @@ +@@ -2398,6 +_,7 @@ public void removeVehicle() { if (this.vehicle != null) { Entity oldVehicle = this.vehicle; @@ -266,7 +265,7 @@ this.vehicle = null; oldVehicle.removePassenger(this); Entity.RemovalReason removalReason = this.getRemovalReason(); -@@ -2427,6 +_,8 @@ +@@ -2448,6 +_,8 @@ return this.passengers.isEmpty(); } @@ -275,7 +274,7 @@ protected boolean couldAcceptPassenger() { return true; } -@@ -2623,7 +_,7 @@ +@@ -2644,7 +_,7 @@ } public boolean isVisuallyCrawling() { @@ -284,7 +283,7 @@ } public void setSwimming(boolean swimming) { -@@ -2739,7 +_,7 @@ +@@ -2760,7 +_,7 @@ this.igniteForSeconds(8.0F); } @@ -293,7 +292,7 @@ } public void onAboveBubbleColumn(boolean dragDown, BlockPos pos) { -@@ -2864,7 +_,7 @@ +@@ -2879,7 +_,7 @@ } protected Component getTypeName() { @@ -302,7 +301,7 @@ } public boolean is(Entity other) { -@@ -2919,10 +_,11 @@ +@@ -2934,10 +_,11 @@ } protected final boolean isInvulnerableToBase(DamageSource source) { @@ -310,12 +309,12 @@ + boolean isVanillaInvulnerable = this.isRemoved() || this.invulnerable && !source.is(DamageTypeTags.BYPASSES_INVULNERABILITY) && !source.isCreativePlayer() || source.is(DamageTypeTags.IS_FIRE) && this.fireImmune() - || source.is(DamageTypeTags.IS_FALL) && this.getType().is(EntityTypeTags.FALL_DAMAGE_IMMUNE); + || source.is(DamageTypeTags.IS_FALL) && this.is(EntityTypeTags.FALL_DAMAGE_IMMUNE); + return net.neoforged.neoforge.common.CommonHooks.isEntityInvulnerableTo(this, source, isVanillaInvulnerable); } public boolean isInvulnerable() { -@@ -2949,6 +_,7 @@ +@@ -2964,6 +_,7 @@ } public @Nullable Entity teleport(TeleportTransition transition) { @@ -323,7 +322,7 @@ if (this.level() instanceof ServerLevel serverLevel && !this.isRemoved()) { ServerLevel newLevel = transition.newLevel(); boolean otherDimension = newLevel.dimension() != serverLevel.dimension(); -@@ -3171,6 +_,7 @@ +@@ -3186,6 +_,7 @@ return this.stringUUID; } @@ -331,7 +330,7 @@ public boolean isPushedByFluid() { return true; } -@@ -3268,6 +_,8 @@ +@@ -3283,6 +_,8 @@ EntityDimensions oldDim = this.dimensions; Pose pose = this.getPose(); EntityDimensions newDim = this.getDimensions(pose); @@ -340,7 +339,7 @@ this.dimensions = newDim; this.eyeHeight = newDim.eyeHeight(); this.reapplyPosition(); -@@ -3549,9 +_,36 @@ +@@ -3560,9 +_,36 @@ return Mth.lerp(partial, this.yRotO, this.yRot); } @@ -378,7 +377,7 @@ } else { AABB box = this.getBoundingBox().deflate(0.001); int x0 = Mth.floor(box.minX); -@@ -3566,25 +_,37 @@ +@@ -3577,25 +_,37 @@ Vec3 current = Vec3.ZERO; int numberOfCurrents = 0; BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); @@ -423,7 +422,7 @@ } } } -@@ -3592,27 +_,30 @@ +@@ -3603,27 +_,30 @@ } } @@ -464,7 +463,7 @@ } } -@@ -3625,7 +_,10 @@ +@@ -3636,7 +_,10 @@ return !this.level().hasChunksAt(x0, z0, x1, z1); } @@ -475,7 +474,7 @@ return this.fluidHeight.getDouble(type); } -@@ -3776,6 +_,10 @@ +@@ -3787,6 +_,10 @@ } } } @@ -486,7 +485,7 @@ } public void checkDespawn() { -@@ -3916,6 +_,130 @@ +@@ -3927,6 +_,130 @@ public boolean mayInteract(ServerLevel level, BlockPos pos) { return true; @@ -524,7 +523,7 @@ + // Neo: Set the default behavior for trampling on Farmland + @Override + public boolean canTrample(ServerLevel level, BlockState state, BlockPos pos, double fallDistance) { -+ return level.random.nextFloat() < fallDistance - 0.5F ++ return level.getRandom().nextFloat() < fallDistance - 0.5F + && this instanceof LivingEntity + && (this instanceof Player || net.neoforged.neoforge.event.EventHooks.canEntityGrief(level, this)) + && this.getBbWidth() * this.getBbWidth() * this.getBbHeight() > 0.512F; diff --git a/patches/net/minecraft/world/entity/EntityType.java.patch b/patches/net/minecraft/world/entity/EntityType.java.patch index 50e6ff8b93a..1fd6f7c06b2 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 -@@ -1227,6 +_,11 @@ +@@ -1225,6 +_,11 @@ private final FeatureFlagSet requiredFeatures; private final boolean allowedInPeaceful; @@ -12,7 +12,7 @@ private static EntityType register(ResourceKey> id, EntityType.Builder builder) { return Registry.register(BuiltInRegistries.ENTITY_TYPE, id, builder.build(id)); } -@@ -1264,6 +_,30 @@ +@@ -1262,6 +_,30 @@ FeatureFlagSet requiredFeatures, boolean allowedInPeaceful ) { @@ -43,7 +43,7 @@ this.factory = factory; this.category = category; this.canSpawnFarFromPlayer = canSpawnFarFromPlayer; -@@ -1279,6 +_,10 @@ +@@ -1277,6 +_,10 @@ this.lootTable = lootTable; this.requiredFeatures = requiredFeatures; this.allowedInPeaceful = allowedInPeaceful; @@ -54,7 +54,7 @@ } public @Nullable T spawn( -@@ -1359,6 +_,13 @@ +@@ -1357,6 +_,13 @@ mob.yHeadRot = mob.getYRot(); mob.yBodyRot = mob.getYRot(); mob.finalizeSpawn(level, level.getCurrentDifficultyAt(mob.blockPosition()), spawnReason, null); @@ -68,7 +68,7 @@ } if (postSpawnConfig != null) { -@@ -1562,14 +_,23 @@ +@@ -1560,14 +_,23 @@ } public int clientTrackingRange() { @@ -92,7 +92,7 @@ return this != PLAYER && this != LLAMA_SPIT && this != WITHER -@@ -1625,9 +_,12 @@ +@@ -1615,9 +_,12 @@ } public boolean onlyOpCanSetNbt() { @@ -100,12 +100,12 @@ return OP_ONLY_CUSTOM_DATA.contains(this); } -+ public Stream>> getTags() {return this.builtInRegistryHolder().tags();} ++ public Stream>> getTags() {return this.builtInRegistryHolder().tags();} + public static class Builder { private final EntityType.EntityFactory factory; private final MobCategory category; -@@ -1647,6 +_,10 @@ +@@ -1637,6 +_,10 @@ ); private final DependantName, String> descriptionId = id -> Util.makeDescriptionId("entity", id.identifier()); private boolean allowedInPeaceful = true; @@ -116,7 +116,7 @@ private Builder(EntityType.EntityFactory factory, MobCategory category) { this.factory = factory; -@@ -1765,6 +_,26 @@ +@@ -1755,6 +_,26 @@ return this; } @@ -143,7 +143,7 @@ public EntityType build(ResourceKey> name) { if (this.serialize) { Util.fetchChoiceType(References.ENTITY_TREE, name.identifier().toString()); -@@ -1785,7 +_,11 @@ +@@ -1775,7 +_,11 @@ this.descriptionId.get(name), this.lootTable.get(name), this.requiredFeatures, diff --git a/patches/net/minecraft/world/entity/LightningBolt.java.patch b/patches/net/minecraft/world/entity/LightningBolt.java.patch index a7e40ee9671..a3733545e02 100644 --- a/patches/net/minecraft/world/entity/LightningBolt.java.patch +++ b/patches/net/minecraft/world/entity/LightningBolt.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/LightningBolt.java +++ b/net/minecraft/world/entity/LightningBolt.java -@@ -38,6 +_,7 @@ +@@ -39,6 +_,7 @@ private @Nullable ServerPlayer cause; private final Set hitEntities = Sets.newHashSet(); private int blocksSetOnFire; @@ -8,7 +8,7 @@ public LightningBolt(EntityType type, Level level) { super(type, level); -@@ -71,6 +_,14 @@ +@@ -72,6 +_,14 @@ } } @@ -23,7 +23,7 @@ @Override public void tick() { super.tick(); -@@ -149,6 +_,7 @@ +@@ -150,6 +_,7 @@ ); for (Entity entity : entities) { diff --git a/patches/net/minecraft/world/entity/LivingEntity.java.patch b/patches/net/minecraft/world/entity/LivingEntity.java.patch index b99a98aa0ce..b2546a2e864 100644 --- a/patches/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/net/minecraft/world/entity/LivingEntity.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -194,13 +_,19 @@ - public static final float EXTRA_RENDER_CULLING_SIZE_WITH_BIG_HAT = 0.5F; - public static final float DEFAULT_BABY_SCALE = 0.5F; - private static final float WATER_FLOAT_IMPULSE = 0.04F; +@@ -198,14 +_,20 @@ + private static final int CURRENT_IMPULSE_CONTEXT_RESET_GRACE_TIME_TICKS = 40; + private static final int DEFAULT_CURRENT_IMPULSE_CONTEXT_RESET_GRACE_TIME = 0; + private int currentImpulseContextResetGraceTime = 0; - public static final Predicate PLAYER_NOT_WEARING_DISGUISE_ITEM = livingEntity -> { + // Neo: Support IItemExtension#isGazeDisguise + public static final java.util.function.BiPredicate PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET = (livingEntity, target) -> { @@ -14,18 +14,19 @@ } else { return true; } -+ }; + }; + /** @deprecated Neo: use {@link #PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET} with target info instead */ + @Deprecated + public static final Predicate PLAYER_NOT_WEARING_DISGUISE_ITEM = livingEntity -> { + return PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET.test(livingEntity, null); - }; ++ }; private static final Dynamic EMPTY_BRAIN = new Dynamic<>(JavaOps.INSTANCE, Map.of("memories", Map.of())); private final AttributeMap attributes; -@@ -267,6 +_,13 @@ - ); - protected final EntityEquipment equipment; + private final CombatTracker combatTracker = new CombatTracker(this); +@@ -273,6 +_,13 @@ private Waypoint.Icon locatorBarIcon = new Waypoint.Icon(); + public @Nullable Vec3 currentImpulseImpactPos; + public @Nullable Entity currentExplosionCause; + /** + * This field stores information about damage dealt to this entity. + * a new {@link net.neoforged.neoforge.common.damagesource.DamageContainer} is instantiated @@ -36,7 +37,7 @@ protected LivingEntity(EntityType type, Level level) { super(type, level); -@@ -343,13 +_,15 @@ +@@ -345,13 +_,15 @@ .add(Attributes.MOVEMENT_EFFICIENCY) .add(Attributes.ATTACK_KNOCKBACK) .add(Attributes.CAMERA_DISTANCE) @@ -54,7 +55,7 @@ } if (this.level() instanceof ServerLevel level && onGround && this.fallDistance > 0.0) { -@@ -370,7 +_,8 @@ +@@ -372,7 +_,8 @@ double scale = Math.min(0.2F + power / 15.0, 2.5); int particles = (int)(150.0 * scale); @@ -64,15 +65,15 @@ } } -@@ -380,6 +_,7 @@ +@@ -382,6 +_,7 @@ } } + @Deprecated //FORGE: Use canDrownInFluidType instead public boolean canBreatheUnderwater() { - return this.getType().is(EntityTypeTags.CAN_BREATHE_UNDER_WATER); + return this.is(EntityTypeTags.CAN_BREATHE_UNDER_WATER); } -@@ -420,6 +_,9 @@ +@@ -422,6 +_,9 @@ } } @@ -82,7 +83,7 @@ if (this.isEyeInFluid(FluidTags.WATER) && !level.getBlockState(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())).is(Blocks.BUBBLE_COLUMN)) { boolean canDrownInWater = !this.canBreatheUnderwater() -@@ -768,7 +_,11 @@ +@@ -772,7 +_,11 @@ } else { ItemEntity entity = this.createItemStackToDrop(itemStack, randomly, thrownFromHand); if (entity != null) { @@ -95,7 +96,7 @@ } return entity; -@@ -834,8 +_,10 @@ +@@ -840,8 +_,10 @@ Holder mobEffect = iterator.next(); MobEffectInstance effect = this.activeEffects.get(mobEffect); if (!effect.tickServer(serverLevel, this, () -> this.onEffectUpdated(effect, true, null))) { @@ -106,7 +107,7 @@ } else if (effect.getDuration() % 600 == 0) { this.onEffectUpdated(effect, false, null); } -@@ -882,8 +_,9 @@ +@@ -888,8 +_,9 @@ List visibleEffectParticles = this.activeEffects .values() .stream() @@ -118,7 +119,7 @@ .toList(); this.entityData.set(DATA_EFFECT_PARTICLES, visibleEffectParticles); this.entityData.set(DATA_EFFECT_AMBIENCE_ID, areAllEffectsAmbient(this.activeEffects.values())); -@@ -923,6 +_,7 @@ +@@ -928,6 +_,7 @@ } } @@ -126,7 +127,7 @@ return visibilityPercent; } -@@ -958,9 +_,14 @@ +@@ -963,9 +_,14 @@ } else if (this.activeEffects.isEmpty()) { return false; } else { @@ -144,7 +145,7 @@ return true; } } -@@ -991,11 +_,12 @@ +@@ -996,11 +_,12 @@ } public boolean addEffect(MobEffectInstance newEffect, @Nullable Entity source) { @@ -158,7 +159,7 @@ if (effect == null) { this.activeEffects.put(newEffect.getEffect(), newEffect); this.onEffectAdded(newEffect, source); -@@ -1011,6 +_,14 @@ +@@ -1016,6 +_,14 @@ } } @@ -171,9 +172,9 @@ + @Deprecated + @org.jetbrains.annotations.ApiStatus.OverrideOnly public boolean canBeAffected(MobEffectInstance newEffect) { - if (this.getType().is(EntityTypeTags.IMMUNE_TO_INFESTED)) { + if (this.is(EntityTypeTags.IMMUNE_TO_INFESTED)) { return !newEffect.is(MobEffects.INFESTED); -@@ -1024,7 +_,7 @@ +@@ -1027,7 +_,7 @@ } public void forceAddEffect(MobEffectInstance newEffect, @Nullable Entity source) { @@ -182,7 +183,7 @@ MobEffectInstance previousEffect = this.activeEffects.put(newEffect.getEffect(), newEffect); if (previousEffect == null) { this.onEffectAdded(newEffect, source); -@@ -1044,6 +_,7 @@ +@@ -1047,6 +_,7 @@ } public boolean removeEffect(Holder effect) { @@ -190,7 +191,7 @@ MobEffectInstance effectInstance = this.removeEffectNoUpdate(effect); if (effectInstance != null) { this.onEffectsRemoved(List.of(effectInstance)); -@@ -1135,6 +_,8 @@ +@@ -1138,6 +_,8 @@ } public void heal(float heal) { @@ -199,7 +200,7 @@ float health = this.getHealth(); if (health > 0.0F) { this.setHealth(health + heal); -@@ -1162,11 +_,14 @@ +@@ -1165,11 +_,14 @@ } else if (source.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) { return false; } else { @@ -214,7 +215,7 @@ if (damage < 0.0F) { damage = 0.0F; } -@@ -1187,24 +_,28 @@ +@@ -1190,24 +_,28 @@ if (Float.isNaN(damage) || Float.isInfinite(damage)) { damage = Float.MAX_VALUE; } @@ -244,7 +245,7 @@ this.resolveMobResponsibleForDamage(source); this.resolvePlayerResponsibleForDamage(source); if (tookFullDamage) { -@@ -1273,6 +_,7 @@ +@@ -1276,6 +_,7 @@ CriteriaTriggers.PLAYER_HURT_ENTITY.trigger(sourcePlayer, this, source, damage, damage, blocked); } @@ -252,7 +253,7 @@ return success; } } -@@ -1286,7 +_,7 @@ +@@ -1289,7 +_,7 @@ return 0.0F; } else { BlocksAttacks blocksAttacks = blockingWith.get(DataComponents.BLOCKS_ATTACKS); @@ -261,7 +262,7 @@ if (source.getDirectEntity() instanceof AbstractArrow abstractArrow && abstractArrow.getPierceLevel() > 0) { return 0.0F; } else { -@@ -1302,7 +_,13 @@ +@@ -1305,7 +_,13 @@ } float damageBlocked = blocksAttacks.resolveBlockedDamage(source, damage, angle); @@ -276,7 +277,7 @@ if (damageBlocked > 0.0F && !source.is(DamageTypeTags.IS_PROJECTILE) && source.getDirectEntity() instanceof LivingEntity livingEntity) { this.blockUsingItem(level, livingEntity); } -@@ -1335,9 +_,9 @@ +@@ -1338,9 +_,9 @@ Entity sourceEntity = source.getEntity(); if (sourceEntity instanceof Player playerSource) { this.setLastHurtByPlayer(playerSource, 100); @@ -289,7 +290,7 @@ } else { this.lastHurtByPlayer = null; this.lastHurtByPlayerMemoryTime = 0; -@@ -1365,7 +_,7 @@ +@@ -1368,7 +_,7 @@ for (InteractionHand hand : InteractionHand.values()) { ItemStack itemStack = this.getItemInHand(hand); protection = itemStack.get(DataComponents.DEATH_PROTECTION); @@ -298,7 +299,7 @@ protectionItem = itemStack.copy(); itemStack.shrink(1); break; -@@ -1428,6 +_,7 @@ +@@ -1424,6 +_,7 @@ } public void die(DamageSource source) { @@ -306,7 +307,7 @@ if (!this.isRemoved() && !this.dead) { Entity sourceEntity = source.getEntity(); LivingEntity killer = this.getKillCredit(); -@@ -1464,7 +_,7 @@ +@@ -1460,7 +_,7 @@ if (this.level() instanceof ServerLevel serverLevel) { boolean var6 = false; if (killer instanceof WitherBoss) { @@ -315,7 +316,7 @@ BlockPos pos = this.blockPosition(); BlockState state = Blocks.WITHER_ROSE.defaultBlockState(); if (this.level().getBlockState(pos).isAir() && state.canSurvive(this.level(), pos)) { -@@ -1482,6 +_,7 @@ +@@ -1478,6 +_,7 @@ } protected void dropAllDeathLoot(ServerLevel level, DamageSource source) { @@ -323,7 +324,7 @@ boolean playerKilled = this.lastHurtByPlayerMemoryTime > 0; if (this.shouldDropLoot(level)) { this.dropFromLootTable(level, source, playerKilled); -@@ -1490,6 +_,10 @@ +@@ -1486,6 +_,10 @@ this.dropEquipment(level); this.dropExperience(level, source.getEntity()); @@ -334,7 +335,7 @@ } protected void dropEquipment(ServerLevel level) { -@@ -1501,7 +_,8 @@ +@@ -1497,7 +_,8 @@ this.isAlwaysExperienceDropper() || this.lastHurtByPlayerMemoryTime > 0 && this.shouldDropExperience() && level.getGameRules().get(GameRules.MOB_DROPS) )) { @@ -344,7 +345,7 @@ } } -@@ -1601,6 +_,11 @@ +@@ -1597,6 +_,11 @@ } public void knockback(double power, double xd, double zd) { @@ -356,7 +357,7 @@ power *= 1.0 - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE); if (!(power <= 0.0)) { this.needsSync = true; -@@ -1682,17 +_,11 @@ +@@ -1678,17 +_,11 @@ } else { BlockPos ladderCheckPos = this.blockPosition(); BlockState state = this.getInBlockState(); @@ -379,19 +380,19 @@ } } -@@ -1740,6 +_,11 @@ +@@ -1749,6 +_,11 @@ + effectiveFallDistance = fallDistance; + } - @Override - public boolean causeFallDamage(double fallDistance, float damageModifier, DamageSource damageSource) { -+ var event = net.neoforged.neoforge.common.CommonHooks.onLivingFall(this, fallDistance, damageModifier); ++ var event = net.neoforged.neoforge.common.CommonHooks.onLivingFall(this, effectiveFallDistance, damageModifier); + if (event.isCanceled()) return false; -+ fallDistance = event.getDistance(); ++ effectiveFallDistance = event.getDistance(); + damageModifier = event.getDamageMultiplier(); + - boolean damaged = super.causeFallDamage(fallDistance, damageModifier, damageSource); - int dmg = this.calculateFallDamage(fallDistance, damageModifier); + boolean damaged = super.causeFallDamage(effectiveFallDistance, damageModifier, damageSource); + int dmg = this.calculateFallDamage(effectiveFallDistance, damageModifier); if (dmg > 0) { -@@ -1770,10 +_,10 @@ +@@ -1813,10 +_,10 @@ int xx = Mth.floor(this.getX()); int yy = Mth.floor(this.getY() - 0.2F); int zz = Mth.floor(this.getZ()); @@ -405,7 +406,7 @@ } } } -@@ -1798,6 +_,8 @@ +@@ -1841,6 +_,8 @@ if (!(damage <= 0.0F)) { int durabilityDamage = (int)Math.max(1.0F, damage / 4.0F); @@ -414,7 +415,7 @@ for (EquipmentSlot slot : slots) { ItemStack itemStack = this.getItemBySlot(slot); Equippable equippable = itemStack.get(DataComponents.EQUIPPABLE); -@@ -1831,6 +_,7 @@ +@@ -1874,6 +_,7 @@ damage = Math.max(v / 25.0F, 0.0F); float damageResisted = oldDamage - damage; if (damageResisted > 0.0F && damageResisted < 3.4028235E37F) { @@ -422,7 +423,7 @@ if (this instanceof ServerPlayer) { ((ServerPlayer)this).awardStat(Stats.DAMAGE_RESISTED, Math.round(damageResisted * 10.0F)); } else if (damageSource.getEntity() instanceof ServerPlayer) { -@@ -1853,6 +_,7 @@ +@@ -1896,6 +_,7 @@ if (enchantmentArmor > 0.0F) { damage = CombatRules.getDamageAfterMagicAbsorb(damage, enchantmentArmor); @@ -430,7 +431,7 @@ } return damage; -@@ -1862,11 +_,13 @@ +@@ -1905,11 +_,13 @@ protected void actuallyHurt(ServerLevel level, DamageSource source, float dmg) { if (!this.isInvulnerableTo(level, source)) { @@ -449,7 +450,7 @@ if (absorbedDamage > 0.0F && absorbedDamage < 3.4028235E37F && source.getEntity() instanceof ServerPlayer serverPlayer) { serverPlayer.awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(absorbedDamage * 10.0F)); } -@@ -1874,9 +_,10 @@ +@@ -1917,9 +_,10 @@ if (var10 != 0.0F) { this.getCombatTracker().recordDamage(source, var10); this.setHealth(this.getHealth() - var10); @@ -461,7 +462,7 @@ } } -@@ -1933,6 +_,8 @@ +@@ -1977,6 +_,8 @@ } public void swing(InteractionHand hand, boolean sendToSwingingEntity) { @@ -470,7 +471,7 @@ if (!this.swinging || this.swingTime >= this.getCurrentSwingDuration() / 2 || this.swingTime < 0) { this.swingTime = -1; this.swinging = true; -@@ -2075,8 +_,10 @@ +@@ -2119,8 +_,10 @@ private void swapHandItems() { ItemStack tmp = this.getItemBySlot(EquipmentSlot.OFFHAND); @@ -483,7 +484,7 @@ } @Override -@@ -2184,7 +_,13 @@ +@@ -2232,7 +_,13 @@ } public void setItemSlot(EquipmentSlot slot, ItemStack itemStack) { @@ -498,7 +499,7 @@ } public float getArmorCoverPercentage() { -@@ -2289,15 +_,18 @@ +@@ -2337,15 +_,18 @@ } this.needsSync = true; @@ -519,7 +520,7 @@ } protected float getWaterSlowDown() { -@@ -2329,7 +_,8 @@ +@@ -2381,7 +_,8 @@ } protected boolean shouldTravelInFluid(FluidState fluidState) { @@ -529,7 +530,7 @@ } protected void travelFlying(Vec3 input, float speed) { -@@ -2354,7 +_,7 @@ +@@ -2406,7 +_,7 @@ private void travelInAir(Vec3 input) { BlockPos posBelow = this.getBlockPosBelowThatAffectsMyMovement(); @@ -538,7 +539,7 @@ float friction = blockFriction * 0.91F; Vec3 movement = this.handleRelativeFrictionAndCalculateMovement(input, blockFriction); double movementY = movement.y; -@@ -2377,11 +_,20 @@ +@@ -2429,11 +_,20 @@ } } @@ -560,7 +561,7 @@ this.travelInWater(input, baseGravity, isFalling, oldY); this.floatInWaterWhileRidden(); } else { -@@ -2406,6 +_,7 @@ +@@ -2458,6 +_,7 @@ slowDown = 0.96F; } @@ -568,7 +569,7 @@ this.moveRelative(speed, input); this.move(MoverType.SELF, this.getDeltaMovement()); Vec3 ladderMovement = this.getDeltaMovement(); -@@ -2579,7 +_,7 @@ +@@ -2631,7 +_,7 @@ double xd = Mth.clamp(delta.x, -0.15F, 0.15F); double zd = Mth.clamp(delta.z, -0.15F, 0.15F); double yd = Math.max(delta.y, -0.15F); @@ -577,7 +578,7 @@ yd = 0.0; } -@@ -2810,6 +_,7 @@ +@@ -2865,6 +_,7 @@ ItemStack previous = this.lastEquipmentItems.get(slot); ItemStack current = this.getItemBySlot(slot); if (this.equipmentHasChanged(previous, current)) { @@ -585,7 +586,7 @@ if (changedItems == null) { changedItems = Maps.newEnumMap(EquipmentSlot.class); } -@@ -2945,6 +_,9 @@ +@@ -3000,6 +_,9 @@ profiler.push("jump"); if (this.jumping && this.isAffectedByFluids()) { double fluidHeight; @@ -595,7 +596,7 @@ if (this.isInLava()) { fluidHeight = this.getFluidHeight(FluidTags.LAVA); } else { -@@ -2955,15 +_,17 @@ +@@ -3010,15 +_,17 @@ double fluidJumpThreshold = this.getFluidJumpThreshold(); if (!inWaterAndHasFluidHeight || this.onGround() && !(fluidHeight > fluidJumpThreshold)) { if (!this.isInLava() || this.onGround() && !(fluidHeight > fluidJumpThreshold)) { @@ -615,7 +616,7 @@ } } else { this.noJumpDelay = 0; -@@ -3281,8 +_,11 @@ +@@ -3336,8 +_,11 @@ private void updatingUsingItem() { if (this.isUsingItem()) { @@ -629,7 +630,7 @@ this.updateUsingItem(this.useItem); } else { this.stopUsingItem(); -@@ -3325,8 +_,11 @@ +@@ -3380,8 +_,11 @@ } protected void updateUsingItem(ItemStack useItem) { @@ -642,7 +643,7 @@ this.completeUsingItem(); } } -@@ -3354,8 +_,10 @@ +@@ -3409,8 +_,10 @@ public void startUsingItem(InteractionHand hand) { ItemStack itemStack = this.getItemInHand(hand); if (!itemStack.isEmpty() && !this.isUsingItem()) { @@ -654,7 +655,7 @@ if (!this.level().isClientSide()) { this.setLivingEntityFlag(1, true); this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND); -@@ -3421,7 +_,8 @@ +@@ -3480,7 +_,8 @@ this.releaseUsingItem(); } else { if (!this.useItem.isEmpty() && this.isUsingItem()) { @@ -664,7 +665,7 @@ if (result != this.useItem) { this.setItemInHand(hand, result); } -@@ -3455,7 +_,11 @@ +@@ -3514,7 +_,11 @@ ItemStack itemInUsedHand = this.getItemInHand(this.getUsedItemHand()); if (!this.useItem.isEmpty() && ItemStack.isSameItem(itemInUsedHand, this.useItem)) { this.useItem = itemInUsedHand; @@ -676,7 +677,7 @@ if (this.useItem.useOnRelease()) { this.updatingUsingItem(); } -@@ -3465,6 +_,7 @@ +@@ -3524,6 +_,7 @@ } public void stopUsingItem() { @@ -684,7 +685,7 @@ if (!this.level().isClientSide()) { boolean wasUsingItem = this.isUsingItem(); this.recentKineticEnemies = null; -@@ -3626,8 +_,8 @@ +@@ -3685,8 +_,8 @@ } BlockState blockState = this.level().getBlockState(bedPosition); @@ -695,7 +696,7 @@ } this.setPose(Pose.SLEEPING); -@@ -3642,15 +_,17 @@ +@@ -3701,15 +_,17 @@ } private boolean checkBedExists() { @@ -716,7 +717,7 @@ Vec3 standUp = BedBlock.findStandUpPosition(this.getType(), this.level(), bedPosition, facing, this.getYRot()).orElseGet(() -> { BlockPos above = bedPosition.above(); return new Vec3(above.getX() + 0.5, above.getY() + 0.1, above.getZ() + 0.5); -@@ -3670,7 +_,9 @@ +@@ -3729,7 +_,9 @@ public @Nullable Direction getBedOrientation() { BlockPos bedPos = this.getSleepingPos().orElse(null); @@ -727,7 +728,7 @@ } @Override -@@ -3679,7 +_,7 @@ +@@ -3738,7 +_,7 @@ } public ItemStack getProjectile(ItemStack heldWeapon) { @@ -736,7 +737,7 @@ } private static byte entityEventForEquipmentBreak(EquipmentSlot equipmentSlot) { -@@ -3731,6 +_,8 @@ +@@ -3790,6 +_,8 @@ } public final EquipmentSlot getEquipmentSlotForItem(ItemStack itemStack) { diff --git a/patches/net/minecraft/world/entity/Mob.java.patch b/patches/net/minecraft/world/entity/Mob.java.patch index 23e408076fc..88e311c8fa0 100644 --- a/patches/net/minecraft/world/entity/Mob.java.patch +++ b/patches/net/minecraft/world/entity/Mob.java.patch @@ -12,11 +12,12 @@ protected Mob(EntityType type, Level level) { super(type, level); -@@ -232,7 +_,10 @@ +@@ -244,7 +_,11 @@ } public void setTarget(@Nullable LivingEntity target) { -- this.target = target; +- this.target = this.asValidTarget(target); ++ target = this.asValidTarget(target); + net.neoforged.neoforge.event.entity.living.LivingChangeTargetEvent changeTargetEvent = net.neoforged.neoforge.common.CommonHooks.onLivingChangeTarget(this, target, net.neoforged.neoforge.event.entity.living.LivingChangeTargetEvent.LivingTargetType.MOB_TARGET); + if(!changeTargetEvent.isCanceled()) { + this.target = changeTargetEvent.getNewAboutToBeSetTarget(); @@ -24,7 +25,7 @@ } @Override -@@ -328,6 +_,12 @@ +@@ -340,6 +_,12 @@ if (!this.level().isClientSide() && this.tickCount % 5 == 0) { this.updateControlFlags(); } @@ -37,7 +38,7 @@ } protected void updateControlFlags() { -@@ -371,6 +_,9 @@ +@@ -383,6 +_,9 @@ if (this.isNoAi()) { output.putBoolean("NoAI", this.isNoAi()); } @@ -47,7 +48,7 @@ } @Override -@@ -389,6 +_,14 @@ +@@ -401,6 +_,14 @@ this.lootTable = input.read("DeathLootTable", LootTable.KEY_CODEC); this.lootTableSeed = input.getLongOr("DeathLootTableSeed", 0L); this.setNoAi(input.getBooleanOr("NoAI", false)); @@ -62,7 +63,7 @@ } @Override -@@ -447,7 +_,7 @@ +@@ -459,7 +_,7 @@ && this.canPickUpLoot() && this.isAlive() && !this.dead @@ -71,7 +72,7 @@ Vec3i pickupReach = this.getPickupReach(); for (ItemEntity entity : this.level() -@@ -602,6 +_,8 @@ +@@ -614,6 +_,8 @@ private double getApproximateAttributeWith(ItemStack itemStack, Holder attribute, EquipmentSlot slot) { double baseValue = this.getAttributes().hasAttribute(attribute) ? this.getAttributeBaseValue(attribute) : 0.0; ItemAttributeModifiers attributeModifiers = itemStack.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); @@ -80,7 +81,7 @@ return attributeModifiers.compute(attribute, baseValue, slot); } -@@ -641,6 +_,7 @@ +@@ -653,6 +_,7 @@ @Override public void checkDespawn() { @@ -88,7 +89,7 @@ if (this.level().getDifficulty() == Difficulty.PEACEFUL && !this.getType().isAllowedInPeaceful()) { this.discard(); } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { -@@ -1038,6 +_,11 @@ +@@ -1054,6 +_,11 @@ } } @@ -100,7 +101,7 @@ public @Nullable SpawnGroupData finalizeSpawn( ServerLevelAccessor level, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData groupData ) { -@@ -1050,6 +_,7 @@ +@@ -1066,6 +_,7 @@ } this.setLeftHanded(random.nextFloat() < 0.05F); @@ -108,7 +109,7 @@ return groupData; } -@@ -1196,6 +_,7 @@ +@@ -1212,6 +_,7 @@ } else { params.type().convert(this, newMob, params); afterConversion.finalizeConversion(newMob); @@ -116,7 +117,7 @@ if (this.level() instanceof ServerLevel serverLevel) { serverLevel.addFreshEntity(newMob); } -@@ -1359,14 +_,24 @@ +@@ -1375,14 +_,24 @@ } @Override @@ -142,7 +143,7 @@ @VisibleForTesting public void removeFreeWill() { this.removeAllGoals(goal -> true); -@@ -1427,5 +_,40 @@ +@@ -1442,5 +_,40 @@ public float chargeSpeedModifier() { return 1.0F; diff --git a/patches/net/minecraft/world/entity/TamableAnimal.java.patch b/patches/net/minecraft/world/entity/TamableAnimal.java.patch index f813ff7b920..51c7f14304c 100644 --- a/patches/net/minecraft/world/entity/TamableAnimal.java.patch +++ b/patches/net/minecraft/world/entity/TamableAnimal.java.patch @@ -1,6 +1,15 @@ --- a/net/minecraft/world/entity/TamableAnimal.java +++ b/net/minecraft/world/entity/TamableAnimal.java -@@ -210,13 +_,16 @@ +@@ -138,6 +_,8 @@ + this.usePlayerItem(player, hand, itemStack); + this.heal(foodProperties != null ? healingFactor * foodProperties.nutrition() : defaultHeal); + this.playEatingSound(); ++ this.usePlayerItem(player, hand, itemStack); ++ this.gameEvent(net.minecraft.world.level.gameevent.GameEvent.EAT); // Neo: add EAT game event + } + + public boolean isInSittingPose() { +@@ -222,13 +_,16 @@ @Override public void die(DamageSource source) { diff --git a/patches/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch b/patches/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch index 933299f30ea..f303ecb75fa 100644 --- a/patches/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch +++ b/patches/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java.patch @@ -13,8 +13,8 @@ BlockState state = level.getBlockState(blockPos); Block block = state.getBlock(); Block blockBelow = level.getBlockState(blockPos.below()).getBlock(); -- return block instanceof CropBlock && ((CropBlock)block).isMaxAge(state) || state.isAir() && blockBelow instanceof FarmBlock; -+ return block instanceof CropBlock && ((CropBlock)block).isMaxAge(state) || state.isAir() && (blockBelow instanceof FarmBlock || blockBelow.builtInRegistryHolder().is(net.neoforged.neoforge.common.Tags.Blocks.VILLAGER_FARMLANDS)); +- return block instanceof CropBlock && ((CropBlock)block).isMaxAge(state) || state.isAir() && blockBelow instanceof FarmlandBlock; ++ return block instanceof CropBlock && ((CropBlock)block).isMaxAge(state) || state.isAir() && (blockBelow instanceof FarmlandBlock || blockBelow.builtInRegistryHolder().is(net.neoforged.neoforge.common.Tags.Blocks.VILLAGER_FARMLANDS)); } protected void start(ServerLevel level, Villager body, long timestamp) { @@ -22,8 +22,8 @@ level.destroyBlock(this.aboveFarmlandPos, true, body); } -- if (blockState.isAir() && blockBelow instanceof FarmBlock && body.hasFarmSeeds()) { -+ if (blockState.isAir() && (blockBelow instanceof FarmBlock || blockBelow.builtInRegistryHolder().is(net.neoforged.neoforge.common.Tags.Blocks.VILLAGER_FARMLANDS)) && body.hasFarmSeeds()) { +- if (blockState.isAir() && blockBelow instanceof FarmlandBlock && body.hasFarmSeeds()) { ++ if (blockState.isAir() && (blockBelow instanceof FarmlandBlock || blockBelow.builtInRegistryHolder().is(net.neoforged.neoforge.common.Tags.Blocks.VILLAGER_FARMLANDS)) && body.hasFarmSeeds()) { SimpleContainer inventory = body.getInventory(); for (int i = 0; i < inventory.getContainerSize(); i++) { diff --git a/patches/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch b/patches/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch index 0ff27295e33..6992644d1c7 100644 --- a/patches/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch +++ b/patches/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java.patch @@ -14,7 +14,7 @@ ItemStack itemStack = inventory.getItem(i); - int itemIndex = COMPOSTABLE_ITEMS.indexOf(itemStack.getItem()); - if (itemIndex != -1) { -+ var compostable = itemStack.getItemHolder().getData(net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps.COMPOSTABLES); ++ var compostable = itemStack.typeHolder().getData(net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps.COMPOSTABLES); + if (compostable != null && compostable.canVillagerCompost()) { int stackSize = itemStack.getCount(); - int totalItemCount = itemsSeenSoFar[itemIndex] + stackSize; diff --git a/patches/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java.patch b/patches/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java.patch index 2291c8bfa81..c7103640d90 100644 --- a/patches/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java.patch +++ b/patches/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java +++ b/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java -@@ -35,7 +_,7 @@ +@@ -34,7 +_,7 @@ @Override public boolean canUse() { @@ -9,7 +9,7 @@ return false; } else if (this.nextStartTick > 0) { this.nextStartTick--; -@@ -142,6 +_,6 @@ +@@ -139,6 +_,6 @@ ChunkAccess chunk = level.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ()), ChunkStatus.FULL, false); return chunk == null ? false diff --git a/patches/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch b/patches/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch index f8d5c95f01c..3351b1ac89e 100644 --- a/patches/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch +++ b/patches/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/net/minecraft/world/entity/ai/navigation/PathNavigation.java -@@ -244,10 +_,10 @@ +@@ -242,10 +_,10 @@ Vec3 mobPos = this.getTempMobPos(); this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F; Vec3i currentNodePos = this.path.getNextNodePos(); diff --git a/patches/net/minecraft/world/entity/ai/village/VillageSiege.java.patch b/patches/net/minecraft/world/entity/ai/village/VillageSiege.java.patch index 4ce87d3356b..db7b6a9420d 100644 --- a/patches/net/minecraft/world/entity/ai/village/VillageSiege.java.patch +++ b/patches/net/minecraft/world/entity/ai/village/VillageSiege.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/village/VillageSiege.java +++ b/net/minecraft/world/entity/ai/village/VillageSiege.java -@@ -71,7 +_,9 @@ +@@ -78,7 +_,9 @@ this.spawnX = center.getX() + Mth.floor(Mth.cos(angle) * 32.0F); this.spawnY = center.getY(); this.spawnZ = center.getZ() + Mth.floor(Mth.sin(angle) * 32.0F); @@ -11,7 +11,7 @@ this.nextSpawnTime = 0; this.zombiesToSpawn = 20; break; -@@ -91,7 +_,7 @@ +@@ -98,7 +_,7 @@ if (spawnPos != null) { Zombie zombie; try { 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 1df1990d236..36792507c8c 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 -@@ -354,9 +_,9 @@ +@@ -337,9 +_,9 @@ public boolean wantsToPickUp(ServerLevel level, ItemStack itemStack) { ItemStack itemInHand = this.getItemInHand(InteractionHand.MAIN_HAND); return !itemInHand.isEmpty() diff --git a/patches/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch b/patches/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch index c123cb5d715..3f44136365a 100644 --- a/patches/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch +++ b/patches/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java +++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java -@@ -298,7 +_,7 @@ +@@ -299,7 +_,7 @@ @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemStack = player.getItemInHand(hand); diff --git a/patches/net/minecraft/world/entity/animal/bee/Bee.java.patch b/patches/net/minecraft/world/entity/animal/bee/Bee.java.patch index 10774fde002..03cb2343851 100644 --- a/patches/net/minecraft/world/entity/animal/bee/Bee.java.patch +++ b/patches/net/minecraft/world/entity/animal/bee/Bee.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/bee/Bee.java +++ b/net/minecraft/world/entity/animal/bee/Bee.java -@@ -479,7 +_,7 @@ +@@ -480,7 +_,7 @@ if (this.hivePos == null) { return null; } else { @@ -9,7 +9,7 @@ } } -@@ -641,8 +_,18 @@ +@@ -646,8 +_,18 @@ } @Override diff --git a/patches/net/minecraft/world/entity/animal/camel/Camel.java.patch b/patches/net/minecraft/world/entity/animal/camel/Camel.java.patch index b4a3d75e1d8..f7228868dc2 100644 --- a/patches/net/minecraft/world/entity/animal/camel/Camel.java.patch +++ b/patches/net/minecraft/world/entity/animal/camel/Camel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/camel/Camel.java +++ b/net/minecraft/world/entity/animal/camel/Camel.java -@@ -300,6 +_,7 @@ +@@ -301,6 +_,7 @@ this.dashCooldown = 55; this.setDashing(true); this.needsSync = true; diff --git a/patches/net/minecraft/world/entity/animal/equine/AbstractHorse.java.patch b/patches/net/minecraft/world/entity/animal/equine/AbstractHorse.java.patch index 35013025db4..e683d5b481a 100644 --- a/patches/net/minecraft/world/entity/animal/equine/AbstractHorse.java.patch +++ b/patches/net/minecraft/world/entity/animal/equine/AbstractHorse.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/equine/AbstractHorse.java +++ b/net/minecraft/world/entity/animal/equine/AbstractHorse.java -@@ -341,9 +_,9 @@ +@@ -343,9 +_,9 @@ protected void playStepSound(BlockPos pos, BlockState blockState) { if (!blockState.liquid()) { BlockState aboveState = this.level().getBlockState(pos.above()); @@ -12,7 +12,7 @@ } if (this.isVehicle() && this.canGallop) { -@@ -770,6 +_,7 @@ +@@ -772,6 +_,7 @@ Vec3 movement = this.getDeltaMovement(); this.setDeltaMovement(movement.x, impulse, movement.z); this.needsSync = true; @@ -20,7 +20,7 @@ if (input.z > 0.0) { float sin = Mth.sin(this.getYRot() * (float) (Math.PI / 180.0)); float cos = Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)); -@@ -1017,6 +_,11 @@ +@@ -1019,6 +_,11 @@ this.randomizeAttributes(level.getRandom()); return super.finalizeSpawn(level, difficulty, spawnReason, groupData); diff --git a/patches/net/minecraft/world/entity/animal/feline/Cat.java.patch b/patches/net/minecraft/world/entity/animal/feline/Cat.java.patch index fe08a9ab0d9..82e2b226377 100644 --- a/patches/net/minecraft/world/entity/animal/feline/Cat.java.patch +++ b/patches/net/minecraft/world/entity/animal/feline/Cat.java.patch @@ -1,16 +1,5 @@ --- a/net/minecraft/world/entity/animal/feline/Cat.java +++ b/net/minecraft/world/entity/animal/feline/Cat.java -@@ -384,9 +_,9 @@ - } - } else if (this.isFood(itemStack) && this.getHealth() < this.getMaxHealth()) { - if (!this.level().isClientSide()) { -- this.usePlayerItem(player, hand, itemStack); - FoodProperties foodProperties = itemStack.get(DataComponents.FOOD); - this.heal(foodProperties != null ? foodProperties.nutrition() : 1.0F); -+ this.usePlayerItem(player, hand, itemStack); - this.playEatingSound(); - } - @@ -448,7 +_,7 @@ } diff --git a/patches/net/minecraft/world/entity/animal/fox/Fox.java.patch b/patches/net/minecraft/world/entity/animal/fox/Fox.java.patch index f54fb1d6d99..8bbd9df9408 100644 --- a/patches/net/minecraft/world/entity/animal/fox/Fox.java.patch +++ b/patches/net/minecraft/world/entity/animal/fox/Fox.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/fox/Fox.java +++ b/net/minecraft/world/entity/animal/fox/Fox.java -@@ -694,13 +_,18 @@ +@@ -698,13 +_,18 @@ @Override protected void dropAllDeathLoot(ServerLevel level, DamageSource source) { @@ -20,7 +20,7 @@ } public static boolean isPathClear(Fox fox, LivingEntity target) { -@@ -856,6 +_,17 @@ +@@ -871,6 +_,17 @@ @Override protected void breed() { Fox offspring = (Fox)this.animal.getBreedOffspring(this.level, this.partner); @@ -38,7 +38,7 @@ if (offspring != null) { ServerPlayer animalLoveCause = this.animal.getLoveCause(); ServerPlayer partnerLoveCause = this.partner.getLoveCause(); -@@ -933,7 +_,7 @@ +@@ -949,7 +_,7 @@ } protected void onReachedTarget() { @@ -47,7 +47,7 @@ BlockState state = Fox.this.level().getBlockState(this.blockPos); if (state.is(Blocks.SWEET_BERRY_BUSH)) { this.pickSweetBerries(state); -@@ -992,7 +_,7 @@ +@@ -1009,7 +_,7 @@ @Override public boolean canUse() { 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 c45acaf594b..df80687dac2 100644 --- a/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch +++ b/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/net/minecraft/world/entity/animal/frog/Tadpole.java -@@ -219,8 +_,10 @@ +@@ -199,8 +_,10 @@ } private void ageUp() { diff --git a/patches/net/minecraft/world/entity/animal/parrot/Parrot.java.patch b/patches/net/minecraft/world/entity/animal/parrot/Parrot.java.patch index 35c70a80b23..09f6963213e 100644 --- a/patches/net/minecraft/world/entity/animal/parrot/Parrot.java.patch +++ b/patches/net/minecraft/world/entity/animal/parrot/Parrot.java.patch @@ -13,7 +13,7 @@ private static final Map, SoundEvent> MOB_SOUND_MAP = Util.make(Maps.newHashMap(), map -> { map.put(EntityType.BLAZE, SoundEvents.PARROT_IMITATE_BLAZE); map.put(EntityType.BOGGED, SoundEvents.PARROT_IMITATE_BOGGED); -@@ -267,7 +_,7 @@ +@@ -268,7 +_,7 @@ } if (!this.level().isClientSide()) { @@ -22,7 +22,7 @@ this.tame(player); this.level().broadcastEntityEvent(this, (byte)7); } else { -@@ -327,7 +_,10 @@ +@@ -328,7 +_,10 @@ public static SoundEvent getAmbient(Level level, RandomSource random) { if (level.getDifficulty() != Difficulty.PEACEFUL && random.nextInt(1000) == 0) { @@ -34,7 +34,7 @@ return getImitatedSound(keys.get(random.nextInt(keys.size()))); } else { return SoundEvents.PARROT_AMBIENT; -@@ -335,7 +_,9 @@ +@@ -336,7 +_,9 @@ } private static SoundEvent getImitatedSound(EntityType id) { diff --git a/patches/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch b/patches/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch index 449a9676063..540819aee5e 100644 --- a/patches/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch +++ b/patches/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/rabbit/Rabbit.java +++ b/net/minecraft/world/entity/animal/rabbit/Rabbit.java -@@ -554,7 +_,7 @@ +@@ -602,7 +_,7 @@ @Override public boolean canUse() { if (this.nextStartTick <= 0) { @@ -9,12 +9,3 @@ return false; } -@@ -603,7 +_,7 @@ - @Override - protected boolean isValidTarget(LevelReader level, BlockPos pos) { - BlockState state = level.getBlockState(pos); -- if (state.is(Blocks.FARMLAND) && this.wantsToRaid && !this.canRaid) { -+ if (state.getBlock() instanceof net.minecraft.world.level.block.FarmBlock && this.wantsToRaid && !this.canRaid) { - state = level.getBlockState(pos.above()); - if (state.getBlock() instanceof CarrotBlock && ((CarrotBlock)state.getBlock()).isMaxAge(state)) { - this.canRaid = true; diff --git a/patches/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch b/patches/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch index 9870648a633..591440170c2 100644 --- a/patches/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch +++ b/patches/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -297,7 +_,7 @@ +@@ -303,7 +_,7 @@ if (this.tickCount % 10 == 0) { this.level() .playLocalSound( diff --git a/patches/net/minecraft/world/entity/animal/wolf/Wolf.java.patch b/patches/net/minecraft/world/entity/animal/wolf/Wolf.java.patch index b52843b81a6..97ea2acf900 100644 --- a/patches/net/minecraft/world/entity/animal/wolf/Wolf.java.patch +++ b/patches/net/minecraft/world/entity/animal/wolf/Wolf.java.patch @@ -1,19 +1,6 @@ --- a/net/minecraft/world/entity/animal/wolf/Wolf.java +++ b/net/minecraft/world/entity/animal/wolf/Wolf.java -@@ -456,10 +_,11 @@ - Item item = itemStack.getItem(); - if (this.isTame()) { - if (this.isFood(itemStack) && this.getHealth() < this.getMaxHealth()) { -- this.usePlayerItem(player, hand, itemStack); - FoodProperties foodProperties = itemStack.get(DataComponents.FOOD); - float nutrition = foodProperties != null ? foodProperties.nutrition() : 1.0F; - this.heal(2.0F * nutrition); -+ this.usePlayerItem(player, hand, itemStack); -+ this.gameEvent(GameEvent.EAT); // Neo: add EAT game event - return InteractionResult.SUCCESS; - } - -@@ -511,7 +_,7 @@ +@@ -502,7 +_,7 @@ } private void tryToTame(Player player) { 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 646d8585267..2b7e719482c 100644 --- a/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch +++ b/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch @@ -44,7 +44,7 @@ destroyedBlock = level.removeBlock(blockPos, false) || destroyedBlock; } else { hitWall = true; -@@ -528,7 +_,8 @@ +@@ -535,7 +_,8 @@ if (this.level() instanceof ServerLevel level) { if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && level.getGameRules().get(GameRules.MOB_DROPS)) { @@ -54,7 +54,7 @@ } if (this.dragonDeathTime == 1 && !this.isSilent()) { -@@ -546,7 +_,8 @@ +@@ -553,7 +_,8 @@ if (this.dragonDeathTime == 200 && this.level() instanceof ServerLevel level) { if (level.getGameRules().get(GameRules.MOB_DROPS)) { @@ -64,7 +64,7 @@ } if (this.dragonFight != null) { -@@ -852,8 +_,19 @@ +@@ -859,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 06782a98c27..94dc9c73a66 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 -@@ -318,7 +_,7 @@ +@@ -319,7 +_,7 @@ if (this.destroyBlocksTick > 0) { this.destroyBlocksTick--; @@ -9,7 +9,7 @@ boolean destroyed = false; int width = Mth.floor(this.getBbWidth() / 2.0F + 1.0F); int height = Mth.floor(this.getBbHeight()); -@@ -332,7 +_,7 @@ +@@ -333,7 +_,7 @@ this.getBlockZ() + width )) { BlockState state = level.getBlockState(blockPos); @@ -18,7 +18,7 @@ destroyed = level.destroyBlock(blockPos, true, this) || destroyed; } } -@@ -351,6 +_,10 @@ +@@ -352,6 +_,10 @@ } } @@ -29,7 +29,7 @@ public static boolean canDestroy(BlockState state) { return !state.isAir() && !state.is(BlockTags.WITHER_IMMUNE); } -@@ -490,6 +_,7 @@ +@@ -491,6 +_,7 @@ @Override public void checkDespawn() { diff --git a/patches/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java.patch b/patches/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java.patch index cda67d9e097..5b0c27f4e61 100644 --- a/patches/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java.patch +++ b/patches/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java.patch @@ -6,6 +6,6 @@ } else { - if (player.getItemInHand(hand).is(Items.SHEARS)) { + if (player.getItemInHand(hand).canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SHEARS_HARVEST)) { - InteractionResult result = super.interact(player, hand); + InteractionResult result = super.interact(player, hand, location); if (result instanceof InteractionResult.Success success && success.wasItemInteraction()) { return result; diff --git a/patches/net/minecraft/world/entity/monster/Shulker.java.patch b/patches/net/minecraft/world/entity/monster/Shulker.java.patch index c0ad78a86b1..5694a84e3a5 100644 --- a/patches/net/minecraft/world/entity/monster/Shulker.java.patch +++ b/patches/net/minecraft/world/entity/monster/Shulker.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java -@@ -389,6 +_,12 @@ +@@ -390,6 +_,12 @@ && this.level().noCollision(this, new AABB(target).deflate(1.0E-6))) { Direction attachmentDirection = this.findAttachableSurface(target); if (attachmentDirection != null) { 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 151a617d5db..5941085120d 100644 --- a/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch +++ b/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/creaking/Creaking.java +++ b/net/minecraft/world/entity/monster/creaking/Creaking.java -@@ -467,7 +_,8 @@ +@@ -468,7 +_,8 @@ for (Player player : players) { if (this.canAttack(player) && !this.isAlliedTo(player)) { hasPotentialTarget = true; diff --git a/patches/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch b/patches/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch index ebb476e0196..7daebf0ff4c 100644 --- a/patches/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch +++ b/patches/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -169,7 +_,7 @@ +@@ -140,7 +_,7 @@ HoglinAi.updateActivity(this); if (this.isConverting()) { this.timeInOverworld++; @@ -9,7 +9,7 @@ this.makeSound(SoundEvents.HOGLIN_CONVERTED_TO_ZOMBIFIED); this.finishConversion(); } -@@ -264,7 +_,10 @@ +@@ -235,7 +_,10 @@ private void finishConversion() { this.convertTo( diff --git a/patches/net/minecraft/world/entity/monster/illager/Evoker.java.patch b/patches/net/minecraft/world/entity/monster/illager/Evoker.java.patch index 6e530d49bb0..82d4fd203c5 100644 --- a/patches/net/minecraft/world/entity/monster/illager/Evoker.java.patch +++ b/patches/net/minecraft/world/entity/monster/illager/Evoker.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/illager/Evoker.java +++ b/net/minecraft/world/entity/monster/illager/Evoker.java -@@ -290,7 +_,7 @@ +@@ -311,7 +_,7 @@ return false; } else { ServerLevel level = getServerLevel(Evoker.this.level()); diff --git a/patches/net/minecraft/world/entity/monster/illager/Illusioner.java.patch b/patches/net/minecraft/world/entity/monster/illager/Illusioner.java.patch index 38bcaa4206f..f276faa6f5d 100644 --- a/patches/net/minecraft/world/entity/monster/illager/Illusioner.java.patch +++ b/patches/net/minecraft/world/entity/monster/illager/Illusioner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/illager/Illusioner.java +++ b/net/minecraft/world/entity/monster/illager/Illusioner.java -@@ -174,9 +_,11 @@ +@@ -175,9 +_,11 @@ @Override public void performRangedAttack(LivingEntity target, float power) { 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 95f810ff352..38f3a418b22 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 -@@ -352,7 +_,7 @@ +@@ -317,7 +_,7 @@ } else if (this.isChargingCrossbow()) { return PiglinArmPose.CROSSBOW_CHARGE; } else { @@ -9,7 +9,7 @@ } } -@@ -381,7 +_,7 @@ +@@ -346,7 +_,7 @@ @Override public boolean canUseNonMeleeWeapon(ItemStack item) { @@ -18,7 +18,7 @@ } protected void holdInMainHand(ItemStack itemStack) { -@@ -389,7 +_,7 @@ +@@ -354,7 +_,7 @@ } protected void holdInOffHand(ItemStack itemStack) { @@ -27,7 +27,7 @@ this.setItemSlot(EquipmentSlot.OFFHAND, itemStack); this.setGuaranteedDrop(EquipmentSlot.OFFHAND); } else { -@@ -399,7 +_,7 @@ +@@ -364,7 +_,7 @@ @Override public boolean wantsToPickUp(ServerLevel level, ItemStack itemStack) { diff --git a/patches/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch b/patches/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch index 0ac6abbe505..74fa6d82749 100644 --- a/patches/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch +++ b/patches/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java +++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -383,7 +_,7 @@ +@@ -385,7 +_,7 @@ ItemStack itemStack = body.getItemInHand(InteractionHand.OFF_HAND); body.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY); if (body.isAdult()) { @@ -9,7 +9,7 @@ if (barteringEnabled && barterCurrency) { throwItems(body, getBarterResponseItems(body)); } else if (!barterCurrency) { -@@ -465,7 +_,7 @@ +@@ -467,7 +_,7 @@ return false; } else if (isAdmiringDisabled(body) && body.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET)) { return false; @@ -18,7 +18,7 @@ return isNotHoldingLovedItemInOffHand(body); } else { boolean hasSpace = body.canAddToInventory(itemStack); -@@ -561,7 +_,7 @@ +@@ -563,7 +_,7 @@ } protected static boolean canAdmire(Piglin body, ItemStack playerHeldItemStack) { @@ -27,7 +27,7 @@ } protected static void wasHurtBy(ServerLevel level, Piglin body, LivingEntity attacker) { -@@ -650,7 +_,7 @@ +@@ -652,7 +_,7 @@ public static boolean isWearingSafeArmor(LivingEntity livingEntity) { for (EquipmentSlot slot : EquipmentSlotGroup.ARMOR) { @@ -36,7 +36,7 @@ return true; } } -@@ -799,7 +_,7 @@ +@@ -801,7 +_,7 @@ } private static boolean hasCrossbow(LivingEntity body) { diff --git a/patches/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch b/patches/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch index 82ee96e1f47..c65631e2f52 100644 --- a/patches/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch +++ b/patches/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java +++ b/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java -@@ -133,8 +_,8 @@ +@@ -138,8 +_,8 @@ if (this.level() != null && !this.level().isClientSide()) { this.goalSelector.removeGoal(this.meleeGoal); this.goalSelector.removeGoal(this.bowGoal); @@ -11,7 +11,7 @@ int minAttackInterval = this.getHardAttackInterval(); if (this.level().getDifficulty() != Difficulty.HARD) { minAttackInterval = this.getAttackInterval(); -@@ -158,9 +_,11 @@ +@@ -163,9 +_,11 @@ @Override public void performRangedAttack(LivingEntity target, float power) { @@ -24,7 +24,7 @@ double xd = target.getX() - this.getX(); double yd = target.getY(0.3333333333333333) - arrow.getY(); double zd = target.getZ() - this.getZ(); -@@ -180,7 +_,7 @@ +@@ -185,7 +_,7 @@ @Override public boolean canUseNonMeleeWeapon(ItemStack item) { diff --git a/patches/net/minecraft/world/entity/monster/zombie/Zombie.java.patch b/patches/net/minecraft/world/entity/monster/zombie/Zombie.java.patch index ceb14f319d0..d17357b31ed 100644 --- a/patches/net/minecraft/world/entity/monster/zombie/Zombie.java.patch +++ b/patches/net/minecraft/world/entity/monster/zombie/Zombie.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/zombie/Zombie.java +++ b/net/minecraft/world/entity/monster/zombie/Zombie.java -@@ -232,6 +_,7 @@ +@@ -233,6 +_,7 @@ } protected void doUnderWaterConversion(ServerLevel level) { @@ -8,19 +8,21 @@ this.convertToZombieType(level, EntityType.DROWNED); if (!this.isSilent()) { level.levelEvent(null, 1040, this.blockPosition(), 0); -@@ -242,7 +_,10 @@ +@@ -243,9 +_,10 @@ this.convertTo( zombieType, ConversionParams.single(this, true, true), -- newZombie -> newZombie.handleAttributes(level.getCurrentDifficultyAt(newZombie.blockPosition()).getSpecialMultiplier()) -+ p_381517_ -> { -+ p_381517_.handleAttributes(level.getCurrentDifficultyAt(p_381517_.blockPosition()).getSpecialMultiplier()); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381517_); +- newZombie -> newZombie.handleAttributes( +- level.getCurrentDifficultyAt(newZombie.blockPosition()).getSpecialMultiplier(), EntitySpawnReason.CONVERSION +- ) ++ newZombie -> { ++ newZombie.handleAttributes(level.getCurrentDifficultyAt(newZombie.blockPosition()).getSpecialMultiplier(), EntitySpawnReason.CONVERSION); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, newZombie); + } ); } -@@ -259,6 +_,7 @@ +@@ -262,6 +_,7 @@ zombie.setGossips(villager.getGossips().copy()); zombie.setTradeOffers(villager.getOffers().copy()); zombie.setVillagerXp(villager.getVillagerXp()); @@ -28,7 +30,7 @@ if (!this.isSilent()) { level.levelEvent(null, 1026, this.blockPosition(), 0); } -@@ -416,7 +_,7 @@ +@@ -419,7 +_,7 @@ @Override public boolean killedEntity(ServerLevel level, LivingEntity entity, DamageSource source) { boolean perished = super.killedEntity(level, entity, source); diff --git a/patches/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch b/patches/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch index 8f377b81ea7..3b9f83955d2 100644 --- a/patches/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch +++ b/patches/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/zombie/ZombieVillager.java +++ b/net/minecraft/world/entity/monster/zombie/ZombieVillager.java -@@ -145,7 +_,7 @@ +@@ -149,7 +_,7 @@ if (!this.level().isClientSide() && this.isAlive() && this.isConverting()) { int amount = this.getConversionProgress(); this.villagerConversionTime -= amount; @@ -9,7 +9,7 @@ this.finishConversion((ServerLevel)this.level()); } } -@@ -254,6 +_,8 @@ +@@ -258,6 +_,8 @@ if (!this.isSilent()) { level.levelEvent(null, 1027, this.blockPosition(), 0); } diff --git a/patches/net/minecraft/world/entity/npc/villager/AbstractVillager.java.patch b/patches/net/minecraft/world/entity/npc/villager/AbstractVillager.java.patch index c31ef45c658..a16633e74bf 100644 --- a/patches/net/minecraft/world/entity/npc/villager/AbstractVillager.java.patch +++ b/patches/net/minecraft/world/entity/npc/villager/AbstractVillager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/villager/AbstractVillager.java +++ b/net/minecraft/world/entity/npc/villager/AbstractVillager.java -@@ -125,6 +_,7 @@ +@@ -138,6 +_,7 @@ if (this.tradingPlayer instanceof ServerPlayer) { CriteriaTriggers.TRADE.trigger((ServerPlayer)this.tradingPlayer, this, offer.getResult()); } diff --git a/patches/net/minecraft/world/entity/npc/villager/Villager.java.patch b/patches/net/minecraft/world/entity/npc/villager/Villager.java.patch index 4f651e96568..849eaae1997 100644 --- a/patches/net/minecraft/world/entity/npc/villager/Villager.java.patch +++ b/patches/net/minecraft/world/entity/npc/villager/Villager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/villager/Villager.java +++ b/net/minecraft/world/entity/npc/villager/Villager.java -@@ -323,7 +_,7 @@ +@@ -299,7 +_,7 @@ @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemStack = player.getItemInHand(hand); @@ -9,7 +9,7 @@ return super.mobInteract(player, hand); } else if (this.isBaby()) { this.setUnhappy(); -@@ -770,10 +_,11 @@ +@@ -755,10 +_,11 @@ @Override public void thunderHit(ServerLevel level, LightningBolt lightningBolt) { @@ -22,7 +22,7 @@ w.setPersistenceRequired(); this.releaseAllPois(); }); -@@ -793,7 +_,10 @@ +@@ -778,7 +_,10 @@ @Override public boolean wantsToPickUp(ServerLevel level, ItemStack itemStack) { Item item = itemStack.getItem(); diff --git a/patches/net/minecraft/world/entity/npc/villager/VillagerTrades.java.patch b/patches/net/minecraft/world/entity/npc/villager/VillagerTrades.java.patch deleted file mode 100644 index 51064e9b763..00000000000 --- a/patches/net/minecraft/world/entity/npc/villager/VillagerTrades.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/net/minecraft/world/entity/npc/villager/VillagerTrades.java -+++ b/net/minecraft/world/entity/npc/villager/VillagerTrades.java -@@ -1387,6 +_,7 @@ - private final int villagerXp; - - public EmeraldsForVillagerTypeItem(int cost, int maxUses, int villagerXp, Map, Item> trades) { -+ if (false) // Neo: disable this check so that mods can add custom villager types - BuiltInRegistries.VILLAGER_TYPE.registryKeySet().stream().filter(t -> !trades.containsKey(t)).findAny().ifPresent(t -> { - throw new IllegalStateException("Missing trade for villager type: " + t); - }); -@@ -1403,8 +_,10 @@ - if (type == null) { - return null; - } else { -- ItemCost cost = new ItemCost(this.trades.get(type), this.cost); -- return new MerchantOffer(cost, new ItemStack(Items.EMERALD), this.maxUses, this.villagerXp, 0.05F); -+ Item item = this.trades.get(type); -+ if (item == null) return null; -+ ItemCost itemcost = new ItemCost(item, this.cost); -+ return new MerchantOffer(itemcost, new ItemStack(Items.EMERALD), this.maxUses, this.villagerXp, 0.05F); - } - } else { - return null; diff --git a/patches/net/minecraft/world/entity/player/Player.java.patch b/patches/net/minecraft/world/entity/player/Player.java.patch index 3954fabeb4a..0b885683f7c 100644 --- a/patches/net/minecraft/world/entity/player/Player.java.patch +++ b/patches/net/minecraft/world/entity/player/Player.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java -@@ -122,6 +_,7 @@ +@@ -123,6 +_,7 @@ import org.jspecify.annotations.Nullable; public abstract class Player extends Avatar implements ContainerUser, net.neoforged.neoforge.common.extensions.IPlayerExtension { @@ -8,10 +8,10 @@ public static final int MAX_HEALTH = 20; public static final int SLEEP_DURATION = 100; public static final int WAKE_UP_DURATION = 10; -@@ -176,6 +_,10 @@ - public @Nullable Entity currentExplosionCause; - private boolean ignoreFallDamageFromCurrentImpulse = false; - private int currentImpulseContextResetGraceTime = 0; +@@ -170,6 +_,10 @@ + private Optional lastDeathLocation = Optional.empty(); + public @Nullable FishingHook fishing; + protected float hurtDir; + private final java.util.Collection prefixes = new java.util.LinkedList<>(); + private final java.util.Collection suffixes = new java.util.LinkedList<>(); + @Nullable @@ -19,7 +19,7 @@ public Player(Level level, GameProfile gameProfile) { super(EntityType.PLAYER, level); -@@ -218,7 +_,8 @@ +@@ -212,7 +_,8 @@ .add(Attributes.MINING_EFFICIENCY) .add(Attributes.SWEEPING_DAMAGE_RATIO) .add(Attributes.WAYPOINT_TRANSMIT_RANGE, 6.0E7) @@ -29,7 +29,7 @@ } @Override -@@ -232,6 +_,7 @@ +@@ -226,6 +_,7 @@ @Override public void tick() { @@ -37,7 +37,7 @@ this.noPhysics = this.isSpectator(); if (this.isSpectator() || this.isPassenger()) { this.setOnGround(false); -@@ -248,7 +_,7 @@ +@@ -242,7 +_,7 @@ } if (!this.level().isClientSide() @@ -46,15 +46,15 @@ this.stopSleepInBed(false, true); } } else if (this.sleepCounter > 0) { -@@ -287,6 +_,7 @@ - if (this.currentImpulseContextResetGraceTime > 0) { - this.currentImpulseContextResetGraceTime--; - } +@@ -278,6 +_,7 @@ + + this.cooldowns.tick(); + this.updatePlayerPose(); + net.neoforged.neoforge.event.EventHooks.firePlayerTickPost(this); } @Override -@@ -307,7 +_,7 @@ +@@ -298,7 +_,7 @@ } protected boolean updateIsUnderwater() { @@ -63,7 +63,7 @@ return this.wasUnderwater; } -@@ -346,6 +_,10 @@ +@@ -337,6 +_,10 @@ } protected void updatePlayerPose() { @@ -74,7 +74,7 @@ if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.SWIMMING)) { Pose desiredPose = this.getDesiredPose(); Pose actualPose; -@@ -530,6 +_,7 @@ +@@ -521,6 +_,7 @@ @Override public void die(DamageSource source) { @@ -82,7 +82,7 @@ super.die(source); this.reapplyPosition(); if (!this.isSpectator() && this.level() instanceof ServerLevel level) { -@@ -586,10 +_,18 @@ +@@ -577,10 +_,18 @@ } public @Nullable ItemEntity drop(ItemStack itemStack, boolean thrownFromHand) { @@ -102,7 +102,7 @@ float speed = this.inventory.getSelectedItem().getDestroySpeed(state); if (speed > 1.0F) { speed += (float)this.getAttributeValue(Attributes.MINING_EFFICIENCY); -@@ -618,13 +_,19 @@ +@@ -609,13 +_,19 @@ speed /= 5.0F; } @@ -122,7 +122,7 @@ @Override protected void readAdditionalSaveData(ValueInput input) { super.readAdditionalSaveData(input); -@@ -699,7 +_,8 @@ +@@ -684,7 +_,8 @@ return false; } else { this.removeEntitiesOnShoulder(); @@ -132,7 +132,7 @@ if (level.getDifficulty() == Difficulty.PEACEFUL) { damage = 0.0F; } -@@ -757,11 +_,14 @@ +@@ -742,11 +_,14 @@ @Override protected void actuallyHurt(ServerLevel level, DamageSource source, float dmg) { if (!this.isInvulnerableTo(level, source)) { @@ -152,7 +152,7 @@ if (absorbedDamage > 0.0F && absorbedDamage < 3.4028235E37F) { this.awardStat(Stats.DAMAGE_ABSORBED, Math.round(absorbedDamage * 10.0F)); } -@@ -775,7 +_,9 @@ +@@ -760,7 +_,9 @@ } this.gameEvent(GameEvent.ENTITY_DAMAGE); @@ -162,7 +162,7 @@ } } -@@ -831,6 +_,8 @@ +@@ -816,6 +_,8 @@ return InteractionResult.PASS; } else { @@ -170,8 +170,8 @@ + if (cancelResult != null) return cancelResult; ItemStack itemStack = this.getItemInHand(hand); ItemStack itemStackClone = itemStack.copy(); - InteractionResult interact = entity.interact(this, hand); -@@ -839,6 +_,10 @@ + InteractionResult interact = entity.interact(this, hand, location); +@@ -824,6 +_,10 @@ itemStack.setCount(itemStackClone.getCount()); } @@ -182,7 +182,7 @@ return interact; } else { if (!itemStack.isEmpty() && entity instanceof LivingEntity) { -@@ -850,6 +_,7 @@ +@@ -835,6 +_,7 @@ if (interactionResult.consumesAction()) { this.level().gameEvent(GameEvent.ENTITY_INTERACT, entity.position(), GameEvent.Context.of(this)); if (itemStack.isEmpty() && !this.hasInfiniteMaterials()) { @@ -190,7 +190,7 @@ this.setItemInHand(hand, ItemStack.EMPTY); } -@@ -879,6 +_,7 @@ +@@ -864,6 +_,7 @@ } @Override @@ -198,7 +198,7 @@ protected Vec3 maybeBackOffFromEdge(Vec3 delta, MoverType moverType) { float maxDownStep = this.maxUpStep(); if (!this.abilities.flying -@@ -928,6 +_,7 @@ +@@ -913,6 +_,7 @@ } } @@ -206,7 +206,7 @@ private boolean isAboveGround(float maxDownStep) { return this.onGround() || this.fallDistance < maxDownStep && !this.canFallAtLeast(0.0, 0.0, maxDownStep - this.fallDistance); } -@@ -949,6 +_,7 @@ +@@ -934,6 +_,7 @@ } public void attack(Entity entity) { @@ -214,7 +214,7 @@ if (!this.cannotAttack(entity)) { float baseDamage = this.isAutoSpinAttack() ? this.autoSpinAttackDmg : (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE); ItemStack attackingItemStack = this.getWeaponItem(); -@@ -956,7 +_,6 @@ +@@ -941,7 +_,6 @@ float attackStrengthScale = this.getAttackStrengthScale(0.5F); float magicBoost = attackStrengthScale * (this.getEnchantedDamage(entity, baseDamage, damageSource) - baseDamage); baseDamage *= this.baseDamageScaleFactor(); @@ -222,7 +222,7 @@ if (!this.deflectProjectile(entity)) { if (baseDamage > 0.0F || magicBoost > 0.0F) { boolean fullStrengthAttack = attackStrengthScale > 0.9F; -@@ -970,12 +_,22 @@ +@@ -955,12 +_,22 @@ baseDamage += attackingItemStack.getItem().getAttackDamageBonus(entity, baseDamage, damageSource); boolean criticalAttack = fullStrengthAttack && this.canCriticalAttack(entity); @@ -247,7 +247,7 @@ float oldLivingEntityHealth = 0.0F; if (entity instanceof LivingEntity livingTarget) { oldLivingEntityHealth = livingTarget.getHealth(); -@@ -986,7 +_,8 @@ +@@ -971,7 +_,8 @@ if (wasHurt) { this.causeExtraKnockback(entity, this.getKnockback(entity, damageSource) + (knockbackAttack ? 0.5F : 0.0F), oldMovement); if (sweepAttack) { @@ -257,16 +257,16 @@ } this.attackVisualEffects(entity, criticalAttack, sweepAttack, fullStrengthAttack, false, magicBoost); -@@ -1001,6 +_,8 @@ +@@ -986,6 +_,8 @@ - this.lungeForwardMaybe(); + this.postPiercingAttack(); } + // Neo: Moved from beginning of attack() so that getAttackStrengthScale() returns an accurate value during all attack events + this.onAttack(); } } -@@ -1043,7 +_,8 @@ +@@ -1028,7 +_,8 @@ double approximateSpeedSq = this.getKnownMovement().horizontalDistanceSqr(); double maxSpeedForSweepAttack = this.getSpeed() * 2.5; if (approximateSpeedSq < Mth.square(maxSpeedForSweepAttack)) { @@ -276,7 +276,7 @@ } } -@@ -1081,11 +_,12 @@ +@@ -1066,11 +_,12 @@ private void itemAttackInteraction(Entity entity, ItemStack attackingItemStack, DamageSource damageSource, boolean applyToTarget) { Entity hurtTarget = entity; @@ -291,7 +291,7 @@ if (this.level() instanceof ServerLevel serverLevel) { if (hurtTarget instanceof LivingEntity livingTarget) { itemHurtEnemy = attackingItemStack.hurtEnemy(livingTarget, this); -@@ -1102,6 +_,7 @@ +@@ -1087,6 +_,7 @@ } if (attackingItemStack.isEmpty()) { @@ -299,7 +299,7 @@ if (attackingItemStack == this.getMainHandItem()) { this.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); } else { -@@ -1142,17 +_,24 @@ +@@ -1127,17 +_,24 @@ return 1.0F; } @@ -326,7 +326,7 @@ float enchantedDamage = this.getEnchantedDamage(nearby, var12, damageSource) * attackStrengthScale; if (nearby.hurtServer(serverLevel, damageSource, enchantedDamage)) { nearby.knockback(0.4F, Mth.sin(this.getYRot() * (float) (Math.PI / 180.0)), -Mth.cos(this.getYRot() * (float) (Math.PI / 180.0))); -@@ -1311,6 +_,7 @@ +@@ -1296,6 +_,7 @@ } public void stopSleepInBed(boolean forcefulWakeUp, boolean updateLevelList) { @@ -334,7 +334,7 @@ super.stopSleeping(); if (this.level() instanceof ServerLevel && updateLevelList) { ((ServerLevel)this.level()).updateSleepingPlayerList(); -@@ -1418,7 +_,8 @@ +@@ -1403,7 +_,8 @@ @Override public boolean causeFallDamage(double fallDistance, float damageModifier, DamageSource damageSource) { @@ -344,7 +344,7 @@ return false; } else { if (fallDistance >= 2.0) { -@@ -1473,13 +_,13 @@ +@@ -1438,13 +_,13 @@ protected void playStepSound(BlockPos onPos, BlockState onState) { if (this.isInWater()) { this.waterSwimSound(); @@ -360,7 +360,7 @@ } else { super.playStepSound(primaryStepSoundPos, primaryStepState); } -@@ -1510,6 +_,10 @@ +@@ -1475,6 +_,10 @@ } public void giveExperiencePoints(int i) { @@ -371,7 +371,7 @@ this.increaseScore(i); this.experienceProgress = this.experienceProgress + (float)i / this.getXpNeededForNextLevel(); this.totalExperience = Mth.clamp(this.totalExperience + i, 0, Integer.MAX_VALUE); -@@ -1537,7 +_,7 @@ +@@ -1502,7 +_,7 @@ } public void onEnchantmentPerformed(ItemStack itemStack, int enchantmentCost) { @@ -380,7 +380,7 @@ if (this.experienceLevel < 0) { this.experienceLevel = 0; this.experienceProgress = 0.0F; -@@ -1548,6 +_,10 @@ +@@ -1513,6 +_,10 @@ } public void giveExperienceLevels(int amount) { @@ -391,7 +391,7 @@ this.experienceLevel = IntMath.saturatedAdd(this.experienceLevel, amount); if (this.experienceLevel < 0) { this.experienceLevel = 0; -@@ -1586,7 +_,7 @@ +@@ -1544,7 +_,7 @@ } protected boolean hasEnoughFoodToDoExhaustiveManoeuvres() { @@ -400,7 +400,7 @@ } public Optional getWardenSpawnTracker() { -@@ -1693,7 +_,11 @@ +@@ -1651,7 +_,11 @@ @Override public Component getDisplayName() { @@ -413,7 +413,7 @@ return this.decorateDisplayNameComponent(result); } -@@ -1874,21 +_,21 @@ +@@ -1840,21 +_,21 @@ if (!(heldWeapon.getItem() instanceof ProjectileWeaponItem)) { return ItemStack.EMPTY; } else { @@ -440,7 +440,7 @@ } } } -@@ -1928,7 +_,7 @@ +@@ -1894,7 +_,7 @@ } public boolean isScoping() { @@ -449,7 +449,7 @@ } @Override -@@ -2068,5 +_,41 @@ +@@ -2000,5 +_,41 @@ public static final Player.BedSleepingProblem OBSTRUCTED = new Player.BedSleepingProblem(Component.translatable("block.minecraft.bed.obstructed")); public static final Player.BedSleepingProblem OTHER_PROBLEM = new Player.BedSleepingProblem(null); public static final Player.BedSleepingProblem NOT_SAFE = new Player.BedSleepingProblem(Component.translatable("block.minecraft.bed.not_safe")); diff --git a/patches/net/minecraft/world/entity/raid/Raid.java.patch b/patches/net/minecraft/world/entity/raid/Raid.java.patch index 5ab9152fc99..66a3ee171aa 100644 --- a/patches/net/minecraft/world/entity/raid/Raid.java.patch +++ b/patches/net/minecraft/world/entity/raid/Raid.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/raid/Raid.java +++ b/net/minecraft/world/entity/raid/Raid.java -@@ -526,7 +_,7 @@ +@@ -528,7 +_,7 @@ int ravagersSpawned = 0; for (int i = 0; i < numSpawns; i++) { @@ -9,7 +9,7 @@ if (raider == null) { break; } -@@ -538,7 +_,7 @@ +@@ -540,7 +_,7 @@ } this.joinRaid(level, groupNumber, raider, pos, false); @@ -18,7 +18,7 @@ Raider ridingRaider = null; if (groupNumber == this.getNumGroups(Difficulty.NORMAL)) { ridingRaider = EntityType.PILLAGER.create(level, EntitySpawnReason.EVENT); -@@ -823,12 +_,26 @@ +@@ -833,12 +_,26 @@ RAVAGER(EntityType.RAVAGER, new int[]{0, 0, 0, 1, 0, 1, 0, 2}); private static final Raid.RaiderType[] VALUES = values(); diff --git a/patches/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch b/patches/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch index b7406ae951d..6fdd9947647 100644 --- a/patches/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java -@@ -102,6 +_,9 @@ +@@ -101,6 +_,9 @@ this.setContainerLootTable(null); LootParams.Builder builder = new LootParams.Builder((ServerLevel)this.level()).withParameter(LootContextParams.ORIGIN, this.position()); diff --git a/patches/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch b/patches/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch index 15dbf846b30..1310634412b 100644 --- a/patches/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch @@ -11,7 +11,7 @@ @@ -458,7 +_,7 @@ BlockState blockState = this.level().getBlockState(blockPos); - if (!(blockState.getBlock() instanceof WaterlilyBlock) + if (!(blockState.getBlock() instanceof LilyPadBlock) && Shapes.joinIsNotEmpty(blockState.getCollisionShape(this.level(), blockPos).move(blockPos), boatShape, BooleanOp.AND)) { - friction += blockState.getBlock().getFriction(); + friction += blockState.getFriction(this.level(), blockPos, this); diff --git a/patches/net/minecraft/world/entity/vehicle/minecart/AbstractMinecartContainer.java.patch b/patches/net/minecraft/world/entity/vehicle/minecart/AbstractMinecartContainer.java.patch index c06a4b79161..c8c29d434fc 100644 --- a/patches/net/minecraft/world/entity/vehicle/minecart/AbstractMinecartContainer.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/minecart/AbstractMinecartContainer.java.patch @@ -3,8 +3,8 @@ @@ -94,6 +_,8 @@ @Override - public InteractionResult interact(Player player, InteractionHand hand) { -+ InteractionResult ret = super.interact(player, hand); + public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) { ++ InteractionResult ret = super.interact(player, hand, location); + if (ret.consumesAction()) return ret; return this.interactWithContainerVehicle(player); } diff --git a/patches/net/minecraft/world/entity/vehicle/minecart/Minecart.java.patch b/patches/net/minecraft/world/entity/vehicle/minecart/Minecart.java.patch index c1e16e40190..cb93fa7f868 100644 --- a/patches/net/minecraft/world/entity/vehicle/minecart/Minecart.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/minecart/Minecart.java.patch @@ -3,8 +3,8 @@ @@ -23,6 +_,8 @@ @Override - public InteractionResult interact(Player player, InteractionHand hand) { -+ InteractionResult ret = super.interact(player, hand); + public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) { ++ InteractionResult ret = super.interact(player, hand, location); + if (ret.consumesAction()) return ret; if (!player.isSecondaryUseActive() && !this.isVehicle() && (this.level().isClientSide() || player.startRiding(this))) { this.playerRotationOffset = this.rotationOffset; diff --git a/patches/net/minecraft/world/entity/vehicle/minecart/MinecartCommandBlock.java.patch b/patches/net/minecraft/world/entity/vehicle/minecart/MinecartCommandBlock.java.patch index 30167b0f5e0..997e80efcbe 100644 --- a/patches/net/minecraft/world/entity/vehicle/minecart/MinecartCommandBlock.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/minecart/MinecartCommandBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/entity/vehicle/minecart/MinecartCommandBlock.java +++ b/net/minecraft/world/entity/vehicle/minecart/MinecartCommandBlock.java -@@ -86,6 +_,8 @@ +@@ -88,6 +_,8 @@ @Override - public InteractionResult interact(Player player, InteractionHand hand) { -+ InteractionResult ret = super.interact(player, hand); + public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) { ++ InteractionResult ret = super.interact(player, hand, location); + if (ret.consumesAction()) return ret; if (!player.canUseGameMasterBlocks()) { return InteractionResult.PASS; diff --git a/patches/net/minecraft/world/entity/vehicle/minecart/MinecartFurnace.java.patch b/patches/net/minecraft/world/entity/vehicle/minecart/MinecartFurnace.java.patch index 5a52c7195a6..c8a8977f8bb 100644 --- a/patches/net/minecraft/world/entity/vehicle/minecart/MinecartFurnace.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/minecart/MinecartFurnace.java.patch @@ -3,8 +3,8 @@ @@ -107,6 +_,8 @@ @Override - public InteractionResult interact(Player player, InteractionHand hand) { -+ InteractionResult ret = super.interact(player, hand); + public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) { ++ InteractionResult ret = super.interact(player, hand, location); + if (ret.consumesAction()) return ret; ItemStack itemStack = player.getItemInHand(hand); if (this.addFuel(player.position(), itemStack)) { diff --git a/patches/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java.patch b/patches/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java.patch index c2e04345f42..0cea38876c4 100644 --- a/patches/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java +++ b/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java -@@ -19,6 +_,11 @@ +@@ -24,6 +_,11 @@ public void broadcastEvent(Level level, BlockPos pos, int id) { level.broadcastEntityEvent(MinecartSpawner.this, (byte)id); } diff --git a/patches/net/minecraft/world/inventory/AbstractContainerMenu.java.patch b/patches/net/minecraft/world/inventory/AbstractContainerMenu.java.patch index 79830beced4..fca4088d03a 100644 --- a/patches/net/minecraft/world/inventory/AbstractContainerMenu.java.patch +++ b/patches/net/minecraft/world/inventory/AbstractContainerMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -559,6 +_,12 @@ +@@ -560,6 +_,12 @@ } private boolean tryItemClickBehaviourOverride(Player player, ClickAction clickAction, Slot slot, ItemStack clicked, ItemStack carried) { diff --git a/patches/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch b/patches/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch index 3bef61b2c35..5c57a0a5684 100644 --- a/patches/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch +++ b/patches/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/AbstractFurnaceMenu.java +++ b/net/minecraft/world/inventory/AbstractFurnaceMenu.java -@@ -142,7 +_,7 @@ +@@ -143,7 +_,7 @@ } protected boolean isFuel(ItemStack itemStack) { diff --git a/patches/net/minecraft/world/inventory/BeaconMenu.java.patch b/patches/net/minecraft/world/inventory/BeaconMenu.java.patch index cd47ea54842..25cc4af7a3f 100644 --- a/patches/net/minecraft/world/inventory/BeaconMenu.java.patch +++ b/patches/net/minecraft/world/inventory/BeaconMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/BeaconMenu.java +++ b/net/minecraft/world/inventory/BeaconMenu.java -@@ -87,10 +_,8 @@ +@@ -92,10 +_,8 @@ } slot.onQuickCraft(stack, clicked); diff --git a/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch b/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch index d0afb7e4f7c..b67a6e06e99 100644 --- a/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch +++ b/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/net/minecraft/world/inventory/EnchantmentMenu.java -@@ -61,7 +_,7 @@ - this.addSlot(new Slot(this.enchantSlots, 1, 35, 47) { +@@ -74,7 +_,7 @@ + @Override public boolean mayPlace(ItemStack itemStack) { - return itemStack.is(Items.LAPIS_LAZULI); @@ -9,7 +9,7 @@ } @Override -@@ -89,23 +_,24 @@ +@@ -102,23 +_,24 @@ if (!itemStack.isEmpty() && itemStack.isEnchantable()) { this.access.execute((level, pos) -> { IdMap> holders = level.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).asHolderIdMap(); @@ -37,7 +37,7 @@ } for (int ix = 0; ix < 3; ix++) { -@@ -149,14 +_,11 @@ +@@ -162,14 +_,11 @@ List newEnchantment = this.getEnchantmentList(level.registryAccess(), itemStack, buttonId, this.costs[buttonId]); if (!newEnchantment.isEmpty()) { player.onEnchantmentPerformed(itemStack, enchantmentCost); @@ -46,7 +46,7 @@ - this.enchantSlots.setItem(0, enchantmentItem); - } + // Neo: Allow items to transform themselves when enchanted, instead of relying on hardcoded transformations for Items.BOOK -+ enchantmentItem = itemStack.transmuteCopy(Items.ENCHANTED_BOOK); ++ enchantmentItem = itemStack.getItem().applyEnchantments(itemStack, newEnchantment); + this.enchantSlots.setItem(0, enchantmentItem); + net.neoforged.neoforge.common.CommonHooks.onPlayerEnchantItem(player, enchantmentItem, newEnchantment); @@ -56,7 +56,7 @@ currency.consume(enchantmentCost, player); if (currency.isEmpty()) { -@@ -232,7 +_,7 @@ +@@ -245,7 +_,7 @@ if (!this.moveItemStackTo(stack, 2, 38, true)) { return ItemStack.EMPTY; } diff --git a/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch b/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch index f27d21919b4..e05ce47f6d6 100644 --- a/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch +++ b/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/net/minecraft/world/inventory/GrindstoneMenu.java -@@ -37,6 +_,7 @@ +@@ -42,6 +_,7 @@ } }; private final ContainerLevelAccess access; @@ -8,8 +8,8 @@ public GrindstoneMenu(int containerId, Inventory inventory) { this(containerId, inventory, ContainerLevelAccess.NULL); -@@ -48,13 +_,13 @@ - this.addSlot(new Slot(this.repairSlots, 0, 49, 19) { +@@ -57,7 +_,7 @@ + @Override public boolean mayPlace(ItemStack itemStack) { - return itemStack.isDamageableItem() || EnchantmentHelper.hasAnyEnchantments(itemStack); @@ -17,6 +17,8 @@ } }); this.addSlot(new Slot(this.repairSlots, 1, 49, 40) { +@@ -67,7 +_,7 @@ + @Override public boolean mayPlace(ItemStack itemStack) { - return itemStack.isDamageableItem() || EnchantmentHelper.hasAnyEnchantments(itemStack); @@ -24,7 +26,7 @@ } }); this.addSlot(new Slot(this.resultSlots, 2, 129, 34) { -@@ -65,6 +_,7 @@ +@@ -82,6 +_,7 @@ @Override public void onTake(Player player, ItemStack carried) { @@ -32,7 +34,7 @@ access.execute((level, pos) -> { if (level instanceof ServerLevel) { ExperienceOrb.award((ServerLevel)level, Vec3.atCenterOf(pos), this.getExperienceAmount(level)); -@@ -77,6 +_,7 @@ +@@ -94,6 +_,7 @@ } private int getExperienceAmount(Level level) { @@ -40,7 +42,7 @@ int amount = 0; amount += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(0)); amount += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(1)); -@@ -115,6 +_,8 @@ +@@ -132,6 +_,8 @@ } private void createResult() { @@ -49,7 +51,7 @@ this.resultSlots.setItem(0, this.computeResult(this.repairSlots.getItem(0), this.repairSlots.getItem(1))); this.broadcastChanges(); } -@@ -145,7 +_,7 @@ +@@ -162,7 +_,7 @@ int remaining2 = additional.getMaxDamage() - additional.getDamageValue(); int remaining = remaining1 + remaining2 + durability * 5 / 100; int count = 1; @@ -58,7 +60,7 @@ if (input.getMaxStackSize() < 2 || !ItemStack.matches(input, additional)) { return ItemStack.EMPTY; } -@@ -157,6 +_,7 @@ +@@ -174,6 +_,7 @@ if (newItem.isDamageableItem()) { newItem.set(DataComponents.MAX_DAMAGE, durability); newItem.setDamageValue(Math.max(durability - remaining, 0)); diff --git a/patches/net/minecraft/world/item/BoneMealItem.java.patch b/patches/net/minecraft/world/item/BoneMealItem.java.patch index 61ed9415faf..c9dbbdbd2b4 100644 --- a/patches/net/minecraft/world/item/BoneMealItem.java.patch +++ b/patches/net/minecraft/world/item/BoneMealItem.java.patch @@ -26,4 +26,4 @@ + if (event.isCanceled()) return event.isSuccessful(); if (state.getBlock() instanceof BonemealableBlock block && block.isValidBonemealTarget(level, pos, state)) { if (level instanceof ServerLevel) { - if (block.isBonemealSuccess(level, level.random, pos, state)) { + if (block.isBonemealSuccess(level, level.getRandom(), pos, state)) { diff --git a/patches/net/minecraft/world/item/BucketItem.java.patch b/patches/net/minecraft/world/item/BucketItem.java.patch index d7c63d1d647..601a677002b 100644 --- a/patches/net/minecraft/world/item/BucketItem.java.patch +++ b/patches/net/minecraft/world/item/BucketItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/BucketItem.java +++ b/net/minecraft/world/item/BucketItem.java -@@ -58,7 +_,7 @@ +@@ -59,7 +_,7 @@ ItemStack taken = bucketPickupBlock.pickupBlock(player, level, pos, blockState); if (!taken.isEmpty()) { player.awardStat(Stats.ITEM_USED.get(this)); @@ -9,7 +9,7 @@ level.gameEvent(player, GameEvent.FLUID_PICKUP, pos); ItemStack result = ItemUtils.createFilledResult(itemStack, player, taken); if (!level.isClientSide()) { -@@ -72,8 +_,8 @@ +@@ -73,8 +_,8 @@ return InteractionResult.FAIL; } else { BlockState clicked = level.getBlockState(pos); @@ -20,7 +20,7 @@ this.checkExtraContent(player, level, itemStack, placePos); if (player instanceof ServerPlayer) { CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer)player, placePos, itemStack); -@@ -98,7 +_,12 @@ +@@ -99,7 +_,12 @@ } @Override @@ -33,7 +33,7 @@ if (!(this.content instanceof FlowingFluid flowingFluid)) { return false; } else { -@@ -108,9 +_,14 @@ +@@ -109,9 +_,14 @@ boolean shiftKeyDown = user != null && user.isShiftKeyDown(); boolean placeLiquid = mayReplace || block instanceof LiquidBlockContainer container && container.canPlaceLiquid(user, level, pos, blockState, this.content); @@ -49,7 +49,7 @@ } else if (level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) && this.content.is(FluidTags.WATER)) { int x = pos.getX(); int y = pos.getY(); -@@ -126,8 +_,8 @@ +@@ -124,8 +_,8 @@ } return true; @@ -60,7 +60,7 @@ this.playEmptySound(user, level, pos); return true; } else { -@@ -146,9 +_,15 @@ +@@ -144,9 +_,15 @@ } protected void playEmptySound(@Nullable LivingEntity user, LevelAccessor level, BlockPos pos) { diff --git a/patches/net/minecraft/world/item/BundleItem.java.patch b/patches/net/minecraft/world/item/BundleItem.java.patch index 7dd5415d355..e8e5be61c57 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 -@@ -49,7 +_,7 @@ +@@ -60,7 +_,7 @@ @Override public boolean overrideStackedOnOther(ItemStack self, Slot slot, ClickAction clickAction, Player player) { BundleContents initialContents = self.get(DataComponents.BUNDLE_CONTENTS); @@ -9,7 +9,7 @@ return false; } else { ItemStack other = slot.getItem(); -@@ -86,6 +_,7 @@ +@@ -97,6 +_,7 @@ @Override public boolean overrideOtherStackedOnMe(ItemStack self, ItemStack other, Slot slot, ClickAction clickAction, Player player, SlotAccess carriedItem) { diff --git a/patches/net/minecraft/world/item/CreativeModeTab.java.patch b/patches/net/minecraft/world/item/CreativeModeTab.java.patch index b9d679d4f2a..815bd66f077 100644 --- a/patches/net/minecraft/world/item/CreativeModeTab.java.patch +++ b/patches/net/minecraft/world/item/CreativeModeTab.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/CreativeModeTab.java +++ b/net/minecraft/world/item/CreativeModeTab.java -@@ -13,6 +_,8 @@ +@@ -11,6 +_,8 @@ import org.jspecify.annotations.Nullable; public class CreativeModeTab { @@ -9,7 +9,7 @@ private static final Identifier DEFAULT_BACKGROUND = createTextureLocation("items"); private final Component displayName; private Identifier backgroundTexture = DEFAULT_BACKGROUND; -@@ -27,6 +_,14 @@ +@@ -25,6 +_,14 @@ private Set displayItemsSearchTab = ItemStackLinkedSet.createTypeAndComponentsSet(); private final Supplier iconGenerator; private final CreativeModeTab.DisplayItemsGenerator displayItemsGenerator; @@ -24,7 +24,7 @@ private CreativeModeTab( CreativeModeTab.Row row, -@@ -34,7 +_,15 @@ +@@ -32,7 +_,15 @@ CreativeModeTab.Type type, Component displayName, Supplier iconGenerator, @@ -41,7 +41,7 @@ ) { this.row = row; this.column = column; -@@ -42,12 +_,29 @@ +@@ -40,12 +_,29 @@ this.iconGenerator = iconGenerator; this.displayItemsGenerator = displayItemsGenerator; this.type = type; @@ -71,16 +71,16 @@ public static CreativeModeTab.Builder builder(CreativeModeTab.Row row, int column) { return new CreativeModeTab.Builder(row, column); } -@@ -105,7 +_,7 @@ - ResourceKey key = BuiltInRegistries.CREATIVE_MODE_TAB - .getResourceKey(this) - .orElseThrow(() -> new IllegalStateException("Unregistered creative tab: " + this)); +@@ -100,7 +_,7 @@ + + public void buildContents(CreativeModeTab.ItemDisplayParameters parameters) { + CreativeModeTab.ItemDisplayBuilder displayList = new CreativeModeTab.ItemDisplayBuilder(this, parameters.enabledFeatures); - this.displayItemsGenerator.accept(parameters, displayList); -+ net.neoforged.neoforge.event.EventHooks.onCreativeModeTabBuildContents(this, key, this.displayItemsGenerator, parameters, displayList); ++ net.neoforged.neoforge.event.EventHooks.onCreativeModeTabBuildContents(this, this.displayItemsGenerator, parameters, displayList); this.displayItems = displayList.tabContents; this.displayItemsSearchTab = displayList.searchTabContents; } -@@ -122,8 +_,36 @@ +@@ -117,8 +_,36 @@ return this.displayItemsSearchTab.contains(stack); } @@ -117,7 +117,7 @@ private final CreativeModeTab.Row row; private final int column; private Component displayName = Component.empty(); -@@ -134,6 +_,15 @@ +@@ -129,6 +_,15 @@ private boolean alignedRight = false; private CreativeModeTab.Type type = CreativeModeTab.Type.CATEGORY; private Identifier backgroundTexture = CreativeModeTab.DEFAULT_BACKGROUND; @@ -133,7 +133,7 @@ public Builder(CreativeModeTab.Row row, int column) { this.row = row; -@@ -172,6 +_,8 @@ +@@ -167,6 +_,8 @@ protected CreativeModeTab.Builder type(CreativeModeTab.Type type) { this.type = type; @@ -142,7 +142,7 @@ return this; } -@@ -180,11 +_,109 @@ +@@ -175,11 +_,109 @@ return this; } diff --git a/patches/net/minecraft/world/item/CrossbowItem.java.patch b/patches/net/minecraft/world/item/CrossbowItem.java.patch index 7a68e835251..a05a81e2813 100644 --- a/patches/net/minecraft/world/item/CrossbowItem.java.patch +++ b/patches/net/minecraft/world/item/CrossbowItem.java.patch @@ -7,4 +7,4 @@ + if (shooter instanceof Player player && net.neoforged.neoforge.event.EventHooks.onArrowLoose(weapon, shooter.level(), player, 1, true) < 0) return; ChargedProjectiles charged = weapon.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.EMPTY); if (charged != null && !charged.isEmpty()) { - this.shoot(serverLevel, shooter, hand, weapon, charged.getItems(), power, uncertainty, shooter instanceof Player, targetOverride); + this.shoot(serverLevel, shooter, hand, weapon, charged.itemCopies(), power, uncertainty, shooter instanceof Player, targetOverride); diff --git a/patches/net/minecraft/world/item/Item.java.patch b/patches/net/minecraft/world/item/Item.java.patch index a5390a0fcc7..bb98f515b23 100644 --- a/patches/net/minecraft/world/item/Item.java.patch +++ b/patches/net/minecraft/world/item/Item.java.patch @@ -1,24 +1,24 @@ --- a/net/minecraft/world/item/Item.java +++ b/net/minecraft/world/item/Item.java -@@ -101,7 +_,7 @@ - .validate(item -> item.is(Items.AIR.builtInRegistryHolder()) ? DataResult.error(() -> "Item must not be minecraft:air") : DataResult.success(item)); - public static final StreamCodec> STREAM_CODEC = ByteBufCodecs.holderRegistry(Registries.ITEM); +@@ -106,7 +_,7 @@ + : DataResult.success(item) + ); private static final Logger LOGGER = LogUtils.getLogger(); - public static final Map BY_BLOCK = Maps.newHashMap(); + public static final Map BY_BLOCK = net.neoforged.neoforge.registries.GameData.getBlockItemMap(); public static final Identifier BASE_ATTACK_DAMAGE_ID = Identifier.withDefaultNamespace("base_attack_damage"); public static final Identifier BASE_ATTACK_SPEED_ID = Identifier.withDefaultNamespace("base_attack_speed"); public static final int DEFAULT_MAX_STACK_SIZE = 64; -@@ -113,6 +_,7 @@ - private final @Nullable Item craftingRemainingItem; +@@ -117,6 +_,7 @@ + private final @Nullable ItemStackTemplate craftingRemainingItem; protected final String descriptionId; private final FeatureFlagSet requiredFeatures; + private net.neoforged.neoforge.transfer.item.@Nullable ItemResource defaultResource; public static int getId(Item item) { return item == null ? 0 : BuiltInRegistries.ITEM.getId(item); -@@ -132,12 +_,13 @@ - this.components = properties.buildAndValidateComponents(Component.translatable(this.descriptionId), properties.effectiveModel()); +@@ -139,12 +_,13 @@ + BuiltInRegistries.DATA_COMPONENT_INITIALIZERS.add(properties.itemIdOrThrow(), componentInitializer); this.craftingRemainingItem = properties.craftingRemainingItem; this.requiredFeatures = properties.requiredFeatures; - if (SharedConstants.IS_RUNNING_IN_IDE) { @@ -32,18 +32,14 @@ } @Deprecated -@@ -149,6 +_,25 @@ - return this.components; +@@ -156,6 +_,21 @@ + return this.builtInRegistryHolder.components(); } -+ /** @deprecated Neo: do not use, use {@link net.neoforged.neoforge.event.ModifyDefaultComponentsEvent the event} instead */ ++ /** @deprecated Neo: do not use, use {@link net.neoforged.neoforge.transfer.item.ItemResource#of} instead. */ + @org.jetbrains.annotations.ApiStatus.Internal @Deprecated -+ public void modifyDefaultComponentsFrom(net.minecraft.core.component.DataComponentPatch patch) { -+ if (!net.neoforged.neoforge.internal.RegistrationEvents.canModifyComponents()) throw new IllegalStateException("Default components cannot be modified now!"); -+ var builder = DataComponentMap.builder().addAll(components); -+ patch.entrySet().forEach(entry -> builder.set((DataComponentType)entry.getKey(), entry.getValue().orElse(null))); -+ components = Properties.validateComponents(builder.build()); -+ defaultResource = null; ++ public void resetDefaultResource() { ++ this.defaultResource = null; + } + + /** @deprecated Neo: do not use, use {@link net.neoforged.neoforge.transfer.item.ItemResource#of} instead. */ @@ -56,9 +52,9 @@ + } + public int getDefaultMaxStackSize() { - return this.components.getOrDefault(DataComponents.MAX_STACK_SIZE, 1); + return this.components().getOrDefault(DataComponents.MAX_STACK_SIZE, 1); } -@@ -156,6 +_,8 @@ +@@ -163,6 +_,8 @@ public void onUseTick(Level level, LivingEntity livingEntity, ItemStack itemStack, int ticksRemaining) { } @@ -67,15 +63,16 @@ public void onDestroyed(ItemEntity itemEntity) { } -@@ -272,6 +_,7 @@ +@@ -279,6 +_,8 @@ return BuiltInRegistries.ITEM.wrapAsHolder(this).getRegisteredName(); } -+ @Deprecated // Use ItemStack sensitive version. - public final ItemStack getCraftingRemainder() { - return this.craftingRemainingItem == null ? ItemStack.EMPTY : new ItemStack(this.craftingRemainingItem); ++ /** @deprecated use {@link #getCraftingRemainder(ItemStack)} instead */ ++ @Deprecated + public final @Nullable ItemStackTemplate getCraftingRemainder() { + return this.craftingRemainingItem; } -@@ -342,13 +_,26 @@ +@@ -345,13 +_,26 @@ } public boolean useOnRelease(ItemStack itemStack) { @@ -103,7 +100,7 @@ public boolean canFitInsideContainerItems() { return true; } -@@ -371,6 +_,12 @@ +@@ -376,6 +_,12 @@ private @Nullable ResourceKey id; private DependantName descriptionId = ITEM_DESCRIPTION_ID; private final DependantName model = ResourceKey::identifier; @@ -116,26 +113,20 @@ public Item.Properties food(FoodProperties foodProperties) { return this.food(foodProperties, Consumables.DEFAULT_FOOD); -@@ -628,6 +_,7 @@ +@@ -651,7 +_,11 @@ } - public Item.Properties component(DataComponentType type, T value) { -+ net.neoforged.neoforge.common.CommonHooks.validateComponent(value); - this.components.set(type, value); + public Item.Properties delayedHolderComponent(DataComponentType> type, ResourceKey valueKey) { +- this.componentInitializer = this.componentInitializer.andThen((components, context, key) -> components.set(type, context.getOrThrow(valueKey))); ++ this.componentInitializer = this.componentInitializer.andThen((components, context, key) -> { ++ var value = context.getOrThrow(valueKey); ++ net.neoforged.neoforge.common.CommonHooks.validateComponent(value); ++ components.set(type, value); ++ }); return this; } -@@ -638,6 +_,10 @@ - private DataComponentMap buildAndValidateComponents(Component name, Identifier model) { - DataComponentMap components = this.components.set(DataComponents.ITEM_NAME, name).set(DataComponents.ITEM_MODEL, model).build(); -+ return validateComponents(components); -+ } -+ -+ public static DataComponentMap validateComponents(DataComponentMap components) { - if (components.has(DataComponents.DAMAGE) && components.getOrDefault(DataComponents.MAX_STACK_SIZE, 1) > 1) { - throw new IllegalStateException("Item cannot have both durability and be stackable"); - } else { -@@ -677,6 +_,14 @@ +@@ -700,6 +_,14 @@ boolean isPeaceful(); @@ -150,7 +141,7 @@ static Item.TooltipContext of(@Nullable Level level) { return level == null ? EMPTY : new Item.TooltipContext() { @Override -@@ -697,6 +_,11 @@ +@@ -720,6 +_,11 @@ @Override public boolean isPeaceful() { return level.getDifficulty() == Difficulty.PEACEFUL; diff --git a/patches/net/minecraft/world/item/ItemStack.java.patch b/patches/net/minecraft/world/item/ItemStack.java.patch index 742b0ca21ab..e0e07d3aec9 100644 --- a/patches/net/minecraft/world/item/ItemStack.java.patch +++ b/patches/net/minecraft/world/item/ItemStack.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -252,6 +_,10 @@ +@@ -239,6 +_,10 @@ return !this.isEmpty() && this.components.hasNonDefault(type); } @@ -8,19 +8,10 @@ + return this.isEmpty() || this.components.isPatchEmpty(); + } + - public ItemStack(ItemLike item) { - this(item, 1); + public ItemStack(ItemLike item, int count) { + this(item.asItem().builtInRegistryHolder(), count); } -@@ -347,7 +_,7 @@ - } - - public boolean is(Holder item) { -- return this.getItem().builtInRegistryHolder() == item; -+ return is(item.value()); // Neo: Fix comparing for custom holders such as DeferredHolders - } - - public boolean is(HolderSet set) { -@@ -359,13 +_,27 @@ +@@ -358,13 +_,27 @@ } public InteractionResult useOn(UseOnContext context) { @@ -49,16 +40,20 @@ if (player != null && result instanceof InteractionResult.Success success && success.wasItemInteraction()) { player.awardStat(Stats.ITEM_USED.get(usedItem)); } -@@ -414,7 +_,7 @@ +@@ -412,6 +_,12 @@ + return result; } - public int getMaxStackSize() { -- return this.getOrDefault(DataComponents.MAX_STACK_SIZE, 1); ++ // Neo: Delegate max stack size logic to the item to allow it to be stack-sensitive ++ @Override ++ public int getMaxStackSize() { + return this.getItem().getMaxStackSize(this); - } - ++ } ++ public boolean isStackable() { -@@ -426,19 +_,19 @@ + return this.getMaxStackSize() > 1 && (!this.isDamageableItem() || !this.isDamaged()); + } +@@ -421,19 +_,19 @@ } public boolean isDamaged() { @@ -82,7 +77,7 @@ } public boolean isBroken() { -@@ -450,6 +_,11 @@ +@@ -445,6 +_,11 @@ } public void hurtAndBreak(int amount, ServerLevel level, @Nullable ServerPlayer player, Consumer onBreak) { @@ -94,7 +89,7 @@ int newAmount = this.processDurabilityChange(amount, level, player); if (newAmount != 0) { this.applyDamage(this.getDamageValue() + newAmount, player, onBreak); -@@ -457,6 +_,10 @@ +@@ -452,6 +_,10 @@ } private int processDurabilityChange(int amount, ServerLevel level, @Nullable ServerPlayer player) { @@ -105,7 +100,7 @@ if (!this.isDamageableItem()) { return 0; } else if (player != null && player.hasInfiniteMaterials()) { -@@ -467,8 +_,12 @@ +@@ -462,8 +_,12 @@ } private void applyDamage(int newDamage, @Nullable ServerPlayer player, Consumer onBreak) { @@ -120,7 +115,7 @@ } this.setDamageValue(newDamage); -@@ -498,7 +_,7 @@ +@@ -493,7 +_,7 @@ public void hurtAndBreak(int amount, LivingEntity owner, EquipmentSlot slot) { if (owner.level() instanceof ServerLevel serverLevel) { this.hurtAndBreak( @@ -129,7 +124,52 @@ ); } } -@@ -825,7 +_,7 @@ +@@ -617,6 +_,16 @@ + } + } + ++ /** ++ * Compares an itemstack with an {@link ItemStackTemplate} as per {@link #matches(ItemStack, ItemStack)}. ++ */ ++ public static boolean matches(ItemStack a, @Nullable ItemStackTemplate b) { ++ if (b == null) { ++ return a.isEmpty(); ++ } ++ return a.getCount() == b.count() && isSameItemSameComponents(a, b); ++ } ++ + @Deprecated + public static boolean listMatches(List left, List right) { + if (left.size() != right.size()) { +@@ -644,6 +_,27 @@ + } + } + ++ ++ /** ++ * {@return true if a and b refer to the same item, or if a is empty and b is null} ++ */ ++ public static boolean isSameItem(ItemStack a, @Nullable ItemStackTemplate b) { ++ return b == null ? a.isEmpty() : a.is(b.item()); ++ } ++ ++ /** ++ * Compares the item and components of this stack against an {@link ItemStackTemplate}. ++ * ++ * @return True if either this stack is empty and the template is null, or they reference the same item and have equivalent component patches. ++ */ ++ public static boolean isSameItemSameComponents(ItemStack a, @Nullable ItemStackTemplate b) { ++ if (a.isEmpty() || b == null) { ++ return a.isEmpty() == (b == null); ++ } else { ++ return a.is(b.item()) && a.components.patchEquals(b.components()); ++ } ++ } ++ + public static boolean matchesIgnoringComponents(ItemStack a, ItemStack b, Predicate> ignoredPredicate) { + if (a == b) { + return true; +@@ -820,7 +_,7 @@ } public Component getStyledHoverName() { @@ -138,7 +178,15 @@ if (this.has(DataComponents.CUSTOM_NAME)) { hoverName.withStyle(ChatFormatting.ITALIC); } -@@ -851,6 +_,7 @@ +@@ -828,6 +_,7 @@ + return hoverName; + } + ++ @Override // Neo: Add override annotation to ensure our extension method signature always matches vanilla + public void addToTooltip( + DataComponentType type, Item.TooltipContext context, TooltipDisplay display, Consumer consumer, TooltipFlag flag + ) { +@@ -846,6 +_,7 @@ List lines = Lists.newArrayList(); lines.add(this.getStyledHoverName()); this.addDetailsToTooltip(context, display, player, tooltipFlag, lines::add); @@ -146,7 +194,7 @@ return lines; } } -@@ -879,7 +_,8 @@ +@@ -874,7 +_,8 @@ this.addToTooltip(DataComponents.DYED_COLOR, context, display, builder, tooltipFlag); this.addToTooltip(DataComponents.PROFILE, context, display, builder, tooltipFlag); this.addToTooltip(DataComponents.LORE, context, display, builder, tooltipFlag); @@ -156,7 +204,7 @@ this.addUnitComponentToTooltip(DataComponents.INTANGIBLE_PROJECTILE, INTANGIBLE_TOOLTIP, display, builder); this.addUnitComponentToTooltip(DataComponents.UNBREAKABLE, UNBREAKABLE_TOOLTIP, display, builder); this.addToTooltip(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, context, display, builder, tooltipFlag); -@@ -932,7 +_,10 @@ +@@ -927,7 +_,10 @@ builder.accept(component); } } @@ -168,7 +216,7 @@ private void addAttributeTooltips(Consumer consumer, TooltipDisplay display, @Nullable Player player) { if (display.shows(DataComponents.ATTRIBUTE_MODIFIERS)) { for (EquipmentSlotGroup slot : EquipmentSlotGroup.values()) { -@@ -987,6 +_,17 @@ +@@ -982,6 +_,17 @@ return !this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty(); } @@ -186,7 +234,7 @@ public ItemEnchantments getEnchantments() { return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); } -@@ -1010,14 +_,26 @@ +@@ -1005,14 +_,26 @@ } public void forEachModifier(EquipmentSlotGroup slot, TriConsumer, AttributeModifier, ItemAttributeModifiers.Display> consumer) { @@ -213,12 +261,12 @@ EnchantmentHelper.forEachModifier(this, slot, consumer); } -@@ -1029,7 +_,7 @@ +@@ -1024,7 +_,7 @@ MutableComponent result = ComponentUtils.wrapInSquareBrackets(hoverName); if (!this.isEmpty()) { -- result.withStyle(this.getRarity().color()).withStyle(s -> s.withHoverEvent(new HoverEvent.ShowItem(this))); -+ result.withStyle(this.getRarity().getStyleModifier()).withStyle(s -> s.withHoverEvent(new HoverEvent.ShowItem(this))); +- result.withStyle(this.getRarity().color()).withStyle(s -> s.withHoverEvent(new HoverEvent.ShowItem(ItemStackTemplate.fromNonEmptyStack(this)))); ++ result.withStyle(this.getRarity().getStyleModifier()).withStyle(s -> s.withHoverEvent(new HoverEvent.ShowItem(ItemStackTemplate.fromNonEmptyStack(this)))); } return result; diff --git a/patches/net/minecraft/world/item/ItemStackTemplate.java.patch b/patches/net/minecraft/world/item/ItemStackTemplate.java.patch new file mode 100644 index 00000000000..2751f7f3d71 --- /dev/null +++ b/patches/net/minecraft/world/item/ItemStackTemplate.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/item/ItemStackTemplate.java ++++ b/net/minecraft/world/item/ItemStackTemplate.java +@@ -49,6 +_,26 @@ + this(item.builtInRegistryHolder(), 1, patch); + } + ++ // Neo: Provide full set of overloads ++ public ItemStackTemplate(Item item, int count, DataComponentPatch patch) { ++ this(item.builtInRegistryHolder(), count, patch); ++ } ++ ++ // Neo: Easier integration with DeferredItem ++ public ItemStackTemplate(Holder item) { ++ this(item, 1, DataComponentPatch.EMPTY); ++ } ++ ++ // Neo: Easier integration with DeferredItem ++ public ItemStackTemplate(Holder item, int count) { ++ this(item, count, DataComponentPatch.EMPTY); ++ } ++ ++ // Neo: Easier integration with DeferredItem ++ public ItemStackTemplate(Holder item, DataComponentPatch patch) { ++ this(item, 1, patch); ++ } ++ + public ItemStackTemplate(Holder item, int count, DataComponentPatch components) { + if (count != 0 && !item.is(Items.AIR.builtInRegistryHolder())) { + this.item = item; diff --git a/patches/net/minecraft/world/item/Items.java.patch b/patches/net/minecraft/world/item/Items.java.patch index 1ba69a22428..79efc038209 100644 --- a/patches/net/minecraft/world/item/Items.java.patch +++ b/patches/net/minecraft/world/item/Items.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/item/Items.java +++ b/net/minecraft/world/item/Items.java -@@ -2321,11 +_,19 @@ +@@ -2324,11 +_,19 @@ } - public static Item registerBlock(Block block, Block... alternatives) { + private static Item registerBlock(Block block, Block... alternatives) { - Item item = registerBlock(block); - - for (Block alternative : alternatives) { diff --git a/patches/net/minecraft/world/item/SpawnEggItem.java.patch b/patches/net/minecraft/world/item/SpawnEggItem.java.patch index dd257ef77c6..01f1dbf985c 100644 --- a/patches/net/minecraft/world/item/SpawnEggItem.java.patch +++ b/patches/net/minecraft/world/item/SpawnEggItem.java.patch @@ -1,42 +1,22 @@ --- a/net/minecraft/world/item/SpawnEggItem.java +++ b/net/minecraft/world/item/SpawnEggItem.java -@@ -194,4 +_,44 @@ +@@ -185,4 +_,24 @@ 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); -+ -+ try { -+ entitytype.spawn( -+ source.level(), egg, null, source.pos().relative(direction), EntitySpawnReason.DISPENSER, direction != Direction.UP, false -+ ); -+ } catch (Exception exception) { -+ LOGGER.error("Error while dispensing spawn egg from dispenser at {}", source.pos(), exception); -+ return ItemStack.EMPTY; -+ } -+ -+ egg.shrink(1); -+ source.level().gameEvent(null, GameEvent.ENTITY_PLACE, source.pos()); -+ return egg; -+ } -+ }; -+ + /** -+ * {@return the dispense behavior to register by default} ++ * {@return the dispense behavior to register or null to register the default} + */ + protected net.minecraft.core.dispenser.@Nullable DispenseItemBehavior createDispenseBehavior() { -+ return DEFAULT_DISPENSE_BEHAVIOR; ++ return null; + } + ++ // TODO 26.1: It's questionable that this is even needed anymore + @net.neoforged.bus.api.SubscribeEvent(priority = net.neoforged.bus.api.EventPriority.LOWEST) + private static void registerDispenseBehavior(final net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent event) { -+ event.enqueueWork(() -> eggs().forEach(egg -> { -+ if (!net.minecraft.world.level.block.DispenserBlock.DISPENSER_REGISTRY.containsKey(egg)) { ++ event.enqueueWork(() -> BuiltInRegistries.ITEM.forEach(item -> { ++ if (item instanceof SpawnEggItem egg && !net.minecraft.world.level.block.DispenserBlock.DISPENSER_REGISTRY.containsKey(egg)) { + var beh = egg.createDispenseBehavior(); + if (beh != null) { + net.minecraft.world.level.block.DispenserBlock.registerBehavior(egg, beh); diff --git a/patches/net/minecraft/world/item/component/BlocksAttacks.java.patch b/patches/net/minecraft/world/item/component/BlocksAttacks.java.patch index 7ca12a8cb66..4b80ac4fdfe 100644 --- a/patches/net/minecraft/world/item/component/BlocksAttacks.java.patch +++ b/patches/net/minecraft/world/item/component/BlocksAttacks.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/component/BlocksAttacks.java +++ b/net/minecraft/world/item/component/BlocksAttacks.java -@@ -104,14 +_,22 @@ +@@ -111,14 +_,22 @@ } public void hurtBlockingItem(Level level, ItemStack item, LivingEntity user, InteractionHand hand, float damage) { diff --git a/patches/net/minecraft/world/item/component/BundleContents.java.patch b/patches/net/minecraft/world/item/component/BundleContents.java.patch index b378d4ecbab..398d014e5ad 100644 --- a/patches/net/minecraft/world/item/component/BundleContents.java.patch +++ b/patches/net/minecraft/world/item/component/BundleContents.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/item/component/BundleContents.java +++ b/net/minecraft/world/item/component/BundleContents.java -@@ -73,7 +_,8 @@ +@@ -77,7 +_,8 @@ } - public static boolean canItemBeInBundle(ItemStack itemsToAdd) { -- return !itemsToAdd.isEmpty() && itemsToAdd.getItem().canFitInsideContainerItems(); + public static boolean canItemBeInBundle(ItemStack itemToAdd) { +- return !itemToAdd.isEmpty() && itemToAdd.getItem().canFitInsideContainerItems(); + // Neo: stack-aware placeability check -+ return !itemsToAdd.isEmpty() && itemsToAdd.canFitInsideContainerItems(); ++ return !itemToAdd.isEmpty() && itemToAdd.canFitInsideContainerItems(); } public int getNumberOfItemsToShow() { diff --git a/patches/net/minecraft/world/item/component/ItemContainerContents.java.patch b/patches/net/minecraft/world/item/component/ItemContainerContents.java.patch index a4f0e061ff8..9c94685c948 100644 --- a/patches/net/minecraft/world/item/component/ItemContainerContents.java.patch +++ b/patches/net/minecraft/world/item/component/ItemContainerContents.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/component/ItemContainerContents.java +++ b/net/minecraft/world/item/component/ItemContainerContents.java -@@ -161,6 +_,35 @@ +@@ -172,6 +_,36 @@ } } @@ -21,7 +21,8 @@ + */ + public ItemStack getStackInSlot(int slot) { + validateSlotIndex(slot); -+ return this.items.get(slot).copy(); ++ // TODO 26.1: Migrate to ItemStackTemplate or ItemInstance ++ return this.items.get(slot).map(ItemStackTemplate::create).orElse(ItemStack.EMPTY); + } + + /** @@ -33,6 +34,6 @@ + } + } + - private record Slot(int index, ItemStack item) { + private record Slot(int index, ItemStackTemplate item) { public static final Codec CODEC = RecordCodecBuilder.create( i -> i.group( diff --git a/patches/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch b/patches/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch index 7de530e0df9..cfa797a5fdd 100644 --- a/patches/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch +++ b/patches/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java +++ b/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java -@@ -55,7 +_,9 @@ +@@ -54,7 +_,9 @@ } Vec3 oldPos = user.position(); diff --git a/patches/net/minecraft/world/item/crafting/AbstractCookingRecipe.java.patch b/patches/net/minecraft/world/item/crafting/AbstractCookingRecipe.java.patch deleted file mode 100644 index a00cef979c6..00000000000 --- a/patches/net/minecraft/world/item/crafting/AbstractCookingRecipe.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/crafting/AbstractCookingRecipe.java -+++ b/net/minecraft/world/item/crafting/AbstractCookingRecipe.java -@@ -74,7 +_,7 @@ - Codec.STRING.optionalFieldOf("group", "").forGetter(SingleItemRecipe::group), - CookingBookCategory.CODEC.fieldOf("category").orElse(CookingBookCategory.MISC).forGetter(AbstractCookingRecipe::category), - Ingredient.CODEC.fieldOf("ingredient").forGetter(SingleItemRecipe::input), -- ItemStack.STRICT_SINGLE_ITEM_CODEC.fieldOf("result").forGetter(SingleItemRecipe::result), -+ ItemStack.CODEC.fieldOf("result").forGetter(SingleItemRecipe::result), - Codec.FLOAT.fieldOf("experience").orElse(0.0F).forGetter(AbstractCookingRecipe::experience), - Codec.INT.fieldOf("cookingtime").orElse(defaultCookingTime).forGetter(AbstractCookingRecipe::cookingTime) - ) diff --git a/patches/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java.patch b/patches/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java.patch index fc8eb9fba60..cb49b5f53c2 100644 --- a/patches/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java.patch @@ -4,8 +4,8 @@ for (int slot = 0; slot < result.size(); slot++) { ItemStack itemStack = input.getItem(slot); if (!itemStack.isEmpty()) { -- ItemStack remainder = itemStack.getItem().getCraftingRemainder(); -+ ItemStack remainder = itemStack.getCraftingRemainder(); - if (!remainder.isEmpty()) { - result.set(slot, remainder); +- ItemStackTemplate remainder = itemStack.getItem().getCraftingRemainder(); ++ ItemStackTemplate remainder = itemStack.getCraftingRemainder(); + if (remainder != null) { + result.set(slot, remainder.create()); } else if (!itemStack.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY).layers().isEmpty()) { diff --git a/patches/net/minecraft/world/item/crafting/BookCloningRecipe.java.patch b/patches/net/minecraft/world/item/crafting/BookCloningRecipe.java.patch index 7437e05ba74..32726b4262e 100644 --- a/patches/net/minecraft/world/item/crafting/BookCloningRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/BookCloningRecipe.java.patch @@ -4,8 +4,8 @@ for (int slot = 0; slot < result.size(); slot++) { ItemStack itemStack = input.getItem(slot); -- ItemStack remainder = itemStack.getItem().getCraftingRemainder(); -+ ItemStack remainder = itemStack.getCraftingRemainder(); - if (!remainder.isEmpty()) { - result.set(slot, remainder); +- ItemStackTemplate remainder = itemStack.getItem().getCraftingRemainder(); ++ ItemStackTemplate remainder = itemStack.getCraftingRemainder(); + if (remainder != null) { + result.set(slot, remainder.create()); } else if (itemStack.has(DataComponents.WRITTEN_BOOK_CONTENT)) { diff --git a/patches/net/minecraft/world/item/crafting/CraftingRecipe.java.patch b/patches/net/minecraft/world/item/crafting/CraftingRecipe.java.patch index d1b07be0114..45a8a653410 100644 --- a/patches/net/minecraft/world/item/crafting/CraftingRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/CraftingRecipe.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/item/crafting/CraftingRecipe.java +++ b/net/minecraft/world/item/crafting/CraftingRecipe.java -@@ -23,7 +_,7 @@ +@@ -24,7 +_,7 @@ NonNullList result = NonNullList.withSize(input.size(), ItemStack.EMPTY); for (int slot = 0; slot < result.size(); slot++) { - Item item = input.getItem(slot).getItem(); + var item = input.getItem(slot); - result.set(slot, item.getCraftingRemainder()); + ItemStackTemplate remainder = item.getCraftingRemainder(); + result.set(slot, remainder != null ? remainder.create() : ItemStack.EMPTY); } - diff --git a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch index bfb66cbb260..09f00b72cdc 100644 --- a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch +++ b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/crafting/Ingredient.java +++ b/net/minecraft/world/item/crafting/Ingredient.java -@@ -22,16 +_,18 @@ +@@ -23,16 +_,18 @@ import net.minecraft.world.level.ItemLike; public final class Ingredient implements Predicate, StackedContents.IngredientInfo> { @@ -12,7 +12,7 @@ + public static final StreamCodec> OPTIONAL_CONTENTS_STREAM_CODEC = net.neoforged.neoforge.common.crafting.IngredientCodecs.optionalStreamCodec(ByteBufCodecs.holderSet(Registries.ITEM) .map( ingredient -> ingredient.size() == 0 ? Optional.empty() : Optional.of(new Ingredient((HolderSet)ingredient)), -- ingredient -> ingredient.>map(i -> i.values).orElse(HolderSet.direct()) +- ingredient -> ingredient.>map(i -> i.values).orElse(HolderSet.empty()) - ); + ingredient -> ingredient.map(i -> i.getValuesForSync()).orElse(HolderSet.direct()) + )); @@ -25,7 +25,7 @@ private Ingredient(HolderSet values) { values.unwrap().ifRight(directValues -> { -@@ -44,30 +_,95 @@ +@@ -45,30 +_,95 @@ this.values = values; } @@ -122,7 +122,7 @@ } public static Ingredient of(ItemLike itemLike) { -@@ -87,6 +_,9 @@ +@@ -88,6 +_,9 @@ } public SlotDisplay display() { diff --git a/patches/net/minecraft/world/item/crafting/Recipe.java.patch b/patches/net/minecraft/world/item/crafting/Recipe.java.patch index b01246a7db6..175e88d9911 100644 --- a/patches/net/minecraft/world/item/crafting/Recipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/Recipe.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/crafting/Recipe.java +++ b/net/minecraft/world/item/crafting/Recipe.java -@@ -16,6 +_,7 @@ +@@ -15,6 +_,7 @@ public interface Recipe { Codec> CODEC = BuiltInRegistries.RECIPE_SERIALIZER.byNameCodec().dispatch(Recipe::getSerializer, RecipeSerializer::codec); Codec>> KEY_CODEC = ResourceKey.codec(Registries.RECIPE); diff --git a/patches/net/minecraft/world/item/crafting/RepairItemRecipe.java.patch b/patches/net/minecraft/world/item/crafting/RepairItemRecipe.java.patch index e838a301852..4e7ae1f77fd 100644 --- a/patches/net/minecraft/world/item/crafting/RepairItemRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/RepairItemRecipe.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/crafting/RepairItemRecipe.java +++ b/net/minecraft/world/item/crafting/RepairItemRecipe.java -@@ -44,7 +_,9 @@ +@@ -45,7 +_,9 @@ && first.has(DataComponents.MAX_DAMAGE) && second.has(DataComponents.MAX_DAMAGE) && first.has(DataComponents.DAMAGE) diff --git a/patches/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch b/patches/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch index 30e5f8a7423..77359a3af09 100644 --- a/patches/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/item/crafting/ShapelessRecipe.java +++ b/net/minecraft/world/item/crafting/ShapelessRecipe.java @@ -22,12 +_,14 @@ - private final ItemStack result; + private final ItemStackTemplate result; private final List ingredients; private @Nullable PlacementInfo placementInfo; + private final boolean isSimple; - public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, List ingredients) { + public ShapelessRecipe(String group, CraftingBookCategory category, ItemStackTemplate result, List ingredients) { this.group = group; this.category = category; this.result = result; @@ -28,10 +28,24 @@ } else { return input.size() == 1 && this.ingredients.size() == 1 ? this.ingredients.getFirst().test(input.getItem(0)) +@@ -64,6 +_,13 @@ + } + } + ++ /** ++ * {@return the result of this shapeless recipe or null if it is not static and needs ot be obtained by assembling it} ++ */ ++ public @Nullable ItemStackTemplate result() { ++ return result; ++ } ++ + public ItemStack assemble(CraftingInput input) { + return this.result.create(); + } @@ -85,7 +_,7 @@ Codec.STRING.optionalFieldOf("group", "").forGetter(o -> o.group), CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter(o -> o.category), - ItemStack.STRICT_CODEC.fieldOf("result").forGetter(o -> o.result), + ItemStackTemplate.CODEC.fieldOf("result").forGetter(o -> o.result), - Ingredient.CODEC.listOf(1, 9).fieldOf("ingredients").forGetter(o -> o.ingredients) + Codec.lazyInitialized(() -> Ingredient.CODEC.listOf(1, ShapedRecipePattern.maxHeight * ShapedRecipePattern.maxWidth)).fieldOf("ingredients").forGetter(o -> o.ingredients) ) diff --git a/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch b/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch index 527d7d37a3c..bc3e8dc2ec4 100644 --- a/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch +++ b/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/enchantment/Enchantment.java +++ b/net/minecraft/world/item/enchantment/Enchantment.java -@@ -121,6 +_,10 @@ +@@ -118,6 +_,10 @@ return itemStacks; } @@ -11,7 +11,7 @@ public HolderSet getSupportedItems() { return this.definition.supportedItems(); } -@@ -129,10 +_,20 @@ +@@ -126,10 +_,20 @@ return this.definition.slots().stream().anyMatch(group -> group.test(slot)); } @@ -32,7 +32,7 @@ public boolean isSupportedItem(ItemStack item) { return item.is(this.definition.supportedItems); } -@@ -185,6 +_,10 @@ +@@ -182,6 +_,10 @@ return result; } @@ -41,9 +41,9 @@ + */ + @Deprecated public boolean canEnchant(ItemStack itemStack) { - return this.definition.supportedItems().contains(itemStack.getItemHolder()); + return this.definition.supportedItems().contains(itemStack.typeHolder()); } -@@ -518,12 +_,26 @@ +@@ -521,12 +_,26 @@ return new Enchantment.Builder(definition); } @@ -58,7 +58,7 @@ + public static class Builder { private final Enchantment.EnchantmentDefinition definition; - private HolderSet exclusiveSet = HolderSet.direct(); + private HolderSet exclusiveSet = HolderSet.empty(); private final Map, List> effectLists = new HashMap<>(); private final DataComponentMap.Builder effectMapBuilder = DataComponentMap.builder(); @@ -70,7 +70,7 @@ public Builder(Enchantment.EnchantmentDefinition definition) { this.definition = definition; } -@@ -576,6 +_,16 @@ +@@ -579,6 +_,16 @@ return this; } @@ -87,7 +87,7 @@ private List getEffectsList(DataComponentType> type) { return (List)this.effectLists.computeIfAbsent(type, k -> { ArrayList newList = new ArrayList<>(); -@@ -586,7 +_,8 @@ +@@ -589,7 +_,8 @@ public Enchantment build(Identifier descriptionKey) { return new Enchantment( diff --git a/patches/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch b/patches/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch index 3924608366b..91767a0710c 100644 --- a/patches/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch +++ b/patches/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch @@ -44,7 +44,7 @@ if (itemEnchantments != null && !itemEnchantments.isEmpty()) { EnchantedItemInUse itemInUse = new EnchantedItemInUse(piece, slot, owner); -@@ -421,6 +_,12 @@ +@@ -419,6 +_,12 @@ public static boolean hasTag(ItemStack item, TagKey tag) { ItemEnchantments enchantments = item.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); @@ -57,7 +57,7 @@ for (Entry> entry : enchantments.entrySet()) { Holder enchantment = entry.getKey(); if (enchantment.is(tag)) { -@@ -575,7 +_,9 @@ +@@ -573,7 +_,9 @@ public static List getAvailableEnchantmentResults(int value, ItemStack itemStack, Stream> source) { List results = Lists.newArrayList(); boolean isBook = itemStack.is(Items.BOOK); diff --git a/patches/net/minecraft/world/level/Level.java.patch b/patches/net/minecraft/world/level/Level.java.patch index e98eee1886c..1eab302d848 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 -@@ -85,7 +_,7 @@ +@@ -90,7 +_,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean; import org.jspecify.annotations.Nullable; @@ -9,7 +9,7 @@ public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("overworld")); public static final ResourceKey NETHER = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("the_nether")); -@@ -125,6 +_,11 @@ +@@ -130,6 +_,11 @@ private final DamageSources damageSources; private final PalettedContainerFactory palettedContainerFactory; private long subTickCount; @@ -21,7 +21,7 @@ protected Level( WritableLevelData levelData, -@@ -217,11 +_,36 @@ +@@ -222,11 +_,36 @@ } else { LevelChunk chunk = this.getChunkAt(pos); Block block = blockState.getBlock(); @@ -58,7 +58,7 @@ if (newState == blockState) { if (oldState != newState) { this.setBlocksDirty(pos, oldState, newState); -@@ -248,9 +_,8 @@ +@@ -253,9 +_,8 @@ } this.updatePOIOnBlockStateChange(pos, oldState, newState); @@ -69,7 +69,7 @@ } } } -@@ -302,6 +_,7 @@ +@@ -307,6 +_,7 @@ } public void updateNeighborsAt(BlockPos pos, Block sourceBlock, @Nullable Orientation orientation) { @@ -77,7 +77,7 @@ } public void updateNeighborsAtExceptFromFacing(BlockPos pos, Block blockObject, Direction skipDirection, @Nullable Orientation orientation) { -@@ -450,8 +_,30 @@ +@@ -455,8 +_,30 @@ (this.tickingBlockEntities ? this.pendingBlockEntityTickers : this.blockEntityTickers).add(ticker); } @@ -108,7 +108,7 @@ if (!this.pendingBlockEntityTickers.isEmpty()) { this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); this.pendingBlockEntityTickers.clear(); -@@ -474,12 +_,19 @@ +@@ -479,12 +_,19 @@ public void guardEntityTick(Consumer tick, T entity) { try { @@ -128,7 +128,7 @@ } } -@@ -625,6 +_,7 @@ +@@ -630,6 +_,7 @@ if (this.isInValidBounds(pos)) { this.getChunkAt(pos).removeBlockEntity(pos); } @@ -136,7 +136,7 @@ } public boolean isLoaded(BlockPos pos) { -@@ -699,8 +_,8 @@ +@@ -704,8 +_,8 @@ } }); @@ -147,7 +147,7 @@ output.add(dragonPart); } } -@@ -729,6 +_,7 @@ +@@ -734,6 +_,7 @@ } } @@ -155,7 +155,7 @@ if (e instanceof EnderDragon enderDragon) { for (EnderDragonPart subEntity : enderDragon.getSubEntities()) { T castSubPart = type.tryCast(subEntity); -@@ -743,6 +_,15 @@ +@@ -748,6 +_,15 @@ return AbortableIterationConsumer.Continuation.CONTINUE; }); @@ -171,7 +171,7 @@ } public boolean hasEntities(EntityTypeTest type, AABB bb, Predicate selector) { -@@ -753,6 +_,7 @@ +@@ -758,6 +_,7 @@ hasEntities.setTrue(); return AbortableIterationConsumer.Continuation.ABORT; } else { @@ -179,7 +179,7 @@ if (e instanceof EnderDragon enderDragon) { for (EnderDragonPart subEntity : enderDragon.getSubEntities()) { T castSubPart = type.tryCast(subEntity); -@@ -766,6 +_,13 @@ +@@ -771,6 +_,13 @@ return AbortableIterationConsumer.Continuation.CONTINUE; } }); @@ -193,7 +193,7 @@ return hasEntities.isTrue(); } -@@ -787,7 +_,7 @@ +@@ -792,7 +_,7 @@ return this.getPlayerByUUID(uuid); } @@ -202,7 +202,7 @@ public void blockEntityChanged(BlockPos pos) { if (this.hasChunkAt(pos)) { -@@ -902,17 +_,20 @@ +@@ -916,17 +_,20 @@ public abstract Scoreboard getScoreboard(); @@ -228,10 +228,12 @@ this.neighborChanged(state, relativePos, changedBlock, null, false); } } -@@ -977,6 +_,18 @@ +@@ -989,6 +_,18 @@ + @Override + public BiomeManager getBiomeManager() { return this.biomeManager; - } - ++ } ++ + private double maxEntityRadius = 2.0D; + @Override + public double getMaxEntityRadius() { @@ -242,47 +244,6 @@ + if (value > maxEntityRadius) + maxEntityRadius = value; + return maxEntityRadius; -+ } -+ - public final boolean isDebug() { - return this.isDebug; } -@@ -1029,5 +_,38 @@ - public String getSerializedName() { - return this.id; - } -+ } -+ -+ // Neo: Variable day time code -+ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public abstract void setDayTimeFraction(float dayTimeFraction); -+ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public abstract float getDayTimeFraction(); -+ -+ /** -+ * Returns the current ratio between game ticks and clock ticks. If this value is negative, no -+ * speed has been set and those two are coupled 1:1 (i.e. vanilla mode). -+ */ -+ public abstract float getDayTimePerTick(); -+ -+ /** -+ * DO NOT CALL. -+ *

-+ * Use {@link net.minecraft.server.level.ServerLevel#setDayTimePerTick(float)} instead. -+ */ -+ public abstract void setDayTimePerTick(float dayTimePerTick); -+ -+ // advances the fractional daytime, returns the integer part of it -+ @org.jetbrains.annotations.ApiStatus.Internal -+ protected long advanceDaytime() { -+ if (getDayTimePerTick() < 0) { -+ return 1L; // avoid doing math (and rounding errors) if no speed has been set -+ } -+ float dayTimeStep = getDayTimeFraction() + getDayTimePerTick(); -+ long result = (long)dayTimeStep; -+ setDayTimeFraction(dayTimeStep - result); -+ return result; - } - } + + public final boolean isDebug() { diff --git a/patches/net/minecraft/world/level/NaturalSpawner.java.patch b/patches/net/minecraft/world/level/NaturalSpawner.java.patch index 0ffeb10576e..a2a3134ace4 100644 --- a/patches/net/minecraft/world/level/NaturalSpawner.java.patch +++ b/patches/net/minecraft/world/level/NaturalSpawner.java.patch @@ -8,7 +8,7 @@ + MobCategory category = entity.getClassification(true); if (category != MobCategory.MISC) { BlockPos pos = entity.blockPosition(); - chunkGetter.query(ChunkPos.asLong(pos), chunk -> { + chunkGetter.query(ChunkPos.pack(pos), chunk -> { @@ -205,7 +_,7 @@ groupSize++; level.addFreshEntityWithPassengers(mob); diff --git a/patches/net/minecraft/world/level/ServerExplosion.java.patch b/patches/net/minecraft/world/level/ServerExplosion.java.patch index d79f5981e4c..21692ae1020 100644 --- a/patches/net/minecraft/world/level/ServerExplosion.java.patch +++ b/patches/net/minecraft/world/level/ServerExplosion.java.patch @@ -30,7 +30,7 @@ Vec3 knockback = direction.scale(knockbackPower); + knockback = net.neoforged.neoforge.event.EventHooks.getExplosionKnockback(this.level, this, entity, knockback, blocks); entity.push(knockback); - if (entity.getType().is(EntityTypeTags.REDIRECTABLE_PROJECTILE) && entity instanceof Projectile projectile) { + if (entity.is(EntityTypeTags.REDIRECTABLE_PROJECTILE) && entity instanceof Projectile projectile) { projectile.setOwner(this.damageSource.getEntity()); @@ -233,7 +_,7 @@ public int explode() { diff --git a/patches/net/minecraft/world/level/TicketStorage.java.patch b/patches/net/minecraft/world/level/TicketStorage.java.patch index 81eb62498fa..5e2f0cbcb60 100644 --- a/patches/net/minecraft/world/level/TicketStorage.java.patch +++ b/patches/net/minecraft/world/level/TicketStorage.java.patch @@ -90,6 +90,6 @@ + } + + public boolean shouldForceNaturalSpawning(ChunkPos chunkPos) { -+ return chunksWithForceNaturalSpawning.contains(chunkPos.toLong()); ++ return chunksWithForceNaturalSpawning.contains(chunkPos.pack()); } } diff --git a/patches/net/minecraft/world/level/biome/Biome.java.patch b/patches/net/minecraft/world/level/biome/Biome.java.patch index 08f22bb10e2..0d82c9a8087 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,9 +_,9 @@ +@@ -36,9 +_,9 @@ public final class Biome { public static final Codec DIRECT_CODEC = RecordCodecBuilder.create( i -> i.group( @@ -12,7 +12,7 @@ BiomeGenerationSettings.CODEC.forGetter(b -> b.generationSettings), MobSpawnSettings.CODEC.forGetter(b -> b.mobSettings) ) -@@ -65,10 +_,12 @@ +@@ -66,10 +_,12 @@ @Deprecated(forRemoval = true) 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; @@ -25,7 +25,7 @@ private final BiomeSpecialEffects specialEffects; private final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> { Long2FloatLinkedOpenHashMap map = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { -@@ -92,10 +_,11 @@ +@@ -97,10 +_,11 @@ this.mobSettings = mobSettings; this.attributes = attributes; this.specialEffects = specialEffects; @@ -38,7 +38,7 @@ } public boolean hasPrecipitation() { -@@ -197,7 +_,7 @@ +@@ -202,7 +_,7 @@ } public BiomeGenerationSettings getGenerationSettings() { @@ -47,7 +47,7 @@ } public int getGrassColor(double x, double z) { -@@ -429,5 +_,32 @@ +@@ -434,5 +_,32 @@ public String getSerializedName() { return this.name; } diff --git a/patches/net/minecraft/world/level/block/AttachedStemBlock.java.patch b/patches/net/minecraft/world/level/block/AttachedStemBlock.java.patch deleted file mode 100644 index ac3464bc420..00000000000 --- a/patches/net/minecraft/world/level/block/AttachedStemBlock.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/block/AttachedStemBlock.java -+++ b/net/minecraft/world/level/block/AttachedStemBlock.java -@@ -80,7 +_,7 @@ - - @Override - protected boolean mayPlaceOn(BlockState state, BlockGetter level, BlockPos pos) { -- return state.is(Blocks.FARMLAND); -+ return state.getBlock() instanceof net.minecraft.world.level.block.FarmBlock; - } - - @Override diff --git a/patches/net/minecraft/world/level/block/BambooSaplingBlock.java.patch b/patches/net/minecraft/world/level/block/BambooSaplingBlock.java.patch index 7ce1a10b5f8..979337fff7c 100644 --- a/patches/net/minecraft/world/level/block/BambooSaplingBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BambooSaplingBlock.java.patch @@ -6,6 +6,6 @@ protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { + var soilDecision = level.getBlockState(pos.below()).canSustainPlant(level, pos.below(), net.minecraft.core.Direction.UP, state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); - return level.getBlockState(pos.below()).is(BlockTags.BAMBOO_PLANTABLE_ON); + return level.getBlockState(pos.below()).is(BlockTags.SUPPORTS_BAMBOO); } diff --git a/patches/net/minecraft/world/level/block/BambooStalkBlock.java.patch b/patches/net/minecraft/world/level/block/BambooStalkBlock.java.patch index 4e239e5c6e2..2b1bdac03db 100644 --- a/patches/net/minecraft/world/level/block/BambooStalkBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BambooStalkBlock.java.patch @@ -4,9 +4,9 @@ return null; } else { BlockState belowState = context.getLevel().getBlockState(context.getClickedPos().below()); -- if (belowState.is(BlockTags.BAMBOO_PLANTABLE_ON)) { +- if (belowState.is(BlockTags.SUPPORTS_BAMBOO)) { + var soilDecision = belowState.canSustainPlant(context.getLevel(), context.getClickedPos().below(), net.minecraft.core.Direction.UP, this.defaultBlockState()); -+ if (soilDecision.isDefault() ? belowState.is(BlockTags.BAMBOO_PLANTABLE_ON) : soilDecision.isTrue()) { ++ if (soilDecision.isDefault() ? belowState.is(BlockTags.SUPPORTS_BAMBOO) : soilDecision.isTrue()) { if (belowState.is(Blocks.BAMBOO_SAPLING)) { return this.defaultBlockState().setValue(AGE, 0); } else if (belowState.is(Blocks.BAMBOO)) { @@ -30,6 +30,6 @@ protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { + var soilDecision = level.getBlockState(pos.below()).canSustainPlant(level, pos.below(), Direction.UP, state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); - return level.getBlockState(pos.below()).is(BlockTags.BAMBOO_PLANTABLE_ON); + return level.getBlockState(pos.below()).is(BlockTags.SUPPORTS_BAMBOO); } diff --git a/patches/net/minecraft/world/level/block/BigDripleafBlock.java.patch b/patches/net/minecraft/world/level/block/BigDripleafBlock.java.patch index 538b83ce2b0..90b184fb482 100644 --- a/patches/net/minecraft/world/level/block/BigDripleafBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BigDripleafBlock.java.patch @@ -6,6 +6,6 @@ BlockState belowState = level.getBlockState(belowPos); + var soilDecision = belowState.canSustainPlant(level, belowPos, Direction.UP, state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); - return belowState.is(this) || belowState.is(Blocks.BIG_DRIPLEAF_STEM) || belowState.is(BlockTags.BIG_DRIPLEAF_PLACEABLE); + return belowState.is(this) || belowState.is(Blocks.BIG_DRIPLEAF_STEM) || belowState.is(BlockTags.SUPPORTS_BIG_DRIPLEAF); } diff --git a/patches/net/minecraft/world/level/block/Block.java.patch b/patches/net/minecraft/world/level/block/Block.java.patch index 4b47ce035bf..f1562e3e42d 100644 --- a/patches/net/minecraft/world/level/block/Block.java.patch +++ b/patches/net/minecraft/world/level/block/Block.java.patch @@ -73,7 +73,7 @@ } } -@@ -411,19 +_,26 @@ +@@ -413,19 +_,26 @@ } private static void popResource(Level level, Supplier entityFactory, ItemStack itemStack) { @@ -103,7 +103,7 @@ public float getExplosionResistance() { return this.explosionResistance; } -@@ -492,6 +_,7 @@ +@@ -494,6 +_,7 @@ public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) { } @@ -111,7 +111,7 @@ public boolean dropFromExplosion(Explosion explosion) { return true; } -@@ -574,6 +_,35 @@ +@@ -576,6 +_,35 @@ return state.setValue(property, (T)value); } diff --git a/patches/net/minecraft/world/level/block/Blocks.java.patch b/patches/net/minecraft/world/level/block/Blocks.java.patch index 6a1d4093778..8430727fff9 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 -@@ -684,7 +_,7 @@ +@@ -685,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().noCollision().strength(0.7F).sound(SoundType.METAL) -@@ -7188,7 +_,8 @@ +@@ -7207,7 +_,8 @@ static { for (Block block : BuiltInRegistries.BLOCK) { for (BlockState state : block.getStateDefinition().getPossibleStates()) { diff --git a/patches/net/minecraft/world/level/block/BubbleColumnBlock.java.patch b/patches/net/minecraft/world/level/block/BubbleColumnBlock.java.patch index 7054a1ec7c4..124c5043a56 100644 --- a/patches/net/minecraft/world/level/block/BubbleColumnBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BubbleColumnBlock.java.patch @@ -1,26 +1,25 @@ --- a/net/minecraft/world/level/block/BubbleColumnBlock.java +++ b/net/minecraft/world/level/block/BubbleColumnBlock.java -@@ -97,10 +_,12 @@ - private static BlockState getColumnState(BlockState belowState) { - if (belowState.is(Blocks.BUBBLE_COLUMN)) { +@@ -102,9 +_,11 @@ + private static BlockState getColumnState(Block bubbleColumn, BlockState belowState, BlockState occupyState) { + if (belowState.is(bubbleColumn)) { return belowState; -- } else if (belowState.is(Blocks.SOUL_SAND)) { +- } else if (belowState.is(BlockTags.ENABLES_BUBBLE_COLUMN_PUSH_UP)) { + } + net.neoforged.neoforge.common.enums.BubbleColumnDirection bubbleColumnDirection = belowState.getBubbleColumnDirection(); // Neo: PR #931 + if (bubbleColumnDirection == net.neoforged.neoforge.common.enums.BubbleColumnDirection.UPWARD) { - return Blocks.BUBBLE_COLUMN.defaultBlockState().setValue(DRAG_DOWN, false); + return bubbleColumn.defaultBlockState().setValue(DRAG_DOWN, false); +- } else if (belowState.is(BlockTags.ENABLES_BUBBLE_COLUMN_DRAG_DOWN)) { ++ } else if (bubbleColumnDirection == net.neoforged.neoforge.common.enums.BubbleColumnDirection.DOWNWARD) { + return bubbleColumn.defaultBlockState().setValue(DRAG_DOWN, true); } else { -- return belowState.is(Blocks.MAGMA_BLOCK) ? Blocks.BUBBLE_COLUMN.defaultBlockState().setValue(DRAG_DOWN, true) : Blocks.WATER.defaultBlockState(); -+ return bubbleColumnDirection == net.neoforged.neoforge.common.enums.BubbleColumnDirection.DOWNWARD ? Blocks.BUBBLE_COLUMN.defaultBlockState().setValue(DRAG_DOWN, true) : Blocks.WATER.defaultBlockState(); - } - } - -@@ -167,7 +_,7 @@ + return occupyState.is(bubbleColumn) ? Blocks.WATER.defaultBlockState() : occupyState; +@@ -174,7 +_,7 @@ @Override protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { BlockState belowState = level.getBlockState(pos.below()); -- return belowState.is(Blocks.BUBBLE_COLUMN) || belowState.is(Blocks.MAGMA_BLOCK) || belowState.is(Blocks.SOUL_SAND); -+ return belowState.is(Blocks.BUBBLE_COLUMN) || belowState.getBubbleColumnDirection() != net.neoforged.neoforge.common.enums.BubbleColumnDirection.NONE; // Neo: PR #931 +- return belowState.is(this) || belowState.is(BlockTags.ENABLES_BUBBLE_COLUMN_PUSH_UP) || belowState.is(BlockTags.ENABLES_BUBBLE_COLUMN_DRAG_DOWN); ++ return belowState.is(this) || belowState.getBubbleColumnDirection() != net.neoforged.neoforge.common.enums.BubbleColumnDirection.NONE; // Neo: PR #931 } @Override diff --git a/patches/net/minecraft/world/level/block/CactusBlock.java.patch b/patches/net/minecraft/world/level/block/CactusBlock.java.patch index 2700e0bfd7c..8697514e5a0 100644 --- a/patches/net/minecraft/world/level/block/CactusBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CactusBlock.java.patch @@ -31,6 +31,6 @@ BlockState belowState = level.getBlockState(pos.below()); + var soilDecision = belowState.canSustainPlant(level, pos.below(), Direction.UP, state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); - return (belowState.is(Blocks.CACTUS) || belowState.is(BlockTags.SAND)) && !level.getBlockState(pos.above()).liquid(); + return (belowState.is(this) || belowState.is(BlockTags.SUPPORTS_CACTUS)) && !level.getBlockState(pos.above()).liquid(); } diff --git a/patches/net/minecraft/world/level/block/ChestBlock.java.patch b/patches/net/minecraft/world/level/block/ChestBlock.java.patch index 8c18dd4314e..7748636093c 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 -@@ -366,7 +_,8 @@ +@@ -368,7 +_,8 @@ @Override protected BlockState mirror(BlockState state, Mirror mirror) { diff --git a/patches/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch b/patches/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch index 6fd5794d8d0..fabd41c1641 100644 --- a/patches/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch @@ -1,30 +1,32 @@ --- a/net/minecraft/world/level/block/ChorusFlowerBlock.java +++ b/net/minecraft/world/level/block/ChorusFlowerBlock.java -@@ -64,10 +_,13 @@ +@@ -65,10 +_,13 @@ BlockPos above = pos.above(); if (level.isEmptyBlock(above) && above.getY() <= level.getMaxY()) { int currentAge = state.getValue(AGE); - if (currentAge < 5) { + if (currentAge < 5 && net.neoforged.neoforge.common.CommonHooks.canCropGrow(level, above, state, true)) { boolean growUpwards = false; - boolean pillarOnEndStone = false; + boolean pillarOnSupportBlock = false; BlockState belowState = level.getBlockState(pos.below()); + var soilDecision = belowState.canSustainPlant(level, pos.below(), Direction.UP, state); + if (!soilDecision.isDefault()) growUpwards = soilDecision.isTrue(); + else - if (belowState.is(Blocks.END_STONE)) { + if (belowState.is(BlockTags.SUPPORTS_CHORUS_FLOWER)) { growUpwards = true; } else if (belowState.is(this.plant)) { -@@ -76,6 +_,8 @@ +@@ -77,7 +_,9 @@ for (int i = 0; i < 4; i++) { BlockState testState = level.getBlockState(pos.below(height + 1)); if (!testState.is(this.plant)) { +- if (testState.is(BlockTags.SUPPORTS_CHORUS_FLOWER)) { + var soilDecision2 = testState.canSustainPlant(level, pos.below(height + 1), Direction.UP, state); -+ if (!soilDecision2.isDefault()) pillarOnEndStone = soilDecision2.isTrue(); - if (testState.is(Blocks.END_STONE)) { - pillarOnEndStone = true; ++ if (!soilDecision2.isDefault()) pillarOnSupportBlock = soilDecision2.isTrue(); ++ else if (testState.is(BlockTags.SUPPORTS_CHORUS_FLOWER)) { + pillarOnSupportBlock = true; } -@@ -120,6 +_,7 @@ + break; +@@ -121,6 +_,7 @@ } else { this.placeDeadFlower(level, pos); } @@ -32,12 +34,12 @@ } } } -@@ -165,6 +_,8 @@ +@@ -166,6 +_,8 @@ @Override protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { BlockState belowState = level.getBlockState(pos.below()); + var soilDecision = belowState.canSustainPlant(level, pos.below(), Direction.UP, state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); - if (!belowState.is(this.plant) && !belowState.is(Blocks.END_STONE)) { + if (!belowState.is(this.plant) && !belowState.is(BlockTags.SUPPORTS_CHORUS_FLOWER)) { if (!belowState.isAir()) { return false; diff --git a/patches/net/minecraft/world/level/block/ChorusPlantBlock.java.patch b/patches/net/minecraft/world/level/block/ChorusPlantBlock.java.patch index a0cabb9d489..17022d474d8 100644 --- a/patches/net/minecraft/world/level/block/ChorusPlantBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ChorusPlantBlock.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/world/level/block/ChorusPlantBlock.java +++ b/net/minecraft/world/level/block/ChorusPlantBlock.java -@@ -49,7 +_,8 @@ +@@ -50,7 +_,8 @@ BlockState south = level.getBlockState(pos.south()); BlockState west = level.getBlockState(pos.west()); Block block = defaultState.getBlock(); -- return defaultState.trySetValue(DOWN, down.is(block) || down.is(Blocks.CHORUS_FLOWER) || down.is(Blocks.END_STONE)) -+ var soilDecision = defaultState.canSustainPlant(level, pos.below(), Direction.UP, defaultState); +- return defaultState.trySetValue(DOWN, down.is(block) || down.is(Blocks.CHORUS_FLOWER) || down.is(BlockTags.SUPPORTS_CHORUS_PLANT)) ++ var soilDecision = down.canSustainPlant(level, pos.below(), Direction.UP, defaultState); + return defaultState.trySetValue(DOWN, down.is(block) || down.is(Blocks.CHORUS_FLOWER) || down.is(Blocks.END_STONE) || soilDecision.isTrue()) .trySetValue(UP, up.is(block) || up.is(Blocks.CHORUS_FLOWER)) .trySetValue(NORTH, north.is(block) || north.is(Blocks.CHORUS_FLOWER)) .trySetValue(EAST, east.is(block) || east.is(Blocks.CHORUS_FLOWER)) -@@ -75,6 +_,12 @@ +@@ -76,6 +_,12 @@ boolean connect = neighbourState.is(this) || neighbourState.is(Blocks.CHORUS_FLOWER) - || directionToNeighbour == Direction.DOWN && neighbourState.is(Blocks.END_STONE); + || directionToNeighbour == Direction.DOWN && neighbourState.is(BlockTags.SUPPORTS_CHORUS_PLANT); + if (directionToNeighbour == Direction.DOWN) { + var soilDecision = neighbourState.canSustainPlant(level, neighbourPos.relative(directionToNeighbour), directionToNeighbour.getOpposite(), state); + if (!soilDecision.isDefault()) { @@ -23,12 +23,12 @@ return state.setValue(PROPERTY_BY_DIRECTION.get(directionToNeighbour), connect); } } -@@ -106,6 +_,8 @@ +@@ -107,6 +_,8 @@ } } + var soilDecision = belowState.canSustainPlant(level, pos.below(), Direction.UP, state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); - return belowState.is(this) || belowState.is(Blocks.END_STONE); + return belowState.is(this) || belowState.is(BlockTags.SUPPORTS_CHORUS_PLANT); } diff --git a/patches/net/minecraft/world/level/block/CocoaBlock.java.patch b/patches/net/minecraft/world/level/block/CocoaBlock.java.patch index 140b51a374d..d43ef04ccfc 100644 --- a/patches/net/minecraft/world/level/block/CocoaBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CocoaBlock.java.patch @@ -4,11 +4,11 @@ @Override protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { -- if (level.random.nextInt(5) == 0) { +- if (level.getRandom().nextInt(5) == 0) { + if (true) { int age = state.getValue(AGE); - if (age < 2) { -+ if (age < 2 && net.neoforged.neoforge.common.CommonHooks.canCropGrow(level, pos, state, level.random.nextInt(5) == 0)) { ++ if (age < 2 && net.neoforged.neoforge.common.CommonHooks.canCropGrow(level, pos, state, level.getRandom().nextInt(5) == 0)) { level.setBlock(pos, state.setValue(AGE, age + 1), 2); + net.neoforged.neoforge.common.CommonHooks.fireCropGrowPost(level, pos, state); } @@ -20,6 +20,6 @@ BlockState relativeState = level.getBlockState(pos.relative(state.getValue(FACING))); + var soilDecision = relativeState.canSustainPlant(level, pos.relative(state.getValue(FACING)), state.getValue(FACING).getOpposite(), state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); - return relativeState.is(BlockTags.JUNGLE_LOGS); + return relativeState.is(BlockTags.SUPPORTS_COCOA); } diff --git a/patches/net/minecraft/world/level/block/ComposterBlock.java.patch b/patches/net/minecraft/world/level/block/ComposterBlock.java.patch index 02f0269f6c2..5b7949a5ec6 100644 --- a/patches/net/minecraft/world/level/block/ComposterBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ComposterBlock.java.patch @@ -68,7 +68,7 @@ + } + + public static float getValue(ItemStack item) { -+ var value = item.getItemHolder().getData(net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps.COMPOSTABLES); ++ var value = item.typeHolder().getData(net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps.COMPOSTABLES); + if (value != null) return value.chance(); + return -1f; } diff --git a/patches/net/minecraft/world/level/block/CropBlock.java.patch b/patches/net/minecraft/world/level/block/CropBlock.java.patch index 3a04d756027..5a2560d1856 100644 --- a/patches/net/minecraft/world/level/block/CropBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CropBlock.java.patch @@ -1,15 +1,6 @@ --- a/net/minecraft/world/level/block/CropBlock.java +++ b/net/minecraft/world/level/block/CropBlock.java -@@ -46,7 +_,7 @@ - - @Override - protected boolean mayPlaceOn(BlockState state, BlockGetter level, BlockPos pos) { -- return state.is(Blocks.FARMLAND); -+ return state.getBlock() instanceof net.minecraft.world.level.block.FarmBlock; - } - - protected IntegerProperty getAgeProperty() { -@@ -76,12 +_,14 @@ +@@ -77,12 +_,14 @@ @Override protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { @@ -26,8 +17,8 @@ } } } -@@ -96,7 +_,8 @@ - return Mth.nextInt(level.random, 2, 5); +@@ -97,7 +_,8 @@ + return Mth.nextInt(level.getRandom(), 2, 5); } - protected static float getGrowthSpeed(Block type, BlockGetter level, BlockPos pos) { @@ -36,20 +27,20 @@ float speed = 1.0F; BlockPos below = pos.below(); -@@ -104,9 +_,10 @@ +@@ -105,9 +_,10 @@ for (int zz = -1; zz <= 1; zz++) { float blockSpeed = 0.0F; BlockState blockState = level.getBlockState(below.offset(xx, 0, zz)); -- if (blockState.is(Blocks.FARMLAND)) { +- if (blockState.is(BlockTags.GROWS_CROPS)) { + var soilDecision = blockState.canSustainPlant(level, below.offset(xx, 0, zz), net.minecraft.core.Direction.UP, blockState); -+ if (soilDecision.isDefault() ? blockState.getBlock() instanceof net.minecraft.world.level.block.FarmBlock : soilDecision.isTrue()) { ++ if (soilDecision.isDefault() ? blockState.is(BlockTags.GROWS_CROPS) : soilDecision.isTrue()) { blockSpeed = 1.0F; -- if (blockState.getValue(FarmBlock.MOISTURE) > 0) { +- if (blockState.getValueOrElse(FarmlandBlock.MOISTURE, 0) > 0) { + if (blockState.isFertile(level, pos.offset(xx, 0, zz))) { blockSpeed = 3.0F; } } -@@ -142,6 +_,8 @@ +@@ -143,6 +_,8 @@ @Override protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { @@ -58,7 +49,7 @@ return hasSufficientLight(level, pos) && super.canSurvive(state, level, pos); } -@@ -151,7 +_,7 @@ +@@ -152,7 +_,7 @@ @Override protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier, boolean isPrecise) { diff --git a/patches/net/minecraft/world/level/block/FarmBlock.java.patch b/patches/net/minecraft/world/level/block/FarmlandBlock.java.patch similarity index 83% rename from patches/net/minecraft/world/level/block/FarmBlock.java.patch rename to patches/net/minecraft/world/level/block/FarmlandBlock.java.patch index b40cdc7b035..979c3d53289 100644 --- a/patches/net/minecraft/world/level/block/FarmBlock.java.patch +++ b/patches/net/minecraft/world/level/block/FarmlandBlock.java.patch @@ -1,14 +1,14 @@ ---- a/net/minecraft/world/level/block/FarmBlock.java -+++ b/net/minecraft/world/level/block/FarmBlock.java +--- a/net/minecraft/world/level/block/FarmlandBlock.java ++++ b/net/minecraft/world/level/block/FarmlandBlock.java @@ -109,10 +_,7 @@ @Override public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, double fallDistance) { if (level instanceof ServerLevel serverLevel -- && level.random.nextFloat() < fallDistance - 0.5 +- && level.getRandom().nextFloat() < fallDistance - 0.5 - && entity instanceof LivingEntity - && (entity instanceof Player || serverLevel.getGameRules().get(GameRules.MOB_GRIEFING)) - && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { -+ && net.neoforged.neoforge.common.CommonHooks.onFarmlandTrample(serverLevel, pos, Blocks.DIRT.defaultBlockState(), fallDistance, entity)) { // Forge: Move logic to Entity#canTrample ++ && net.neoforged.neoforge.common.CommonHooks.onFarmlandTrample(serverLevel, pos, Blocks.DIRT.defaultBlockState(), fallDistance, entity)) { // Neo: Move logic to Entity#canTrample turnToDirt(entity, state, level, pos); } diff --git a/patches/net/minecraft/world/level/block/FireBlock.java.patch b/patches/net/minecraft/world/level/block/FireBlock.java.patch index c76cc750f38..d618091cbc7 100644 --- a/patches/net/minecraft/world/level/block/FireBlock.java.patch +++ b/patches/net/minecraft/world/level/block/FireBlock.java.patch @@ -122,7 +122,7 @@ @@ -302,8 +_,21 @@ } - public void setFlammable(Block block, int igniteOdds, int burnOdds) { + private void setFlammable(Block block, int igniteOdds, int burnOdds) { + if (block == Blocks.AIR) throw new IllegalArgumentException("Tried to set air on fire... This is bad."); this.igniteOdds.put(block, igniteOdds); this.burnOdds.put(block, burnOdds); diff --git a/patches/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch b/patches/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch index c9b9aaf0f02..4bd75c04ea8 100644 --- a/patches/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch +++ b/patches/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch @@ -8,7 +8,7 @@ + if (state.getValue(AGE) < 25 && net.neoforged.neoforge.common.CommonHooks.canCropGrow(level, pos.relative(this.growthDirection), state, random.nextDouble() < this.growPerTickProbability)) { BlockPos growthPos = pos.relative(this.growthDirection); if (this.canGrowInto(level.getBlockState(growthPos))) { - level.setBlockAndUpdate(growthPos, this.getGrowIntoState(state, level.random)); + level.setBlockAndUpdate(growthPos, this.getGrowIntoState(state, level.getRandom())); + net.neoforged.neoforge.common.CommonHooks.fireCropGrowPost(level, growthPos, level.getBlockState(growthPos)); } } diff --git a/patches/net/minecraft/world/level/block/LiquidBlock.java.patch b/patches/net/minecraft/world/level/block/LiquidBlock.java.patch index 003e428db3d..0f35dbc833a 100644 --- a/patches/net/minecraft/world/level/block/LiquidBlock.java.patch +++ b/patches/net/minecraft/world/level/block/LiquidBlock.java.patch @@ -1,25 +1,19 @@ --- a/net/minecraft/world/level/block/LiquidBlock.java +++ b/net/minecraft/world/level/block/LiquidBlock.java -@@ -137,7 +_,7 @@ +@@ -191,7 +_,7 @@ @Override - protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) { + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, @Nullable Orientation orientation, boolean movedByPiston) { - if (this.shouldSpreadLiquid(level, pos, state)) { + if (!net.neoforged.neoforge.fluids.FluidInteractionRegistry.canInteract(level, pos)) { level.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(level)); } - } -@@ -162,11 +_,12 @@ - @Override - protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, @Nullable Orientation orientation, boolean movedByPiston) { -- if (this.shouldSpreadLiquid(level, pos, state)) { -+ if (!net.neoforged.neoforge.fluids.FluidInteractionRegistry.canInteract(level, pos)) { - level.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(level)); +@@ -205,6 +_,7 @@ } } -+ @Deprecated // FORGE: Use FluidInteractionRegistry#canInteract instead ++ @Deprecated // Neo: Use FluidInteractionRegistry#canInteract instead private boolean shouldSpreadLiquid(Level level, BlockPos pos, BlockState state) { if (this.fluid.is(FluidTags.LAVA)) { boolean isOverSoulSoil = level.getBlockState(pos.below()).is(Blocks.SOUL_SOIL); diff --git a/patches/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch b/patches/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch index a333574a0b5..cc64675cc81 100644 --- a/patches/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch +++ b/patches/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/MangrovePropaguleBlock.java +++ b/net/minecraft/world/level/block/MangrovePropaguleBlock.java -@@ -70,7 +_,12 @@ +@@ -71,7 +_,12 @@ @Override protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { -- return isHanging(state) ? level.getBlockState(pos.above()).is(Blocks.MANGROVE_LEAVES) : super.canSurvive(state, level, pos); +- return isHanging(state) ? level.getBlockState(pos.above()).is(BlockTags.SUPPORTS_HANGING_MANGROVE_PROPAGULE) : super.canSurvive(state, level, pos); + if (isHanging(state)) { + var soilDecision = level.getBlockState(pos.above()).canSustainPlant(level, pos.above(), Direction.DOWN, state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); diff --git a/patches/net/minecraft/world/level/block/MushroomBlock.java.patch b/patches/net/minecraft/world/level/block/MushroomBlock.java.patch index 3dc609e1856..8eb4ca1e48a 100644 --- a/patches/net/minecraft/world/level/block/MushroomBlock.java.patch +++ b/patches/net/minecraft/world/level/block/MushroomBlock.java.patch @@ -4,9 +4,9 @@ protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { BlockPos belowPos = pos.below(); BlockState below = level.getBlockState(belowPos); -- return below.is(BlockTags.MUSHROOM_GROW_BLOCK) ? true : level.getRawBrightness(pos, 0) < 13 && this.mayPlaceOn(below, level, belowPos); +- return below.is(BlockTags.OVERRIDES_MUSHROOM_LIGHT_REQUIREMENT) ? true : level.getRawBrightness(pos, 0) < 13 && this.mayPlaceOn(below, level, belowPos); + var soilDecision = below.canSustainPlant(level, belowPos, net.minecraft.core.Direction.UP, state); -+ return below.is(BlockTags.MUSHROOM_GROW_BLOCK) ? true : soilDecision.isDefault() ? (level.getRawBrightness(pos, 0) < 13 && this.mayPlaceOn(below, level, belowPos)) : soilDecision.isTrue(); ++ return below.is(BlockTags.OVERRIDES_MUSHROOM_LIGHT_REQUIREMENT) ? true : soilDecision.isDefault() ? (level.getRawBrightness(pos, 0) < 13 && this.mayPlaceOn(below, level, belowPos)) : soilDecision.isTrue(); } public boolean growMushroom(ServerLevel level, BlockPos pos, BlockState state, RandomSource random) { diff --git a/patches/net/minecraft/world/level/block/FungusBlock.java.patch b/patches/net/minecraft/world/level/block/NetherFungusBlock.java.patch similarity index 83% rename from patches/net/minecraft/world/level/block/FungusBlock.java.patch rename to patches/net/minecraft/world/level/block/NetherFungusBlock.java.patch index a3e985dcf8b..4a395214aff 100644 --- a/patches/net/minecraft/world/level/block/FungusBlock.java.patch +++ b/patches/net/minecraft/world/level/block/NetherFungusBlock.java.patch @@ -1,6 +1,6 @@ ---- a/net/minecraft/world/level/block/FungusBlock.java -+++ b/net/minecraft/world/level/block/FungusBlock.java -@@ -72,6 +_,9 @@ +--- a/net/minecraft/world/level/block/NetherFungusBlock.java ++++ b/net/minecraft/world/level/block/NetherFungusBlock.java +@@ -77,6 +_,9 @@ @Override public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { diff --git a/patches/net/minecraft/world/level/block/NetherWartBlock.java.patch b/patches/net/minecraft/world/level/block/NetherWartBlock.java.patch index dddc7a10d7d..7836d42ba63 100644 --- a/patches/net/minecraft/world/level/block/NetherWartBlock.java.patch +++ b/patches/net/minecraft/world/level/block/NetherWartBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/NetherWartBlock.java +++ b/net/minecraft/world/level/block/NetherWartBlock.java -@@ -50,9 +_,10 @@ +@@ -51,9 +_,10 @@ @Override protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { int age = state.getValue(AGE); diff --git a/patches/net/minecraft/world/level/block/PitcherCropBlock.java.patch b/patches/net/minecraft/world/level/block/PitcherCropBlock.java.patch index 560450ca873..04963635aff 100644 --- a/patches/net/minecraft/world/level/block/PitcherCropBlock.java.patch +++ b/patches/net/minecraft/world/level/block/PitcherCropBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/PitcherCropBlock.java +++ b/net/minecraft/world/level/block/PitcherCropBlock.java -@@ -101,12 +_,13 @@ +@@ -102,7 +_,8 @@ @Override public boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { @@ -10,13 +10,7 @@ } @Override - protected boolean mayPlaceOn(BlockState state, BlockGetter level, BlockPos pos) { -- return state.is(Blocks.FARMLAND); -+ return state.getBlock() instanceof net.minecraft.world.level.block.FarmBlock; - } - - @Override -@@ -138,7 +_,7 @@ +@@ -139,7 +_,7 @@ @Override public void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { diff --git a/patches/net/minecraft/world/level/block/PowderSnowBlock.java.patch b/patches/net/minecraft/world/level/block/PowderSnowBlock.java.patch index d6ef0e96812..dfb323263ec 100644 --- a/patches/net/minecraft/world/level/block/PowderSnowBlock.java.patch +++ b/patches/net/minecraft/world/level/block/PowderSnowBlock.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/block/PowderSnowBlock.java +++ b/net/minecraft/world/level/block/PowderSnowBlock.java @@ -138,7 +_,7 @@ - if (entity.getType().is(EntityTypeTags.POWDER_SNOW_WALKABLE_MOBS)) { + if (entity.is(EntityTypeTags.POWDER_SNOW_WALKABLE_MOBS)) { return true; } else { - return entity instanceof LivingEntity ? ((LivingEntity)entity).getItemBySlot(EquipmentSlot.FEET).is(Items.LEATHER_BOOTS) : false; diff --git a/patches/net/minecraft/world/level/block/PumpkinBlock.java.patch b/patches/net/minecraft/world/level/block/PumpkinBlock.java.patch index c13e07d8bf1..632a514e0c6 100644 --- a/patches/net/minecraft/world/level/block/PumpkinBlock.java.patch +++ b/patches/net/minecraft/world/level/block/PumpkinBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/PumpkinBlock.java +++ b/net/minecraft/world/level/block/PumpkinBlock.java -@@ -36,7 +_,7 @@ +@@ -37,7 +_,7 @@ protected InteractionResult useItemOn( ItemStack itemStack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult ) { diff --git a/patches/net/minecraft/world/level/block/SpawnerBlock.java.patch b/patches/net/minecraft/world/level/block/SpawnerBlock.java.patch index 242cdb0586c..03507422cdd 100644 --- a/patches/net/minecraft/world/level/block/SpawnerBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SpawnerBlock.java.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/world/level/block/SpawnerBlock.java +++ b/net/minecraft/world/level/block/SpawnerBlock.java -@@ -38,9 +_,14 @@ +@@ -39,10 +_,14 @@ @Override protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack tool, boolean dropExperience) { super.spawnAfterBreak(state, level, pos, tool, dropExperience); - if (dropExperience) { -- int magicCount = 15 + level.random.nextInt(15) + level.random.nextInt(15); +- RandomSource random = level.getRandom(); +- int magicCount = 15 + random.nextInt(15) + random.nextInt(15); - this.popExperience(level, pos, magicCount); - } + } diff --git a/patches/net/minecraft/world/level/block/StemBlock.java.patch b/patches/net/minecraft/world/level/block/StemBlock.java.patch index 8f24fa87580..3b9e7b16640 100644 --- a/patches/net/minecraft/world/level/block/StemBlock.java.patch +++ b/patches/net/minecraft/world/level/block/StemBlock.java.patch @@ -1,12 +1,6 @@ --- a/net/minecraft/world/level/block/StemBlock.java +++ b/net/minecraft/world/level/block/StemBlock.java -@@ -63,23 +_,23 @@ - - @Override - protected boolean mayPlaceOn(BlockState state, BlockGetter level, BlockPos pos) { -- return state.is(Blocks.FARMLAND); -+ return state.getBlock() instanceof net.minecraft.world.level.block.FarmBlock; - } +@@ -81,13 +_,13 @@ @Override protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { @@ -24,13 +18,7 @@ } else { Direction direction = Direction.Plane.HORIZONTAL.getRandomDirection(random); BlockPos relative = pos.relative(direction); - BlockState stateBelow = level.getBlockState(relative.below()); -- if (level.getBlockState(relative).isAir() && (stateBelow.is(Blocks.FARMLAND) || stateBelow.is(BlockTags.DIRT))) { -+ if (level.isEmptyBlock(relative) && (stateBelow.getBlock() instanceof net.minecraft.world.level.block.FarmBlock || stateBelow.is(BlockTags.DIRT))) { - Registry blocks = level.registryAccess().lookupOrThrow(Registries.BLOCK); - Optional fruit = blocks.getOptional(this.fruit); - Optional stem = blocks.getOptional(this.attachedStem); -@@ -89,6 +_,7 @@ +@@ -102,6 +_,7 @@ } } } diff --git a/patches/net/minecraft/world/level/block/SugarCaneBlock.java.patch b/patches/net/minecraft/world/level/block/SugarCaneBlock.java.patch index eba21128736..c79df692877 100644 --- a/patches/net/minecraft/world/level/block/SugarCaneBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SugarCaneBlock.java.patch @@ -16,20 +16,21 @@ } } } -@@ -91,13 +_,15 @@ +@@ -91,13 +_,16 @@ if (stateBelow.is(this)) { return true; } else { + var soilDecision = stateBelow.canSustainPlant(level, pos.below(), Direction.UP, state); + if (!soilDecision.isDefault()) return soilDecision.isTrue(); - if (stateBelow.is(BlockTags.DIRT) || stateBelow.is(BlockTags.SAND)) { + if (stateBelow.is(BlockTags.SUPPORTS_SUGAR_CANE)) { BlockPos below = pos.below(); for (Direction direction : Direction.Plane.HORIZONTAL) { BlockState blockState = level.getBlockState(below.relative(direction)); FluidState fluidState = level.getFluidState(below.relative(direction)); -- if (fluidState.is(FluidTags.WATER) || blockState.is(Blocks.FROSTED_ICE)) { -+ if (state.canBeHydrated(level, pos, fluidState, below.relative(direction)) || blockState.is(Blocks.FROSTED_ICE)) { +- if (fluidState.is(FluidTags.SUPPORTS_SUGAR_CANE_ADJACENTLY) || blockState.is(BlockTags.SUPPORTS_SUGAR_CANE_ADJACENTLY)) { ++ // Neo: Allow the fluid state to dynamically decide whether it hydrates here if the tag-based checks fail ++ if (fluidState.is(FluidTags.SUPPORTS_SUGAR_CANE_ADJACENTLY) || blockState.is(BlockTags.SUPPORTS_SUGAR_CANE_ADJACENTLY) || state.canBeHydrated(level, pos, fluidState, below.relative(direction))) { return true; } } diff --git a/patches/net/minecraft/world/level/block/VegetationBlock.java.patch b/patches/net/minecraft/world/level/block/VegetationBlock.java.patch index 225d40de251..6af75bee32a 100644 --- a/patches/net/minecraft/world/level/block/VegetationBlock.java.patch +++ b/patches/net/minecraft/world/level/block/VegetationBlock.java.patch @@ -1,14 +1,5 @@ --- a/net/minecraft/world/level/block/VegetationBlock.java +++ b/net/minecraft/world/level/block/VegetationBlock.java -@@ -21,7 +_,7 @@ - protected abstract MapCodec codec(); - - protected boolean mayPlaceOn(BlockState state, BlockGetter level, BlockPos pos) { -- return state.is(BlockTags.DIRT) || state.is(Blocks.FARMLAND); -+ return state.is(BlockTags.DIRT) || state.getBlock() instanceof net.minecraft.world.level.block.FarmBlock; - } - - @Override @@ -43,7 +_,10 @@ @Override protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { diff --git a/patches/net/minecraft/world/level/block/VineBlock.java.patch b/patches/net/minecraft/world/level/block/VineBlock.java.patch index abb69945f7c..e4478bae05a 100644 --- a/patches/net/minecraft/world/level/block/VineBlock.java.patch +++ b/patches/net/minecraft/world/level/block/VineBlock.java.patch @@ -5,7 +5,7 @@ protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { if (level.getGameRules().get(GameRules.SPREAD_VINES)) { - if (random.nextInt(4) == 0) { -+ if (level.random.nextInt(4) == 0 && level.isAreaLoaded(pos, 4)) { // Forge: check area to prevent loading unloaded chunks ++ if (level.getRandom().nextInt(4) == 0 && level.isAreaLoaded(pos, 4)) { // Forge: check area to prevent loading unloaded chunks Direction testDirection = Direction.getRandom(random); BlockPos abovePos = pos.above(); if (testDirection.getAxis().isHorizontal() && !state.getValue(getPropertyForFace(testDirection))) { 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 6c5e3902c35..9bbbce80a90 100644 --- a/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -68,9 +_,14 @@ +@@ -73,9 +_,14 @@ public int get(int dataId) { switch (dataId) { case 0: @@ -16,7 +16,7 @@ case 2: return AbstractFurnaceBlockEntity.this.cookingTimer; case 3: -@@ -104,12 +_,14 @@ +@@ -109,12 +_,14 @@ }; private final Reference2IntOpenHashMap>> recipesUsed = new Reference2IntOpenHashMap<>(); private final RecipeManager.CachedCheck quickCheck; @@ -31,7 +31,7 @@ } private boolean isLit() { -@@ -121,10 +_,10 @@ +@@ -126,10 +_,10 @@ super.loadAdditional(input); this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); ContainerHelper.loadAllItems(input, this.items); @@ -46,7 +46,7 @@ this.recipesUsed.clear(); this.recipesUsed.putAll(input.read("RecipesUsed", RECIPES_USED_CODEC).orElse(Map.of())); } -@@ -132,10 +_,10 @@ +@@ -137,10 +_,10 @@ @Override protected void saveAdditional(ValueOutput output) { super.saveAdditional(output); @@ -61,24 +61,25 @@ ContainerHelper.saveAllItems(output, this.items); output.store("RecipesUsed", RECIPES_USED_CODEC, this.recipesUsed); } -@@ -166,11 +_,15 @@ +@@ -171,12 +_,15 @@ entity.litTotalTime = entity.litTimeRemaining; if (entity.isLit()) { changed = true; + var remainder = fuel.getCraftingRemainder(); -+ if (!remainder.isEmpty()) -+ entity.items.set(1, remainder); ++ if (remainder != null) ++ entity.items.set(1, remainder.create()); + else if (hasFuel) { Item fuelItem = fuel.getItem(); fuel.shrink(1); if (fuel.isEmpty()) { -- entity.items.set(1, fuelItem.getCraftingRemainder()); -+ entity.items.set(1, fuelItem.getCraftingRemainder()); // Neo: Remainder is handled in the `if` check above. +- ItemStackTemplate remainder = fuelItem.getCraftingRemainder(); +- entity.items.set(1, remainder != null ? remainder.create() : ItemStack.EMPTY); ++ entity.items.set(1, ItemStack.EMPTY); // Neo: Remainder is handled in the `if` check above. } } } -@@ -223,9 +_,9 @@ +@@ -225,9 +_,9 @@ } else if (!ItemStack.isSameItemSameComponents(resultItemStack, burnResult)) { return false; } else { @@ -90,7 +91,7 @@ } } } else { -@@ -262,7 +_,7 @@ +@@ -260,7 +_,7 @@ } protected int getBurnDuration(FuelValues fuelValues, ItemStack itemStack) { @@ -99,7 +100,7 @@ } private static int getTotalCookTime(ServerLevel level, AbstractFurnaceBlockEntity entity) { -@@ -306,17 +_,57 @@ +@@ -304,17 +_,57 @@ @Override public void setItem(int slot, ItemStack itemStack) { @@ -158,7 +159,7 @@ @Override public boolean canPlaceItem(int slot, ItemStack itemStack) { if (slot == 2) { -@@ -325,7 +_,7 @@ +@@ -323,7 +_,7 @@ return true; } else { ItemStack fuelSlot = this.items.get(1); diff --git a/patches/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch index af2e86c98b9..fb9e08df471 100644 --- a/patches/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -@@ -136,8 +_,8 @@ +@@ -140,8 +_,8 @@ for (int i = 0; i < 10 && checkPos.getY() <= lastSetBlock; i++) { BlockState state = level.getBlockState(checkPos); 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 44b72ccd43d..58f34b3ca24 100644 --- a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -36,15 +_,18 @@ +@@ -39,15 +_,20 @@ import org.jspecify.annotations.Nullable; import org.slf4j.Logger; --public abstract class BlockEntity implements DebugValueSource, net.neoforged.neoforge.common.extensions.IBlockEntityExtension { -+public abstract class BlockEntity extends net.neoforged.neoforge.attachment.AttachmentHolder implements DebugValueSource, net.neoforged.neoforge.common.extensions.IBlockEntityExtension { +-public abstract class BlockEntity implements DebugValueSource, TypedInstance>, net.neoforged.neoforge.common.extensions.IBlockEntityExtension { ++public abstract class BlockEntity extends net.neoforged.neoforge.attachment.AttachmentHolder implements DebugValueSource, TypedInstance>, net.neoforged.neoforge.common.extensions.IBlockEntityExtension { private static final Codec> TYPE_CODEC = BuiltInRegistries.BLOCK_ENTITY_TYPE.byNameCodec(); private static final Logger LOGGER = LogUtils.getLogger(); + @Deprecated // Neo: always use getType() @@ -17,10 +17,12 @@ private DataComponentMap components = DataComponentMap.EMPTY; + @Nullable + private CompoundTag customPersistentData; ++ @Nullable ++ private Set> attachmentTypesToSync; public BlockEntity(BlockEntityType type, BlockPos worldPosition, BlockState blockState) { this.type = type; -@@ -60,7 +_,7 @@ +@@ -63,7 +_,7 @@ } public boolean isValidBlockState(BlockState blockState) { @@ -29,7 +31,7 @@ } public static BlockPos getPosFromTag(ChunkPos base, CompoundTag entityTag) { -@@ -91,6 +_,8 @@ +@@ -94,6 +_,8 @@ } protected void loadAdditional(ValueInput input) { @@ -38,7 +40,7 @@ } public final void loadWithComponents(ValueInput input) { -@@ -103,6 +_,11 @@ +@@ -106,6 +_,11 @@ } protected void saveAdditional(ValueOutput output) { @@ -50,7 +52,7 @@ } public final CompoundTag saveWithFullMetadata(HolderLookup.Provider registries) { -@@ -236,10 +_,14 @@ +@@ -239,10 +_,14 @@ public void setRemoved() { this.remove = true; @@ -65,7 +67,7 @@ } public void preRemoveSideEffects(BlockPos pos, BlockState state) { -@@ -269,6 +_,32 @@ +@@ -272,6 +_,48 @@ public BlockEntityType getType() { return this.type; @@ -94,7 +96,23 @@ + + @Override + public final void syncData(net.neoforged.neoforge.attachment.AttachmentType type) { -+ net.neoforged.neoforge.attachment.AttachmentSync.syncBlockEntityUpdate(this, type); ++ if (!(level instanceof ServerLevel serverLevel)) { ++ return; ++ } ++ if (attachmentTypesToSync == null) { ++ attachmentTypesToSync = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); ++ } ++ attachmentTypesToSync.add(type); ++ // Schedule the BE for syncing ++ serverLevel.getChunkSource().blockChanged(worldPosition); ++ } ++ ++ @Nullable ++ @org.jetbrains.annotations.ApiStatus.Internal ++ public final Set> getAndClearAttachmentTypesToSync() { ++ var ret = attachmentTypesToSync; ++ attachmentTypesToSync = null; ++ return ret; } - @Deprecated + @Override 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 6b4ab3e222a..2e4a3634e00 100644 --- a/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BlockEntityType.java +++ b/net/minecraft/world/level/block/entity/BlockEntityType.java -@@ -274,8 +_,11 @@ +@@ -273,8 +_,11 @@ ); 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; @@ -10,9 +10,9 @@ + // Neo: Allow modded BE types to declare that they have NBT data only OPs can set + private final boolean onlyOpCanSetNbt; - public static @Nullable Identifier getKey(BlockEntityType type) { - return BuiltInRegistries.BLOCK_ENTITY_TYPE.getKey(type); -@@ -293,14 +_,39 @@ + private static BlockEntityType register( + String name, BlockEntityType.BlockEntitySupplier factory, Block... validBlocks +@@ -288,14 +_,39 @@ } public BlockEntityType(BlockEntityType.BlockEntitySupplier factory, Set validBlocks) { @@ -52,7 +52,7 @@ public boolean isValid(BlockState state) { return this.validBlocks.contains(state.getBlock()); } -@@ -316,6 +_,7 @@ +@@ -311,6 +_,7 @@ } public boolean onlyOpCanSetNbt() { diff --git a/patches/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch index 2c8d0bb7c05..8f342ddeed6 100644 --- a/patches/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -@@ -168,6 +_,7 @@ +@@ -174,6 +_,7 @@ } private static void doBrew(Level level, BlockPos pos, NonNullList items) { @@ -8,15 +8,15 @@ ItemStack ingredient = items.get(3); PotionBrewing potionBrewing = level.potionBrewing(); -@@ -175,6 +_,7 @@ +@@ -181,6 +_,7 @@ items.set(dest, potionBrewing.mix(ingredient, items.get(dest))); } + net.neoforged.neoforge.event.EventHooks.onPotionBrewed(items); ingredient.shrink(1); - ItemStack remainder = ingredient.getItem().getCraftingRemainder(); - if (!remainder.isEmpty()) { -@@ -212,13 +_,13 @@ + ItemStackTemplate remainder = ingredient.getItem().getCraftingRemainder(); + if (remainder != null) { +@@ -218,13 +_,13 @@ @Override public boolean canPlaceItem(int slot, ItemStack itemStack) { diff --git a/patches/net/minecraft/world/level/block/entity/ChestBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/ChestBlockEntity.java.patch index 531a4905004..f3aa35aa3c1 100644 --- a/patches/net/minecraft/world/level/block/entity/ChestBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/ChestBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/ChestBlockEntity.java +++ b/net/minecraft/world/level/block/entity/ChestBlockEntity.java -@@ -187,6 +_,17 @@ +@@ -192,6 +_,17 @@ return ChestMenu.threeRows(containerId, inventory, this); } diff --git a/patches/net/minecraft/world/level/block/entity/HopperBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/HopperBlockEntity.java.patch index 50e549126fe..bd1e0cf769b 100644 --- a/patches/net/minecraft/world/level/block/entity/HopperBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/HopperBlockEntity.java.patch @@ -97,7 +97,7 @@ return getContainerAt(level, pos, level.getBlockState(pos), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); } @@ -389,6 +_,28 @@ - return !entities.isEmpty() ? (Container)entities.get(level.random.nextInt(entities.size())) : null; + return !entities.isEmpty() ? (Container)entities.get(level.getRandom().nextInt(entities.size())) : null; } + private static net.neoforged.neoforge.transfer.item.ContainerOrHandler getSourceContainerOrHandler(Level level, Hopper hopper, BlockPos pos, BlockState state) { diff --git a/patches/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch index d03a499689b..af46edf6337 100644 --- a/patches/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch @@ -33,5 +33,5 @@ + } + private void itemChanged() { boolean itemWasInserted = !this.item.isEmpty(); - Optional> maybeSong = JukeboxSong.fromStack(this.level.registryAccess(), this.item); + Optional> maybeSong = JukeboxSong.fromStack(this.item); this.notifyItemChangedInJukebox(itemWasInserted); diff --git a/patches/net/minecraft/world/level/block/entity/ShelfBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/ShelfBlockEntity.java.patch new file mode 100644 index 00000000000..de2d5d3d243 --- /dev/null +++ b/patches/net/minecraft/world/level/block/entity/ShelfBlockEntity.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/world/level/block/entity/ShelfBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/ShelfBlockEntity.java +@@ -87,6 +_,20 @@ + return retrievedItem; + } + ++ @Override ++ public void setItem(int slot, ItemStack itemStack) { ++ setItem(slot, itemStack, false); ++ } ++ ++ // Neo: Skip side effects if insideTransaction is true so the caller can defer them until the transaction commits ++ @Override ++ public void setItem(int slot, ItemStack itemStack, boolean insideTransaction) { ++ this.setItemNoUpdate(slot, itemStack); ++ if (!insideTransaction) { ++ this.setChanged(); ++ } ++ } ++ + public void setChanged(Holder.@Nullable Reference event) { + super.setChanged(); + if (this.level != null) { 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 1814f53e2d6..509dc8c3e90 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 -@@ -236,7 +_,8 @@ +@@ -240,7 +_,8 @@ @Override public boolean canPlaceItemThroughFace(int slot, ItemStack itemStack, @Nullable Direction direction) { diff --git a/patches/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java.patch index 8bba6f0d82b..4eec95030b4 100644 --- a/patches/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java -@@ -32,6 +_,11 @@ +@@ -37,6 +_,11 @@ level.sendBlockUpdated(pos, state, state, 260); } } diff --git a/patches/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch b/patches/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch index 0beb77fe3ce..ef7fcd0347b 100644 --- a/patches/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch +++ b/patches/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch @@ -1,22 +1,22 @@ --- a/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/net/minecraft/world/level/block/piston/PistonBaseBlock.java -@@ -160,6 +_,7 @@ - } +@@ -162,6 +_,7 @@ + RandomSource random = level.getRandom(); if (b0 == 0) { + if (net.neoforged.neoforge.event.EventHooks.onPistonMovePre(level, pos, direction, true)) return false; if (!this.moveBlocks(level, pos, direction, true)) { return false; } -@@ -168,6 +_,7 @@ - level.playSound(null, pos, SoundEvents.PISTON_EXTEND, SoundSource.BLOCKS, 0.5F, level.random.nextFloat() * 0.25F + 0.6F); +@@ -170,6 +_,7 @@ + level.playSound(null, pos, SoundEvents.PISTON_EXTEND, SoundSource.BLOCKS, 0.5F, random.nextFloat() * 0.25F + 0.6F); level.gameEvent(GameEvent.BLOCK_ACTIVATE, pos, GameEvent.Context.of(extendedState)); } else if (b0 == 1 || b0 == 2) { + if (net.neoforged.neoforge.event.EventHooks.onPistonMovePre(level, pos, direction, false)) return false; BlockEntity prevBlockEntity = level.getBlockEntity(pos.relative(direction)); if (prevBlockEntity instanceof PistonMovingBlockEntity) { ((PistonMovingBlockEntity)prevBlockEntity).finalTick(); -@@ -217,6 +_,7 @@ +@@ -219,6 +_,7 @@ level.gameEvent(GameEvent.BLOCK_DEACTIVATE, pos, GameEvent.Context.of(movingPistonState)); } @@ -24,7 +24,7 @@ return true; } -@@ -287,8 +_,7 @@ +@@ -289,8 +_,7 @@ level.levelEvent(2001, pos, getId(state)); } @@ -34,7 +34,7 @@ toUpdate[updateIndex++] = state; } -@@ -358,6 +_,10 @@ +@@ -360,6 +_,10 @@ @Override protected BlockState rotate(BlockState state, Rotation rotation) { return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); 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 98f5dc4fed9..0819d4e6262 100644 --- a/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch +++ b/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -176,7 +_,7 @@ +@@ -175,7 +_,7 @@ if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK) { Block block = state.getBlock(); boolean doDropExperienceHack = explosion.getIndirectSourceEntity() instanceof Player; @@ -9,7 +9,7 @@ BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(pos) : null; LootParams.Builder params = new LootParams.Builder(level) .withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos)) -@@ -191,8 +_,7 @@ +@@ -190,8 +_,7 @@ state.getDrops(params).forEach(stack -> onHit.accept(stack, pos)); } @@ -19,7 +19,7 @@ } } -@@ -345,8 +_,8 @@ +@@ -344,8 +_,8 @@ if (destroySpeed == -1.0F) { return 0.0F; } else { @@ -30,7 +30,7 @@ } } -@@ -386,10 +_,13 @@ +@@ -385,10 +_,13 @@ return this.isRandomlyTicking; } @@ -44,7 +44,7 @@ protected ItemStack getCloneItemStack(LevelReader level, BlockPos pos, BlockState state, boolean includeData) { return new ItemStack(this.asItem()); } -@@ -406,6 +_,10 @@ +@@ -405,6 +_,10 @@ return this.properties.destroyTime; } @@ -52,10 +52,10 @@ + return ((BlockStateBase)state).isAir; + } + - public abstract static class BlockStateBase extends StateHolder { + public abstract static class BlockStateBase extends StateHolder implements TypedInstance { private static final Direction[] DIRECTIONS = Direction.values(); private static final VoxelShape[] EMPTY_OCCLUSION_SHAPES = Util.make(new VoxelShape[DIRECTIONS.length], s -> Arrays.fill(s, Shapes.empty())); -@@ -501,7 +_,12 @@ +@@ -500,7 +_,12 @@ this.occlusionShapesByFace = new VoxelShape[DIRECTIONS.length]; for (Direction direction : DIRECTIONS) { @@ -121,7 +121,7 @@ return this.getBlock().useItemOn(itemStack, this.asState(), level, hitResult.getBlockPos(), player, hand, hitResult); } -@@ -867,6 +_,7 @@ +@@ -843,6 +_,7 @@ return this.getBlock().getSeed(this.asState(), pos); } @@ -129,7 +129,7 @@ public SoundType getSoundType() { return this.getBlock().getSoundType(this.asState()); } -@@ -995,7 +_,7 @@ +@@ -971,7 +_,7 @@ private BlockBehaviour.StateArgumentPredicate> isValidSpawn = (state, level, pos, entityType) -> state.isFaceSturdy( level, pos, Direction.UP ) diff --git a/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch b/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch index fa2084603ef..dff3cb52afb 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 -@@ -154,6 +_,7 @@ +@@ -155,6 +_,7 @@ this.setAllStarts(protoChunk.getAllStarts()); this.setAllReferences(protoChunk.getAllReferences()); @@ -8,8 +8,8 @@ for (Entry entry : protoChunk.getHeightmaps()) { if (ChunkStatus.FULL.heightmapsAfter().contains(entry.getKey())) { this.setHeightmap(entry.getKey(), entry.getValue().getRawData()); -@@ -290,7 +_,7 @@ - this.level.getChunkSource().onSectionEmptinessChanged(this.chunkPos.x, SectionPos.blockToSectionCoord(y), this.chunkPos.z, isEmpty); +@@ -291,7 +_,7 @@ + this.level.getChunkSource().onSectionEmptinessChanged(this.chunkPos.x(), SectionPos.blockToSectionCoord(y), this.chunkPos.z(), isEmpty); } - if (LightEngine.hasDifferentLightProperties(oldState, state)) { @@ -17,7 +17,7 @@ ProfilerFiller profiler = Profiler.get(); profiler.push("updateSkyLightSources"); this.skyLightSources.update(this, localX, y, localZ); -@@ -322,7 +_,7 @@ +@@ -323,7 +_,7 @@ if (!section.getBlockState(localX, localY, localZ).is(newBlock)) { return null; } else { @@ -26,7 +26,7 @@ state.onPlace(this.level, pos, oldState, movedByPiston); } -@@ -374,6 +_,10 @@ +@@ -370,6 +_,10 @@ public @Nullable BlockEntity getBlockEntity(BlockPos pos, LevelChunk.EntityCreationType creationType) { BlockEntity blockEntity = this.blockEntities.get(pos); @@ -37,7 +37,7 @@ if (blockEntity == null) { CompoundTag tag = this.pendingBlockEntities.remove(pos); if (tag != null) { -@@ -391,9 +_,6 @@ +@@ -387,9 +_,6 @@ this.addAndRegisterBlockEntity(blockEntity); } } @@ -47,7 +47,7 @@ } return blockEntity; -@@ -408,6 +_,7 @@ +@@ -404,6 +_,7 @@ this.level.onBlockEntityAdded(blockEntity); this.updateBlockEntityTicker(blockEntity); @@ -55,7 +55,7 @@ } } -@@ -451,6 +_,7 @@ +@@ -447,6 +_,7 @@ BlockEntity previousEntry = this.blockEntities.put(pos.immutable(), blockEntity); if (previousEntry != null && previousEntry != blockEntity) { previousEntry.setRemoved(); @@ -63,7 +63,7 @@ } } } -@@ -459,9 +_,14 @@ +@@ -455,9 +_,14 @@ public @Nullable CompoundTag getBlockEntityNbtForSaving(BlockPos blockPos, HolderLookup.Provider registryAccess) { BlockEntity blockEntity = this.getBlockEntity(blockPos); if (blockEntity != null && !blockEntity.isRemoved()) { @@ -78,7 +78,7 @@ } else { CompoundTag result = this.pendingBlockEntities.get(blockPos); if (result != null) { -@@ -484,6 +_,7 @@ +@@ -480,6 +_,7 @@ } removeThis.setRemoved(); @@ -86,7 +86,7 @@ } } -@@ -540,7 +_,7 @@ +@@ -536,7 +_,7 @@ blockEntities.accept((pos, type, tag) -> { BlockEntity blockEntity = this.getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE); if (blockEntity != null && tag != null && blockEntity.getType() == type) { @@ -95,7 +95,7 @@ } }); } -@@ -677,6 +_,7 @@ +@@ -673,6 +_,7 @@ } public void clearAllBlockEntities() { @@ -103,7 +103,7 @@ this.blockEntities.values().forEach(BlockEntity::setRemoved); this.blockEntities.clear(); this.tickersInLevel.values().forEach(ticker -> ticker.rebind(NULL_TICKER)); -@@ -684,6 +_,7 @@ +@@ -680,6 +_,7 @@ } public void registerAllBlockEntitiesAfterLevelLoad() { @@ -111,7 +111,7 @@ this.blockEntities.values().forEach(blockEntity -> { if (this.level instanceof ServerLevel serverLevel) { this.addGameEventListener(blockEntity, serverLevel); -@@ -730,6 +_,19 @@ +@@ -726,6 +_,19 @@ return new LevelChunk.BoundTickingBlockEntity<>(blockEntity, ticker); } @@ -131,7 +131,7 @@ private class BoundTickingBlockEntity implements TickingBlockEntity { private final T blockEntity; private final BlockEntityTicker ticker; -@@ -747,6 +_,7 @@ +@@ -745,6 +_,7 @@ if (LevelChunk.this.isTicking(pos)) { try { ProfilerFiller profiler = Profiler.get(); @@ -139,7 +139,7 @@ profiler.push(this::getType); BlockState blockState = LevelChunk.this.getBlockState(pos); if (this.blockEntity.getType().isValid(blockState)) { -@@ -768,7 +_,14 @@ +@@ -766,7 +_,14 @@ CrashReport report = CrashReport.forThrowable(var5, "Ticking block entity"); CrashReportCategory category = report.addCategory("Block entity being ticked"); this.blockEntity.fillCrashReportCategory(category); diff --git a/patches/net/minecraft/world/level/chunk/LevelChunkSection.java.patch b/patches/net/minecraft/world/level/chunk/LevelChunkSection.java.patch index 68a3d42b998..88c21640b33 100644 --- a/patches/net/minecraft/world/level/chunk/LevelChunkSection.java.patch +++ b/patches/net/minecraft/world/level/chunk/LevelChunkSection.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -69,7 +_,7 @@ +@@ -70,7 +_,7 @@ FluidState previousFluid = previous.getFluidState(); FluidState fluid = state.getFluidState(); - if (!previous.isAir()) { -+ if (!previousFluid.isEmpty()) { // Neo: Fix MC-232360 for modded blocks (Makes modded isAir blocks not be replaced with Blocks.AIR in all-air chunk sections) ++ if (!previous.isEmpty()) { // Neo: Fix MC-232360 for modded blocks (Makes modded isAir blocks not be replaced with Blocks.AIR in all-air chunk sections) this.nonEmptyBlockCount--; if (previous.isRandomlyTicking()) { this.tickingBlockCount--; -@@ -80,7 +_,7 @@ +@@ -81,7 +_,7 @@ this.tickingFluidCount--; } @@ -18,7 +18,7 @@ this.nonEmptyBlockCount++; if (state.isRandomlyTicking()) { this.tickingBlockCount++; -@@ -118,7 +_,7 @@ +@@ -124,7 +_,7 @@ public void accept(BlockState state, int count) { FluidState fluid = state.getFluidState(); 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 b526539c8a7..e6a11ae88ed 100644 --- a/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch +++ b/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch @@ -13,7 +13,7 @@ + for (int y = this.levelHeightAccessor.getMinSectionY(); y <= this.levelHeightAccessor.getMaxSectionY(); y++) { + this.storage.remove(getKey(chunkPos, y)); + } -+ this.loadedChunks.remove(chunkPos.toLong()); ++ this.loadedChunks.remove(chunkPos.pack()); + } + } + diff --git a/patches/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch b/patches/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch index 2b15cd3f78a..f8ce524e675 100644 --- a/patches/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch +++ b/patches/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +++ b/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -@@ -71,7 +_,16 @@ +@@ -72,7 +_,16 @@ return this.addEntity(entity, false); } @@ -17,7 +17,7 @@ if (!this.addEntityUuid(entity)) { return false; } else { -@@ -105,11 +_,17 @@ +@@ -106,11 +_,17 @@ } public void addLegacyChunkEntities(Stream entities) { @@ -37,7 +37,7 @@ } private void startTicking(T entity) { -@@ -232,7 +_,10 @@ +@@ -233,7 +_,10 @@ public void processPendingLoads() { ChunkEntities loadedChunk; while ((loadedChunk = this.loadingInbox.poll()) != null) { @@ -46,10 +46,10 @@ + this.addEntity(e, true); + if (e instanceof Entity entity) entity.onAddedToLevel(); + }); - this.chunkLoadStatuses.put(loadedChunk.getPos().toLong(), PersistentEntitySectionManager.ChunkLoadStatus.LOADED); + this.chunkLoadStatuses.put(loadedChunk.getPos().pack(), PersistentEntitySectionManager.ChunkLoadStatus.LOADED); } } -@@ -369,11 +_,13 @@ +@@ -370,6 +_,7 @@ private class Callback implements EntityInLevelCallback { private final T entity; @@ -57,13 +57,15 @@ private long currentSectionKey; private EntitySection currentSection; - private Callback(T entity, long currentSectionKey, EntitySection currentSection) { +@@ -377,6 +_,7 @@ + Objects.requireNonNull(PersistentEntitySectionManager.this); + super(); this.entity = entity; + this.realEntity = entity instanceof Entity ? (Entity) entity : null; this.currentSectionKey = currentSectionKey; this.currentSection = currentSection; } -@@ -392,9 +_,11 @@ +@@ -395,9 +_,11 @@ PersistentEntitySectionManager.this.removeSectionIfEmpty(this.currentSectionKey, this.currentSection); EntitySection newSection = PersistentEntitySectionManager.this.sectionStorage.getOrCreateSection(newSectionPos); newSection.add(this.entity); diff --git a/patches/net/minecraft/world/level/entity/TransientEntitySectionManager.java.patch b/patches/net/minecraft/world/level/entity/TransientEntitySectionManager.java.patch index d9a89e7be13..989a2396acf 100644 --- a/patches/net/minecraft/world/level/entity/TransientEntitySectionManager.java.patch +++ b/patches/net/minecraft/world/level/entity/TransientEntitySectionManager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/entity/TransientEntitySectionManager.java +++ b/net/minecraft/world/level/entity/TransientEntitySectionManager.java -@@ -82,11 +_,13 @@ +@@ -83,6 +_,7 @@ private class Callback implements EntityInLevelCallback { private final T entity; @@ -8,13 +8,15 @@ private long currentSectionKey; private EntitySection currentSection; - private Callback(T entity, long currentSectionKey, EntitySection currentSection) { +@@ -90,6 +_,7 @@ + Objects.requireNonNull(TransientEntitySectionManager.this); + super(); this.entity = entity; + this.realEntity = entity instanceof Entity ? (Entity) entity : null; this.currentSectionKey = currentSectionKey; this.currentSection = currentSection; } -@@ -105,6 +_,7 @@ +@@ -108,6 +_,7 @@ TransientEntitySectionManager.this.removeSectionIfEmpty(this.currentSectionKey, this.currentSection); EntitySection newSection = TransientEntitySectionManager.this.sectionStorage.getOrCreateSection(newSectionPos); newSection.add(this.entity); @@ -22,7 +24,7 @@ this.currentSection = newSection; this.currentSectionKey = newSectionPos; TransientEntitySectionManager.this.callbacks.onSectionChange(this.entity); -@@ -117,6 +_,7 @@ +@@ -120,6 +_,7 @@ TransientEntitySectionManager.this.callbacks.onTickingStart(this.entity); } } diff --git a/patches/net/minecraft/world/level/gamerules/GameRuleCategory.java.patch b/patches/net/minecraft/world/level/gamerules/GameRuleCategory.java.patch new file mode 100644 index 00000000000..7b599a085a3 --- /dev/null +++ b/patches/net/minecraft/world/level/gamerules/GameRuleCategory.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/level/gamerules/GameRuleCategory.java ++++ b/net/minecraft/world/level/gamerules/GameRuleCategory.java +@@ -25,6 +_,9 @@ + return register(Identifier.withDefaultNamespace(name)); + } + ++ /** ++ * @deprecated Prefer registering using {@link net.neoforged.neoforge.event.RegisterGameRuleCategoryEvent} ++ */ + public static GameRuleCategory register(Identifier id) { + GameRuleCategory category = new GameRuleCategory(id); + if (SORT_ORDER.contains(category)) { +@@ -37,5 +_,17 @@ + + public MutableComponent label() { + return Component.translatable(this.id.toLanguageKey("gamerule.category")); ++ } ++ ++ // Neo: Allow custom categories to be registered safely ++ @org.jetbrains.annotations.ApiStatus.Internal ++ public static void registerModdedCategories() { ++ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.event.RegisterGameRuleCategoryEvent(category -> { ++ if (SORT_ORDER.contains(category)) { ++ throw new IllegalArgumentException(String.format(Locale.ROOT, "Category '%s' is already registered.", category.id)); ++ } else { ++ SORT_ORDER.add(category); ++ } ++ })); + } + } diff --git a/patches/net/minecraft/world/level/gamerules/GameRuleType.java.patch b/patches/net/minecraft/world/level/gamerules/GameRuleType.java.patch new file mode 100644 index 00000000000..663d864fcab --- /dev/null +++ b/patches/net/minecraft/world/level/gamerules/GameRuleType.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/level/gamerules/GameRuleType.java ++++ b/net/minecraft/world/level/gamerules/GameRuleType.java +@@ -2,6 +_,7 @@ + + import net.minecraft.util.StringRepresentable; + ++@net.neoforged.fml.common.asm.enumextension.NamedEnum + public enum GameRuleType implements StringRepresentable, net.neoforged.fml.common.asm.enumextension.IExtensibleEnum { + INT("integer"), + BOOL("boolean"); +@@ -15,5 +_,9 @@ + @Override + public String getSerializedName() { + return this.name; ++ } ++ ++ public static net.neoforged.fml.common.asm.enumextension.ExtensionInfo getExtensionInfo() { ++ return net.neoforged.fml.common.asm.enumextension.ExtensionInfo.nonExtended(GameRuleType.class); + } + } diff --git a/patches/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch b/patches/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch index 74c79ddcc4b..e975ff1aac6 100644 --- a/patches/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch +++ b/patches/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch @@ -8,5 +8,5 @@ + throw new RuntimeException("StructureStart \"" + this.getClass().getName() + "\": \"" + this.getStructure() + "\" unregistered, serializing impossible."); + } tag.putString("id", context.registryAccess().lookupOrThrow(Registries.STRUCTURE).getKey(this.structure).toString()); - tag.putInt("ChunkX", chunkPos.x); - tag.putInt("ChunkZ", chunkPos.z); + tag.putInt("ChunkX", chunkPos.x()); + tag.putInt("ChunkZ", chunkPos.z()); diff --git a/patches/net/minecraft/world/level/lighting/BlockLightEngine.java.patch b/patches/net/minecraft/world/level/lighting/BlockLightEngine.java.patch index 95e71a734ac..ea5dd27dddf 100644 --- a/patches/net/minecraft/world/level/lighting/BlockLightEngine.java.patch +++ b/patches/net/minecraft/world/level/lighting/BlockLightEngine.java.patch @@ -10,7 +10,7 @@ } @@ -120,7 +_,7 @@ - LightChunk chunk = this.chunkSource.getChunkForLighting(pos.x, pos.z); + LightChunk chunk = this.chunkSource.getChunkForLighting(pos.x(), pos.z()); if (chunk != null) { chunk.findBlockLightSources((lightPos, state) -> { - int lightEmission = state.getLightEmission(); diff --git a/patches/net/minecraft/world/level/material/FlowingFluid.java.patch b/patches/net/minecraft/world/level/material/FlowingFluid.java.patch index d556da05082..4d75753c967 100644 --- a/patches/net/minecraft/world/level/material/FlowingFluid.java.patch +++ b/patches/net/minecraft/world/level/material/FlowingFluid.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/material/FlowingFluid.java +++ b/net/minecraft/world/level/material/FlowingFluid.java -@@ -168,7 +_,7 @@ +@@ -169,7 +_,7 @@ BlockState blockState = level.getBlockState(relativePos); FluidState fluidState = blockState.getFluidState(); if (fluidState.getType().isSame(this) && canPassThroughWall(direction, level, pos, state, relativePos, blockState)) { @@ -9,7 +9,16 @@ neighbourSources++; } -@@ -256,6 +_,15 @@ +@@ -177,7 +_,7 @@ + } + } + +- if (neighbourSources >= 2 && this.canConvertToSource(level)) { ++ if (neighbourSources >= 2) { + BlockState belowState = level.getBlockState(mutablePos.setWithOffset(pos, Direction.DOWN)); + FluidState belowFluid = belowState.getFluidState(); + if (belowState.isSolid() || this.isSourceBlockOfThisType(belowFluid)) { +@@ -257,6 +_,15 @@ return this.getSource().defaultFluidState().setValue(FALLING, falling); } diff --git a/patches/net/minecraft/world/level/material/FluidState.java.patch b/patches/net/minecraft/world/level/material/FluidState.java.patch index fbfa1fa7417..41b47c023c3 100644 --- a/patches/net/minecraft/world/level/material/FluidState.java.patch +++ b/patches/net/minecraft/world/level/material/FluidState.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/material/FluidState.java +++ b/net/minecraft/world/level/material/FluidState.java -@@ -116,6 +_,7 @@ - return this.getType() == fluid; +@@ -111,6 +_,7 @@ + return this.getType().builtInRegistryHolder(); } + @Deprecated //Forge: Use more sensitive version diff --git a/patches/net/minecraft/world/level/material/LavaFluid.java.patch b/patches/net/minecraft/world/level/material/LavaFluid.java.patch index 4fd391c6322..9dfb3f1f2b1 100644 --- a/patches/net/minecraft/world/level/material/LavaFluid.java.patch +++ b/patches/net/minecraft/world/level/material/LavaFluid.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/material/LavaFluid.java +++ b/net/minecraft/world/level/material/LavaFluid.java -@@ -92,7 +_,7 @@ +@@ -93,7 +_,7 @@ BlockState blockState = level.getBlockState(testPos); if (blockState.isAir()) { if (this.hasFlammableNeighbours(level, testPos)) { @@ -9,7 +9,7 @@ return; } } else if (blockState.blocksMotion()) { -@@ -106,8 +_,8 @@ +@@ -107,8 +_,8 @@ return; } @@ -20,7 +20,7 @@ } } } -@@ -123,7 +_,7 @@ +@@ -124,7 +_,7 @@ private boolean hasFlammableNeighbours(LevelReader level, BlockPos pos) { for (Direction direction : Direction.values()) { @@ -29,7 +29,7 @@ return true; } } -@@ -131,10 +_,20 @@ +@@ -132,10 +_,20 @@ return false; } @@ -50,7 +50,7 @@ @Override public @Nullable ParticleOptions getDripParticle() { return ParticleTypes.DRIPPING_LAVA; -@@ -205,7 +_,7 @@ +@@ -206,7 +_,7 @@ FluidState fluidState = level.getFluidState(pos); if (this.is(FluidTags.LAVA) && fluidState.is(FluidTags.WATER)) { if (state.getBlock() instanceof LiquidBlock) { diff --git a/patches/net/minecraft/world/level/storage/DerivedLevelData.java.patch b/patches/net/minecraft/world/level/storage/DerivedLevelData.java.patch index b4a537b0cab..3c5e4fc66a7 100644 --- a/patches/net/minecraft/world/level/storage/DerivedLevelData.java.patch +++ b/patches/net/minecraft/world/level/storage/DerivedLevelData.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/DerivedLevelData.java +++ b/net/minecraft/world/level/storage/DerivedLevelData.java -@@ -187,4 +_,26 @@ +@@ -188,4 +_,26 @@ category.setDetail("Derived", true); this.wrapped.fillCrashReportCategory(category, levelHeightAccessor); } diff --git a/patches/net/minecraft/world/level/storage/LevelStorageSource.java.patch b/patches/net/minecraft/world/level/storage/LevelStorageSource.java.patch index 09cf806605f..f5d38e5dd98 100644 --- a/patches/net/minecraft/world/level/storage/LevelStorageSource.java.patch +++ b/patches/net/minecraft/world/level/storage/LevelStorageSource.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/LevelStorageSource.java +++ b/net/minecraft/world/level/storage/LevelStorageSource.java -@@ -458,6 +_,19 @@ +@@ -461,6 +_,19 @@ } } @@ -20,7 +20,7 @@ public PlayerDataStorage createPlayerStorage() { this.checkLock(); return new PlayerDataStorage(this, LevelStorageSource.this.fixerUpper); -@@ -491,6 +_,7 @@ +@@ -494,6 +_,7 @@ CompoundTag dataTag = levelData.createTag(registryAccess, playerData); CompoundTag root = new CompoundTag(); root.put("Data", dataTag); @@ -28,7 +28,7 @@ this.saveLevelData(root); } -@@ -510,6 +_,10 @@ +@@ -513,6 +_,10 @@ public Optional getIconFile() { return !this.lock.isValid() ? Optional.empty() : Optional.of(this.levelDirectory.iconFile()); diff --git a/patches/net/minecraft/world/level/storage/PrimaryLevelData.java.patch b/patches/net/minecraft/world/level/storage/PrimaryLevelData.java.patch index 064ffd1112a..51cfd0ad4b6 100644 --- a/patches/net/minecraft/world/level/storage/PrimaryLevelData.java.patch +++ b/patches/net/minecraft/world/level/storage/PrimaryLevelData.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/PrimaryLevelData.java +++ b/net/minecraft/world/level/storage/PrimaryLevelData.java -@@ -70,6 +_,7 @@ +@@ -71,6 +_,7 @@ private boolean wasModded; private final Set removedFeatureFlags; private final TimerQueue scheduledEvents; @@ -8,7 +8,7 @@ private PrimaryLevelData( @Nullable CompoundTag loadedPlayerTag, -@@ -168,7 +_,7 @@ +@@ -169,7 +_,7 @@ Lifecycle worldGenSettingsLifecycle ) { long gameTime = input.get("Time").asLong(0L); @@ -17,7 +17,7 @@ input.get("Player").flatMap(CompoundTag.CODEC::parse).result().orElse(null), input.get("WasModded").asBoolean(false), input.get("spawn").read(LevelData.RespawnData.CODEC).result().orElse(LevelData.RespawnData.DEFAULT), -@@ -187,7 +_,8 @@ +@@ -191,7 +_,8 @@ input.get("WanderingTraderSpawnChance").asInt(0), input.get("WanderingTraderId").read(UUIDUtil.CODEC).result().orElse(null), input.get("ServerBrands").asStream().flatMap(b -> b.asString().result().stream()).collect(Collectors.toCollection(Sets::newLinkedHashSet)), @@ -27,7 +27,7 @@ new TimerQueue<>(TimerCallbacks.SERVER_CALLBACKS, input.get("ScheduledEvents").asStream()), (CompoundTag)input.get("CustomBossEvents").orElseEmptyMap().getValue(), input.get("DragonFight").read(EndDragonFight.Data.CODEC).resultOrPartial(LOGGER::error).orElse(EndDragonFight.Data.DEFAULT), -@@ -195,7 +_,11 @@ +@@ -199,7 +_,11 @@ worldOptions, specialWorldProperty, worldGenSettingsLifecycle @@ -40,7 +40,7 @@ } @Override -@@ -260,6 +_,12 @@ +@@ -264,6 +_,12 @@ tag.putInt("WanderingTraderSpawnDelay", this.wanderingTraderSpawnDelay); tag.putInt("WanderingTraderSpawnChance", this.wanderingTraderSpawnChance); tag.storeNullable("WanderingTraderId", UUIDUtil.CODEC, this.wanderingTraderId); @@ -53,7 +53,7 @@ } private static ListTag stringCollectionToTag(Set values) { -@@ -550,10 +_,58 @@ +@@ -554,10 +_,58 @@ return this.settings.copy(); } diff --git a/patches/net/minecraft/world/level/storage/ServerLevelData.java.patch b/patches/net/minecraft/world/level/storage/ServerLevelData.java.patch index e25451309f3..ab42323ad1e 100644 --- a/patches/net/minecraft/world/level/storage/ServerLevelData.java.patch +++ b/patches/net/minecraft/world/level/storage/ServerLevelData.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/storage/ServerLevelData.java +++ b/net/minecraft/world/level/storage/ServerLevelData.java -@@ -92,4 +_,10 @@ - void setDayTime(final long time); +@@ -95,4 +_,10 @@ + PackedClockStates clockStates(); GameRules getGameRules(); + diff --git a/patches/net/minecraft/world/level/storage/loot/LootDataType.java.patch b/patches/net/minecraft/world/level/storage/loot/LootDataType.java.patch index ebbaad23dd5..a0ca2c31ed1 100644 --- a/patches/net/minecraft/world/level/storage/loot/LootDataType.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/LootDataType.java.patch @@ -1,31 +1,31 @@ --- a/net/minecraft/world/level/storage/loot/LootDataType.java +++ b/net/minecraft/world/level/storage/loot/LootDataType.java -@@ -10,14 +_,26 @@ - import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +@@ -13,14 +_,26 @@ + import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; --public record LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator) { -+public record LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator, @org.jspecify.annotations.Nullable T defaultValue, Codec> conditionalCodec, java.util.function.BiConsumer idSetter) { +-public record LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.ContextGetter contextGetter) { ++public record LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.ContextGetter contextGetter, @org.jspecify.annotations.Nullable T defaultValue, Codec> conditionalCodec, java.util.function.BiConsumer idSetter) { public static final LootDataType PREDICATE = new LootDataType<>( - Registries.PREDICATE, LootItemCondition.DIRECT_CODEC, createSimpleValidator() + Registries.PREDICATE, LootItemCondition.DIRECT_CODEC, LootDataType.ContextGetter.constant(LootContextParamSets.ALL_PARAMS) ); public static final LootDataType MODIFIER = new LootDataType<>( - Registries.ITEM_MODIFIER, LootItemFunctions.ROOT_CODEC, createSimpleValidator() + Registries.ITEM_MODIFIER, LootItemFunctions.ROOT_CODEC, LootDataType.ContextGetter.constant(LootContextParamSets.ALL_PARAMS) ); -- public static final LootDataType TABLE = new LootDataType<>(Registries.LOOT_TABLE, LootTable.DIRECT_CODEC, createLootTableValidator()); -+ public static final LootDataType TABLE = new LootDataType<>(Registries.LOOT_TABLE, LootTable.DIRECT_CODEC, createLootTableValidator(), LootTable.EMPTY, LootTable::setLootTableId); +- public static final LootDataType TABLE = new LootDataType<>(Registries.LOOT_TABLE, LootTable.DIRECT_CODEC, LootTable::getParamSet); ++ public static final LootDataType TABLE = new LootDataType<>(Registries.LOOT_TABLE, LootTable.DIRECT_CODEC, LootTable::getParamSet, LootTable.EMPTY, LootTable::setLootTableId); + + /** -+ * @deprecated Neo: use the constructor {@link #LootDataType(ResourceKey, Codec, Validator, T, java.util.function.BiConsumer) with a default value and id setter} to support conditions ++ * @deprecated Neo: use the constructor {@link #LootDataType(ResourceKey, Codec, LootDataType.ContextGetter, T, java.util.function.BiConsumer) with a default value and id setter} to support conditions + */ + @Deprecated -+ private LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator) { -+ this(registryKey, codec, validator, null, (it, id) -> {}); ++ private LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.ContextGetter contextGetter) { ++ this(registryKey, codec, contextGetter, null, (it, id) -> {}); + } + -+ private LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator, @org.jspecify.annotations.Nullable T defaultValue, java.util.function.BiConsumer idSetter) { -+ this(registryKey, codec, validator, defaultValue, net.neoforged.neoforge.common.conditions.ConditionalOps.createConditionalCodec(codec), idSetter); ++ private LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.ContextGetter contextGetter, @org.jspecify.annotations.Nullable T defaultValue, java.util.function.BiConsumer idSetter) { ++ this(registryKey, codec, contextGetter, defaultValue, net.neoforged.neoforge.common.conditions.ConditionalOps.createConditionalCodec(codec), idSetter); + } - public void runValidation(ValidationContext rootContext, ResourceKey key, T value) { - this.validator.run(rootContext, key, value); + public void runValidation(ValidationContextSource contextSource, ResourceKey key, T value) { + ContextKeySet contextKeys = this.contextGetter.context(value); diff --git a/patches/net/minecraft/world/level/storage/loot/LootPool.java.patch b/patches/net/minecraft/world/level/storage/loot/LootPool.java.patch index 82a416f44c2..09a9833903d 100644 --- a/patches/net/minecraft/world/level/storage/loot/LootPool.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/LootPool.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/loot/LootPool.java +++ b/net/minecraft/world/level/storage/loot/LootPool.java -@@ -33,7 +_,8 @@ +@@ -32,7 +_,8 @@ LootItemCondition.DIRECT_CODEC.listOf().optionalFieldOf("conditions", List.of()).forGetter(p -> p.conditions), LootItemFunctions.ROOT_CODEC.listOf().optionalFieldOf("functions", List.of()).forGetter(p -> p.functions), NumberProviders.CODEC.fieldOf("rolls").forGetter(p -> p.rolls), @@ -10,7 +10,7 @@ ) .apply(i, LootPool::new) ); -@@ -50,7 +_,8 @@ +@@ -49,7 +_,8 @@ List conditions, List functions, NumberProvider rolls, @@ -20,7 +20,7 @@ ) { this.entries = entries; this.conditions = conditions; -@@ -59,6 +_,7 @@ +@@ -58,6 +_,7 @@ this.compositeFunction = LootItemFunctions.compose(functions); this.rolls = rolls; this.bonusRolls = bonusRolls; @@ -28,8 +28,8 @@ } private void addRandomItem(Consumer result, LootContext context) { -@@ -122,6 +_,57 @@ - this.bonusRolls.validate(output.forChild(new ProblemReporter.FieldPathElement("bonus_rolls"))); +@@ -113,6 +_,57 @@ + Validatable.validate(output, "bonus_rolls", this.bonusRolls); } + // Neo: Implement LootPool freezing to prevent manipulation outside of Neo APIs @@ -86,7 +86,7 @@ public static LootPool.Builder lootPool() { return new LootPool.Builder(); } -@@ -132,6 +_,8 @@ +@@ -123,6 +_,8 @@ private final ImmutableList.Builder functions = ImmutableList.builder(); private NumberProvider rolls = ConstantValue.exactly(1.0F); private NumberProvider bonusRolls = ConstantValue.exactly(0.0F); @@ -95,7 +95,7 @@ public LootPool.Builder setRolls(NumberProvider rolls) { this.rolls = rolls; -@@ -162,8 +_,13 @@ +@@ -153,8 +_,13 @@ return this; } diff --git a/patches/net/minecraft/world/level/storage/loot/LootTable.java.patch b/patches/net/minecraft/world/level/storage/loot/LootTable.java.patch index 39e653eb37b..69521f5e872 100644 --- a/patches/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/loot/LootTable.java +++ b/net/minecraft/world/level/storage/loot/LootTable.java -@@ -40,12 +_,14 @@ +@@ -39,12 +_,14 @@ i -> i.group( LootContextParamSets.CODEC.lenientOptionalFieldOf("type", DEFAULT_PARAM_SET).forGetter(t -> t.paramSet), Identifier.CODEC.optionalFieldOf("random_sequence").forGetter(t -> t.randomSequence), @@ -17,7 +17,7 @@ public static final Codec> CODEC = RegistryFileCodec.create(Registries.LOOT_TABLE, DIRECT_CODEC); public static final LootTable EMPTY = new LootTable(LootContextParamSets.EMPTY, Optional.empty(), List.of(), List.of()); private final ContextKeySet paramSet; -@@ -57,7 +_,7 @@ +@@ -56,7 +_,7 @@ private LootTable(ContextKeySet paramSet, Optional randomSequence, List pools, List functions) { this.paramSet = paramSet; this.randomSequence = randomSequence; @@ -26,7 +26,7 @@ this.functions = functions; this.compositeFunction = LootItemFunctions.compose(functions); } -@@ -80,10 +_,12 @@ +@@ -79,10 +_,12 @@ }; } @@ -39,7 +39,7 @@ public void getRandomItemsRaw(LootContext context, Consumer output) { LootContext.VisitedEntry breadcrumb = LootContext.createVisitedEntry(this); if (context.pushVisitedElement(breadcrumb)) { -@@ -100,18 +_,15 @@ +@@ -99,18 +_,15 @@ } public void getRandomItems(LootParams params, long optionalLootTableSeed, Consumer output) { @@ -61,7 +61,7 @@ } public ObjectArrayList getRandomItems(LootParams params, RandomSource randomSource) { -@@ -128,7 +_,8 @@ +@@ -127,7 +_,8 @@ private ObjectArrayList getRandomItems(LootContext context) { ObjectArrayList result = new ObjectArrayList<>(); @@ -71,7 +71,7 @@ return result; } -@@ -219,11 +_,68 @@ +@@ -214,11 +_,68 @@ return new LootTable.Builder(); } @@ -140,7 +140,7 @@ public LootTable.Builder withPool(LootPool.Builder pool) { this.pools.add(pool.build()); -@@ -251,6 +_,20 @@ +@@ -246,6 +_,20 @@ public LootTable build() { return new LootTable(this.paramSet, this.randomSequence, this.pools.build(), this.functions.build()); diff --git a/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch b/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch index 9077387a91b..30402786b37 100644 --- a/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java +++ b/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java -@@ -58,7 +_,7 @@ +@@ -72,7 +_,7 @@ Stream> compatibleEnchantmentsStream = this.options .map(HolderSet::stream) .orElseGet(() -> context.getLevel().registryAccess().lookupOrThrow(Registries.ENCHANTMENT).listElements().map(Function.identity())) diff --git a/patches/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java.patch b/patches/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java.patch index 65dfa5930b3..d6782054797 100644 --- a/patches/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java.patch @@ -2,7 +2,7 @@ +++ b/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java @@ -37,7 +_,7 @@ if (recipe.isPresent()) { - ItemStack result = recipe.get().value().assemble(input, context.getLevel().registryAccess()); + ItemStack result = recipe.get().value().assemble(input); if (!result.isEmpty()) { - return result.copyWithCount(itemStack.getCount()); + return result.copyWithCount(itemStack.getCount() * result.getCount()); // Forge: Support smelting returning multiple diff --git a/patches/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch b/patches/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch index 8e732edbdfb..bded35364da 100644 --- a/patches/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch @@ -9,12 +9,12 @@ public static final ContextKeySet COMMAND = register( "command", builder -> builder.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY) ); -@@ -27,7 +_,7 @@ - "selector", builder -> builder.required(LootContextParams.ORIGIN).required(LootContextParams.THIS_ENTITY) +@@ -33,7 +_,7 @@ + .required(LootContextParams.ADDITIONAL_COST_COMPONENT_ALLOWED) ); public static final ContextKeySet FISHING = register( - "fishing", builder -> builder.required(LootContextParams.ORIGIN).required(LootContextParams.TOOL).optional(LootContextParams.THIS_ENTITY) -+ "fishing", p_81446_ -> p_81446_.required(LootContextParams.ORIGIN).required(LootContextParams.TOOL).optional(LootContextParams.THIS_ENTITY).optional(LootContextParams.ATTACKING_ENTITY) //Forge: Add the fisher as a killer. ++ "fishing", builder -> builder.required(LootContextParams.ORIGIN).required(LootContextParams.TOOL).optional(LootContextParams.THIS_ENTITY).optional(LootContextParams.ATTACKING_ENTITY) // Neo: Add the fisher as a killer. ); public static final ContextKeySet ENTITY = register( "entity", diff --git a/projects/neoforge/build.gradle b/projects/neoforge/build.gradle index dff1ae57891..542a26dd77b 100644 --- a/projects/neoforge/build.gradle +++ b/projects/neoforge/build.gradle @@ -20,11 +20,6 @@ evaluationDependsOn(":neoforge-coremods") gradleutils.setupSigning(project: project, signAllPublications: true) -changelog { - from '21.6' - disableAutomaticPublicationRegistration() -} - sourceSets { main { java { @@ -104,7 +99,7 @@ dependencies { } endorseStrictVersions() } - minecraftDependencies("net.neoforged:minecraft-dependencies:${project.minecraft_dependencies_version}") + minecraftDependencies("net.neoforged:minecraft-dependencies:${project.minecraft_version}") for (var asmModule : ["org.ow2.asm:asm", "org.ow2.asm:asm-commons", "org.ow2.asm:asm-tree", "org.ow2.asm:asm-util", "org.ow2.asm:asm-analysis"]) { libraries(asmModule) { @@ -255,17 +250,6 @@ generateAccessTransformers { fieldsOfType(named('net/minecraft/resources/ResourceKey')) ) - // Make all villager item listings classes and constructors public for use in custom trades - classGroup( - 'villager item listings', PUBLIC, - classesWithSuperclass('net/minecraft/world/entity/npc/villager/VillagerTrades$ItemListing') - ) - methodGroup( - 'villager item listing constructors', PUBLIC, - classesWithSuperclass('net/minecraft/world/entity/npc/villager/VillagerTrades$ItemListing'), - named('') - ) - // Make all DebugScreenEntry groups public fieldGroup( 'DebugScreenEntry groups', PUBLIC, @@ -417,18 +401,6 @@ configurations { // Publish it javaComponent.addVariantsFromConfiguration(it) {} } - changelog { - canBeDeclared = false - canBeResolved = false - attributes { - attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.DOCUMENTATION)) - attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType, "changelog")) - } - // Publish it, but only for release versions - if (!rootProject.isPreReleaseVersion) { - javaComponent.addVariantsFromConfiguration(it) {} - } - } modDevApiElements { canBeDeclared = false canBeResolved = false @@ -493,18 +465,6 @@ javadoc { source += sourceSets.client.allSource } -processResources { - inputs.property("version", project.version) - final version = project.version - filesMatching("META-INF/neoforge.mods.toml") { - expand([ - "global": [ - "neoForgeVersion": version - ] - ]) - } -} - artifacts { modDevBundle(userdevJar) { setClassifier("userdev") // Legacy @@ -518,11 +478,6 @@ artifacts { installerJar(installerJar) { setClassifier("installer") } - changelog(createChangelog.outputFile) { - builtBy(createChangelog) - setClassifier("changelog") - setExtension("txt") - } } publishing { @@ -551,6 +506,13 @@ publishing { url = 'https://github.com/NeoForged/NeoForge' connection = 'scm:git:git://github.com/NeoForged/NeoForge.git' developerConnection = 'scm:git:git@github.com:NeoForged/NeoForge.git' + // Set tag in pom.xml to allow tracing back to the source-code for this release + tag = (providers.environmentVariable("GITHUB_REF").map { ref -> + if (ref.startsWith("refs/tags/")) { + return ref.substring("refs/tags/".length()) + } + return null + }).orElse(providers.environmentVariable("GITHUB_SHA")) } issueManagement { diff --git a/rejects_26.1-snapshot-3/net/minecraft/client/multiplayer/ClientLevel.java.patch b/rejects_26.1-snapshot-3/net/minecraft/client/multiplayer/ClientLevel.java.patch new file mode 100644 index 00000000000..e79c2c44905 --- /dev/null +++ b/rejects_26.1-snapshot-3/net/minecraft/client/multiplayer/ClientLevel.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/client/multiplayer/ClientLevel.java ++++ b/net/minecraft/client/multiplayer/ClientLevel.java +@@ -320,7 +328,7 @@ + private void tickTime() { + this.clientLevelData.setGameTime(this.clientLevelData.getGameTime() + 1L); + if (this.tickDayTime) { +- this.clientLevelData.setDayTime(this.clientLevelData.getDayTime() + 1L); ++ this.clientLevelData.setDayTime(this.clientLevelData.getDayTime() + advanceDaytime()); + } + } + diff --git a/rejects_26.1-snapshot-3/net/minecraft/server/MinecraftServer.java.patch b/rejects_26.1-snapshot-3/net/minecraft/server/MinecraftServer.java.patch new file mode 100644 index 00000000000..2ac6cd6987f --- /dev/null +++ b/rejects_26.1-snapshot-3/net/minecraft/server/MinecraftServer.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -1193,10 +1222,17 @@ + } + + private void synchronizeTime(ServerLevel level) { +- this.playerList +- .broadcastAll( +- new ClientboundSetTimePacket(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME)), level.dimension() +- ); ++ ClientboundSetTimePacket vanillaPacket = new ClientboundSetTimePacket(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME)); ++ net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload neoPacket = new net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME), level.getDayTimeFraction(), level.getDayTimePerTick()); ++ for (ServerPlayer serverplayer : playerList.getPlayers()) { ++ if (serverplayer.level().dimension() == level.dimension()) { ++ if (serverplayer.connection.hasChannel(net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload.TYPE)) { ++ serverplayer.connection.send(neoPacket); ++ } else { ++ serverplayer.connection.send(vanillaPacket); ++ } ++ } ++ } + } + + public void forceTimeSynchronization() { diff --git a/rejects_26.1-snapshot-3/net/minecraft/server/level/ServerLevel.java.patch b/rejects_26.1-snapshot-3/net/minecraft/server/level/ServerLevel.java.patch new file mode 100644 index 00000000000..a9d7d90c2f7 --- /dev/null +++ b/rejects_26.1-snapshot-3/net/minecraft/server/level/ServerLevel.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -350,7 +354,7 @@ + if (this.sleepStatus.areEnoughSleeping(percentage) && this.sleepStatus.areEnoughDeepSleeping(percentage, this.players)) { + if (this.getGameRules().get(GameRules.ADVANCE_TIME)) { + long newTime = this.levelData.getDayTime() + 24000L; +- this.setDayTime(newTime - newTime % 24000L); ++ this.setDayTime(net.neoforged.neoforge.event.EventHooks.onSleepFinished(this, newTime - newTime % 24000L, this.getDayTime())); + } + + this.wakeUpAllPlayers(); +@@ -466,7 +472,7 @@ + this.serverLevelData.getScheduledEvents().tick(this.server, time); + Profiler.get().pop(); + if (this.getGameRules().get(GameRules.ADVANCE_TIME)) { +- this.setDayTime(this.levelData.getDayTime() + 1L); ++ this.setDayTime(this.levelData.getDayTime() + advanceDaytime()); + } + } + } diff --git a/rejects_26.1-snapshot-3/net/minecraft/server/players/PlayerList.java.patch b/rejects_26.1-snapshot-3/net/minecraft/server/players/PlayerList.java.patch new file mode 100644 index 00000000000..fc5bae9c715 --- /dev/null +++ b/rejects_26.1-snapshot-3/net/minecraft/server/players/PlayerList.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/server/players/PlayerList.java ++++ b/net/minecraft/server/players/PlayerList.java +@@ -641,7 +660,11 @@ + public void sendLevelInfo(ServerPlayer player, ServerLevel level) { + WorldBorder worldBorder = level.getWorldBorder(); + player.connection.send(new ClientboundInitializeBorderPacket(worldBorder)); ++ if (player.connection.hasChannel(net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload.TYPE)) { ++ player.connection.send(new net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME), level.getDayTimeFraction(), level.getDayTimePerTick())); ++ } else { + player.connection.send(new ClientboundSetTimePacket(level.getGameTime(), level.getDayTime(), level.getGameRules().get(GameRules.ADVANCE_TIME))); ++ } + player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getRespawnData())); + if (level.isRaining()) { + player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0.0F)); diff --git a/rejects_26.1-snapshot-3/net/minecraft/world/level/block/VegetationBlock.java.patch b/rejects_26.1-snapshot-3/net/minecraft/world/level/block/VegetationBlock.java.patch new file mode 100644 index 00000000000..d66e713338f --- /dev/null +++ b/rejects_26.1-snapshot-3/net/minecraft/world/level/block/VegetationBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/VegetationBlock.java ++++ b/net/minecraft/world/level/block/VegetationBlock.java +@@ -21,7 +21,7 @@ + protected abstract MapCodec codec(); + + protected boolean mayPlaceOn(BlockState state, BlockGetter level, BlockPos pos) { +- return state.is(BlockTags.DIRT) || state.is(Blocks.FARMLAND); ++ return state.is(BlockTags.DIRT) || state.getBlock() instanceof net.minecraft.world.level.block.FarmBlock; + } + + @Override diff --git a/settings.gradle b/settings.gradle index ecd40597e0e..9819940cfa4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,13 +8,12 @@ pluginManagement { plugins { id 'net.neoforged.moddev.repositories' version "${moddevgradle_plugin_version}" - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' } // This makes the version available to buildSrc gradle.ext.moddevgradle_plugin_version = moddevgradle_plugin_version gradle.ext.minecraft_version = minecraft_version -gradle.ext.minecraft_dependencies_version = minecraft_dependencies_version gradle.ext.diffpatch_version = diffpatch_version gradle.ext.asm_version = asm_version diff --git a/src/client/java/net/neoforged/neoforge/client/ClientHooks.java b/src/client/java/net/neoforged/neoforge/client/ClientHooks.java index 40970cb4998..dc9c49a1c47 100644 --- a/src/client/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/client/java/net/neoforged/neoforge/client/ClientHooks.java @@ -14,6 +14,7 @@ import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.resource.RenderTargetDescriptor; +import com.mojang.blaze3d.shaders.GpuDebugOptions; import com.mojang.blaze3d.shaders.ShaderSource; import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.RenderSystem; @@ -127,7 +128,6 @@ import net.minecraft.server.packs.resources.ReloadableResourceManager; import net.minecraft.sounds.Music; import net.minecraft.util.ARGB; -import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.InteractionHand; @@ -197,6 +197,7 @@ import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; import net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions; +import net.neoforged.neoforge.client.gamerules.GameRuleEntryFactoryManager; import net.neoforged.neoforge.client.gui.ClientTooltipComponentManager; import net.neoforged.neoforge.client.gui.PictureInPictureRendererRegistration; import net.neoforged.neoforge.client.gui.map.MapDecorationRendererManager; @@ -472,6 +473,11 @@ public static Material getBlockMaterial(Identifier loc) { return new Material(TextureAtlas.LOCATION_BLOCKS, loc); } + @SuppressWarnings("deprecation") + public static Material getItemMaterial(Identifier loc) { + return new Material(TextureAtlas.LOCATION_ITEMS, loc); + } + public static boolean loadEntityShader(@Nullable Entity entity, GameRenderer gameRenderer) { if (entity != null) { Identifier shader = EntitySpectatorShaderManager.get(entity.getType()); @@ -734,7 +740,7 @@ public static List gatherTooltipComponents(ItemStack sta List> elements = textElements.stream() .map((Function>) Either::left) .collect(Collectors.toCollection(ArrayList::new)); - itemComponent.ifPresent(c -> elements.add(1, Either.right(c))); + itemComponent.ifPresent(c -> elements.add(elements.isEmpty() ? 0 : 1, Either.right(c))); return gatherTooltipComponentsFromElements(stack, elements, mouseX, screenWidth, screenHeight, fallbackFont); } @@ -815,12 +821,6 @@ public static boolean renderBlockOverlay(Player player, PoseStack poseStack, Ren return NeoForge.EVENT_BUS.post(new RenderBlockScreenEffectEvent(player, poseStack, type, block, pos, materials, bufferSource)).isCanceled(); } - public static int getMaxMipmapLevel(int width, int height) { - return Math.min( - Mth.log2(Math.max(1, width)), - Mth.log2(Math.max(1, height))); - } - public static List gatherAdditionalRenderers( BlockPos sectionOrigin, Level level) { final var event = new AddSectionGeometryEvent(sectionOrigin, level); @@ -879,6 +879,7 @@ public static void initClientHooks(Minecraft mc, ReloadableResourceManager resou DimensionTransitionScreenManager.init(); RenderPipelines.registerCustomPipelines(); PipelineModifiers.init(); + GameRuleEntryFactoryManager.register(); } // Runs during Minecraft construction, before initial resource loading and during datagen startup @@ -965,7 +966,7 @@ public static boolean isInTranslucentBlockOutlinePass(Level level, BlockPos pos, model.collectParts(level, pos, state, OUTLINE_PASS_RANDOM, OUTLINE_PART_SCRATCH_LIST); for (BlockModelPart part : OUTLINE_PART_SCRATCH_LIST) { ChunkSectionLayer renderType = part.getRenderType(state); - if (renderType == ChunkSectionLayer.TRANSLUCENT || renderType == ChunkSectionLayer.TRIPWIRE) { + if (renderType == ChunkSectionLayer.TRANSLUCENT) { return true; } } @@ -1025,8 +1026,8 @@ public static List> gatherPictureInPictu return List.copyOf(vanillaRenderers); } - public static GpuDevice createGpuDevice(long window, int debugLevel, boolean syncDebug, ShaderSource defaultShaderSource, boolean enableDebugLabels) { - final var glDevice = new GlDevice(window, debugLevel, syncDebug, defaultShaderSource, enableDebugLabels); + public static GpuDevice createGpuDevice(long window, ShaderSource defaultShaderSource, GpuDebugOptions debugOptions) { + final var glDevice = new GlDevice(window, defaultShaderSource, debugOptions); boolean enableValidation; try { enableValidation = NeoForgeClientConfig.INSTANCE.enableB3DValidationLayer.getAsBoolean(); diff --git a/src/client/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java b/src/client/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java index b6815ebf9eb..5df69094673 100644 --- a/src/client/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java +++ b/src/client/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java @@ -12,6 +12,8 @@ import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.commands.Commands; import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.metadata.PackMetadataGenerator; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; @@ -76,6 +78,7 @@ import net.neoforged.neoforge.common.data.internal.NeoForgeStructureTagsProvider; import net.neoforged.neoforge.common.data.internal.VanillaSoundDefinitionsProvider; import net.neoforged.neoforge.data.event.GatherDataEvent; +import net.neoforged.neoforge.event.DefaultDataComponentsBoundEvent; import net.neoforged.neoforge.internal.BrandingControl; import net.neoforged.neoforge.resource.NeoForgeReloadListeners; import org.jetbrains.annotations.ApiStatus; @@ -135,6 +138,17 @@ public ClientNeoForgeMod(IEventBus modEventBus, ModContainer container) { return Command.SINGLE_SUCCESS; }))); }); + + // Eagerly report missing item models when client resources reload + NeoForge.EVENT_BUS.addListener(DefaultDataComponentsBoundEvent.class, _ -> { + for (var item : BuiltInRegistries.ITEM) { + var modelId = item.components().get(DataComponents.ITEM_MODEL); + if (modelId != null) { + // This will internally warn about each missing model at most once + Minecraft.getInstance().getModelManager().getItemModel(modelId); + } + } + }); } @SubscribeEvent diff --git a/src/client/java/net/neoforged/neoforge/client/NamedRenderTypeManager.java b/src/client/java/net/neoforged/neoforge/client/NamedRenderTypeManager.java index 9323773efb5..202bbffa222 100644 --- a/src/client/java/net/neoforged/neoforge/client/NamedRenderTypeManager.java +++ b/src/client/java/net/neoforged/neoforge/client/NamedRenderTypeManager.java @@ -46,7 +46,6 @@ private static void preRegisterVanillaRenderTypes(Map RenderTypes.solidMovingBlock(); case CUTOUT -> RenderTypes.cutoutMovingBlock(); case TRANSLUCENT -> RenderTypes.translucentMovingBlock(); - case TRIPWIRE -> RenderTypes.tripwireMovingBlock(); }; } diff --git a/src/client/java/net/neoforged/neoforge/client/TagConventionLogWarningClient.java b/src/client/java/net/neoforged/neoforge/client/TagConventionLogWarningClient.java index ac3c3f32004..65df256fe87 100644 --- a/src/client/java/net/neoforged/neoforge/client/TagConventionLogWarningClient.java +++ b/src/client/java/net/neoforged/neoforge/client/TagConventionLogWarningClient.java @@ -15,10 +15,9 @@ import net.minecraft.tags.TagKey; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.neoforge.client.config.NeoForgeClientConfig; import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.common.TagConventionLogWarning; import net.neoforged.neoforge.common.Tags; -import net.neoforged.neoforge.common.config.NeoForgeCommonConfig; import net.neoforged.neoforge.event.server.ServerStartingEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -28,6 +27,14 @@ private TagConventionLogWarningClient() {} private static final Logger LOGGER = LogManager.getLogger(); + public enum LogWarningMode { + SILENCED, + DEV_SHORT, + DEV_VERBOSE, + PROD_SHORT, + PROD_VERBOSE + } + /*package private*/ static void init() { IEventBus forgeBus = NeoForge.EVENT_BUS; @@ -40,10 +47,10 @@ static void setupUntranslatedItemTagWarning(IEventBus forgeBus) { // Log missing item tag translations only in integrated server so we can safely get translations. forgeBus.addListener((ServerStartingEvent serverStartingEvent) -> { // We have to wait for server start to read the server config. - TagConventionLogWarning.LogWarningMode untranslatedTagWarningMode = NeoForgeCommonConfig.INSTANCE.logUntranslatedItemTagWarnings.get(); - if (FMLEnvironment.getDist().isClient() && untranslatedTagWarningMode != TagConventionLogWarning.LogWarningMode.SILENCED) { - boolean isConfigSetToDev = untranslatedTagWarningMode == TagConventionLogWarning.LogWarningMode.DEV_SHORT || - untranslatedTagWarningMode == TagConventionLogWarning.LogWarningMode.DEV_VERBOSE; + TagConventionLogWarningClient.LogWarningMode untranslatedTagWarningMode = NeoForgeClientConfig.INSTANCE.logUntranslatedItemTagWarnings.get(); + if (FMLEnvironment.getDist().isClient() && untranslatedTagWarningMode != TagConventionLogWarningClient.LogWarningMode.SILENCED) { + boolean isConfigSetToDev = untranslatedTagWarningMode == TagConventionLogWarningClient.LogWarningMode.DEV_SHORT || + untranslatedTagWarningMode == TagConventionLogWarningClient.LogWarningMode.DEV_VERBOSE; if (!FMLEnvironment.isProduction() == isConfigSetToDev) { List> untranslatedTags = new ObjectArrayList<>(); @@ -61,8 +68,8 @@ static void setupUntranslatedItemTagWarning(IEventBus forgeBus) { """); // Print out all untranslated tags when desired. - boolean isConfigSetToVerbose = untranslatedTagWarningMode == TagConventionLogWarning.LogWarningMode.DEV_VERBOSE || - untranslatedTagWarningMode == TagConventionLogWarning.LogWarningMode.PROD_VERBOSE; + boolean isConfigSetToVerbose = untranslatedTagWarningMode == TagConventionLogWarningClient.LogWarningMode.DEV_VERBOSE || + untranslatedTagWarningMode == TagConventionLogWarningClient.LogWarningMode.PROD_VERBOSE; if (isConfigSetToVerbose) { stringBuilder.append("\nUntranslated item tags:"); diff --git a/src/client/java/net/neoforged/neoforge/client/blaze3d/validation/ValidationGpuDevice.java b/src/client/java/net/neoforged/neoforge/client/blaze3d/validation/ValidationGpuDevice.java index c1add833dc9..872ef833d92 100644 --- a/src/client/java/net/neoforged/neoforge/client/blaze3d/validation/ValidationGpuDevice.java +++ b/src/client/java/net/neoforged/neoforge/client/blaze3d/validation/ValidationGpuDevice.java @@ -194,4 +194,25 @@ public GpuDeviceProperties deviceProperties() { public GpuDeviceFeatures enabledFeatures() { return realDevice.enabledFeatures(); } + + @Override + public CompiledRenderPipeline precompilePipeline(RenderPipeline pipeline) { + validator.validatePipeline(pipeline); + return realDevice.precompilePipeline(pipeline); + } + + @Override + public void setVsync(boolean enabled) { + realDevice.setVsync(enabled); + } + + @Override + public void presentFrame() { + realDevice.presentFrame(); + } + + @Override + public boolean isZZeroToOne() { + return realDevice.isZZeroToOne(); + } } diff --git a/src/client/java/net/neoforged/neoforge/client/config/NeoForgeClientConfig.java b/src/client/java/net/neoforged/neoforge/client/config/NeoForgeClientConfig.java index c5ae707e5cc..4d1354b0b37 100644 --- a/src/client/java/net/neoforged/neoforge/client/config/NeoForgeClientConfig.java +++ b/src/client/java/net/neoforged/neoforge/client/config/NeoForgeClientConfig.java @@ -10,6 +10,7 @@ import net.neoforged.fml.event.config.ModConfigEvent; import net.neoforged.fml.loading.FMLEnvironment; import net.neoforged.neoforge.client.ClientHooks; +import net.neoforged.neoforge.client.TagConventionLogWarningClient; import net.neoforged.neoforge.common.ModConfigSpec; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; @@ -27,6 +28,8 @@ public final class NeoForgeClientConfig { public final ModConfigSpec.BooleanValue showLoadWarnings; + public final ModConfigSpec.EnumValue logUntranslatedItemTagWarnings; + public final ModConfigSpec.BooleanValue logUntranslatedConfigurationWarnings; public final ModConfigSpec.BooleanValue reducedDepthStencilFormat; @@ -52,6 +55,11 @@ private NeoForgeClientConfig(ModConfigSpec.Builder builder) { .translation("neoforge.configgui.logUntranslatedConfigurationWarnings") .define("logUntranslatedConfigurationWarnings", true); + 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.") + .translation("neoforge.configgui.logUntranslatedItemTagWarnings") + .defineEnum("logUntranslatedItemTagWarnings", TagConventionLogWarningClient.LogWarningMode.SILENCED); + reducedDepthStencilFormat = builder .comment("Configures how many bits are used for the depth buffer when stenciling has been enabled by a mod. Set to true for 24+8 bits and to false for 32+8 bits. Setting to true will slightly reduce VRAM usage, but risks introducing visual artifacts.") .translation("neoforge.configgui.reducedDepthStencilFormat") diff --git a/src/client/java/net/neoforged/neoforge/client/event/AddDebugSubscriptionFlagsEvent.java b/src/client/java/net/neoforged/neoforge/client/event/AddDebugSubscriptionFlagsEvent.java new file mode 100644 index 00000000000..4a138f1f75b --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/event/AddDebugSubscriptionFlagsEvent.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import it.unimi.dsi.fastutil.objects.ObjectBooleanBiConsumer; +import java.util.function.Supplier; +import net.minecraft.client.multiplayer.ClientDebugSubscriber; +import net.minecraft.util.debug.DebugSubscription; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.loading.FMLEnvironment; +import org.jetbrains.annotations.ApiStatus; + +/** + * This event allows mods to register client-side {@linkplain DebugSubscription debug subscription} flags. + *

+ * These flags are used to determine when subscriptions are allowed to register and store debug renderer values. + * If no flag is registered for a given debug subscription then it will be treated as a {@code always-disabled} flag and no debug values will be stored for it. + *

+ * This event is fired once per tick during {@linkplain ClientDebugSubscriber#requestedSubscriptions()}. + *

+ * This event is fired on the {@linkplain LogicalSide#CLIENT logical client}. + * + * @apiNote Each {@linkplain DebugSubscription debug subscription} should only be registered once. + */ +public final class AddDebugSubscriptionFlagsEvent extends Event { + private final ObjectBooleanBiConsumer> registrar; + + @ApiStatus.Internal + public AddDebugSubscriptionFlagsEvent(ObjectBooleanBiConsumer> registrar) { + this.registrar = registrar; + } + + /** + * Register a new flag for the given {@linkplain DebugSubscription debug subscription}. + * + * @param subscription {@linkplain DebugSubscription debug subscription} to register flag for. + * @param flag Flag used to conditionally enable or disable the given {@linkplain DebugSubscription debug subscription}. + */ + public void addFlag(DebugSubscription subscription, boolean flag) { + registrar.accept(subscription, flag); + } + + /** + * Register a new flag for the given {@linkplain DebugSubscription debug subscription}. + * + * @param subscription {@linkplain DebugSubscription Debug subscription} to register flag for. + * @param flag Flag used to conditionally enable or disable the given {@linkplain DebugSubscription debug subscription}. + */ + public void addFlag(Supplier> subscription, boolean flag) { + addFlag(subscription.get(), flag); + } + + /** + * Mark the given {@linkplain DebugSubscription debug subscription} as only active in dev. + *

+ * Using this method will mark your {@linkplain DebugSubscription debug subscription} as only being enabled in dev a.k.a when {@linkplain FMLEnvironment#isProduction()} == {@code false}. + * + * @param subscription {@linkplain DebugSubscription debug subscription} to register flag for. + */ + public void addActiveInDev(DebugSubscription subscription) { + addFlag(subscription, !FMLEnvironment.isProduction()); + } + + /** + * Mark the given {@linkplain DebugSubscription debug subscription} as only active in dev. + *

+ * Using this method will mark your {@linkplain DebugSubscription debug subscription} as only being enabled in dev a.k.a when {@linkplain FMLEnvironment#isProduction()} == {@code false}. + * + * @param subscription {@linkplain DebugSubscription Debug subscription} to register flag for. + */ + public void addActiveInDev(Supplier> subscription) { + addActiveInDev(subscription.get()); + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/event/GatherEffectScreenTooltipsEvent.java b/src/client/java/net/neoforged/neoforge/client/event/GatherEffectScreenTooltipsEvent.java index 9cb08ceae6f..7df89c6866e 100644 --- a/src/client/java/net/neoforged/neoforge/client/event/GatherEffectScreenTooltipsEvent.java +++ b/src/client/java/net/neoforged/neoforge/client/event/GatherEffectScreenTooltipsEvent.java @@ -15,8 +15,9 @@ import net.neoforged.bus.api.Event; /** - * This event is called when {@link EffectsInInventory} draws the tooltip lines for a hovered {@link MobEffectInstance} in an {@link AbstractContainerScreen}. - * It can be used to modify the tooltip. + * This event is called when the cursor is hovering over an {@link MobEffectInstance} rendered by + * {@link EffectsInInventory} in an {@link AbstractContainerScreen}. + * It can be used to create or modify the tooltip. *

* This event is only fired on the {@linkplain Dist#CLIENT physical client}. */ @@ -32,21 +33,24 @@ public GatherEffectScreenTooltipsEvent(AbstractContainerScreen screen, MobEff } /** - * @return The screen which will be rendering the tooltip lines. + * {@return the screen which will be rendering the tooltip lines} */ public AbstractContainerScreen getScreen() { return this.screen; } /** - * @return The effect whose tooltip is being drawn. + * {@return The effect whose tooltip is being drawn} */ public MobEffectInstance getEffectInstance() { return this.effectInst; } /** - * @return A mutable list of tooltip lines. + * {@return a mutable list of tooltip lines} If this list is empty, no tooltip will be rendered. + *

+ * This list will be initially empty when hovering over an effect widget which has no tooltip by default + * (when the effect information is fully visible). */ public List getTooltip() { return this.tooltip; diff --git a/src/client/java/net/neoforged/neoforge/client/event/RegisterDebugRenderersEvent.java b/src/client/java/net/neoforged/neoforge/client/event/RegisterDebugRenderersEvent.java new file mode 100644 index 00000000000..ee2d87358c0 --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/event/RegisterDebugRenderersEvent.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import java.util.function.Consumer; +import java.util.function.Function; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.debug.DebugRenderer; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * This event allows mods to register custom {@link DebugRenderer.SimpleDebugRenderer}s. + *

+ * This event is fired during {@link DebugRenderer#refreshRendererList()}. + *

+ * This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}. + */ +public final class RegisterDebugRenderersEvent extends Event implements IModBusEvent { + private final Consumer> registrar; + + @ApiStatus.Internal + public RegisterDebugRenderersEvent(Consumer> registrar) { + this.registrar = registrar; + } + + /** + * Registers the given debug renderer + * + * @param factory Factory used to construct the debug renderer + */ + public void register(Function factory) { + registrar.accept(factory); + } + + /** + * Registers the given debug renderer + * + * @param renderer Debug renderer to be registered + */ + public void register(DebugRenderer.SimpleDebugRenderer renderer) { + register(client -> renderer); + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/event/RenderArmEvent.java b/src/client/java/net/neoforged/neoforge/client/event/RenderArmEvent.java index d8c408250fc..d8eb3965689 100644 --- a/src/client/java/net/neoforged/neoforge/client/event/RenderArmEvent.java +++ b/src/client/java/net/neoforged/neoforge/client/event/RenderArmEvent.java @@ -7,7 +7,6 @@ import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.world.entity.HumanoidArm; import net.neoforged.bus.api.Event; @@ -67,7 +66,7 @@ public SubmitNodeCollector getSubmitNodeCollector() { /** * {@return the amount of packed (sky and block) light for rendering} * - * @see LightTexture + * @see net.minecraft.util.LightCoordsUtil */ public int getPackedLight() { return packedLight; diff --git a/src/client/java/net/neoforged/neoforge/client/event/RenderHandEvent.java b/src/client/java/net/neoforged/neoforge/client/event/RenderHandEvent.java index 0c61e12e72d..d1cb2683060 100644 --- a/src/client/java/net/neoforged/neoforge/client/event/RenderHandEvent.java +++ b/src/client/java/net/neoforged/neoforge/client/event/RenderHandEvent.java @@ -6,7 +6,6 @@ package net.neoforged.neoforge.client.event; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.world.InteractionHand; import net.minecraft.world.item.ItemStack; @@ -77,7 +76,7 @@ public SubmitNodeCollector getSubmitNodeCollector() { /** * {@return the amount of packed (sky and block) light for rendering} * - * @see LightTexture + * @see net.minecraft.util.LightCoordsUtil */ public int getPackedLight() { return packedLight; diff --git a/src/client/java/net/neoforged/neoforge/client/event/RenderLevelStageEvent.java b/src/client/java/net/neoforged/neoforge/client/event/RenderLevelStageEvent.java index c937f548f32..1316bdf434a 100644 --- a/src/client/java/net/neoforged/neoforge/client/event/RenderLevelStageEvent.java +++ b/src/client/java/net/neoforged/neoforge/client/event/RenderLevelStageEvent.java @@ -127,15 +127,6 @@ public AfterTranslucentBlocks(LevelRenderer levelRenderer, LevelRenderState leve } } - /** - * Fired near the end of {@linkplain LevelRenderer#addMainPass} after tripwire chunk geometry has been rendered. - */ - public static class AfterTripwireBlocks extends RenderLevelStageEvent { - public AfterTripwireBlocks(LevelRenderer levelRenderer, LevelRenderState levelRenderState, @Nullable PoseStack poseStack, Matrix4f modelViewMatrix, Iterable renderableSections) { - super(levelRenderer, levelRenderState, poseStack, modelViewMatrix, renderableSections); - } - } - /** * Fired at the end of {@linkplain LevelRenderer#addParticlesPass} after particles have been rendered. */ diff --git a/src/client/java/net/neoforged/neoforge/client/extensions/IVertexConsumerExtension.java b/src/client/java/net/neoforged/neoforge/client/extensions/IVertexConsumerExtension.java index b542aefeed3..a2ce3a08655 100644 --- a/src/client/java/net/neoforged/neoforge/client/extensions/IVertexConsumerExtension.java +++ b/src/client/java/net/neoforged/neoforge/client/extensions/IVertexConsumerExtension.java @@ -5,11 +5,19 @@ package net.neoforged.neoforge.client.extensions; +import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexFormatElement; +import net.minecraft.client.model.geom.builders.UVPair; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.ARGB; +import net.minecraft.util.LightCoordsUtil; import net.neoforged.neoforge.client.model.quad.BakedNormals; +import net.neoforged.neoforge.client.model.quad.MutableQuad; import org.joml.Matrix3f; +import org.joml.Matrix4f; import org.joml.Vector3f; +import org.joml.Vector3fc; /** * Extension interface for {@link VertexConsumer}. @@ -28,6 +36,45 @@ default VertexConsumer misc(VertexFormatElement element, int... rawData) { return self(); } + /** + * Same as {@link #putBulkData(PoseStack.Pose, MutableQuad, float[], float, float, float, float, int[], int)}, + * but does not shade the color (assumes brightness = 1), and uses the same {@code lightCoords} for all four vertices. + */ + default void putBulkData(PoseStack.Pose pose, net.neoforged.neoforge.client.model.quad.MutableQuad quad, float r, float g, float b, float a, int lightCoords, int overlayCoords) { + this.putBulkData( + pose, quad, new float[] { 1.0F, 1.0F, 1.0F, 1.0F }, r, g, b, a, new int[] { lightCoords, lightCoords, lightCoords, lightCoords }, overlayCoords); + } + + /** + * Same as {@link VertexConsumer#putBulkData(PoseStack.Pose, BakedQuad, float[], float, float, float, float, int[], int)}, + * but sources the data from a {@link MutableQuad}. + */ + default void putBulkData( + PoseStack.Pose pose, net.neoforged.neoforge.client.model.quad.MutableQuad quad, float[] brightness, float r, float g, float b, float a, int[] lightmapCoord, int overlayCoords) { + Matrix4f matrix = pose.pose(); + Vector3f faceNormal = pose.transformNormal(quad.direction().getUnitVec3f(), new Vector3f()); + int lightEmission = quad.lightEmission(); + + for (int vertex = 0; vertex < 4; vertex++) { + long packedUv = quad.packedUv(vertex); + float brightnessForVertex = brightness[vertex]; + int color = ARGB.colorFromFloat(a, brightnessForVertex * r, brightnessForVertex * g, brightnessForVertex * b); + color = ARGB.multiply(color, quad.color(vertex)); // Neo: apply baked color from the quad + int light = LightCoordsUtil.lightCoordsWithEmission(lightmapCoord[vertex], lightEmission); + Vector3f pos = matrix.transformPosition(quad.x(vertex), quad.y(vertex), quad.z(vertex), new Vector3f()); + float u = UVPair.unpackU(packedUv); + float v = UVPair.unpackV(packedUv); + int packedNormal = quad.packedNormal(vertex); + Vector3fc normal; + if (!BakedNormals.isUnspecified(packedNormal)) { + normal = BakedNormals.unpack(packedNormal, new Vector3f()).mul(pose.normal()); + } else { + normal = faceNormal; + } + self().addVertex(pos.x(), pos.y(), pos.z(), color, u, v, overlayCoords, light, normal.x(), normal.y(), normal.z()); + } + } + default void applyBakedNormals(Vector3f generated, BakedNormals data, int vertex, Matrix3f normalTransform) { int packed = data.normal(vertex); if (!BakedNormals.isUnspecified(packed)) { diff --git a/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntry.java b/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntry.java new file mode 100644 index 00000000000..a434aa521a5 --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntry.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.gamerules; + +import com.google.common.collect.Lists; +import java.util.List; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.util.FormattedCharSequence; +import org.jspecify.annotations.Nullable; + +/** + * Copy of {@link AbstractGameRulesScreen.GameRuleEntry} modified to be used in a static context. + */ +public abstract class GameRuleEntry extends AbstractGameRulesScreen.RuleEntry { + private final List label; + protected final List children = Lists.newArrayList(); + protected final Font font; + + public GameRuleEntry(Font font, @Nullable List tooltip, Component label) { + super(tooltip); + + this.font = font; + this.label = font.split(label, 175); + } + + @Override + public List children() { + return children; + } + + @Override + public List narratables() { + return children; + } + + protected void renderLabel(GuiGraphics graphics, int rowTop, int rowLeft) { + if (label.size() == 1) { + graphics.drawString(font, label.getFirst(), rowLeft, rowTop + 5, -1); + } else if (label.size() >= 2) { + graphics.drawString(font, label.getFirst(), rowLeft, rowTop, -1); + graphics.drawString(font, label.get(1), rowLeft, rowTop + 10, -1); + } + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntryFactory.java b/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntryFactory.java new file mode 100644 index 00000000000..fde88cb52a1 --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntryFactory.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.gamerules; + +import java.util.List; +import net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.level.gamerules.GameRule; + +@FunctionalInterface +public interface GameRuleEntryFactory { + AbstractGameRulesScreen.RuleEntry create(AbstractGameRulesScreen screen, Component description, List tooltip, String str, GameRule gameRule); + + default AbstractGameRulesScreen.EntryFactory toVanilla(AbstractGameRulesScreen screen) { + return (label, tooltip, str, gameRule) -> create(screen, label, tooltip, str, gameRule); + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntryFactoryManager.java b/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntryFactoryManager.java new file mode 100644 index 00000000000..a3bd5acaa24 --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/gamerules/GameRuleEntryFactoryManager.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.gamerules; + +import com.google.common.collect.Maps; +import java.util.Map; +import java.util.function.BiConsumer; +import net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen; +import net.minecraft.world.level.gamerules.GameRule; +import net.minecraft.world.level.gamerules.GameRuleType; +import net.neoforged.fml.ModLoader; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public final class GameRuleEntryFactoryManager { + private static final Map> FACTORIES = Maps.newEnumMap(GameRuleType.class); + private static final GameRuleEntryFactory GENERIC_FACTORY = GenericGameRuleEntry::new; + + public static void register() { + ModLoader.postEvent(new RegisterGameRuleEntryFactoryEvent(FACTORIES)); + } + + @SuppressWarnings("unchecked") + public static void appendGameRuleEntry(AbstractGameRulesScreen screen, GameRule gameRule, BiConsumer, AbstractGameRulesScreen.EntryFactory> addEntry) { + var ruleType = gameRule.gameRuleType(); + + if (ruleType == GameRuleType.BOOL || ruleType == GameRuleType.INT) { + // vanilla rule types are appened using the `visitInteger`/`visitBoolean` overloads + return; + } + + var factory = FACTORIES.get(gameRule.gameRuleType()); + var vanillaFactory = ((GameRuleEntryFactory) (factory == null ? GENERIC_FACTORY : factory)).toVanilla(screen); + addEntry.accept(gameRule, vanillaFactory); + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/gamerules/GenericGameRuleEntry.java b/src/client/java/net/neoforged/neoforge/client/gamerules/GenericGameRuleEntry.java new file mode 100644 index 00000000000..423e1309a3e --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/gamerules/GenericGameRuleEntry.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.gamerules; + +import java.util.List; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.util.CommonColors; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.level.gamerules.GameRule; + +/** + * Copy of {@link AbstractGameRulesScreen.IntegerRuleEntry} updated to be used in a static context for any {@link GameRule} + *

+ * It is recommended for advanced types to make use of {@link RegisterGameRuleEntryFactoryEvent} + */ +public class GenericGameRuleEntry extends GameRuleEntry { + private final EditBox input; + + public GenericGameRuleEntry(AbstractGameRulesScreen screen, Component label, List tooltip, String narration, GameRule gameRule) { + super(screen.getFont(), tooltip, label); + + input = new EditBox(screen.getFont(), 10, 5, 44, 20, label.copy().append("\n").append(narration).append("\n")); + input.setValue(screen.gameRules.getAsString(gameRule)); + input.setResponder(v -> { + var value = gameRule.deserialize(v); + + if (value.isSuccess()) { + input.setTextColor(CommonColors.TEXT_GRAY); + screen.clearInvalid(this); + screen.gameRules.set(gameRule, value.getOrThrow(), null); + } else { + input.setTextColor(CommonColors.RED); + screen.markInvalid(this); + } + }); + + children.add(input); + } + + @Override + public void renderContent(GuiGraphics graphics, int mouseX, int mouseY, boolean hovered, float a) { + renderLabel(graphics, getContentY(), getContentX()); + input.setX(getContentRight() - 45); + input.setY(getContentY()); + input.render(graphics, mouseX, mouseY, a); + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/gamerules/RegisterGameRuleEntryFactoryEvent.java b/src/client/java/net/neoforged/neoforge/client/gamerules/RegisterGameRuleEntryFactoryEvent.java new file mode 100644 index 00000000000..5671db93d32 --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/gamerules/RegisterGameRuleEntryFactoryEvent.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.gamerules; + +import java.util.Map; +import net.minecraft.client.gui.components.CycleButton; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen; +import net.minecraft.world.level.gamerules.GameRuleType; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Fired to allow modders to register custom {@link AbstractGameRulesScreen.RuleEntry} factories. + *

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

+ * While you are not required to register a custom factory for your {@link GameRuleType}, it is recommended to do so + * if your game rule requires more than a simple {@link EditBox}. For example a togglable type similar to {@link GameRuleType#BOOL Boolean} + * would register a new factory which makes use of a {@link CycleButton} insead of a {@link EditBox}. + *

+ * When no factory exists for a given type the {@link GenericGameRuleEntry generic entry} will be used instead. + */ +public final class RegisterGameRuleEntryFactoryEvent extends Event implements IModBusEvent { + private final Map> factories; + + @ApiStatus.Internal + RegisterGameRuleEntryFactoryEvent(Map> factories) { + this.factories = factories; + } + + public void register(GameRuleType gameRuleType, GameRuleEntryFactory factory) { + if (gameRuleType == GameRuleType.INT || gameRuleType == GameRuleType.BOOL) { + throw new IllegalStateException("Registering custom entry factory for vanilla GameRuleTypes is disallowed"); + } + + if (factories.putIfAbsent(gameRuleType, factory) != null) { + throw new IllegalStateException("Duplicate GameRuleTypeEntryFactory registration!"); + } + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/gamerules/package-info.java b/src/client/java/net/neoforged/neoforge/client/gamerules/package-info.java new file mode 100644 index 00000000000..21b19fee86d --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/gamerules/package-info.java @@ -0,0 +1,9 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +@NullMarked +package net.neoforged.neoforge.client.gamerules; + +import org.jspecify.annotations.NullMarked; diff --git a/src/client/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java b/src/client/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java index 8e0aaf67791..cc796e39879 100644 --- a/src/client/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java +++ b/src/client/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java @@ -35,6 +35,7 @@ import net.minecraft.client.Options; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractContainerWidget; +import net.minecraft.client.gui.components.AbstractScrollArea; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.CycleButton; @@ -1272,7 +1273,7 @@ public class ListLabelWidget extends AbstractContainerWidget { protected final boolean isLast; public ListLabelWidget(final int x, final int y, final int width, final int height, final Component labelText, final int idx) { - super(x, y, width, height, labelText); + super(x, y, width, height, labelText, AbstractScrollArea.defaultSettings(font.lineHeight)); this.idx = idx; this.isFirst = idx == 0; this.isLast = idx + 1 == cfgList.size(); diff --git a/src/client/java/net/neoforged/neoforge/client/loading/ClientModLoader.java b/src/client/java/net/neoforged/neoforge/client/loading/ClientModLoader.java index 7478c31b442..08736af3318 100644 --- a/src/client/java/net/neoforged/neoforge/client/loading/ClientModLoader.java +++ b/src/client/java/net/neoforged/neoforge/client/loading/ClientModLoader.java @@ -53,12 +53,8 @@ public static void begin() { loading = true; LanguageHook.loadBuiltinLanguages(); - try { - Runnable periodicTick = earlyLoadingScreen != null ? earlyLoadingScreen::periodicTick : () -> {}; - begin(periodicTick, false); - } catch (ModLoadingException e) { - error = e; - } + Runnable periodicTick = earlyLoadingScreen != null ? earlyLoadingScreen::periodicTick : () -> {}; + begin(periodicTick, false); } public static void finish(final PackRepository defaultResourcePacks, final ReloadableResourceManager mcResourceManager) { diff --git a/src/client/java/net/neoforged/neoforge/client/loading/NeoForgeLoadingOverlay.java b/src/client/java/net/neoforged/neoforge/client/loading/NeoForgeLoadingOverlay.java index cbbf2db52be..0992473fb7c 100644 --- a/src/client/java/net/neoforged/neoforge/client/loading/NeoForgeLoadingOverlay.java +++ b/src/client/java/net/neoforged/neoforge/client/loading/NeoForgeLoadingOverlay.java @@ -98,7 +98,7 @@ static class ExternalTexture extends AbstractTexture { public ExternalTexture(GpuTexture texture) { this.texture = texture; this.sampler = RenderSystem.getSamplerCache() - .getSampler(AddressMode.REPEAT, AddressMode.REPEAT, FilterMode.LINEAR, FilterMode.LINEAR, false); + .getSampler(AddressMode.REPEAT, AddressMode.REPEAT, FilterMode.NEAREST, FilterMode.NEAREST, false); var gpuDevice = RenderSystem.getDevice(); // ValidationGpuDevice.createTextureView is expecting a ValidationGpuTexture instance, but the previous reach around created a GlTexture instance instead so validation must be reached around again if (gpuDevice instanceof ValidationGpuDevice validationGpuDevice) { diff --git a/src/client/java/net/neoforged/neoforge/client/model/ao/EnhancedAoRenderStorage.java b/src/client/java/net/neoforged/neoforge/client/model/ao/EnhancedAoRenderStorage.java index de54f52c0f5..78faaa945a4 100644 --- a/src/client/java/net/neoforged/neoforge/client/model/ao/EnhancedAoRenderStorage.java +++ b/src/client/java/net/neoforged/neoforge/client/model/ao/EnhancedAoRenderStorage.java @@ -6,11 +6,11 @@ package net.neoforged.neoforge.client.model.ao; import com.mojang.logging.LogUtils; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.block.ModelBlockRenderer; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.state.BlockState; @@ -265,7 +265,7 @@ private static float interpolateBrightness(AoCalculatedFace in, float[] weights) * Interpolates lightmap from the 4 corners of a face. */ private static int interpolateLightmap(AoCalculatedFace in, float[] weights) { - return blend(in.lightmap0, in.lightmap1, in.lightmap2, in.lightmap3, weights[0], weights[1], weights[2], weights[3]); + return LightCoordsUtil.smoothWeightedBlend(in.lightmap0, in.lightmap1, in.lightmap2, in.lightmap3, weights[0], weights[1], weights[2], weights[3]); } /** @@ -273,20 +273,20 @@ private static int interpolateLightmap(AoCalculatedFace in, float[] weights) { */ private static int lerpLightmap(int lightmap1, float w1, int lightmap2, float w2) { // Interpolate the two components separately - int block1 = LightTexture.blockWithFraction(lightmap1); - int block2 = LightTexture.blockWithFraction(lightmap2); + int block1 = LightCoordsUtil.smoothBlock(lightmap1); + int block2 = LightCoordsUtil.smoothBlock(lightmap2); int block = 0xFF & Math.round(block1 * w1 + block2 * w2); - int sky1 = LightTexture.skyWithFraction(lightmap1); - int sky2 = LightTexture.skyWithFraction(lightmap2); + int sky1 = LightCoordsUtil.smoothSky(lightmap1); + int sky2 = LightCoordsUtil.smoothSky(lightmap2); int sky = 0xFF & Math.round(sky1 * w1 + sky2 * w2); - return LightTexture.packWithFraction(block, sky); + return LightCoordsUtil.smoothPack(block, sky); } static int maxLightmap(int lightmap1, int lightmap2) { - return LightTexture.packWithFraction( - Math.max(LightTexture.blockWithFraction(lightmap1), LightTexture.blockWithFraction(lightmap2)), - Math.max(LightTexture.skyWithFraction(lightmap1), LightTexture.skyWithFraction(lightmap2))); + return LightCoordsUtil.smoothPack( + Math.max(LightCoordsUtil.smoothBlock(lightmap1), LightCoordsUtil.smoothBlock(lightmap2)), + Math.max(LightCoordsUtil.smoothSky(lightmap1), LightCoordsUtil.smoothSky(lightmap2))); } } diff --git a/src/client/java/net/neoforged/neoforge/client/model/ao/FullFaceCalculator.java b/src/client/java/net/neoforged/neoforge/client/model/ao/FullFaceCalculator.java index 1aa420aa201..50cd702bb42 100644 --- a/src/client/java/net/neoforged/neoforge/client/model/ao/FullFaceCalculator.java +++ b/src/client/java/net/neoforged/neoforge/client/model/ao/FullFaceCalculator.java @@ -5,10 +5,10 @@ package net.neoforged.neoforge.client.model.ao; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.block.ModelBlockRenderer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.state.BlockState; @@ -89,25 +89,25 @@ private void calculateFaceUncached(AoCalculatedFace out, BlockAndTintGetter leve // AdjacencyInfo calls them corners, but they are actually sides scratchPos.setWithOffset(samplePos, adjacencyInfo.corners[0]); BlockState sideState0 = level.getBlockState(scratchPos); - int sideLightmap0 = this.cache.getLightColor(sideState0, level, scratchPos); + int sideLightmap0 = this.cache.getLightCoords(sideState0, level, scratchPos); float sideBrightness0 = this.cache.getShadeBrightness(sideState0, level, scratchPos); boolean sideClear0 = !sideState0.isViewBlocking(level, scratchPos) || sideState0.getLightBlock() == 0; scratchPos.setWithOffset(samplePos, adjacencyInfo.corners[1]); BlockState sideState1 = level.getBlockState(scratchPos); - int sideLightmap1 = this.cache.getLightColor(sideState1, level, scratchPos); + int sideLightmap1 = this.cache.getLightCoords(sideState1, level, scratchPos); float sideBrightness1 = this.cache.getShadeBrightness(sideState1, level, scratchPos); boolean sideClear1 = !sideState1.isViewBlocking(level, scratchPos) || sideState1.getLightBlock() == 0; scratchPos.setWithOffset(samplePos, adjacencyInfo.corners[2]); BlockState sideState2 = level.getBlockState(scratchPos); - int sideLightmap2 = this.cache.getLightColor(sideState2, level, scratchPos); + int sideLightmap2 = this.cache.getLightCoords(sideState2, level, scratchPos); float sideBrightness2 = this.cache.getShadeBrightness(sideState2, level, scratchPos); boolean sideClear2 = !sideState2.isViewBlocking(level, scratchPos) || sideState2.getLightBlock() == 0; scratchPos.setWithOffset(samplePos, adjacencyInfo.corners[3]); BlockState sideState3 = level.getBlockState(scratchPos); - int sideLightmap3 = this.cache.getLightColor(sideState3, level, scratchPos); + int sideLightmap3 = this.cache.getLightCoords(sideState3, level, scratchPos); float sideBrightness3 = this.cache.getShadeBrightness(sideState3, level, scratchPos); boolean sideClear3 = !sideState3.isViewBlocking(level, scratchPos) || sideState3.getLightBlock() == 0; @@ -125,7 +125,7 @@ private void calculateFaceUncached(AoCalculatedFace out, BlockAndTintGetter leve scratchPos.setWithOffset(samplePos, adjacencyInfo.corners[0]).move(adjacencyInfo.corners[2]); BlockState cornerState0 = level.getBlockState(scratchPos); cornerBrightness0 = this.cache.getShadeBrightness(cornerState0, level, scratchPos); - cornerLightmap0 = this.cache.getLightColor(cornerState0, level, scratchPos); + cornerLightmap0 = this.cache.getLightCoords(cornerState0, level, scratchPos); cornerClear0 = !cornerState0.isViewBlocking(level, scratchPos) || cornerState0.getLightBlock() == 0; } @@ -140,7 +140,7 @@ private void calculateFaceUncached(AoCalculatedFace out, BlockAndTintGetter leve scratchPos.setWithOffset(samplePos, adjacencyInfo.corners[0]).move(adjacencyInfo.corners[3]); BlockState cornerState1 = level.getBlockState(scratchPos); cornerBrightness1 = this.cache.getShadeBrightness(cornerState1, level, scratchPos); - cornerLightmap1 = this.cache.getLightColor(cornerState1, level, scratchPos); + cornerLightmap1 = this.cache.getLightCoords(cornerState1, level, scratchPos); cornerClear1 = !cornerState1.isViewBlocking(level, scratchPos) || cornerState1.getLightBlock() == 0; } @@ -156,7 +156,7 @@ private void calculateFaceUncached(AoCalculatedFace out, BlockAndTintGetter leve scratchPos.setWithOffset(samplePos, adjacencyInfo.corners[1]).move(adjacencyInfo.corners[2]); BlockState cornerState2 = level.getBlockState(scratchPos); cornerBrightness2 = this.cache.getShadeBrightness(cornerState2, level, scratchPos); - cornerLightmap2 = this.cache.getLightColor(cornerState2, level, scratchPos); + cornerLightmap2 = this.cache.getLightCoords(cornerState2, level, scratchPos); cornerClear2 = !cornerState2.isViewBlocking(level, scratchPos) || cornerState2.getLightBlock() == 0; } @@ -172,7 +172,7 @@ private void calculateFaceUncached(AoCalculatedFace out, BlockAndTintGetter leve scratchPos.setWithOffset(samplePos, adjacencyInfo.corners[1]).move(adjacencyInfo.corners[3]); BlockState cornerState3 = level.getBlockState(scratchPos); cornerBrightness3 = this.cache.getShadeBrightness(cornerState3, level, scratchPos); - cornerLightmap3 = this.cache.getLightColor(cornerState3, level, scratchPos); + cornerLightmap3 = this.cache.getLightCoords(cornerState3, level, scratchPos); cornerClear3 = !cornerState3.isViewBlocking(level, scratchPos) || cornerState3.getLightBlock() == 0; } @@ -182,7 +182,7 @@ private void calculateFaceUncached(AoCalculatedFace out, BlockAndTintGetter leve // which causes seams e.g. when a slab is placed below an active sculk sensor BlockState insideState = sampleOutside ? level.getBlockState(samplePos) : renderedState; float insideBrightness = this.cache.getShadeBrightness(insideState, level, samplePos); - int insideLightmap = this.cache.getLightColor(insideState, level, samplePos); + int insideLightmap = this.cache.getLightCoords(insideState, level, samplePos); boolean insideClear = !insideState.isViewBlocking(level, samplePos) || insideState.getLightBlock() == 0; // Wrap up @@ -230,14 +230,14 @@ private static int blend( // which means that a natural 0 value will not get ignored in the blending. // - It treats all 4 lightmaps equally. - int sideBlockA = LightTexture.blockWithFraction(sideLightmapA); - int sideBlockB = LightTexture.blockWithFraction(sideLightmapB); - int cornerBlock = LightTexture.blockWithFraction(cornerLightmap); - int insideBlock = LightTexture.blockWithFraction(insideLightmap); - int sideSkyA = LightTexture.skyWithFraction(sideLightmapA); - int sideSkyB = LightTexture.skyWithFraction(sideLightmapB); - int cornerSky = LightTexture.skyWithFraction(cornerLightmap); - int insideSky = LightTexture.skyWithFraction(insideLightmap); + int sideBlockA = LightCoordsUtil.smoothBlock(sideLightmapA); + int sideBlockB = LightCoordsUtil.smoothBlock(sideLightmapB); + int cornerBlock = LightCoordsUtil.smoothBlock(cornerLightmap); + int insideBlock = LightCoordsUtil.smoothBlock(insideLightmap); + int sideSkyA = LightCoordsUtil.smoothSky(sideLightmapA); + int sideSkyB = LightCoordsUtil.smoothSky(sideLightmapB); + int cornerSky = LightCoordsUtil.smoothSky(cornerLightmap); + int insideSky = LightCoordsUtil.smoothSky(insideLightmap); // Compute per-component minimum light, only including values from clear positions int minBlock = 0x10000; @@ -265,10 +265,10 @@ private static int blend( minSky &= 0xFFFF; // Increase all components of non-clear blocks to the minimum light value - sideLightmapA = LightTexture.packWithFraction(Math.max(minBlock, sideBlockA), Math.max(minSky, sideSkyA)); - sideLightmapB = LightTexture.packWithFraction(Math.max(minBlock, sideBlockB), Math.max(minSky, sideSkyB)); - cornerLightmap = LightTexture.packWithFraction(Math.max(minBlock, cornerBlock), Math.max(minSky, cornerSky)); - insideLightmap = LightTexture.packWithFraction(Math.max(minBlock, insideBlock), Math.max(minSky, insideSky)); + sideLightmapA = LightCoordsUtil.smoothPack(Math.max(minBlock, sideBlockA), Math.max(minSky, sideSkyA)); + sideLightmapB = LightCoordsUtil.smoothPack(Math.max(minBlock, sideBlockB), Math.max(minSky, sideSkyB)); + cornerLightmap = LightCoordsUtil.smoothPack(Math.max(minBlock, cornerBlock), Math.max(minSky, cornerSky)); + insideLightmap = LightCoordsUtil.smoothPack(Math.max(minBlock, insideBlock), Math.max(minSky, insideSky)); } return sideLightmapA + sideLightmapB + cornerLightmap + insideLightmap >> 2 & 0xFF00FF; diff --git a/src/client/java/net/neoforged/neoforge/client/model/item/DynamicFluidContainerModel.java b/src/client/java/net/neoforged/neoforge/client/model/item/DynamicFluidContainerModel.java index 0f2d10decb1..73f813f513a 100644 --- a/src/client/java/net/neoforged/neoforge/client/model/item/DynamicFluidContainerModel.java +++ b/src/client/java/net/neoforged/neoforge/client/model/item/DynamicFluidContainerModel.java @@ -88,10 +88,10 @@ private DynamicFluidContainerModel(Unbaked unbakedModel, BakingContext bakingCon 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); + Material particleLocation = unbakedModel.textures.particle.map(ClientHooks::getItemMaterial).orElse(null); + Material baseLocation = unbakedModel.textures.base.map(ClientHooks::getItemMaterial).orElse(null); + Material fluidMaskLocation = unbakedModel.textures.fluid.map(ClientHooks::getItemMaterial).orElse(null); + Material coverLocation = unbakedModel.textures.cover.map(ClientHooks::getItemMaterial).orElse(null); TextureAtlasSprite baseSprite = baseLocation != null ? sprites.get(baseLocation, DEBUG_NAME) : null; TextureAtlasSprite fluidSprite = fluid != Fluids.EMPTY ? sprites.get(ClientHooks.getBlockMaterial(IClientFluidTypeExtensions.of(fluid).getStillTexture()), DEBUG_NAME) : null; diff --git a/src/client/java/net/neoforged/neoforge/client/model/quad/BakedNormals.java b/src/client/java/net/neoforged/neoforge/client/model/quad/BakedNormals.java index 5df4afa66bf..c18b46cd6d0 100644 --- a/src/client/java/net/neoforged/neoforge/client/model/quad/BakedNormals.java +++ b/src/client/java/net/neoforged/neoforge/client/model/quad/BakedNormals.java @@ -136,7 +136,7 @@ static float unpackZ(int packedNormal) { * @param destination The vector to unpack the packed normal into, if {@code null}, a new vector will be allocated. * @return The vector that the normal was unpacked into. */ - static Vector3fc unpack(int packedNormal, @Nullable Vector3f destination) { + static Vector3f unpack(int packedNormal, @Nullable Vector3f destination) { if (destination == null) { destination = new Vector3f(); } diff --git a/src/client/java/net/neoforged/neoforge/client/model/quad/MutableQuad.java b/src/client/java/net/neoforged/neoforge/client/model/quad/MutableQuad.java new file mode 100644 index 00000000000..a247590247a --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/model/quad/MutableQuad.java @@ -0,0 +1,960 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model.quad; + +import java.util.Arrays; +import net.minecraft.client.model.geom.builders.UVPair; +import net.minecraft.client.renderer.FaceInfo; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.FaceBakery; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; +import net.minecraft.util.ARGB; +import org.jetbrains.annotations.Contract; +import org.joml.Matrix4f; +import org.joml.Vector2f; +import org.joml.Vector2fc; +import org.joml.Vector3f; +import org.joml.Vector3fc; +import org.jspecify.annotations.Nullable; + +/** + * A mutable representation of a {@link BakedQuad}. + * + *

This class can be used for constructing quads from scratch, or for loading and modifying existing quads. + *

It provides several utility methods that go beyond simply manipulating the attributes of the quad: + *

    + *
  • {@link #setCubeFaceFromSpriteCoords(Direction, float, float, float, float, float)} generates the positions of a face by using a 2D coordinate system as if you were looking at the sprite textured on that face.
  • + *
  • {@link #setCubeFace(Direction, Vector3fc, Vector3fc)} generates the positions of a 3D cube face by giving the cubes extent.
  • + *
  • {@link #bakeUvsFromPosition(UVTransform)} generates the texture coordinates of the quad similar to how Vanilla block models do, with optional transformations.
  • + *
  • {@link #recalculateWinding()} can reorder the vertices of the quad to match the vertex order expected by Vanilla ambient occlusion for axis-aligned quads.
  • + *
  • {@link #setSpriteAndMoveUv(TextureAtlasSprite)} can change the sprite used by a quad while remapping the atlas uv automatically.
  • + *
+ */ +public class MutableQuad { + private final Vector3f[] positions = new Vector3f[] { + new Vector3f(), + new Vector3f(), + new Vector3f(), + new Vector3f() + }; + private final long[] uvs = new long[4]; + private final int[] normals = new int[4]; + private final int[] colors = new int[4]; + + private int tintIndex = -1; + private Direction direction = Direction.DOWN; + @Nullable + private TextureAtlasSprite sprite; + private boolean shade = true; + private int lightEmission; + private boolean hasAmbientOcclusion; + /** + * This is only used to reuse position vectors when possible. + */ + @Nullable + private BakedQuad lastSourceQuad; + + public MutableQuad() { + reset(); + } + + /** + * {@return the x-component of a vertex's position} + */ + @Contract(pure = true) + public float x(int vertexIndex) { + return positions[vertexIndex].x; + } + + /** + * {@return the y-component of a vertex's position} + */ + @Contract(pure = true) + public float y(int vertexIndex) { + return positions[vertexIndex].y; + } + + /** + * {@return the z-component of a vertex's position} + */ + @Contract(pure = true) + public float z(int vertexIndex) { + return positions[vertexIndex].z; + } + + /** + * {@return a component of a vertex's position} + * + * @see Vector3f#get(int) + */ + @Contract(pure = true) + public float positionComponent(int vertexIndex, int componentIndex) { + return positions[vertexIndex].get(componentIndex); + } + + /** + * Copies a vertex's position into a new vector and returns it. + */ + @Contract(pure = true) + public Vector3f copyPosition(int vertexIndex) { + return new Vector3f(positions[vertexIndex]); + } + + /** + * Copies a vertex's position into the given vector and returns it. + */ + public Vector3f copyPosition(int vertexIndex, Vector3f dest) { + var pos = positions[vertexIndex]; + dest.set(pos); + return dest; + } + + /** + * Sets the x-component of a vertex's position. + */ + public MutableQuad setX(int vertexIndex, float x) { + positions[vertexIndex].x = x; + return this; + } + + /** + * Sets the y-component of a vertex's position. + */ + public MutableQuad setY(int vertexIndex, float y) { + positions[vertexIndex].y = y; + return this; + } + + /** + * Sets the x-component of a vertex's position. + */ + public MutableQuad setZ(int vertexIndex, float z) { + positions[vertexIndex].z = z; + return this; + } + + /** + * Sets a component of a vertex's position. + * + * @see Vector3f#setComponent(int, float) + */ + public MutableQuad setPositionComponent(int vertexIndex, int componentIndex, float value) { + positions[vertexIndex].setComponent(componentIndex, value); + return this; + } + + /** + * Sets a vertex's position. + */ + public MutableQuad setPosition(int vertexIndex, float x, float y, float z) { + positions[vertexIndex].set(x, y, z); + return this; + } + + /** + * Sets a vertex's position. + */ + public MutableQuad setPosition(int vertexIndex, Vector3fc position) { + positions[vertexIndex].set(position); + return this; + } + + /** + * Sets the positions of this quad to form a rectangle on the given block side using a coordinate-system matching + * the default orientation of sprites in Vanilla block-models. + *

+ * Inspired by the Fabric Renderer API method {@code square}. + *

+ * The left, bottom, right and top parameters correspond to the default sprite orientation in Vanilla block models. + * For {@link Direction#UP} the "up" direction is facing {@link Direction#NORTH}, while for {@link Direction#DOWN}, + * it faces {@link Direction#SOUTH}. + *

All coordinates use a normalized [0,1] range. + *

Passing left=0, bottom=0, right=1, top=1, depth=0 will produce a face on the blocks {@code side}. + */ + public MutableQuad setCubeFaceFromSpriteCoords(Direction side, + float left, + float bottom, + float right, + float top, + float depth) { + this.direction = side; + + switch (side) { + case NORTH -> { + // -Z (looking south at north face) + // left is +X, bottom is -Y + positions[0].set(1 - left, top, depth); + positions[1].set(1 - left, bottom, depth); + positions[2].set(1 - right, bottom, depth); + positions[3].set(1 - right, top, depth); + } + case SOUTH -> { + // +Z (looking north at south face) + // left is +X, bottom is -Y + positions[0].set(left, top, 1 - depth); + positions[1].set(left, bottom, 1 - depth); + positions[2].set(right, bottom, 1 - depth); + positions[3].set(right, top, 1 - depth); + } + case EAST -> { + // -X (looking west at east face) + // left is +Z, bottom is -Y + positions[0].set(1 - depth, top, 1 - left); + positions[1].set(1 - depth, bottom, 1 - left); + positions[2].set(1 - depth, bottom, 1 - right); + positions[3].set(1 - depth, top, 1 - right); + } + case WEST -> { + // +X (looking east at west face) + // left is -Z, bottom is -Y + positions[0].set(depth, top, left); + positions[1].set(depth, bottom, left); + positions[2].set(depth, bottom, right); + positions[3].set(depth, top, right); + } + case UP -> { + // -Y (looking down at up face) + // left is -X, bottom is +Z + positions[0].set(left, 1 - depth, 1 - top); + positions[1].set(left, 1 - depth, 1 - bottom); + positions[2].set(right, 1 - depth, 1 - bottom); + positions[3].set(right, 1 - depth, 1 - top); + } + case DOWN -> { + // +Y (looking up at down face) + // left is -X, bottom is -Z + positions[0].set(left, depth, top); + positions[1].set(left, depth, bottom); + positions[2].set(right, depth, bottom); + positions[3].set(right, depth, top); + } + } + return this; + } + + /** + * Same as {@link #setCubeFace(Direction, float, float, float, float, float, float)}, but uses the full cube. + */ + public MutableQuad setFullCubeFace(Direction side) { + return setCubeFace(side, 0, 0, 0, 1, 1, 1); + } + + /** + * Same as {@link #setCubeFace(Direction, float, float, float, float, float, float)}, but takes the from and to + * positions from vectors. + */ + public MutableQuad setCubeFace(Direction side, Vector3fc from, Vector3fc to) { + return setCubeFace(side, from.x(), from.y(), from.z(), to.x(), to.y(), to.z()); + } + + /** + * Sets the positions of this quad to the face of a cube as it would be defined in a Vanilla block model. + *

All coordinates use a normalized [0,1] range. + */ + public MutableQuad setCubeFace(Direction side, + float fromX, + float fromY, + float fromZ, + float toX, + float toY, + float toZ) { + this.direction = side; + + for (int i = 0; i < 4; i++) { + var vertexInfo = FaceInfo.fromFacing(side).getVertexInfo(i); + positions[i].set( + vertexInfo.xFace().select(fromX, fromY, fromZ, toX, toY, toZ), + vertexInfo.yFace().select(fromX, fromY, fromZ, toX, toY, toZ), + vertexInfo.zFace().select(fromX, fromY, fromZ, toX, toY, toZ)); + } + return this; + } + + /** + * {@return the horizontal texture coordinate in atlas-space for a vertex} + */ + @Contract(pure = true) + public float u(int vertexIndex) { + return UVPair.unpackU(uvs[vertexIndex]); + } + + /** + * {@return the vertical texture coordinate in atlas-space for a vertex} + */ + @Contract(pure = true) + public float v(int vertexIndex) { + return UVPair.unpackV(uvs[vertexIndex]); + } + + /** + * {@return the a texture coordinate in atlas-space for a vertex} + */ + @Contract(pure = true) + public float uvComponent(int vertexIndex, int componentIndex) { + return switch (componentIndex) { + case 0 -> u(vertexIndex); + case 1 -> v(vertexIndex); + default -> throw new IllegalArgumentException("Invalid UV index: " + componentIndex); + }; + } + + /** + * {@return the texture coordinates in atlas-space for a vertex in packed form} + * + * @see UVPair#unpackU(long) + * @see UVPair#unpackV(long) + */ + @Contract(pure = true) + public long packedUv(int vertexIndex) { + return uvs[vertexIndex]; + } + + /** + * Same as {@link #copyUv(int, Vector2f)}, but constructs a destination vector automatically. + */ + @Contract(pure = true) + public Vector2f copyUv(int vertexIndex) { + return copyUv(vertexIndex, new Vector2f()); + } + + /** + * Copies the texture coordinates of a vertex into a given vector and returns it. + */ + public Vector2f copyUv(int vertexIndex, Vector2f dest) { + var packedUv = uvs[vertexIndex]; + dest.x = UVPair.unpackU(packedUv); + dest.y = UVPair.unpackV(packedUv); + return dest; + } + + /** + * Sets the texture coordinate of a vertex. + * + *

Note that this method expects texture coordinates in the coordinate space of the atlas, not the sprite. + * + * @see #setUvFromSprite(int, float, float) + */ + public MutableQuad setUv(int vertexIndex, float u, float v) { + uvs[vertexIndex] = UVPair.pack(u, v); + return this; + } + + /** + * Sets the texture coordinate of a vertex. + * + *

Note that this method expects texture coordinates in the coordinate space of the atlas, not the sprite. + * + * @see #setUvFromSprite(int, Vector2fc) + */ + public MutableQuad setUv(int vertexIndex, Vector2fc uv) { + return setUv(vertexIndex, uv.x(), uv.y()); + } + + /** + * Sets a component of the texture coordinate of a vertex. + * + *

Note that this method expects texture coordinates in the coordinate space of the atlas, not the sprite. + * + * @see #setUvFromSprite(int, float, float) + */ + public MutableQuad setUvComponent(int vertexIndex, int componentIndex, float value) { + return switch (componentIndex) { + case 0 -> setUv(vertexIndex, value, v(vertexIndex)); + case 1 -> setUv(vertexIndex, u(vertexIndex), value); + default -> throw new IllegalArgumentException("Invalid UV index: " + componentIndex); + }; + } + + /** + * Sets the texture coordinate of a vertex from their packed representation. + * + *

Note that this method expects texture coordinates in the coordinate space of the atlas, not the sprite. + * + * @see UVPair + */ + public MutableQuad setPackedUv(int vertexIndex, long packedUv) { + uvs[vertexIndex] = packedUv; + return this; + } + + /** + * Assigns UV coordinates to a vertex of the current quad based on its {@linkplain #sprite() sprite} and the + * given UV coordinates within that sprite. + */ + public MutableQuad setUvFromSprite(int vertexIndex, float u, float v) { + var sprite = requiredSprite(); + return setUv(vertexIndex, sprite.getU(u), sprite.getV(v)); + } + + /** + * Assigns UV coordinates to a vertex of the current quad based on its {@linkplain #sprite() sprite} and the + * given UV coordinates within that sprite. + */ + public MutableQuad setUvFromSprite(int vertexIndex, Vector2fc uv) { + return setUvFromSprite(vertexIndex, uv.x(), uv.y()); + } + + /** + * Projects each vertex onto the cube face the quad is sourcing its block lighting from, + * and derives the vertex UV that way. + * + *

Requires {@link #sprite()} to be set. + */ + public MutableQuad bakeUvsFromPosition() { + return bakeUvsFromPosition(UVTransform.IDENTITY); + } + + /** + * Same as {@link #bakeUvsFromPosition()}, but applies a transform to the generated UVs before baking. + */ + public MutableQuad bakeUvsFromPosition(UVTransform transform) { + switch (direction) { + case DOWN -> { + for (int i = 0; i < 4; i++) { + uvs[i] = UVPair.pack(positions[i].x, 1 - positions[i].z); + } + } + case UP -> { + for (int i = 0; i < 4; i++) { + uvs[i] = UVPair.pack(positions[i].x, positions[i].z); + } + } + case NORTH -> { + for (int i = 0; i < 4; i++) { + uvs[i] = UVPair.pack(1 - positions[i].x, 1 - positions[i].y); + } + } + case SOUTH -> { + for (int i = 0; i < 4; i++) { + uvs[i] = UVPair.pack(positions[i].x, 1 - positions[i].y); + } + } + case WEST -> { + for (int i = 0; i < 4; i++) { + uvs[i] = UVPair.pack(positions[i].z, 1 - positions[i].y); + } + } + case EAST -> { + for (int i = 0; i < 4; i++) { + uvs[i] = UVPair.pack(1 - positions[i].z, 1 - positions[i].y); + } + } + } + + if (!transform.isIdentity()) { + for (int i = 0; i < 4; i++) { + uvs[i] = transform.transformPacked(uvs[i]); + } + } + + transformUvsFromSpriteToAtlas(); + return this; + } + + @Contract(pure = true) + public int tintIndex() { + return tintIndex; + } + + public MutableQuad setTintIndex(int tintIndex) { + this.tintIndex = tintIndex; + return this; + } + + @Contract(pure = true) + public Direction direction() { + return direction; + } + + public MutableQuad setDirection(Direction direction) { + this.direction = direction; + return this; + } + + /** + * {@return the sprite associated with the quad or null if no sprite has been set yet} + * + *

Note that {@link BakedQuad} must have an associated sprite. + */ + @Contract(pure = true) + @Nullable + public TextureAtlasSprite sprite() { + return sprite; + } + + /** + * Same as {@link #sprite()}, but throws an exception if no sprite is set on the quad yet. + * + * @throws IllegalStateException If no sprite is set yet. + */ + @Contract(pure = true) + public TextureAtlasSprite requiredSprite() { + if (sprite == null) { + throw new IllegalStateException("A sprite has to be set on this quad before UVs are manipulated"); + } + return sprite; + } + + /** + * Changes the texture atlas sprite used by this quad. + * + *

Note that changing the sprite does not automatically translate the current UV coordinates within the atlas + * to be within this new sprite. Use {@link #setSpriteAndMoveUv(TextureAtlasSprite)} to change sprites and remap them, + * {@link #bakeUvsFromPosition()} to generate texture coordinates from scratch, or set them manually. + */ + public MutableQuad setSprite(TextureAtlasSprite sprite) { + this.sprite = sprite; + return this; + } + + /** + * Changes the sprite and remaps the UV to the new sprites position in the texture atlas. + * + * @throws IllegalStateException If no sprite is currently set. There would be nothing to remap from. + */ + public MutableQuad setSpriteAndMoveUv(TextureAtlasSprite sprite) { + transformUvsFromAtlasToSprite(); + this.sprite = sprite; + transformUvsFromSpriteToAtlas(); + return this; + } + + @Contract(pure = true) + public boolean shade() { + return shade; + } + + public MutableQuad setShade(boolean shade) { + this.shade = shade; + return this; + } + + @Contract(pure = true) + public int lightEmission() { + return lightEmission; + } + + public MutableQuad setLightEmission(int lightEmission) { + this.lightEmission = lightEmission; + return this; + } + + /** + * {@return the x-component of a vertex's normal or NaN if the normal is undefined} + */ + @Contract(pure = true) + public float normalX(int vertexIndex) { + return normalComponent(vertexIndex, 0); + } + + /** + * {@return the y-component of a vertex's normal or NaN if the normal is undefined} + */ + @Contract(pure = true) + public float normalY(int vertexIndex) { + return normalComponent(vertexIndex, 1); + } + + /** + * {@return the z-component of a vertex's normal or NaN if the normal is undefined} + */ + @Contract(pure = true) + public float normalZ(int vertexIndex) { + return normalComponent(vertexIndex, 2); + } + + /** + * {@return a component of a vertex's normal or NaN if the normal is undefined} + * + * @see Vector3f#get(int) + */ + @Contract(pure = true) + public float normalComponent(int vertexIndex, int componentIndex) { + var packedNormal = normals[vertexIndex]; + if (BakedNormals.isUnspecified(packedNormal)) { + return Float.NaN; + } else { + return BakedNormals.unpackComponent(packedNormal, componentIndex); + } + } + + /** + * {@return a vertex normal in packed form} + * + * @see BakedNormals#unpack(int, Vector3f) + * @see BakedNormals#pack(float, float, float) + */ + @Contract(pure = true) + public int packedNormal(int vertexIndex) { + return normals[vertexIndex]; + } + + /** + * Same as {@link #copyNormal(int, Vector3f)}, but constructs a new destination vector automatically. + */ + @Contract(pure = true) + public Vector3f copyNormal(int vertexIndex) { + return copyNormal(vertexIndex, new Vector3f()); + } + + /** + * Copies the normal vector of a vertex into a given vector and returns it. + */ + public Vector3f copyNormal(int vertexIndex, Vector3f dest) { + return BakedNormals.unpack(normals[vertexIndex], dest); + } + + /** + * Sets the normal vector of a vertex. + */ + public MutableQuad setNormal(int vertexIndex, float x, float y, float z) { + normals[vertexIndex] = BakedNormals.pack(x, y, z); + return this; + } + + /** + * Sets the normal vector of a vertex. + */ + public MutableQuad setNormal(int vertexIndex, Vector3fc normal) { + normals[vertexIndex] = BakedNormals.pack(normal); + return this; + } + + /** + * Sets a component of a vertex's normal. + * + *

If a normal was unspecified before this method was called, its other components will be set to 0. + * + * @see Vector3f#setComponent(int, float) + */ + public MutableQuad setNormalComponent(int vertexIndex, int componentIndex, float value) { + int normal = normals[vertexIndex]; + float x, y, z; + if (BakedNormals.isUnspecified(normal)) { + x = 0; + y = 0; + z = 0; + } else { + x = BakedNormals.unpackX(normal); + y = BakedNormals.unpackY(normal); + z = BakedNormals.unpackZ(normal); + } + + switch (componentIndex) { + case 0 -> x = value; + case 1 -> y = value; + case 2 -> z = value; + default -> throw new IllegalArgumentException(); + } + + normals[vertexIndex] = BakedNormals.pack(x, y, z); + return this; + } + + /** + * Sets the normal vector of a vertex from its packed representation. + * + * @see BakedNormals + */ + public MutableQuad setPackedNormal(int vertexIndex, int packedNormal) { + normals[vertexIndex] = packedNormal; + return this; + } + + /** + * Sets the normal vector of all vertices to the normal vectors encoded in the given baked normals object. + */ + public MutableQuad setNormal(BakedNormals bakedNormals) { + normals[0] = bakedNormals.normal(0); + normals[1] = bakedNormals.normal(1); + normals[2] = bakedNormals.normal(2); + normals[3] = bakedNormals.normal(3); + return this; + } + + /** + * Recomputes the quad normal from the vertex positions. + * + *

Assumes that the quad is planar. + */ + public MutableQuad recomputeNormals(boolean updateDirection) { + int normal = BakedNormals.computeQuadNormal(positions[0], positions[1], positions[2], positions[3]); + Arrays.fill(normals, normal); + if (updateDirection) { + float nX = BakedNormals.unpackX(normal); + float nY = BakedNormals.unpackY(normal); + float nZ = BakedNormals.unpackZ(normal); + setDirection(Direction.getApproximateNearest(nX, nY, nZ)); + } + return this; + } + + /** + * {@return the color of a given vertex in ARGB form} + * + * @see ARGB + */ + @Contract(pure = true) + public int color(int vertexIndex) { + return colors[vertexIndex]; + } + + /** + * Sets the color of all vertices to a packed ARGB color. + * + * @see ARGB + */ + public MutableQuad setColor(int packedColor) { + colors[0] = packedColor; + colors[1] = packedColor; + colors[2] = packedColor; + colors[3] = packedColor; + return this; + } + + /** + * Sets the color of a vertex to a packed ARGB color. + * + * @see ARGB + */ + public MutableQuad setColor(int vertexIndex, int packedColor) { + colors[vertexIndex] = packedColor; + return this; + } + + /** + * Sets the color of a vertex from integer components (0-255). + * + * @see ARGB + */ + public MutableQuad setColor(int vertexIndex, int r, int g, int b, int a) { + return setColor(vertexIndex, ARGB.color(a, r, g, b)); + } + + /** + * Sets the color of all vertices to a packed ARGB color. + */ + public MutableQuad setColor(BakedColors bakedColors) { + colors[0] = bakedColors.color(0); + colors[1] = bakedColors.color(1); + colors[2] = bakedColors.color(2); + colors[3] = bakedColors.color(3); + return this; + } + + @Contract(pure = true) + public boolean hasAmbientOcclusion() { + return hasAmbientOcclusion; + } + + public MutableQuad setHasAmbientOcclusion(boolean hasAmbientOcclusion) { + this.hasAmbientOcclusion = hasAmbientOcclusion; + return this; + } + + public MutableQuad setFrom(BakedQuad quad) { + lastSourceQuad = quad; + for (int i = 0; i < 4; i++) { + positions[i].set(quad.position(i)); + normals[i] = quad.bakedNormals().normal(i); + colors[i] = quad.bakedColors().color(i); + uvs[i] = quad.packedUV(i); + } + tintIndex = quad.tintIndex(); + direction = quad.direction(); + sprite = quad.sprite(); + shade = quad.shade(); + lightEmission = quad.lightEmission(); + hasAmbientOcclusion = quad.hasAmbientOcclusion(); + return this; + } + + /** + * Assumes that the UV coordinates are in sprite-space and transforms + * them to atlas-space. + */ + private void transformUvsFromSpriteToAtlas() { + var sprite = requiredSprite(); + for (int i = 0; i < 4; i++) { + long packedUv = packedUv(i); + setUv(i, sprite.getU(UVPair.unpackU(packedUv)), sprite.getV(UVPair.unpackV(packedUv))); + } + } + + /** + * Assumes that the UV coordinates are in atlas-space and transforms + * them to sprite-space. + */ + private void transformUvsFromAtlasToSprite() { + var sprite = requiredSprite(); + var uOrigin = sprite.getU0(); + var vOrigin = sprite.getV0(); + var uWidth = sprite.getU1() - uOrigin; + var vWidth = sprite.getV1() - vOrigin; + + for (int i = 0; i < 4; i++) { + long packedUv = packedUv(i); + float u = (UVPair.unpackU(packedUv) - uOrigin) / uWidth; + float v = (UVPair.unpackV(packedUv) - vOrigin) / vWidth; + setUv(i, u, v); + } + } + + @Contract(pure = true) + public BakedQuad toBakedQuad() { + // Try to reuse objects from the last baked quad that we copied from to reduce allocations if + // the quad was only partially transformed. + Vector3fc pos0; + Vector3fc pos1; + Vector3fc pos2; + Vector3fc pos3; + BakedNormals bakedNormals; + BakedColors bakedColors; + if (lastSourceQuad != null) { + pos0 = reuseVector(lastSourceQuad, positions[0]); + pos1 = reuseVector(lastSourceQuad, positions[1]); + pos2 = reuseVector(lastSourceQuad, positions[2]); + pos3 = reuseVector(lastSourceQuad, positions[3]); + + // If the normals did not change, reuse the old object + bakedNormals = lastSourceQuad.bakedNormals(); + for (int i = 0; i < 4; i++) { + if (bakedNormals.normal(i) != normals[i]) { + // At least one normal is different -> copy + bakedNormals = BakedNormals.of(normals[0], normals[1], normals[2], normals[3]); + break; + } + } + + // If the colors did not change, reuse the old object + bakedColors = lastSourceQuad.bakedColors(); + for (int i = 0; i < 4; i++) { + if (bakedColors.color(i) != colors[i]) { + // The color for at least one vertex is different -> copy + bakedColors = BakedColors.of(colors[0], colors[1], colors[2], colors[3]); + break; + } + } + } else { + pos0 = new Vector3f(positions[0]); + pos1 = new Vector3f(positions[1]); + pos2 = new Vector3f(positions[2]); + pos3 = new Vector3f(positions[3]); + bakedNormals = BakedNormals.of(normals[0], normals[1], normals[2], normals[3]); + bakedColors = BakedColors.of(colors[0], colors[1], colors[2], colors[3]); + } + + var sprite = requiredSprite(); + return new BakedQuad( + pos0, + pos1, + pos2, + pos3, + uvs[0], + uvs[1], + uvs[2], + uvs[3], + tintIndex, + direction, + sprite, + shade, + lightEmission, + bakedNormals, + bakedColors, + hasAmbientOcclusion); + } + + /** + * Tries to reuse the position vectors of the last quad we sourced any data from. + * This avoids unnecessary allocations if the positions of the quad were not transformed, + * or if a rotation simply rotated the order of positions. + */ + private static Vector3fc reuseVector(BakedQuad quad, Vector3f position) { + for (int i = 0; i < 4; i++) { + if (quad.position(i).equals(position)) { + return quad.position(i); + } + } + return new Vector3f(position); // Copy if reuse is not possible + } + + /** + * Applies the given matrix to this quads position and normals (if specified). + *

Note that the {@linkplain #direction()} is not transformed. + */ + public MutableQuad transform(Matrix4f rotation) { + Vector3f tmp = null; + for (int i = 0; i < 4; i++) { + rotation.transformPosition(positions[i]); + var normal = normals[i]; + if (!BakedNormals.isUnspecified(normal)) { + tmp = BakedNormals.unpack(normal, tmp); + rotation.transformDirection(tmp); + normals[i] = BakedNormals.pack(tmp); + } + } + + return this; + } + + /** + * Recalculates the order of vertices to conform to the order expected by the Vanilla AO algorithm. + * + *

It uses the current {@linkplain #direction() direction} and only works correctly for axis-aligned quads. + * + * @see FaceBakery#recalculateWinding + */ + public MutableQuad recalculateWinding() { + FaceBakery.recalculateWinding(positions, uvs, direction, colors, normals); + return this; + } + + /** + * {@return a copy of this mutable quad} + */ + public MutableQuad copy() { + return copyInto(new MutableQuad()); + } + + /** + * Copies the contents of this mutable quad into the provided mutable quad and returns it. + */ + public MutableQuad copyInto(MutableQuad dest) { + for (int i = 0; i < 4; i++) { + dest.positions[i].set(positions[i]); + } + System.arraycopy(uvs, 0, dest.uvs, 0, uvs.length); + System.arraycopy(normals, 0, dest.normals, 0, normals.length); + System.arraycopy(colors, 0, dest.colors, 0, colors.length); + dest.tintIndex = tintIndex; + dest.direction = direction; + dest.sprite = sprite; + dest.shade = shade; + dest.lightEmission = lightEmission; + dest.hasAmbientOcclusion = hasAmbientOcclusion; + dest.lastSourceQuad = lastSourceQuad; + return dest; + } + + public MutableQuad reset() { + for (int i = 0; i < 4; i++) { + positions[i].set(0, 0, 0); + } + Arrays.fill(uvs, 0L); + Arrays.fill(normals, 0); + Arrays.fill(colors, 0xFFFFFFFF); + direction = Direction.DOWN; + sprite = null; + tintIndex = -1; + shade = true; + lightEmission = 0; + hasAmbientOcclusion = false; + lastSourceQuad = null; + + return this; + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/model/quad/UVTransform.java b/src/client/java/net/neoforged/neoforge/client/model/quad/UVTransform.java new file mode 100644 index 00000000000..20fadfd4b14 --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/model/quad/UVTransform.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.model.quad; + +import com.mojang.math.Quadrant; +import java.util.Objects; +import net.minecraft.client.model.geom.builders.UVPair; + +public class UVTransform { + private static final UVTransform[] TRANSFORMS = createTransforms(); + public static final UVTransform IDENTITY = of(Quadrant.R0, false, false); + + final int rotation; + final boolean flipU; + final boolean flipV; + final Quadrant quadrant; + + private UVTransform(Quadrant rotation, boolean flipU, boolean flipV) { + this.rotation = rotation.shift; + this.quadrant = rotation; + this.flipU = flipU; + this.flipV = flipV; + } + + public boolean isIdentity() { + return this == IDENTITY; + } + + public static UVTransform of(Quadrant rotation, boolean flipU, boolean flipV) { + return TRANSFORMS[makeIndex(rotation.shift, flipU, flipV)]; + } + + public long transformPacked(long packedUv) { + float u = UVPair.unpackU(packedUv); + float v = UVPair.unpackV(packedUv); + + switch (rotation) { + case 0 -> {} + case 1 -> { + var tmp = u; + u = v; + v = 1 - tmp; + } + case 2 -> { + u = 1 - u; + v = 1 - v; + } + case 3 -> { + var tmp = u; + u = 1 - v; + v = tmp; + } + } + + if (flipU) { + u = 1 - u; + } + if (flipV) { + v = 1 - v; + } + + return UVPair.pack(u, v); + } + + private static UVTransform[] createTransforms() { + var result = new UVTransform[16]; + for (var quadrant : Quadrant.values()) { + for (var flipU = 0; flipU < 2; flipU++) { + for (var flipV = 0; flipV < 2; flipV++) { + var transform = new UVTransform(quadrant, flipU > 0, flipV > 0); + result[makeIndex(transform.rotation, flipU > 0, flipV > 0)] = transform; + } + } + } + // Just to be sure + for (var uvTransform : result) { + Objects.requireNonNull(uvTransform); + } + return result; + } + + private static int makeIndex(int rotation, boolean flipU, boolean flipV) { + var result = rotation & 3; + if (flipU) { + result |= 0x4; + } + if (flipV) { + result |= 0x8; + } + return result; + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/network/ClientPayloadHandler.java b/src/client/java/net/neoforged/neoforge/client/network/ClientPayloadHandler.java index 9fdcb5764d8..472abcbf2b1 100644 --- a/src/client/java/net/neoforged/neoforge/client/network/ClientPayloadHandler.java +++ b/src/client/java/net/neoforged/neoforge/client/network/ClientPayloadHandler.java @@ -15,7 +15,6 @@ import net.minecraft.client.gui.screens.MenuScreens; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.MenuAccess; -import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.RegistryAccess; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; @@ -44,7 +43,6 @@ import net.neoforged.neoforge.network.payload.AdvancedContainerSetDataPayload; import net.neoforged.neoforge.network.payload.AdvancedOpenScreenPayload; import net.neoforged.neoforge.network.payload.AuxiliaryLightDataPayload; -import net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload; import net.neoforged.neoforge.network.payload.ConfigFilePayload; import net.neoforged.neoforge.network.payload.FrozenRegistryPayload; import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload; @@ -80,7 +78,6 @@ private static void register(RegisterClientPayloadHandlersEvent event) { event.register(AuxiliaryLightDataPayload.TYPE, ClientPayloadHandler::handle); event.register(RegistryDataMapSyncPayload.TYPE, ClientRegistryManager::handleDataMapSync); event.register(AdvancedContainerSetDataPayload.TYPE, ClientPayloadHandler::handle); - event.register(ClientboundCustomSetTimePayload.TYPE, ClientPayloadHandler::handle); event.register(RecipeContentPayload.TYPE, ClientPayloadHandler::handle); event.register(SyncAttachmentsPayload.TYPE, ClientPayloadHandler::handle); } @@ -183,14 +180,6 @@ private static void handle(AdvancedContainerSetDataPayload msg, IPayloadContext context.handle(msg.toVanillaPacket()); } - private static void handle(final ClientboundCustomSetTimePayload payload, final IPayloadContext context) { - @SuppressWarnings("resource") - final ClientLevel level = Minecraft.getInstance().level; - level.setTimeFromServer(payload.gameTime(), payload.dayTime(), payload.gameRule()); - level.setDayTimeFraction(payload.dayTimeFraction()); - level.setDayTimePerTick(payload.dayTimePerTick()); - } - private static void handle(final RecipeContentPayload payload, final IPayloadContext context) { var recipeMap = RecipeMap.create(payload.recipes()); NeoForge.EVENT_BUS.post(new RecipesReceivedEvent(payload.recipeTypes(), recipeMap)); @@ -207,7 +196,7 @@ private static void handle(SyncAttachmentsPayload payload, IPayloadContext conte } } case SyncAttachmentsPayload.ChunkTarget(var pos) -> { - var chunk = context.player().level().getChunk(pos.x, pos.z, ChunkStatus.FULL, false); + var chunk = context.player().level().getChunk(pos.x(), pos.z(), ChunkStatus.FULL, false); if (chunk == null) { LOGGER.warn("Received synced attachments from unknown chunk"); } else { diff --git a/src/client/java/net/neoforged/neoforge/client/settings/KeyModifier.java b/src/client/java/net/neoforged/neoforge/client/settings/KeyModifier.java index 2c8525b1661..c1c6e0e9376 100644 --- a/src/client/java/net/neoforged/neoforge/client/settings/KeyModifier.java +++ b/src/client/java/net/neoforged/neoforge/client/settings/KeyModifier.java @@ -6,6 +6,7 @@ package net.neoforged.neoforge.client.settings; import com.mojang.blaze3d.platform.InputConstants; +import com.mojang.blaze3d.platform.Window; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; @@ -16,6 +17,15 @@ import org.lwjgl.glfw.GLFW; public enum KeyModifier { + /** + * Always matches the Control Key, even on OSX which normally uses the Command Key for hotkeys. + * Since 1.21.11, Mojang uses Control on OSX for hotkeys that conflict with OSX global system shortcuts. + *

+ * For hotkeys that should use the Command key on OSX (like system hotkeys ⌘C for copy, ⌘P for paste, etc.), + * use {@link #CONTROL_OR_COMMAND} instead. + * For examples of places where Command should be used, see uses of + * `net.minecraft.client.input.InputWithModifiers#hasControlDownWithQuirk()`. + */ CONTROL { private static final InputConstants.Key[] KEYS = new InputConstants.Key[] { InputConstants.Type.KEYSYM.getOrCreate(GLFW.GLFW_KEY_LEFT_CONTROL), @@ -35,8 +45,7 @@ public boolean isActive(@Nullable IKeyConflictContext conflictContext) { @Override public Component getCombinedName(InputConstants.Key key, Supplier defaultLogic) { - String localizationFormatKey = InputQuirks.ON_OSX ? "neoforge.controlsgui.control.mac" : "neoforge.controlsgui.control"; - return Component.translatable(localizationFormatKey, defaultLogic.get()); + return Component.translatable("neoforge.controlsgui.control", defaultLogic.get()); } @Override @@ -44,6 +53,62 @@ public InputConstants.Key[] codes() { return KEYS; } }, + /** + * On Windows and Linux, this matches the {@link #CONTROL Control} Key. + * On OSX, this matches the Command Key (⌘). + *

+ * This is the default behavior expected by OSX players for system hotkeys (like ⌘C for copy, ⌘P for paste, etc.), + * and this follows the {@link InputQuirks#REPLACE_CTRL_KEY_WITH_CMD_KEY} rule. + * For examples of places where Command should be used, see uses of + * `net.minecraft.client.input.InputWithModifiers#hasControlDownWithQuirk()`. + *

+ * For hotkeys that should use Control even on OSX, use {@link #CONTROL} instead. + *

+ * Since 1.21.11, Mojang uses {@link #CONTROL Control} on OSX for hotkeys that conflict with OSX global system shortcuts. + * Use caution when setting default hotkeys with this modifier, because it's possible to end up minimizing + * the window or triggering some other system behavior instead of what you intended. + */ + CONTROL_OR_COMMAND { + private static final InputConstants.Key[] COMMAND_KEYS = new InputConstants.Key[] { + InputConstants.Type.KEYSYM.getOrCreate(GLFW.GLFW_KEY_LEFT_SUPER), + InputConstants.Type.KEYSYM.getOrCreate(GLFW.GLFW_KEY_RIGHT_SUPER), + }; + + @Override + public boolean matches(InputConstants.Key key) { + if (InputQuirks.REPLACE_CTRL_KEY_WITH_CMD_KEY) { + int keyCode = key.getValue(); + return keyCode == GLFW.GLFW_KEY_LEFT_SUPER || keyCode == GLFW.GLFW_KEY_RIGHT_SUPER; + } + return CONTROL.matches(key); + } + + @Override + public boolean isActive(@Nullable IKeyConflictContext conflictContext) { + if (InputQuirks.REPLACE_CTRL_KEY_WITH_CMD_KEY) { + Minecraft minecraft = Minecraft.getInstance(); + Window window = minecraft.getWindow(); + return InputConstants.isKeyDown(window, GLFW.GLFW_KEY_LEFT_SUPER) || InputConstants.isKeyDown(window, GLFW.GLFW_KEY_RIGHT_SUPER); + } + return CONTROL.isActive(conflictContext); + } + + @Override + public Component getCombinedName(InputConstants.Key key, Supplier defaultLogic) { + if (InputQuirks.REPLACE_CTRL_KEY_WITH_CMD_KEY) { + return Component.translatable("neoforge.controlsgui.control.mac", defaultLogic.get()); + } + return CONTROL.getCombinedName(key, defaultLogic); + } + + @Override + public InputConstants.Key[] codes() { + if (InputQuirks.REPLACE_CTRL_KEY_WITH_CMD_KEY) { + return COMMAND_KEYS; + } + return CONTROL.codes(); + } + }, SHIFT { private static final InputConstants.Key[] KEYS = new InputConstants.Key[] { InputConstants.Type.KEYSYM.getOrCreate(GLFW.GLFW_KEY_LEFT_SHIFT), @@ -127,7 +192,7 @@ public InputConstants.Key[] codes() { } }; - public static final KeyModifier[] MODIFIER_VALUES = { SHIFT, CONTROL, ALT }; + public static final KeyModifier[] MODIFIER_VALUES = InputQuirks.ON_OSX ? new KeyModifier[] { SHIFT, CONTROL_OR_COMMAND, CONTROL, ALT } : new KeyModifier[] { SHIFT, CONTROL, ALT }; public static List getActiveModifiers() { List modifiers = new ArrayList<>(); @@ -166,8 +231,5 @@ public static KeyModifier valueFromString(String stringValue) { public abstract Component getCombinedName(InputConstants.Key key, Supplier defaultLogic); - // Neo: Make abstract in 1.21.5 - public InputConstants.Key[] codes() { - return null; - } + public abstract InputConstants.Key[] codes(); } diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 2c0cf103808..323c9172663 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -409,7 +409,7 @@ "tag.item.c.tools.ranged_weapon": "Ranged Weapons", "tag.item.c.tools.shear": "Shears", "tag.item.c.tools.shield": "Shields", - "tag.item.c.tools.spear": "Spears", + "tag.item.c.tools.trident": "Tridents", "tag.item.c.tools.wrench": "Wrenches", "tag.item.c.villager_job_sites": "Villager Job Sites", "tag.item.neoforge.enchanting_fuels": "Enchanting Fuels", diff --git a/src/generated/resources/data/c/tags/block/barrels.json b/src/generated/resources/data/c/tags/block/barrels.json index 94bded15d86..5e84e807f63 100644 --- a/src/generated/resources/data/c/tags/block/barrels.json +++ b/src/generated/resources/data/c/tags/block/barrels.json @@ -1,9 +1,5 @@ { "values": [ - "#c:barrels/wooden", - { - "id": "#forge:barrels", - "required": false - } + "#c:barrels/wooden" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/barrels/wooden.json b/src/generated/resources/data/c/tags/block/barrels/wooden.json index fedbc8ac53d..b07daae1c09 100644 --- a/src/generated/resources/data/c/tags/block/barrels/wooden.json +++ b/src/generated/resources/data/c/tags/block/barrels/wooden.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:barrel", - { - "id": "#forge:barrels/wooden", - "required": false - } + "minecraft:barrel" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/bookshelves.json b/src/generated/resources/data/c/tags/block/bookshelves.json index 68f756dba9b..c09b2185bd1 100644 --- a/src/generated/resources/data/c/tags/block/bookshelves.json +++ b/src/generated/resources/data/c/tags/block/bookshelves.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:bookshelf", - { - "id": "#forge:bookshelves", - "required": false - } + "minecraft:bookshelf" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/chests.json b/src/generated/resources/data/c/tags/block/chests.json index 9638aca09d0..16ea3146853 100644 --- a/src/generated/resources/data/c/tags/block/chests.json +++ b/src/generated/resources/data/c/tags/block/chests.json @@ -3,10 +3,6 @@ "minecraft:copper_chest", "#c:chests/ender", "#c:chests/trapped", - "#c:chests/wooden", - { - "id": "#forge:chests", - "required": false - } + "#c:chests/wooden" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/chests/ender.json b/src/generated/resources/data/c/tags/block/chests/ender.json index 1e652bcf24f..8c0af53136f 100644 --- a/src/generated/resources/data/c/tags/block/chests/ender.json +++ b/src/generated/resources/data/c/tags/block/chests/ender.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:ender_chest", - { - "id": "#forge:chests/ender", - "required": false - } + "minecraft:ender_chest" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/chests/trapped.json b/src/generated/resources/data/c/tags/block/chests/trapped.json index d0d8da248bf..f8924f5a051 100644 --- a/src/generated/resources/data/c/tags/block/chests/trapped.json +++ b/src/generated/resources/data/c/tags/block/chests/trapped.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:trapped_chest", - { - "id": "#forge:chests/trapped", - "required": false - } + "minecraft:trapped_chest" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/chests/wooden.json b/src/generated/resources/data/c/tags/block/chests/wooden.json index 0659e860e6b..86533f935bf 100644 --- a/src/generated/resources/data/c/tags/block/chests/wooden.json +++ b/src/generated/resources/data/c/tags/block/chests/wooden.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:chest", - "minecraft:trapped_chest", - { - "id": "#forge:chests/wooden", - "required": false - } + "minecraft:trapped_chest" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/cobblestones.json b/src/generated/resources/data/c/tags/block/cobblestones.json index b3c480393cc..6019d0d40e6 100644 --- a/src/generated/resources/data/c/tags/block/cobblestones.json +++ b/src/generated/resources/data/c/tags/block/cobblestones.json @@ -3,10 +3,6 @@ "#c:cobblestones/normal", "#c:cobblestones/infested", "#c:cobblestones/mossy", - "#c:cobblestones/deepslate", - { - "id": "#forge:cobblestone", - "required": false - } + "#c:cobblestones/deepslate" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/cobblestones/deepslate.json b/src/generated/resources/data/c/tags/block/cobblestones/deepslate.json index 34e7d23b82f..75f1ba31f44 100644 --- a/src/generated/resources/data/c/tags/block/cobblestones/deepslate.json +++ b/src/generated/resources/data/c/tags/block/cobblestones/deepslate.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:cobbled_deepslate", - { - "id": "#forge:cobblestone/deepslate", - "required": false - } + "minecraft:cobbled_deepslate" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/cobblestones/infested.json b/src/generated/resources/data/c/tags/block/cobblestones/infested.json index 2752247f3ad..a1d276601e6 100644 --- a/src/generated/resources/data/c/tags/block/cobblestones/infested.json +++ b/src/generated/resources/data/c/tags/block/cobblestones/infested.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:infested_cobblestone", - { - "id": "#forge:cobblestone/infested", - "required": false - } + "minecraft:infested_cobblestone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/cobblestones/mossy.json b/src/generated/resources/data/c/tags/block/cobblestones/mossy.json index 9a2e19c5694..c32be6c962c 100644 --- a/src/generated/resources/data/c/tags/block/cobblestones/mossy.json +++ b/src/generated/resources/data/c/tags/block/cobblestones/mossy.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:mossy_cobblestone", - { - "id": "#forge:cobblestone/mossy", - "required": false - } + "minecraft:mossy_cobblestone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/cobblestones/normal.json b/src/generated/resources/data/c/tags/block/cobblestones/normal.json index 6cebee9d29f..dac674da5d4 100644 --- a/src/generated/resources/data/c/tags/block/cobblestones/normal.json +++ b/src/generated/resources/data/c/tags/block/cobblestones/normal.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:cobblestone", - { - "id": "#forge:cobblestone/normal", - "required": false - } + "minecraft:cobblestone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/black.json b/src/generated/resources/data/c/tags/block/dyed/black.json index 52e29dcd466..d751a8001c6 100644 --- a/src/generated/resources/data/c/tags/block/dyed/black.json +++ b/src/generated/resources/data/c/tags/block/dyed/black.json @@ -12,14 +12,6 @@ "minecraft:black_stained_glass_pane", "minecraft:black_terracotta", "minecraft:black_wall_banner", - "minecraft:black_wool", - { - "id": "#forge:glass/black", - "required": false - }, - { - "id": "#forge:stained_glass/black", - "required": false - } + "minecraft:black_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/blue.json b/src/generated/resources/data/c/tags/block/dyed/blue.json index aa6f32d07c2..6aa8440457f 100644 --- a/src/generated/resources/data/c/tags/block/dyed/blue.json +++ b/src/generated/resources/data/c/tags/block/dyed/blue.json @@ -12,14 +12,6 @@ "minecraft:blue_stained_glass_pane", "minecraft:blue_terracotta", "minecraft:blue_wall_banner", - "minecraft:blue_wool", - { - "id": "#forge:glass/blue", - "required": false - }, - { - "id": "#forge:stained_glass/blue", - "required": false - } + "minecraft:blue_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/brown.json b/src/generated/resources/data/c/tags/block/dyed/brown.json index 94d1d0a7c7f..b8307f72467 100644 --- a/src/generated/resources/data/c/tags/block/dyed/brown.json +++ b/src/generated/resources/data/c/tags/block/dyed/brown.json @@ -12,14 +12,6 @@ "minecraft:brown_stained_glass_pane", "minecraft:brown_terracotta", "minecraft:brown_wall_banner", - "minecraft:brown_wool", - { - "id": "#forge:glass/brown", - "required": false - }, - { - "id": "#forge:stained_glass/brown", - "required": false - } + "minecraft:brown_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/cyan.json b/src/generated/resources/data/c/tags/block/dyed/cyan.json index b67187d66dd..6e5c8123b6b 100644 --- a/src/generated/resources/data/c/tags/block/dyed/cyan.json +++ b/src/generated/resources/data/c/tags/block/dyed/cyan.json @@ -12,14 +12,6 @@ "minecraft:cyan_stained_glass_pane", "minecraft:cyan_terracotta", "minecraft:cyan_wall_banner", - "minecraft:cyan_wool", - { - "id": "#forge:glass/cyan", - "required": false - }, - { - "id": "#forge:stained_glass/cyan", - "required": false - } + "minecraft:cyan_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/gray.json b/src/generated/resources/data/c/tags/block/dyed/gray.json index 172655a1a57..f71d3c82509 100644 --- a/src/generated/resources/data/c/tags/block/dyed/gray.json +++ b/src/generated/resources/data/c/tags/block/dyed/gray.json @@ -12,14 +12,6 @@ "minecraft:gray_stained_glass_pane", "minecraft:gray_terracotta", "minecraft:gray_wall_banner", - "minecraft:gray_wool", - { - "id": "#forge:glass/gray", - "required": false - }, - { - "id": "#forge:stained_glass/gray", - "required": false - } + "minecraft:gray_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/green.json b/src/generated/resources/data/c/tags/block/dyed/green.json index 12dd3904fc5..55e2fb08a1d 100644 --- a/src/generated/resources/data/c/tags/block/dyed/green.json +++ b/src/generated/resources/data/c/tags/block/dyed/green.json @@ -12,14 +12,6 @@ "minecraft:green_stained_glass_pane", "minecraft:green_terracotta", "minecraft:green_wall_banner", - "minecraft:green_wool", - { - "id": "#forge:glass/green", - "required": false - }, - { - "id": "#forge:stained_glass/green", - "required": false - } + "minecraft:green_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/light_blue.json b/src/generated/resources/data/c/tags/block/dyed/light_blue.json index ce884b573da..c13fe22e481 100644 --- a/src/generated/resources/data/c/tags/block/dyed/light_blue.json +++ b/src/generated/resources/data/c/tags/block/dyed/light_blue.json @@ -12,14 +12,6 @@ "minecraft:light_blue_stained_glass_pane", "minecraft:light_blue_terracotta", "minecraft:light_blue_wall_banner", - "minecraft:light_blue_wool", - { - "id": "#forge:glass/light_blue", - "required": false - }, - { - "id": "#forge:stained_glass/light_blue", - "required": false - } + "minecraft:light_blue_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/light_gray.json b/src/generated/resources/data/c/tags/block/dyed/light_gray.json index 439c12aec8d..ec0eb75bf40 100644 --- a/src/generated/resources/data/c/tags/block/dyed/light_gray.json +++ b/src/generated/resources/data/c/tags/block/dyed/light_gray.json @@ -12,14 +12,6 @@ "minecraft:light_gray_stained_glass_pane", "minecraft:light_gray_terracotta", "minecraft:light_gray_wall_banner", - "minecraft:light_gray_wool", - { - "id": "#forge:glass/light_gray", - "required": false - }, - { - "id": "#forge:stained_glass/light_gray", - "required": false - } + "minecraft:light_gray_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/lime.json b/src/generated/resources/data/c/tags/block/dyed/lime.json index 17e5b7ddf58..5a32316c66d 100644 --- a/src/generated/resources/data/c/tags/block/dyed/lime.json +++ b/src/generated/resources/data/c/tags/block/dyed/lime.json @@ -12,14 +12,6 @@ "minecraft:lime_stained_glass_pane", "minecraft:lime_terracotta", "minecraft:lime_wall_banner", - "minecraft:lime_wool", - { - "id": "#forge:glass/lime", - "required": false - }, - { - "id": "#forge:stained_glass/lime", - "required": false - } + "minecraft:lime_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/magenta.json b/src/generated/resources/data/c/tags/block/dyed/magenta.json index f833d1210ae..98aee6c88ec 100644 --- a/src/generated/resources/data/c/tags/block/dyed/magenta.json +++ b/src/generated/resources/data/c/tags/block/dyed/magenta.json @@ -12,22 +12,6 @@ "minecraft:magenta_stained_glass_pane", "minecraft:magenta_terracotta", "minecraft:magenta_wall_banner", - "minecraft:magenta_wool", - { - "id": "#forge:glass/magenta", - "required": false - }, - { - "id": "#forge:stained_glass/magenta", - "required": false - }, - { - "id": "#forge:glass/magenta", - "required": false - }, - { - "id": "#forge:stained_glass/magenta", - "required": false - } + "minecraft:magenta_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/orange.json b/src/generated/resources/data/c/tags/block/dyed/orange.json index 20076162d78..22d7b60a3d0 100644 --- a/src/generated/resources/data/c/tags/block/dyed/orange.json +++ b/src/generated/resources/data/c/tags/block/dyed/orange.json @@ -12,14 +12,6 @@ "minecraft:orange_stained_glass_pane", "minecraft:orange_terracotta", "minecraft:orange_wall_banner", - "minecraft:orange_wool", - { - "id": "#forge:glass/orange", - "required": false - }, - { - "id": "#forge:stained_glass/orange", - "required": false - } + "minecraft:orange_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/pink.json b/src/generated/resources/data/c/tags/block/dyed/pink.json index f9bdfe6c028..c45b47d69b5 100644 --- a/src/generated/resources/data/c/tags/block/dyed/pink.json +++ b/src/generated/resources/data/c/tags/block/dyed/pink.json @@ -12,14 +12,6 @@ "minecraft:pink_stained_glass_pane", "minecraft:pink_terracotta", "minecraft:pink_wall_banner", - "minecraft:pink_wool", - { - "id": "#forge:glass/pink", - "required": false - }, - { - "id": "#forge:stained_glass/pink", - "required": false - } + "minecraft:pink_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/purple.json b/src/generated/resources/data/c/tags/block/dyed/purple.json index 8d443e3a8b2..1d8bd2dcf56 100644 --- a/src/generated/resources/data/c/tags/block/dyed/purple.json +++ b/src/generated/resources/data/c/tags/block/dyed/purple.json @@ -12,14 +12,6 @@ "minecraft:purple_stained_glass_pane", "minecraft:purple_terracotta", "minecraft:purple_wall_banner", - "minecraft:purple_wool", - { - "id": "#forge:glass/purple", - "required": false - }, - { - "id": "#forge:stained_glass/purple", - "required": false - } + "minecraft:purple_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/red.json b/src/generated/resources/data/c/tags/block/dyed/red.json index 88ae73f6774..8e900dceab3 100644 --- a/src/generated/resources/data/c/tags/block/dyed/red.json +++ b/src/generated/resources/data/c/tags/block/dyed/red.json @@ -12,14 +12,6 @@ "minecraft:red_stained_glass_pane", "minecraft:red_terracotta", "minecraft:red_wall_banner", - "minecraft:red_wool", - { - "id": "#forge:glass/red", - "required": false - }, - { - "id": "#forge:stained_glass/red", - "required": false - } + "minecraft:red_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/white.json b/src/generated/resources/data/c/tags/block/dyed/white.json index 86c2a017891..e534cdf69c2 100644 --- a/src/generated/resources/data/c/tags/block/dyed/white.json +++ b/src/generated/resources/data/c/tags/block/dyed/white.json @@ -12,14 +12,6 @@ "minecraft:white_stained_glass_pane", "minecraft:white_terracotta", "minecraft:white_wall_banner", - "minecraft:white_wool", - { - "id": "#forge:glass/white", - "required": false - }, - { - "id": "#forge:stained_glass/white", - "required": false - } + "minecraft:white_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/dyed/yellow.json b/src/generated/resources/data/c/tags/block/dyed/yellow.json index 31711d54590..9086f0dd8ff 100644 --- a/src/generated/resources/data/c/tags/block/dyed/yellow.json +++ b/src/generated/resources/data/c/tags/block/dyed/yellow.json @@ -12,14 +12,6 @@ "minecraft:yellow_stained_glass_pane", "minecraft:yellow_terracotta", "minecraft:yellow_wall_banner", - "minecraft:yellow_wool", - { - "id": "#forge:glass/yellow", - "required": false - }, - { - "id": "#forge:stained_glass/yellow", - "required": false - } + "minecraft:yellow_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/end_stones.json b/src/generated/resources/data/c/tags/block/end_stones.json index aa227f8a3b9..f2d11375bce 100644 --- a/src/generated/resources/data/c/tags/block/end_stones.json +++ b/src/generated/resources/data/c/tags/block/end_stones.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:end_stone", - { - "id": "#forge:end_stones", - "required": false - } + "minecraft:end_stone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/fence_gates.json b/src/generated/resources/data/c/tags/block/fence_gates.json index 56c90931ccb..42dca6b914c 100644 --- a/src/generated/resources/data/c/tags/block/fence_gates.json +++ b/src/generated/resources/data/c/tags/block/fence_gates.json @@ -1,9 +1,5 @@ { "values": [ - "#c:fence_gates/wooden", - { - "id": "#forge:fence_gates", - "required": false - } + "#c:fence_gates/wooden" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/fence_gates/wooden.json b/src/generated/resources/data/c/tags/block/fence_gates/wooden.json index db55cb84ed4..88a130fa504 100644 --- a/src/generated/resources/data/c/tags/block/fence_gates/wooden.json +++ b/src/generated/resources/data/c/tags/block/fence_gates/wooden.json @@ -10,10 +10,6 @@ "minecraft:warped_fence_gate", "minecraft:mangrove_fence_gate", "minecraft:bamboo_fence_gate", - "minecraft:cherry_fence_gate", - { - "id": "#forge:fence_gates/wooden", - "required": false - } + "minecraft:cherry_fence_gate" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/fences.json b/src/generated/resources/data/c/tags/block/fences.json index 1e79564adee..3185a1f46b6 100644 --- a/src/generated/resources/data/c/tags/block/fences.json +++ b/src/generated/resources/data/c/tags/block/fences.json @@ -1,10 +1,6 @@ { "values": [ "#c:fences/nether_brick", - "#c:fences/wooden", - { - "id": "#forge:fences", - "required": false - } + "#c:fences/wooden" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/fences/nether_brick.json b/src/generated/resources/data/c/tags/block/fences/nether_brick.json index 30a88aea365..3f1aacfa7ef 100644 --- a/src/generated/resources/data/c/tags/block/fences/nether_brick.json +++ b/src/generated/resources/data/c/tags/block/fences/nether_brick.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_brick_fence", - { - "id": "#forge:fences/nether_brick", - "required": false - } + "minecraft:nether_brick_fence" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/fences/wooden.json b/src/generated/resources/data/c/tags/block/fences/wooden.json index bf67fa132ef..81202621144 100644 --- a/src/generated/resources/data/c/tags/block/fences/wooden.json +++ b/src/generated/resources/data/c/tags/block/fences/wooden.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:wooden_fences", - { - "id": "#forge:fences/wooden", - "required": false - } + "#minecraft:wooden_fences" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/glass_blocks.json b/src/generated/resources/data/c/tags/block/glass_blocks.json index 55b243f654a..61618a74980 100644 --- a/src/generated/resources/data/c/tags/block/glass_blocks.json +++ b/src/generated/resources/data/c/tags/block/glass_blocks.json @@ -2,10 +2,6 @@ "values": [ "#c:glass_blocks/colorless", "#c:glass_blocks/cheap", - "#c:glass_blocks/tinted", - { - "id": "#forge:glass", - "required": false - } + "#c:glass_blocks/tinted" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/glass_blocks/cheap.json b/src/generated/resources/data/c/tags/block/glass_blocks/cheap.json index ccd28136a66..3465b3884b0 100644 --- a/src/generated/resources/data/c/tags/block/glass_blocks/cheap.json +++ b/src/generated/resources/data/c/tags/block/glass_blocks/cheap.json @@ -16,10 +16,6 @@ "minecraft:brown_stained_glass", "minecraft:green_stained_glass", "minecraft:red_stained_glass", - "minecraft:black_stained_glass", - { - "id": "#forge:glass_silica", - "required": false - } + "minecraft:black_stained_glass" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/glass_blocks/colorless.json b/src/generated/resources/data/c/tags/block/glass_blocks/colorless.json index 7d2e81b6c44..ac8b5e50863 100644 --- a/src/generated/resources/data/c/tags/block/glass_blocks/colorless.json +++ b/src/generated/resources/data/c/tags/block/glass_blocks/colorless.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:glass", - { - "id": "#forge:glass_colorless", - "required": false - } + "minecraft:glass" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/glass_blocks/tinted.json b/src/generated/resources/data/c/tags/block/glass_blocks/tinted.json index 0a7d0f3f00d..4075a1556b3 100644 --- a/src/generated/resources/data/c/tags/block/glass_blocks/tinted.json +++ b/src/generated/resources/data/c/tags/block/glass_blocks/tinted.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:tinted_glass", - { - "id": "#forge:glass_tinted", - "required": false - } + "minecraft:tinted_glass" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/glass_panes/colorless.json b/src/generated/resources/data/c/tags/block/glass_panes/colorless.json index b7d7245a6aa..eb5756f9643 100644 --- a/src/generated/resources/data/c/tags/block/glass_panes/colorless.json +++ b/src/generated/resources/data/c/tags/block/glass_panes/colorless.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:glass_pane", - { - "id": "#forge:glass_panes_colorless", - "required": false - } + "minecraft:glass_pane" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/gravels.json b/src/generated/resources/data/c/tags/block/gravels.json index 80440dd1d45..f6968bff68a 100644 --- a/src/generated/resources/data/c/tags/block/gravels.json +++ b/src/generated/resources/data/c/tags/block/gravels.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:gravel", - { - "id": "#forge:gravel", - "required": false - } + "minecraft:gravel" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/netherracks.json b/src/generated/resources/data/c/tags/block/netherracks.json index 21c1554741f..daa9c66701a 100644 --- a/src/generated/resources/data/c/tags/block/netherracks.json +++ b/src/generated/resources/data/c/tags/block/netherracks.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:netherrack", - { - "id": "#forge:netherrack", - "required": false - } + "minecraft:netherrack" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/obsidians.json b/src/generated/resources/data/c/tags/block/obsidians.json index 3986b73df1c..5df539fb0ee 100644 --- a/src/generated/resources/data/c/tags/block/obsidians.json +++ b/src/generated/resources/data/c/tags/block/obsidians.json @@ -1,10 +1,6 @@ { "values": [ "#c:obsidians/normal", - "#c:obsidians/crying", - { - "id": "#forge:obsidian", - "required": false - } + "#c:obsidians/crying" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ore_bearing_ground/deepslate.json b/src/generated/resources/data/c/tags/block/ore_bearing_ground/deepslate.json index e3a93227979..0012c241a31 100644 --- a/src/generated/resources/data/c/tags/block/ore_bearing_ground/deepslate.json +++ b/src/generated/resources/data/c/tags/block/ore_bearing_ground/deepslate.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:deepslate", - { - "id": "#forge:ore_bearing_ground/deepslate", - "required": false - } + "minecraft:deepslate" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ore_bearing_ground/netherrack.json b/src/generated/resources/data/c/tags/block/ore_bearing_ground/netherrack.json index d8156115518..daa9c66701a 100644 --- a/src/generated/resources/data/c/tags/block/ore_bearing_ground/netherrack.json +++ b/src/generated/resources/data/c/tags/block/ore_bearing_ground/netherrack.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:netherrack", - { - "id": "#forge:ore_bearing_ground/netherrack", - "required": false - } + "minecraft:netherrack" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ore_bearing_ground/stone.json b/src/generated/resources/data/c/tags/block/ore_bearing_ground/stone.json index 08d0efdfe57..c2d7c79f3e7 100644 --- a/src/generated/resources/data/c/tags/block/ore_bearing_ground/stone.json +++ b/src/generated/resources/data/c/tags/block/ore_bearing_ground/stone.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:stone", - { - "id": "#forge:ore_bearing_ground/stone", - "required": false - } + "minecraft:stone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ore_rates/dense.json b/src/generated/resources/data/c/tags/block/ore_rates/dense.json index ded4e6606a3..69cfa783438 100644 --- a/src/generated/resources/data/c/tags/block/ore_rates/dense.json +++ b/src/generated/resources/data/c/tags/block/ore_rates/dense.json @@ -5,10 +5,6 @@ "minecraft:deepslate_lapis_ore", "minecraft:deepslate_redstone_ore", "minecraft:lapis_ore", - "minecraft:redstone_ore", - { - "id": "#forge:ore_rates/dense", - "required": false - } + "minecraft:redstone_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ore_rates/singular.json b/src/generated/resources/data/c/tags/block/ore_rates/singular.json index 3a2f12d573f..79e0f4b9a7c 100644 --- a/src/generated/resources/data/c/tags/block/ore_rates/singular.json +++ b/src/generated/resources/data/c/tags/block/ore_rates/singular.json @@ -11,10 +11,6 @@ "minecraft:emerald_ore", "minecraft:gold_ore", "minecraft:iron_ore", - "minecraft:nether_quartz_ore", - { - "id": "#forge:ore_rates/singular", - "required": false - } + "minecraft:nether_quartz_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ore_rates/sparse.json b/src/generated/resources/data/c/tags/block/ore_rates/sparse.json index 349b1e3d4be..3caf9ffe44e 100644 --- a/src/generated/resources/data/c/tags/block/ore_rates/sparse.json +++ b/src/generated/resources/data/c/tags/block/ore_rates/sparse.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_gold_ore", - { - "id": "#forge:ore_rates/sparse", - "required": false - } + "minecraft:nether_gold_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores.json b/src/generated/resources/data/c/tags/block/ores.json index ffce3487bec..3b2293aa8d8 100644 --- a/src/generated/resources/data/c/tags/block/ores.json +++ b/src/generated/resources/data/c/tags/block/ores.json @@ -9,10 +9,6 @@ "#c:ores/lapis", "#c:ores/netherite_scrap", "#c:ores/redstone", - "#c:ores/quartz", - { - "id": "#forge:ores", - "required": false - } + "#c:ores/quartz" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/coal.json b/src/generated/resources/data/c/tags/block/ores/coal.json index 2e088c72415..c1246af5163 100644 --- a/src/generated/resources/data/c/tags/block/ores/coal.json +++ b/src/generated/resources/data/c/tags/block/ores/coal.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:coal_ores", - { - "id": "#forge:ores/coal", - "required": false - } + "#minecraft:coal_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/copper.json b/src/generated/resources/data/c/tags/block/ores/copper.json index f51e56171f2..bfa31f2aed5 100644 --- a/src/generated/resources/data/c/tags/block/ores/copper.json +++ b/src/generated/resources/data/c/tags/block/ores/copper.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:copper_ores", - { - "id": "#forge:ores/copper", - "required": false - } + "#minecraft:copper_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/diamond.json b/src/generated/resources/data/c/tags/block/ores/diamond.json index 3a595fe6482..e0fe2e9d0ff 100644 --- a/src/generated/resources/data/c/tags/block/ores/diamond.json +++ b/src/generated/resources/data/c/tags/block/ores/diamond.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:diamond_ores", - { - "id": "#forge:ores/diamond", - "required": false - } + "#minecraft:diamond_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/emerald.json b/src/generated/resources/data/c/tags/block/ores/emerald.json index 25ec90670f7..fe8bed587cd 100644 --- a/src/generated/resources/data/c/tags/block/ores/emerald.json +++ b/src/generated/resources/data/c/tags/block/ores/emerald.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:emerald_ores", - { - "id": "#forge:ores/emerald", - "required": false - } + "#minecraft:emerald_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/gold.json b/src/generated/resources/data/c/tags/block/ores/gold.json index ab8f217a24d..52f7c26ba19 100644 --- a/src/generated/resources/data/c/tags/block/ores/gold.json +++ b/src/generated/resources/data/c/tags/block/ores/gold.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:gold_ores", - { - "id": "#forge:ores/gold", - "required": false - } + "#minecraft:gold_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/iron.json b/src/generated/resources/data/c/tags/block/ores/iron.json index 12fed97a891..9b135890e97 100644 --- a/src/generated/resources/data/c/tags/block/ores/iron.json +++ b/src/generated/resources/data/c/tags/block/ores/iron.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:iron_ores", - { - "id": "#forge:ores/iron", - "required": false - } + "#minecraft:iron_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/lapis.json b/src/generated/resources/data/c/tags/block/ores/lapis.json index 4609a406dcf..901b01187cd 100644 --- a/src/generated/resources/data/c/tags/block/ores/lapis.json +++ b/src/generated/resources/data/c/tags/block/ores/lapis.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:lapis_ores", - { - "id": "#forge:ores/lapis", - "required": false - } + "#minecraft:lapis_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/netherite_scrap.json b/src/generated/resources/data/c/tags/block/ores/netherite_scrap.json index 6cc208db8e5..910d1fb8e6a 100644 --- a/src/generated/resources/data/c/tags/block/ores/netherite_scrap.json +++ b/src/generated/resources/data/c/tags/block/ores/netherite_scrap.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:ancient_debris", - { - "id": "#forge:ores/netherite_scrap", - "required": false - } + "minecraft:ancient_debris" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/quartz.json b/src/generated/resources/data/c/tags/block/ores/quartz.json index 5433b2ed6fa..f0bc7a4657c 100644 --- a/src/generated/resources/data/c/tags/block/ores/quartz.json +++ b/src/generated/resources/data/c/tags/block/ores/quartz.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_quartz_ore", - { - "id": "#forge:ores/quartz", - "required": false - } + "minecraft:nether_quartz_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores/redstone.json b/src/generated/resources/data/c/tags/block/ores/redstone.json index 42cb0fd1ee4..252cdcbb38e 100644 --- a/src/generated/resources/data/c/tags/block/ores/redstone.json +++ b/src/generated/resources/data/c/tags/block/ores/redstone.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:redstone_ores", - { - "id": "#forge:ores/redstone", - "required": false - } + "#minecraft:redstone_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores_in_ground/deepslate.json b/src/generated/resources/data/c/tags/block/ores_in_ground/deepslate.json index 6b172a1533b..13e0c38aa16 100644 --- a/src/generated/resources/data/c/tags/block/ores_in_ground/deepslate.json +++ b/src/generated/resources/data/c/tags/block/ores_in_ground/deepslate.json @@ -7,10 +7,6 @@ "minecraft:deepslate_gold_ore", "minecraft:deepslate_iron_ore", "minecraft:deepslate_lapis_ore", - "minecraft:deepslate_redstone_ore", - { - "id": "#forge:ores_in_ground/deepslate", - "required": false - } + "minecraft:deepslate_redstone_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores_in_ground/netherrack.json b/src/generated/resources/data/c/tags/block/ores_in_ground/netherrack.json index 83b110ef9e5..090233bd460 100644 --- a/src/generated/resources/data/c/tags/block/ores_in_ground/netherrack.json +++ b/src/generated/resources/data/c/tags/block/ores_in_ground/netherrack.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:nether_gold_ore", - "minecraft:nether_quartz_ore", - { - "id": "#forge:ores_in_ground/netherrack", - "required": false - } + "minecraft:nether_quartz_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/ores_in_ground/stone.json b/src/generated/resources/data/c/tags/block/ores_in_ground/stone.json index 97b26721aeb..568fbe7cb67 100644 --- a/src/generated/resources/data/c/tags/block/ores_in_ground/stone.json +++ b/src/generated/resources/data/c/tags/block/ores_in_ground/stone.json @@ -7,10 +7,6 @@ "minecraft:gold_ore", "minecraft:iron_ore", "minecraft:lapis_ore", - "minecraft:redstone_ore", - { - "id": "#forge:ores_in_ground/stone", - "required": false - } + "minecraft:redstone_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/relocation_not_supported.json b/src/generated/resources/data/c/tags/block/relocation_not_supported.json index 0c0cf3a08fd..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/block/relocation_not_supported.json +++ b/src/generated/resources/data/c/tags/block/relocation_not_supported.json @@ -1,12 +1,3 @@ { - "values": [ - { - "id": "#forge:relocation_not_supported", - "required": false - }, - { - "id": "#forge:immovable", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/sands.json b/src/generated/resources/data/c/tags/block/sands.json index 43eaac83ae7..f4b6e6a7691 100644 --- a/src/generated/resources/data/c/tags/block/sands.json +++ b/src/generated/resources/data/c/tags/block/sands.json @@ -1,10 +1,6 @@ { "values": [ "#c:sands/colorless", - "#c:sands/red", - { - "id": "#forge:sand", - "required": false - } + "#c:sands/red" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/sands/colorless.json b/src/generated/resources/data/c/tags/block/sands/colorless.json index 93cdef191bc..af14f42f568 100644 --- a/src/generated/resources/data/c/tags/block/sands/colorless.json +++ b/src/generated/resources/data/c/tags/block/sands/colorless.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:sand", - { - "id": "#forge:sand/colorless", - "required": false - } + "minecraft:sand" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/sands/red.json b/src/generated/resources/data/c/tags/block/sands/red.json index 03eba73b127..9934cb5bbcf 100644 --- a/src/generated/resources/data/c/tags/block/sands/red.json +++ b/src/generated/resources/data/c/tags/block/sands/red.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:red_sand", - { - "id": "#forge:sand/red", - "required": false - } + "minecraft:red_sand" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/sandstone/blocks.json b/src/generated/resources/data/c/tags/block/sandstone/blocks.json index 5684db6caf7..df1b934e5c7 100644 --- a/src/generated/resources/data/c/tags/block/sandstone/blocks.json +++ b/src/generated/resources/data/c/tags/block/sandstone/blocks.json @@ -1,10 +1,6 @@ { "values": [ "#c:sandstone/red_blocks", - "#c:sandstone/uncolored_blocks", - { - "id": "#forge:sandstone", - "required": false - } + "#c:sandstone/uncolored_blocks" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/stones.json b/src/generated/resources/data/c/tags/block/stones.json index 28489984599..c95195f10c8 100644 --- a/src/generated/resources/data/c/tags/block/stones.json +++ b/src/generated/resources/data/c/tags/block/stones.json @@ -5,10 +5,6 @@ "minecraft:granite", "minecraft:stone", "minecraft:deepslate", - "minecraft:tuff", - { - "id": "#forge:stone", - "required": false - } + "minecraft:tuff" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks.json b/src/generated/resources/data/c/tags/block/storage_blocks.json index a837ec688cf..bb0022c04fa 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks.json @@ -16,10 +16,6 @@ "#c:storage_blocks/redstone", "#c:storage_blocks/resin", "#c:storage_blocks/slime", - "#c:storage_blocks/wheat", - { - "id": "#forge:storage_blocks", - "required": false - } + "#c:storage_blocks/wheat" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/coal.json b/src/generated/resources/data/c/tags/block/storage_blocks/coal.json index b8479ced38e..4b7921705b6 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/coal.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/coal.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:coal_block", - { - "id": "#forge:storage_blocks/coal", - "required": false - } + "minecraft:coal_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/copper.json b/src/generated/resources/data/c/tags/block/storage_blocks/copper.json index acd2a6a7a48..015bec70c31 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/copper.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/copper.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:copper_block", - { - "id": "#forge:storage_blocks/copper", - "required": false - } + "minecraft:copper_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/diamond.json b/src/generated/resources/data/c/tags/block/storage_blocks/diamond.json index 76426ba425f..acd7f52de5e 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/diamond.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/diamond.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:diamond_block", - { - "id": "#forge:storage_blocks/diamond", - "required": false - } + "minecraft:diamond_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/emerald.json b/src/generated/resources/data/c/tags/block/storage_blocks/emerald.json index 7a41454d94d..152063ec6c6 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/emerald.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/emerald.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:emerald_block", - { - "id": "#forge:storage_blocks/emerald", - "required": false - } + "minecraft:emerald_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/gold.json b/src/generated/resources/data/c/tags/block/storage_blocks/gold.json index a4116fc77fd..546dde03c96 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/gold.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/gold.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:gold_block", - { - "id": "#forge:storage_blocks/gold", - "required": false - } + "minecraft:gold_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/iron.json b/src/generated/resources/data/c/tags/block/storage_blocks/iron.json index f0e9fcca1fe..01fb2965f2c 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/iron.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/iron.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:iron_block", - { - "id": "#forge:storage_blocks/iron", - "required": false - } + "minecraft:iron_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/lapis.json b/src/generated/resources/data/c/tags/block/storage_blocks/lapis.json index b5f41d8d4e7..f4ca82bbd4d 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/lapis.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/lapis.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:lapis_block", - { - "id": "#forge:storage_blocks/lapis", - "required": false - } + "minecraft:lapis_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/netherite.json b/src/generated/resources/data/c/tags/block/storage_blocks/netherite.json index a3dfe0d53c5..83433d44eb8 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/netherite.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/netherite.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:netherite_block", - { - "id": "#forge:storage_blocks/netherite", - "required": false - } + "minecraft:netherite_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/raw_copper.json b/src/generated/resources/data/c/tags/block/storage_blocks/raw_copper.json index 8f12fb63a74..1a21e230ef0 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/raw_copper.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/raw_copper.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_copper_block", - { - "id": "#forge:storage_blocks/raw_copper", - "required": false - } + "minecraft:raw_copper_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/raw_gold.json b/src/generated/resources/data/c/tags/block/storage_blocks/raw_gold.json index dcee1e225b1..80781ce6675 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/raw_gold.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/raw_gold.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_gold_block", - { - "id": "#forge:storage_blocks/raw_gold", - "required": false - } + "minecraft:raw_gold_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/raw_iron.json b/src/generated/resources/data/c/tags/block/storage_blocks/raw_iron.json index 3f0ecf27ad1..13ed9fc651b 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/raw_iron.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/raw_iron.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_iron_block", - { - "id": "#forge:storage_blocks/raw_iron", - "required": false - } + "minecraft:raw_iron_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/redstone.json b/src/generated/resources/data/c/tags/block/storage_blocks/redstone.json index 49fa7a5a26a..f5fd89c5414 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks/redstone.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks/redstone.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:redstone_block", - { - "id": "#forge:storage_blocks/redstone", - "required": false - } + "minecraft:redstone_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/entity_type/boats.json b/src/generated/resources/data/c/tags/entity_type/boats.json index 785162519ce..258462ccd14 100644 --- a/src/generated/resources/data/c/tags/entity_type/boats.json +++ b/src/generated/resources/data/c/tags/entity_type/boats.json @@ -10,10 +10,6 @@ "minecraft:pale_oak_chest_boat", "minecraft:dark_oak_chest_boat", "minecraft:mangrove_chest_boat", - "minecraft:bamboo_chest_raft", - { - "id": "#forge:boats", - "required": false - } + "minecraft:bamboo_chest_raft" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/entity_type/bosses.json b/src/generated/resources/data/c/tags/entity_type/bosses.json index 5b52cfe527e..4be4cce8312 100644 --- a/src/generated/resources/data/c/tags/entity_type/bosses.json +++ b/src/generated/resources/data/c/tags/entity_type/bosses.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:ender_dragon", - "minecraft:wither", - { - "id": "#forge:bosses", - "required": false - } + "minecraft:wither" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/entity_type/minecarts.json b/src/generated/resources/data/c/tags/entity_type/minecarts.json index 6b7fe052ea9..a29375ad2e7 100644 --- a/src/generated/resources/data/c/tags/entity_type/minecarts.json +++ b/src/generated/resources/data/c/tags/entity_type/minecarts.json @@ -6,10 +6,6 @@ "minecraft:hopper_minecart", "minecraft:spawner_minecart", "minecraft:tnt_minecart", - "minecraft:command_block_minecart", - { - "id": "#forge:minecarts", - "required": false - } + "minecraft:command_block_minecart" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/beetroot_soup.json b/src/generated/resources/data/c/tags/fluid/beetroot_soup.json index df5cf202597..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/fluid/beetroot_soup.json +++ b/src/generated/resources/data/c/tags/fluid/beetroot_soup.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:beetroot_soup", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/gaseous.json b/src/generated/resources/data/c/tags/fluid/gaseous.json index 37a9047e11a..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/fluid/gaseous.json +++ b/src/generated/resources/data/c/tags/fluid/gaseous.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:gaseous", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/honey.json b/src/generated/resources/data/c/tags/fluid/honey.json index 5b2fe217e25..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/fluid/honey.json +++ b/src/generated/resources/data/c/tags/fluid/honey.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:honey", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/milk.json b/src/generated/resources/data/c/tags/fluid/milk.json index 5e27201a7ec..3bab1951b34 100644 --- a/src/generated/resources/data/c/tags/fluid/milk.json +++ b/src/generated/resources/data/c/tags/fluid/milk.json @@ -7,10 +7,6 @@ { "id": "minecraft:flowing_milk", "required": false - }, - { - "id": "#forge:milk", - "required": false } ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/mushroom_stew.json b/src/generated/resources/data/c/tags/fluid/mushroom_stew.json index 7f40246aadb..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/fluid/mushroom_stew.json +++ b/src/generated/resources/data/c/tags/fluid/mushroom_stew.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:mushroom_stew", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/potion.json b/src/generated/resources/data/c/tags/fluid/potion.json index 3c851413d48..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/fluid/potion.json +++ b/src/generated/resources/data/c/tags/fluid/potion.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:potion", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/rabbit_stew.json b/src/generated/resources/data/c/tags/fluid/rabbit_stew.json index fb82b6b59c5..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/fluid/rabbit_stew.json +++ b/src/generated/resources/data/c/tags/fluid/rabbit_stew.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:rabbit_stew", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/suspicious_stew.json b/src/generated/resources/data/c/tags/fluid/suspicious_stew.json index 3069b778c79..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/fluid/suspicious_stew.json +++ b/src/generated/resources/data/c/tags/fluid/suspicious_stew.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:suspicious_stew", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/armors.json b/src/generated/resources/data/c/tags/item/armors.json index 14a7f19912b..40c7e26de01 100644 --- a/src/generated/resources/data/c/tags/item/armors.json +++ b/src/generated/resources/data/c/tags/item/armors.json @@ -15,10 +15,6 @@ { "id": "#c:armors/wolf", "required": false - }, - { - "id": "#forge:armors", - "required": false } ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/barrels.json b/src/generated/resources/data/c/tags/item/barrels.json index 94bded15d86..5e84e807f63 100644 --- a/src/generated/resources/data/c/tags/item/barrels.json +++ b/src/generated/resources/data/c/tags/item/barrels.json @@ -1,9 +1,5 @@ { "values": [ - "#c:barrels/wooden", - { - "id": "#forge:barrels", - "required": false - } + "#c:barrels/wooden" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/barrels/wooden.json b/src/generated/resources/data/c/tags/item/barrels/wooden.json index fedbc8ac53d..b07daae1c09 100644 --- a/src/generated/resources/data/c/tags/item/barrels/wooden.json +++ b/src/generated/resources/data/c/tags/item/barrels/wooden.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:barrel", - { - "id": "#forge:barrels/wooden", - "required": false - } + "minecraft:barrel" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/bones.json b/src/generated/resources/data/c/tags/item/bones.json index 883cdcc2e12..5af534fcffb 100644 --- a/src/generated/resources/data/c/tags/item/bones.json +++ b/src/generated/resources/data/c/tags/item/bones.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:bone", - { - "id": "#forge:bones", - "required": false - } + "minecraft:bone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/bookshelves.json b/src/generated/resources/data/c/tags/item/bookshelves.json index 68f756dba9b..c09b2185bd1 100644 --- a/src/generated/resources/data/c/tags/item/bookshelves.json +++ b/src/generated/resources/data/c/tags/item/bookshelves.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:bookshelf", - { - "id": "#forge:bookshelves", - "required": false - } + "minecraft:bookshelf" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/bricks/nether.json b/src/generated/resources/data/c/tags/item/bricks/nether.json index 3f63a414f04..ec7ed3ee9ad 100644 --- a/src/generated/resources/data/c/tags/item/bricks/nether.json +++ b/src/generated/resources/data/c/tags/item/bricks/nether.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_brick", - { - "id": "#forge:ingots/nether_brick", - "required": false - } + "minecraft:nether_brick" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/bricks/normal.json b/src/generated/resources/data/c/tags/item/bricks/normal.json index a40223a69ba..8f632e499a6 100644 --- a/src/generated/resources/data/c/tags/item/bricks/normal.json +++ b/src/generated/resources/data/c/tags/item/bricks/normal.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:brick", - { - "id": "#forge:ingots/brick", - "required": false - } + "minecraft:brick" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/chests.json b/src/generated/resources/data/c/tags/item/chests.json index 9638aca09d0..16ea3146853 100644 --- a/src/generated/resources/data/c/tags/item/chests.json +++ b/src/generated/resources/data/c/tags/item/chests.json @@ -3,10 +3,6 @@ "minecraft:copper_chest", "#c:chests/ender", "#c:chests/trapped", - "#c:chests/wooden", - { - "id": "#forge:chests", - "required": false - } + "#c:chests/wooden" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/chests/ender.json b/src/generated/resources/data/c/tags/item/chests/ender.json index 1e652bcf24f..8c0af53136f 100644 --- a/src/generated/resources/data/c/tags/item/chests/ender.json +++ b/src/generated/resources/data/c/tags/item/chests/ender.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:ender_chest", - { - "id": "#forge:chests/ender", - "required": false - } + "minecraft:ender_chest" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/chests/trapped.json b/src/generated/resources/data/c/tags/item/chests/trapped.json index d0d8da248bf..f8924f5a051 100644 --- a/src/generated/resources/data/c/tags/item/chests/trapped.json +++ b/src/generated/resources/data/c/tags/item/chests/trapped.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:trapped_chest", - { - "id": "#forge:chests/trapped", - "required": false - } + "minecraft:trapped_chest" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/chests/wooden.json b/src/generated/resources/data/c/tags/item/chests/wooden.json index 0659e860e6b..86533f935bf 100644 --- a/src/generated/resources/data/c/tags/item/chests/wooden.json +++ b/src/generated/resources/data/c/tags/item/chests/wooden.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:chest", - "minecraft:trapped_chest", - { - "id": "#forge:chests/wooden", - "required": false - } + "minecraft:trapped_chest" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/cobblestones.json b/src/generated/resources/data/c/tags/item/cobblestones.json index b3c480393cc..6019d0d40e6 100644 --- a/src/generated/resources/data/c/tags/item/cobblestones.json +++ b/src/generated/resources/data/c/tags/item/cobblestones.json @@ -3,10 +3,6 @@ "#c:cobblestones/normal", "#c:cobblestones/infested", "#c:cobblestones/mossy", - "#c:cobblestones/deepslate", - { - "id": "#forge:cobblestone", - "required": false - } + "#c:cobblestones/deepslate" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/cobblestones/deepslate.json b/src/generated/resources/data/c/tags/item/cobblestones/deepslate.json index 34e7d23b82f..75f1ba31f44 100644 --- a/src/generated/resources/data/c/tags/item/cobblestones/deepslate.json +++ b/src/generated/resources/data/c/tags/item/cobblestones/deepslate.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:cobbled_deepslate", - { - "id": "#forge:cobblestone/deepslate", - "required": false - } + "minecraft:cobbled_deepslate" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/cobblestones/infested.json b/src/generated/resources/data/c/tags/item/cobblestones/infested.json index 2752247f3ad..a1d276601e6 100644 --- a/src/generated/resources/data/c/tags/item/cobblestones/infested.json +++ b/src/generated/resources/data/c/tags/item/cobblestones/infested.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:infested_cobblestone", - { - "id": "#forge:cobblestone/infested", - "required": false - } + "minecraft:infested_cobblestone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/cobblestones/mossy.json b/src/generated/resources/data/c/tags/item/cobblestones/mossy.json index 9a2e19c5694..c32be6c962c 100644 --- a/src/generated/resources/data/c/tags/item/cobblestones/mossy.json +++ b/src/generated/resources/data/c/tags/item/cobblestones/mossy.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:mossy_cobblestone", - { - "id": "#forge:cobblestone/mossy", - "required": false - } + "minecraft:mossy_cobblestone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/cobblestones/normal.json b/src/generated/resources/data/c/tags/item/cobblestones/normal.json index 6cebee9d29f..dac674da5d4 100644 --- a/src/generated/resources/data/c/tags/item/cobblestones/normal.json +++ b/src/generated/resources/data/c/tags/item/cobblestones/normal.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:cobblestone", - { - "id": "#forge:cobblestone/normal", - "required": false - } + "minecraft:cobblestone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops.json b/src/generated/resources/data/c/tags/item/crops.json index 7a0bad9caba..452317ff338 100644 --- a/src/generated/resources/data/c/tags/item/crops.json +++ b/src/generated/resources/data/c/tags/item/crops.json @@ -9,10 +9,6 @@ "#c:crops/potato", "#c:crops/pumpkin", "#c:crops/sugar_cane", - "#c:crops/wheat", - { - "id": "#forge:crops", - "required": false - } + "#c:crops/wheat" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/beetroot.json b/src/generated/resources/data/c/tags/item/crops/beetroot.json index cc56242351e..b28b723c4b1 100644 --- a/src/generated/resources/data/c/tags/item/crops/beetroot.json +++ b/src/generated/resources/data/c/tags/item/crops/beetroot.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:beetroot", - { - "id": "#forge:crops/beetroot", - "required": false - } + "minecraft:beetroot" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/carrot.json b/src/generated/resources/data/c/tags/item/crops/carrot.json index 9a637ed3cc2..f9630d13474 100644 --- a/src/generated/resources/data/c/tags/item/crops/carrot.json +++ b/src/generated/resources/data/c/tags/item/crops/carrot.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:carrot", - { - "id": "#forge:crops/carrot", - "required": false - } + "minecraft:carrot" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/nether_wart.json b/src/generated/resources/data/c/tags/item/crops/nether_wart.json index 9e8eb9e0369..5960d80cb92 100644 --- a/src/generated/resources/data/c/tags/item/crops/nether_wart.json +++ b/src/generated/resources/data/c/tags/item/crops/nether_wart.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_wart", - { - "id": "#forge:crops/nether_wart", - "required": false - } + "minecraft:nether_wart" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/potato.json b/src/generated/resources/data/c/tags/item/crops/potato.json index fca8ec880c9..47fc151cd15 100644 --- a/src/generated/resources/data/c/tags/item/crops/potato.json +++ b/src/generated/resources/data/c/tags/item/crops/potato.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:potato", - { - "id": "#forge:crops/potato", - "required": false - } + "minecraft:potato" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/wheat.json b/src/generated/resources/data/c/tags/item/crops/wheat.json index 05dac35cc15..498cb445f6e 100644 --- a/src/generated/resources/data/c/tags/item/crops/wheat.json +++ b/src/generated/resources/data/c/tags/item/crops/wheat.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:wheat", - { - "id": "#forge:crops/wheat", - "required": false - } + "minecraft:wheat" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dusts.json b/src/generated/resources/data/c/tags/item/dusts.json index 45f697f1b07..4642bb1cb73 100644 --- a/src/generated/resources/data/c/tags/item/dusts.json +++ b/src/generated/resources/data/c/tags/item/dusts.json @@ -1,10 +1,6 @@ { "values": [ "#c:dusts/glowstone", - "#c:dusts/redstone", - { - "id": "#forge:dusts", - "required": false - } + "#c:dusts/redstone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dusts/glowstone.json b/src/generated/resources/data/c/tags/item/dusts/glowstone.json index b7bd60b0267..668258c523d 100644 --- a/src/generated/resources/data/c/tags/item/dusts/glowstone.json +++ b/src/generated/resources/data/c/tags/item/dusts/glowstone.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:glowstone_dust", - { - "id": "#forge:dusts/glowstone", - "required": false - } + "minecraft:glowstone_dust" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dusts/redstone.json b/src/generated/resources/data/c/tags/item/dusts/redstone.json index ec7a3ceb0a5..a096239ec12 100644 --- a/src/generated/resources/data/c/tags/item/dusts/redstone.json +++ b/src/generated/resources/data/c/tags/item/dusts/redstone.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:redstone", - { - "id": "#forge:dusts/redstone", - "required": false - } + "minecraft:redstone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/black.json b/src/generated/resources/data/c/tags/item/dyed/black.json index 493e96b6c0b..174ba5e3c49 100644 --- a/src/generated/resources/data/c/tags/item/dyed/black.json +++ b/src/generated/resources/data/c/tags/item/dyed/black.json @@ -11,14 +11,6 @@ "minecraft:black_stained_glass", "minecraft:black_stained_glass_pane", "minecraft:black_terracotta", - "minecraft:black_wool", - { - "id": "#forge:glass/black", - "required": false - }, - { - "id": "#forge:stained_glass/black", - "required": false - } + "minecraft:black_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/blue.json b/src/generated/resources/data/c/tags/item/dyed/blue.json index 0704821f98e..ca4b83cd7dc 100644 --- a/src/generated/resources/data/c/tags/item/dyed/blue.json +++ b/src/generated/resources/data/c/tags/item/dyed/blue.json @@ -11,14 +11,6 @@ "minecraft:blue_stained_glass", "minecraft:blue_stained_glass_pane", "minecraft:blue_terracotta", - "minecraft:blue_wool", - { - "id": "#forge:glass/blue", - "required": false - }, - { - "id": "#forge:stained_glass/blue", - "required": false - } + "minecraft:blue_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/brown.json b/src/generated/resources/data/c/tags/item/dyed/brown.json index 41b1bc3f6f3..502f5bccec6 100644 --- a/src/generated/resources/data/c/tags/item/dyed/brown.json +++ b/src/generated/resources/data/c/tags/item/dyed/brown.json @@ -11,14 +11,6 @@ "minecraft:brown_stained_glass", "minecraft:brown_stained_glass_pane", "minecraft:brown_terracotta", - "minecraft:brown_wool", - { - "id": "#forge:glass/brown", - "required": false - }, - { - "id": "#forge:stained_glass/brown", - "required": false - } + "minecraft:brown_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/cyan.json b/src/generated/resources/data/c/tags/item/dyed/cyan.json index a09984e0633..f3e0d24c655 100644 --- a/src/generated/resources/data/c/tags/item/dyed/cyan.json +++ b/src/generated/resources/data/c/tags/item/dyed/cyan.json @@ -11,14 +11,6 @@ "minecraft:cyan_stained_glass", "minecraft:cyan_stained_glass_pane", "minecraft:cyan_terracotta", - "minecraft:cyan_wool", - { - "id": "#forge:glass/cyan", - "required": false - }, - { - "id": "#forge:stained_glass/cyan", - "required": false - } + "minecraft:cyan_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/gray.json b/src/generated/resources/data/c/tags/item/dyed/gray.json index 191db19733e..58a9ff3549c 100644 --- a/src/generated/resources/data/c/tags/item/dyed/gray.json +++ b/src/generated/resources/data/c/tags/item/dyed/gray.json @@ -11,14 +11,6 @@ "minecraft:gray_stained_glass", "minecraft:gray_stained_glass_pane", "minecraft:gray_terracotta", - "minecraft:gray_wool", - { - "id": "#forge:glass/gray", - "required": false - }, - { - "id": "#forge:stained_glass/gray", - "required": false - } + "minecraft:gray_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/green.json b/src/generated/resources/data/c/tags/item/dyed/green.json index 80e3b0bcd12..27dc8416097 100644 --- a/src/generated/resources/data/c/tags/item/dyed/green.json +++ b/src/generated/resources/data/c/tags/item/dyed/green.json @@ -11,14 +11,6 @@ "minecraft:green_stained_glass", "minecraft:green_stained_glass_pane", "minecraft:green_terracotta", - "minecraft:green_wool", - { - "id": "#forge:glass/green", - "required": false - }, - { - "id": "#forge:stained_glass/green", - "required": false - } + "minecraft:green_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/light_blue.json b/src/generated/resources/data/c/tags/item/dyed/light_blue.json index 73525eab12e..63e842c4e06 100644 --- a/src/generated/resources/data/c/tags/item/dyed/light_blue.json +++ b/src/generated/resources/data/c/tags/item/dyed/light_blue.json @@ -11,14 +11,6 @@ "minecraft:light_blue_stained_glass", "minecraft:light_blue_stained_glass_pane", "minecraft:light_blue_terracotta", - "minecraft:light_blue_wool", - { - "id": "#forge:glass/light_blue", - "required": false - }, - { - "id": "#forge:stained_glass/light_blue", - "required": false - } + "minecraft:light_blue_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/light_gray.json b/src/generated/resources/data/c/tags/item/dyed/light_gray.json index ddfb3e54ad8..5a46bc1a159 100644 --- a/src/generated/resources/data/c/tags/item/dyed/light_gray.json +++ b/src/generated/resources/data/c/tags/item/dyed/light_gray.json @@ -11,14 +11,6 @@ "minecraft:light_gray_stained_glass", "minecraft:light_gray_stained_glass_pane", "minecraft:light_gray_terracotta", - "minecraft:light_gray_wool", - { - "id": "#forge:glass/light_gray", - "required": false - }, - { - "id": "#forge:stained_glass/light_gray", - "required": false - } + "minecraft:light_gray_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/lime.json b/src/generated/resources/data/c/tags/item/dyed/lime.json index aa463406081..56f424525c2 100644 --- a/src/generated/resources/data/c/tags/item/dyed/lime.json +++ b/src/generated/resources/data/c/tags/item/dyed/lime.json @@ -11,14 +11,6 @@ "minecraft:lime_stained_glass", "minecraft:lime_stained_glass_pane", "minecraft:lime_terracotta", - "minecraft:lime_wool", - { - "id": "#forge:glass/lime", - "required": false - }, - { - "id": "#forge:stained_glass/lime", - "required": false - } + "minecraft:lime_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/magenta.json b/src/generated/resources/data/c/tags/item/dyed/magenta.json index fe71a097ba4..f837aefc8a8 100644 --- a/src/generated/resources/data/c/tags/item/dyed/magenta.json +++ b/src/generated/resources/data/c/tags/item/dyed/magenta.json @@ -11,22 +11,6 @@ "minecraft:magenta_stained_glass", "minecraft:magenta_stained_glass_pane", "minecraft:magenta_terracotta", - "minecraft:magenta_wool", - { - "id": "#forge:glass/magenta", - "required": false - }, - { - "id": "#forge:stained_glass/magenta", - "required": false - }, - { - "id": "#forge:glass/magenta", - "required": false - }, - { - "id": "#forge:stained_glass/magenta", - "required": false - } + "minecraft:magenta_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/orange.json b/src/generated/resources/data/c/tags/item/dyed/orange.json index 6641433e65d..7fa2a7ef847 100644 --- a/src/generated/resources/data/c/tags/item/dyed/orange.json +++ b/src/generated/resources/data/c/tags/item/dyed/orange.json @@ -11,14 +11,6 @@ "minecraft:orange_stained_glass", "minecraft:orange_stained_glass_pane", "minecraft:orange_terracotta", - "minecraft:orange_wool", - { - "id": "#forge:glass/orange", - "required": false - }, - { - "id": "#forge:stained_glass/orange", - "required": false - } + "minecraft:orange_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/pink.json b/src/generated/resources/data/c/tags/item/dyed/pink.json index edca352827a..7538cceb024 100644 --- a/src/generated/resources/data/c/tags/item/dyed/pink.json +++ b/src/generated/resources/data/c/tags/item/dyed/pink.json @@ -11,14 +11,6 @@ "minecraft:pink_stained_glass", "minecraft:pink_stained_glass_pane", "minecraft:pink_terracotta", - "minecraft:pink_wool", - { - "id": "#forge:glass/pink", - "required": false - }, - { - "id": "#forge:stained_glass/pink", - "required": false - } + "minecraft:pink_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/purple.json b/src/generated/resources/data/c/tags/item/dyed/purple.json index 3be40b64c6e..61355c9ae22 100644 --- a/src/generated/resources/data/c/tags/item/dyed/purple.json +++ b/src/generated/resources/data/c/tags/item/dyed/purple.json @@ -11,14 +11,6 @@ "minecraft:purple_stained_glass", "minecraft:purple_stained_glass_pane", "minecraft:purple_terracotta", - "minecraft:purple_wool", - { - "id": "#forge:glass/purple", - "required": false - }, - { - "id": "#forge:stained_glass/purple", - "required": false - } + "minecraft:purple_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/red.json b/src/generated/resources/data/c/tags/item/dyed/red.json index 7dea013276c..252f4660e07 100644 --- a/src/generated/resources/data/c/tags/item/dyed/red.json +++ b/src/generated/resources/data/c/tags/item/dyed/red.json @@ -11,14 +11,6 @@ "minecraft:red_stained_glass", "minecraft:red_stained_glass_pane", "minecraft:red_terracotta", - "minecraft:red_wool", - { - "id": "#forge:glass/red", - "required": false - }, - { - "id": "#forge:stained_glass/red", - "required": false - } + "minecraft:red_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/white.json b/src/generated/resources/data/c/tags/item/dyed/white.json index 9edbf324cc0..2e1979e8142 100644 --- a/src/generated/resources/data/c/tags/item/dyed/white.json +++ b/src/generated/resources/data/c/tags/item/dyed/white.json @@ -11,14 +11,6 @@ "minecraft:white_stained_glass", "minecraft:white_stained_glass_pane", "minecraft:white_terracotta", - "minecraft:white_wool", - { - "id": "#forge:glass/white", - "required": false - }, - { - "id": "#forge:stained_glass/white", - "required": false - } + "minecraft:white_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyed/yellow.json b/src/generated/resources/data/c/tags/item/dyed/yellow.json index 57aeacb16f8..0e353cc64e4 100644 --- a/src/generated/resources/data/c/tags/item/dyed/yellow.json +++ b/src/generated/resources/data/c/tags/item/dyed/yellow.json @@ -11,14 +11,6 @@ "minecraft:yellow_stained_glass", "minecraft:yellow_stained_glass_pane", "minecraft:yellow_terracotta", - "minecraft:yellow_wool", - { - "id": "#forge:glass/yellow", - "required": false - }, - { - "id": "#forge:stained_glass/yellow", - "required": false - } + "minecraft:yellow_wool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/black.json b/src/generated/resources/data/c/tags/item/dyes/black.json index 516aeff755f..a2ecf55c464 100644 --- a/src/generated/resources/data/c/tags/item/dyes/black.json +++ b/src/generated/resources/data/c/tags/item/dyes/black.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:black_dye", - { - "id": "#forge:dyes/black", - "required": false - } + "minecraft:black_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/blue.json b/src/generated/resources/data/c/tags/item/dyes/blue.json index d64a97e464d..e7b78e12a35 100644 --- a/src/generated/resources/data/c/tags/item/dyes/blue.json +++ b/src/generated/resources/data/c/tags/item/dyes/blue.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:blue_dye", - { - "id": "#forge:dyes/blue", - "required": false - } + "minecraft:blue_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/brown.json b/src/generated/resources/data/c/tags/item/dyes/brown.json index 220ece0dfe0..8c7249234eb 100644 --- a/src/generated/resources/data/c/tags/item/dyes/brown.json +++ b/src/generated/resources/data/c/tags/item/dyes/brown.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:brown_dye", - { - "id": "#forge:dyes/brown", - "required": false - } + "minecraft:brown_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/cyan.json b/src/generated/resources/data/c/tags/item/dyes/cyan.json index 275830210e9..f0c5a44002d 100644 --- a/src/generated/resources/data/c/tags/item/dyes/cyan.json +++ b/src/generated/resources/data/c/tags/item/dyes/cyan.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:cyan_dye", - { - "id": "#forge:dyes/cyan", - "required": false - } + "minecraft:cyan_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/gray.json b/src/generated/resources/data/c/tags/item/dyes/gray.json index 56f595ede51..6cdbb27a491 100644 --- a/src/generated/resources/data/c/tags/item/dyes/gray.json +++ b/src/generated/resources/data/c/tags/item/dyes/gray.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:gray_dye", - { - "id": "#forge:dyes/gray", - "required": false - } + "minecraft:gray_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/green.json b/src/generated/resources/data/c/tags/item/dyes/green.json index 9f9a8311cfd..89fe8ccaf39 100644 --- a/src/generated/resources/data/c/tags/item/dyes/green.json +++ b/src/generated/resources/data/c/tags/item/dyes/green.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:green_dye", - { - "id": "#forge:dyes/green", - "required": false - } + "minecraft:green_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/light_blue.json b/src/generated/resources/data/c/tags/item/dyes/light_blue.json index e5a48d1fedf..76f1a7786cc 100644 --- a/src/generated/resources/data/c/tags/item/dyes/light_blue.json +++ b/src/generated/resources/data/c/tags/item/dyes/light_blue.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:light_blue_dye", - { - "id": "#forge:dyes/light_blue", - "required": false - } + "minecraft:light_blue_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/light_gray.json b/src/generated/resources/data/c/tags/item/dyes/light_gray.json index 6627597c69a..596b2efb37f 100644 --- a/src/generated/resources/data/c/tags/item/dyes/light_gray.json +++ b/src/generated/resources/data/c/tags/item/dyes/light_gray.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:light_gray_dye", - { - "id": "#forge:dyes/light_gray", - "required": false - } + "minecraft:light_gray_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/lime.json b/src/generated/resources/data/c/tags/item/dyes/lime.json index fc0af1757b6..b0ac91f97e4 100644 --- a/src/generated/resources/data/c/tags/item/dyes/lime.json +++ b/src/generated/resources/data/c/tags/item/dyes/lime.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:lime_dye", - { - "id": "#forge:dyes/lime", - "required": false - } + "minecraft:lime_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/magenta.json b/src/generated/resources/data/c/tags/item/dyes/magenta.json index d2032d3de2a..f6898d4c9b6 100644 --- a/src/generated/resources/data/c/tags/item/dyes/magenta.json +++ b/src/generated/resources/data/c/tags/item/dyes/magenta.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:magenta_dye", - { - "id": "#forge:dyes/magenta", - "required": false - } + "minecraft:magenta_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/orange.json b/src/generated/resources/data/c/tags/item/dyes/orange.json index 3534947be33..df54849c593 100644 --- a/src/generated/resources/data/c/tags/item/dyes/orange.json +++ b/src/generated/resources/data/c/tags/item/dyes/orange.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:orange_dye", - { - "id": "#forge:dyes/orange", - "required": false - } + "minecraft:orange_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/pink.json b/src/generated/resources/data/c/tags/item/dyes/pink.json index f7ffc037f00..d9f2898629b 100644 --- a/src/generated/resources/data/c/tags/item/dyes/pink.json +++ b/src/generated/resources/data/c/tags/item/dyes/pink.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:pink_dye", - { - "id": "#forge:dyes/pink", - "required": false - } + "minecraft:pink_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/purple.json b/src/generated/resources/data/c/tags/item/dyes/purple.json index 38a9a298683..b3ebfe3c262 100644 --- a/src/generated/resources/data/c/tags/item/dyes/purple.json +++ b/src/generated/resources/data/c/tags/item/dyes/purple.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:purple_dye", - { - "id": "#forge:dyes/purple", - "required": false - } + "minecraft:purple_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/red.json b/src/generated/resources/data/c/tags/item/dyes/red.json index f36b684e011..9c6fe34671f 100644 --- a/src/generated/resources/data/c/tags/item/dyes/red.json +++ b/src/generated/resources/data/c/tags/item/dyes/red.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:red_dye", - { - "id": "#forge:dyes/red", - "required": false - } + "minecraft:red_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/white.json b/src/generated/resources/data/c/tags/item/dyes/white.json index 217dfda5c37..3a30d72b10b 100644 --- a/src/generated/resources/data/c/tags/item/dyes/white.json +++ b/src/generated/resources/data/c/tags/item/dyes/white.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:white_dye", - { - "id": "#forge:dyes/white", - "required": false - } + "minecraft:white_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/dyes/yellow.json b/src/generated/resources/data/c/tags/item/dyes/yellow.json index 8f469111bf8..43499598369 100644 --- a/src/generated/resources/data/c/tags/item/dyes/yellow.json +++ b/src/generated/resources/data/c/tags/item/dyes/yellow.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:yellow_dye", - { - "id": "#forge:dyes/yellow", - "required": false - } + "minecraft:yellow_dye" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/end_stones.json b/src/generated/resources/data/c/tags/item/end_stones.json index aa227f8a3b9..f2d11375bce 100644 --- a/src/generated/resources/data/c/tags/item/end_stones.json +++ b/src/generated/resources/data/c/tags/item/end_stones.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:end_stone", - { - "id": "#forge:end_stones", - "required": false - } + "minecraft:end_stone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ender_pearls.json b/src/generated/resources/data/c/tags/item/ender_pearls.json index bd8b93cf850..135cd1d7761 100644 --- a/src/generated/resources/data/c/tags/item/ender_pearls.json +++ b/src/generated/resources/data/c/tags/item/ender_pearls.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:ender_pearl", - { - "id": "#forge:ender_pearls", - "required": false - } + "minecraft:ender_pearl" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/feathers.json b/src/generated/resources/data/c/tags/item/feathers.json index 84f3dedf59c..8086200700e 100644 --- a/src/generated/resources/data/c/tags/item/feathers.json +++ b/src/generated/resources/data/c/tags/item/feathers.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:feather", - { - "id": "#forge:feathers", - "required": false - } + "minecraft:feather" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/fence_gates.json b/src/generated/resources/data/c/tags/item/fence_gates.json index 56c90931ccb..42dca6b914c 100644 --- a/src/generated/resources/data/c/tags/item/fence_gates.json +++ b/src/generated/resources/data/c/tags/item/fence_gates.json @@ -1,9 +1,5 @@ { "values": [ - "#c:fence_gates/wooden", - { - "id": "#forge:fence_gates", - "required": false - } + "#c:fence_gates/wooden" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/fence_gates/wooden.json b/src/generated/resources/data/c/tags/item/fence_gates/wooden.json index db55cb84ed4..88a130fa504 100644 --- a/src/generated/resources/data/c/tags/item/fence_gates/wooden.json +++ b/src/generated/resources/data/c/tags/item/fence_gates/wooden.json @@ -10,10 +10,6 @@ "minecraft:warped_fence_gate", "minecraft:mangrove_fence_gate", "minecraft:bamboo_fence_gate", - "minecraft:cherry_fence_gate", - { - "id": "#forge:fence_gates/wooden", - "required": false - } + "minecraft:cherry_fence_gate" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/fences.json b/src/generated/resources/data/c/tags/item/fences.json index 1e79564adee..3185a1f46b6 100644 --- a/src/generated/resources/data/c/tags/item/fences.json +++ b/src/generated/resources/data/c/tags/item/fences.json @@ -1,10 +1,6 @@ { "values": [ "#c:fences/nether_brick", - "#c:fences/wooden", - { - "id": "#forge:fences", - "required": false - } + "#c:fences/wooden" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/fences/nether_brick.json b/src/generated/resources/data/c/tags/item/fences/nether_brick.json index 30a88aea365..3f1aacfa7ef 100644 --- a/src/generated/resources/data/c/tags/item/fences/nether_brick.json +++ b/src/generated/resources/data/c/tags/item/fences/nether_brick.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_brick_fence", - { - "id": "#forge:fences/nether_brick", - "required": false - } + "minecraft:nether_brick_fence" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/fences/wooden.json b/src/generated/resources/data/c/tags/item/fences/wooden.json index bf67fa132ef..81202621144 100644 --- a/src/generated/resources/data/c/tags/item/fences/wooden.json +++ b/src/generated/resources/data/c/tags/item/fences/wooden.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:wooden_fences", - { - "id": "#forge:fences/wooden", - "required": false - } + "#minecraft:wooden_fences" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/berry.json b/src/generated/resources/data/c/tags/item/foods/berry.json index 4c65d0faa76..500bd9432cb 100644 --- a/src/generated/resources/data/c/tags/item/foods/berry.json +++ b/src/generated/resources/data/c/tags/item/foods/berry.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:sweet_berries", - "minecraft:glow_berries", - { - "id": "#c:foods/berries", - "required": false - } + "minecraft:glow_berries" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/bread.json b/src/generated/resources/data/c/tags/item/foods/bread.json index 8986174722a..7873bb3c3f8 100644 --- a/src/generated/resources/data/c/tags/item/foods/bread.json +++ b/src/generated/resources/data/c/tags/item/foods/bread.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:bread", - { - "id": "#c:foods/breads", - "required": false - } + "minecraft:bread" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/candy.json b/src/generated/resources/data/c/tags/item/foods/candy.json index 0a23e7d3f38..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/item/foods/candy.json +++ b/src/generated/resources/data/c/tags/item/foods/candy.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#c:foods/candies", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/cooked_fish.json b/src/generated/resources/data/c/tags/item/foods/cooked_fish.json index ff8f009668d..4e459bea9e5 100644 --- a/src/generated/resources/data/c/tags/item/foods/cooked_fish.json +++ b/src/generated/resources/data/c/tags/item/foods/cooked_fish.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:cooked_cod", - "minecraft:cooked_salmon", - { - "id": "#c:foods/cooked_fishes", - "required": false - } + "minecraft:cooked_salmon" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/cooked_meat.json b/src/generated/resources/data/c/tags/item/foods/cooked_meat.json index 0dbfd200c6c..ffd78dc19ad 100644 --- a/src/generated/resources/data/c/tags/item/foods/cooked_meat.json +++ b/src/generated/resources/data/c/tags/item/foods/cooked_meat.json @@ -4,10 +4,6 @@ "minecraft:cooked_porkchop", "minecraft:cooked_chicken", "minecraft:cooked_rabbit", - "minecraft:cooked_mutton", - { - "id": "#c:foods/cooked_meats", - "required": false - } + "minecraft:cooked_mutton" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/cookie.json b/src/generated/resources/data/c/tags/item/foods/cookie.json index a3c32a13606..a7c0dc91d8a 100644 --- a/src/generated/resources/data/c/tags/item/foods/cookie.json +++ b/src/generated/resources/data/c/tags/item/foods/cookie.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:cookie", - { - "id": "#c:foods/cookies", - "required": false - } + "minecraft:cookie" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/fruit.json b/src/generated/resources/data/c/tags/item/foods/fruit.json index 419d207c10c..d28fee4f3ab 100644 --- a/src/generated/resources/data/c/tags/item/foods/fruit.json +++ b/src/generated/resources/data/c/tags/item/foods/fruit.json @@ -4,10 +4,6 @@ "minecraft:golden_apple", "minecraft:enchanted_golden_apple", "minecraft:chorus_fruit", - "minecraft:melon_slice", - { - "id": "#c:foods/fruits", - "required": false - } + "minecraft:melon_slice" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/raw_fish.json b/src/generated/resources/data/c/tags/item/foods/raw_fish.json index 2b3c9312f0d..83d056aa447 100644 --- a/src/generated/resources/data/c/tags/item/foods/raw_fish.json +++ b/src/generated/resources/data/c/tags/item/foods/raw_fish.json @@ -3,10 +3,6 @@ "minecraft:cod", "minecraft:salmon", "minecraft:tropical_fish", - "minecraft:pufferfish", - { - "id": "#c:foods/raw_fishes", - "required": false - } + "minecraft:pufferfish" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/raw_meat.json b/src/generated/resources/data/c/tags/item/foods/raw_meat.json index 793d860074a..c548b57f3a8 100644 --- a/src/generated/resources/data/c/tags/item/foods/raw_meat.json +++ b/src/generated/resources/data/c/tags/item/foods/raw_meat.json @@ -4,10 +4,6 @@ "minecraft:porkchop", "minecraft:chicken", "minecraft:rabbit", - "minecraft:mutton", - { - "id": "#c:foods/raw_meats", - "required": false - } + "minecraft:mutton" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/soup.json b/src/generated/resources/data/c/tags/item/foods/soup.json index d0e1081301f..5a1a3392494 100644 --- a/src/generated/resources/data/c/tags/item/foods/soup.json +++ b/src/generated/resources/data/c/tags/item/foods/soup.json @@ -3,10 +3,6 @@ "minecraft:beetroot_soup", "minecraft:mushroom_stew", "minecraft:rabbit_stew", - "minecraft:suspicious_stew", - { - "id": "#c:foods/soups", - "required": false - } + "minecraft:suspicious_stew" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/vegetable.json b/src/generated/resources/data/c/tags/item/foods/vegetable.json index c6ae447d59b..17ecdb1ca64 100644 --- a/src/generated/resources/data/c/tags/item/foods/vegetable.json +++ b/src/generated/resources/data/c/tags/item/foods/vegetable.json @@ -3,10 +3,6 @@ "minecraft:carrot", "minecraft:golden_carrot", "minecraft:potato", - "minecraft:beetroot", - { - "id": "#c:foods/vegetables", - "required": false - } + "minecraft:beetroot" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gems.json b/src/generated/resources/data/c/tags/item/gems.json index 6f340c553c9..fb578882219 100644 --- a/src/generated/resources/data/c/tags/item/gems.json +++ b/src/generated/resources/data/c/tags/item/gems.json @@ -5,10 +5,6 @@ "#c:gems/emerald", "#c:gems/lapis", "#c:gems/prismarine", - "#c:gems/quartz", - { - "id": "#forge:gems", - "required": false - } + "#c:gems/quartz" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gems/amethyst.json b/src/generated/resources/data/c/tags/item/gems/amethyst.json index d222353687d..742ef896d5b 100644 --- a/src/generated/resources/data/c/tags/item/gems/amethyst.json +++ b/src/generated/resources/data/c/tags/item/gems/amethyst.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:amethyst_shard", - { - "id": "#forge:gems/amethyst", - "required": false - } + "minecraft:amethyst_shard" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gems/diamond.json b/src/generated/resources/data/c/tags/item/gems/diamond.json index 1ca2673f215..f44f30dd550 100644 --- a/src/generated/resources/data/c/tags/item/gems/diamond.json +++ b/src/generated/resources/data/c/tags/item/gems/diamond.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:diamond", - { - "id": "#forge:gems/diamond", - "required": false - } + "minecraft:diamond" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gems/emerald.json b/src/generated/resources/data/c/tags/item/gems/emerald.json index de1e12af1b8..07a09821180 100644 --- a/src/generated/resources/data/c/tags/item/gems/emerald.json +++ b/src/generated/resources/data/c/tags/item/gems/emerald.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:emerald", - { - "id": "#forge:gems/emerald", - "required": false - } + "minecraft:emerald" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gems/lapis.json b/src/generated/resources/data/c/tags/item/gems/lapis.json index 0e926125485..614441df46c 100644 --- a/src/generated/resources/data/c/tags/item/gems/lapis.json +++ b/src/generated/resources/data/c/tags/item/gems/lapis.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:lapis_lazuli", - { - "id": "#forge:gems/lapis", - "required": false - } + "minecraft:lapis_lazuli" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gems/prismarine.json b/src/generated/resources/data/c/tags/item/gems/prismarine.json index df7aa663124..150e7ff7114 100644 --- a/src/generated/resources/data/c/tags/item/gems/prismarine.json +++ b/src/generated/resources/data/c/tags/item/gems/prismarine.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:prismarine_crystals", - { - "id": "#forge:gems/prismarine", - "required": false - } + "minecraft:prismarine_crystals" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gems/quartz.json b/src/generated/resources/data/c/tags/item/gems/quartz.json index d0604485bde..aad2eef95bf 100644 --- a/src/generated/resources/data/c/tags/item/gems/quartz.json +++ b/src/generated/resources/data/c/tags/item/gems/quartz.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:quartz", - { - "id": "#forge:gems/quartz", - "required": false - } + "minecraft:quartz" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/glass_blocks.json b/src/generated/resources/data/c/tags/item/glass_blocks.json index 55b243f654a..61618a74980 100644 --- a/src/generated/resources/data/c/tags/item/glass_blocks.json +++ b/src/generated/resources/data/c/tags/item/glass_blocks.json @@ -2,10 +2,6 @@ "values": [ "#c:glass_blocks/colorless", "#c:glass_blocks/cheap", - "#c:glass_blocks/tinted", - { - "id": "#forge:glass", - "required": false - } + "#c:glass_blocks/tinted" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/glass_blocks/cheap.json b/src/generated/resources/data/c/tags/item/glass_blocks/cheap.json index ccd28136a66..3465b3884b0 100644 --- a/src/generated/resources/data/c/tags/item/glass_blocks/cheap.json +++ b/src/generated/resources/data/c/tags/item/glass_blocks/cheap.json @@ -16,10 +16,6 @@ "minecraft:brown_stained_glass", "minecraft:green_stained_glass", "minecraft:red_stained_glass", - "minecraft:black_stained_glass", - { - "id": "#forge:glass_silica", - "required": false - } + "minecraft:black_stained_glass" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/glass_blocks/colorless.json b/src/generated/resources/data/c/tags/item/glass_blocks/colorless.json index 7d2e81b6c44..ac8b5e50863 100644 --- a/src/generated/resources/data/c/tags/item/glass_blocks/colorless.json +++ b/src/generated/resources/data/c/tags/item/glass_blocks/colorless.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:glass", - { - "id": "#forge:glass_colorless", - "required": false - } + "minecraft:glass" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/glass_blocks/tinted.json b/src/generated/resources/data/c/tags/item/glass_blocks/tinted.json index 0a7d0f3f00d..4075a1556b3 100644 --- a/src/generated/resources/data/c/tags/item/glass_blocks/tinted.json +++ b/src/generated/resources/data/c/tags/item/glass_blocks/tinted.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:tinted_glass", - { - "id": "#forge:glass_tinted", - "required": false - } + "minecraft:tinted_glass" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/glass_panes/colorless.json b/src/generated/resources/data/c/tags/item/glass_panes/colorless.json index b7d7245a6aa..eb5756f9643 100644 --- a/src/generated/resources/data/c/tags/item/glass_panes/colorless.json +++ b/src/generated/resources/data/c/tags/item/glass_panes/colorless.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:glass_pane", - { - "id": "#forge:glass_panes_colorless", - "required": false - } + "minecraft:glass_pane" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gravels.json b/src/generated/resources/data/c/tags/item/gravels.json index 80440dd1d45..f6968bff68a 100644 --- a/src/generated/resources/data/c/tags/item/gravels.json +++ b/src/generated/resources/data/c/tags/item/gravels.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:gravel", - { - "id": "#forge:gravel", - "required": false - } + "minecraft:gravel" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/gunpowders.json b/src/generated/resources/data/c/tags/item/gunpowders.json index 90ef8c349e2..d5835ce7f91 100644 --- a/src/generated/resources/data/c/tags/item/gunpowders.json +++ b/src/generated/resources/data/c/tags/item/gunpowders.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:gunpowder", - { - "id": "#forge:gunpowder", - "required": false - } + "minecraft:gunpowder" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ingots.json b/src/generated/resources/data/c/tags/item/ingots.json index 45846683558..a1e5ead59aa 100644 --- a/src/generated/resources/data/c/tags/item/ingots.json +++ b/src/generated/resources/data/c/tags/item/ingots.json @@ -3,10 +3,6 @@ "#c:ingots/copper", "#c:ingots/gold", "#c:ingots/iron", - "#c:ingots/netherite", - { - "id": "#forge:ingots", - "required": false - } + "#c:ingots/netherite" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ingots/copper.json b/src/generated/resources/data/c/tags/item/ingots/copper.json index 2043a331d03..1cc1f065c5f 100644 --- a/src/generated/resources/data/c/tags/item/ingots/copper.json +++ b/src/generated/resources/data/c/tags/item/ingots/copper.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:copper_ingot", - { - "id": "#forge:ingots/copper", - "required": false - } + "minecraft:copper_ingot" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ingots/gold.json b/src/generated/resources/data/c/tags/item/ingots/gold.json index 70299fe3049..07e9f66a309 100644 --- a/src/generated/resources/data/c/tags/item/ingots/gold.json +++ b/src/generated/resources/data/c/tags/item/ingots/gold.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:gold_ingot", - { - "id": "#forge:ingots/gold", - "required": false - } + "minecraft:gold_ingot" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ingots/iron.json b/src/generated/resources/data/c/tags/item/ingots/iron.json index 7fa35c33e3d..c656021bdbe 100644 --- a/src/generated/resources/data/c/tags/item/ingots/iron.json +++ b/src/generated/resources/data/c/tags/item/ingots/iron.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:iron_ingot", - { - "id": "#forge:ingots/iron", - "required": false - } + "minecraft:iron_ingot" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ingots/netherite.json b/src/generated/resources/data/c/tags/item/ingots/netherite.json index 61b250abae6..bd6929df75c 100644 --- a/src/generated/resources/data/c/tags/item/ingots/netherite.json +++ b/src/generated/resources/data/c/tags/item/ingots/netherite.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:netherite_ingot", - { - "id": "#forge:ingots/netherite", - "required": false - } + "minecraft:netherite_ingot" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/leathers.json b/src/generated/resources/data/c/tags/item/leathers.json index 71f8c03e099..71b797d35ba 100644 --- a/src/generated/resources/data/c/tags/item/leathers.json +++ b/src/generated/resources/data/c/tags/item/leathers.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:leather", - { - "id": "#forge:leather", - "required": false - } + "minecraft:leather" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/mushrooms.json b/src/generated/resources/data/c/tags/item/mushrooms.json index 0823f66b558..471cd77f070 100644 --- a/src/generated/resources/data/c/tags/item/mushrooms.json +++ b/src/generated/resources/data/c/tags/item/mushrooms.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:brown_mushroom", - "minecraft:red_mushroom", - { - "id": "#forge:mushrooms", - "required": false - } + "minecraft:red_mushroom" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/nether_stars.json b/src/generated/resources/data/c/tags/item/nether_stars.json index 3e02f9a226a..737a95d0833 100644 --- a/src/generated/resources/data/c/tags/item/nether_stars.json +++ b/src/generated/resources/data/c/tags/item/nether_stars.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_star", - { - "id": "#forge:nether_stars", - "required": false - } + "minecraft:nether_star" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/netherracks.json b/src/generated/resources/data/c/tags/item/netherracks.json index 21c1554741f..daa9c66701a 100644 --- a/src/generated/resources/data/c/tags/item/netherracks.json +++ b/src/generated/resources/data/c/tags/item/netherracks.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:netherrack", - { - "id": "#forge:netherrack", - "required": false - } + "minecraft:netherrack" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/nuggets.json b/src/generated/resources/data/c/tags/item/nuggets.json index ae39ad19d05..472d55fc2e2 100644 --- a/src/generated/resources/data/c/tags/item/nuggets.json +++ b/src/generated/resources/data/c/tags/item/nuggets.json @@ -2,10 +2,6 @@ "values": [ "#c:nuggets/copper", "#c:nuggets/iron", - "#c:nuggets/gold", - { - "id": "#forge:nuggets", - "required": false - } + "#c:nuggets/gold" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/nuggets/gold.json b/src/generated/resources/data/c/tags/item/nuggets/gold.json index 77eb1519091..4d943459579 100644 --- a/src/generated/resources/data/c/tags/item/nuggets/gold.json +++ b/src/generated/resources/data/c/tags/item/nuggets/gold.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:gold_nugget", - { - "id": "#forge:nuggets/gold", - "required": false - } + "minecraft:gold_nugget" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/nuggets/iron.json b/src/generated/resources/data/c/tags/item/nuggets/iron.json index 0f529f154f5..cbd20ac6e4f 100644 --- a/src/generated/resources/data/c/tags/item/nuggets/iron.json +++ b/src/generated/resources/data/c/tags/item/nuggets/iron.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:iron_nugget", - { - "id": "#forge:nuggets/iron", - "required": false - } + "minecraft:iron_nugget" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/obsidians.json b/src/generated/resources/data/c/tags/item/obsidians.json index 3986b73df1c..5df539fb0ee 100644 --- a/src/generated/resources/data/c/tags/item/obsidians.json +++ b/src/generated/resources/data/c/tags/item/obsidians.json @@ -1,10 +1,6 @@ { "values": [ "#c:obsidians/normal", - "#c:obsidians/crying", - { - "id": "#forge:obsidian", - "required": false - } + "#c:obsidians/crying" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ore_bearing_ground/deepslate.json b/src/generated/resources/data/c/tags/item/ore_bearing_ground/deepslate.json index e3a93227979..0012c241a31 100644 --- a/src/generated/resources/data/c/tags/item/ore_bearing_ground/deepslate.json +++ b/src/generated/resources/data/c/tags/item/ore_bearing_ground/deepslate.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:deepslate", - { - "id": "#forge:ore_bearing_ground/deepslate", - "required": false - } + "minecraft:deepslate" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ore_bearing_ground/netherrack.json b/src/generated/resources/data/c/tags/item/ore_bearing_ground/netherrack.json index d8156115518..daa9c66701a 100644 --- a/src/generated/resources/data/c/tags/item/ore_bearing_ground/netherrack.json +++ b/src/generated/resources/data/c/tags/item/ore_bearing_ground/netherrack.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:netherrack", - { - "id": "#forge:ore_bearing_ground/netherrack", - "required": false - } + "minecraft:netherrack" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ore_bearing_ground/stone.json b/src/generated/resources/data/c/tags/item/ore_bearing_ground/stone.json index 08d0efdfe57..c2d7c79f3e7 100644 --- a/src/generated/resources/data/c/tags/item/ore_bearing_ground/stone.json +++ b/src/generated/resources/data/c/tags/item/ore_bearing_ground/stone.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:stone", - { - "id": "#forge:ore_bearing_ground/stone", - "required": false - } + "minecraft:stone" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ore_rates/dense.json b/src/generated/resources/data/c/tags/item/ore_rates/dense.json index ded4e6606a3..69cfa783438 100644 --- a/src/generated/resources/data/c/tags/item/ore_rates/dense.json +++ b/src/generated/resources/data/c/tags/item/ore_rates/dense.json @@ -5,10 +5,6 @@ "minecraft:deepslate_lapis_ore", "minecraft:deepslate_redstone_ore", "minecraft:lapis_ore", - "minecraft:redstone_ore", - { - "id": "#forge:ore_rates/dense", - "required": false - } + "minecraft:redstone_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ore_rates/singular.json b/src/generated/resources/data/c/tags/item/ore_rates/singular.json index 3a2f12d573f..79e0f4b9a7c 100644 --- a/src/generated/resources/data/c/tags/item/ore_rates/singular.json +++ b/src/generated/resources/data/c/tags/item/ore_rates/singular.json @@ -11,10 +11,6 @@ "minecraft:emerald_ore", "minecraft:gold_ore", "minecraft:iron_ore", - "minecraft:nether_quartz_ore", - { - "id": "#forge:ore_rates/singular", - "required": false - } + "minecraft:nether_quartz_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ore_rates/sparse.json b/src/generated/resources/data/c/tags/item/ore_rates/sparse.json index 349b1e3d4be..3caf9ffe44e 100644 --- a/src/generated/resources/data/c/tags/item/ore_rates/sparse.json +++ b/src/generated/resources/data/c/tags/item/ore_rates/sparse.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_gold_ore", - { - "id": "#forge:ore_rates/sparse", - "required": false - } + "minecraft:nether_gold_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores.json b/src/generated/resources/data/c/tags/item/ores.json index ffce3487bec..3b2293aa8d8 100644 --- a/src/generated/resources/data/c/tags/item/ores.json +++ b/src/generated/resources/data/c/tags/item/ores.json @@ -9,10 +9,6 @@ "#c:ores/lapis", "#c:ores/netherite_scrap", "#c:ores/redstone", - "#c:ores/quartz", - { - "id": "#forge:ores", - "required": false - } + "#c:ores/quartz" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/coal.json b/src/generated/resources/data/c/tags/item/ores/coal.json index 2e088c72415..c1246af5163 100644 --- a/src/generated/resources/data/c/tags/item/ores/coal.json +++ b/src/generated/resources/data/c/tags/item/ores/coal.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:coal_ores", - { - "id": "#forge:ores/coal", - "required": false - } + "#minecraft:coal_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/copper.json b/src/generated/resources/data/c/tags/item/ores/copper.json index f51e56171f2..bfa31f2aed5 100644 --- a/src/generated/resources/data/c/tags/item/ores/copper.json +++ b/src/generated/resources/data/c/tags/item/ores/copper.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:copper_ores", - { - "id": "#forge:ores/copper", - "required": false - } + "#minecraft:copper_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/diamond.json b/src/generated/resources/data/c/tags/item/ores/diamond.json index 3a595fe6482..e0fe2e9d0ff 100644 --- a/src/generated/resources/data/c/tags/item/ores/diamond.json +++ b/src/generated/resources/data/c/tags/item/ores/diamond.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:diamond_ores", - { - "id": "#forge:ores/diamond", - "required": false - } + "#minecraft:diamond_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/emerald.json b/src/generated/resources/data/c/tags/item/ores/emerald.json index 25ec90670f7..fe8bed587cd 100644 --- a/src/generated/resources/data/c/tags/item/ores/emerald.json +++ b/src/generated/resources/data/c/tags/item/ores/emerald.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:emerald_ores", - { - "id": "#forge:ores/emerald", - "required": false - } + "#minecraft:emerald_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/gold.json b/src/generated/resources/data/c/tags/item/ores/gold.json index ab8f217a24d..52f7c26ba19 100644 --- a/src/generated/resources/data/c/tags/item/ores/gold.json +++ b/src/generated/resources/data/c/tags/item/ores/gold.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:gold_ores", - { - "id": "#forge:ores/gold", - "required": false - } + "#minecraft:gold_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/iron.json b/src/generated/resources/data/c/tags/item/ores/iron.json index 12fed97a891..9b135890e97 100644 --- a/src/generated/resources/data/c/tags/item/ores/iron.json +++ b/src/generated/resources/data/c/tags/item/ores/iron.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:iron_ores", - { - "id": "#forge:ores/iron", - "required": false - } + "#minecraft:iron_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/lapis.json b/src/generated/resources/data/c/tags/item/ores/lapis.json index 4609a406dcf..901b01187cd 100644 --- a/src/generated/resources/data/c/tags/item/ores/lapis.json +++ b/src/generated/resources/data/c/tags/item/ores/lapis.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:lapis_ores", - { - "id": "#forge:ores/lapis", - "required": false - } + "#minecraft:lapis_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/netherite_scrap.json b/src/generated/resources/data/c/tags/item/ores/netherite_scrap.json index 6cc208db8e5..910d1fb8e6a 100644 --- a/src/generated/resources/data/c/tags/item/ores/netherite_scrap.json +++ b/src/generated/resources/data/c/tags/item/ores/netherite_scrap.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:ancient_debris", - { - "id": "#forge:ores/netherite_scrap", - "required": false - } + "minecraft:ancient_debris" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/quartz.json b/src/generated/resources/data/c/tags/item/ores/quartz.json index 5433b2ed6fa..f0bc7a4657c 100644 --- a/src/generated/resources/data/c/tags/item/ores/quartz.json +++ b/src/generated/resources/data/c/tags/item/ores/quartz.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:nether_quartz_ore", - { - "id": "#forge:ores/quartz", - "required": false - } + "minecraft:nether_quartz_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores/redstone.json b/src/generated/resources/data/c/tags/item/ores/redstone.json index 42cb0fd1ee4..252cdcbb38e 100644 --- a/src/generated/resources/data/c/tags/item/ores/redstone.json +++ b/src/generated/resources/data/c/tags/item/ores/redstone.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:redstone_ores", - { - "id": "#forge:ores/redstone", - "required": false - } + "#minecraft:redstone_ores" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores_in_ground/deepslate.json b/src/generated/resources/data/c/tags/item/ores_in_ground/deepslate.json index 6b172a1533b..13e0c38aa16 100644 --- a/src/generated/resources/data/c/tags/item/ores_in_ground/deepslate.json +++ b/src/generated/resources/data/c/tags/item/ores_in_ground/deepslate.json @@ -7,10 +7,6 @@ "minecraft:deepslate_gold_ore", "minecraft:deepslate_iron_ore", "minecraft:deepslate_lapis_ore", - "minecraft:deepslate_redstone_ore", - { - "id": "#forge:ores_in_ground/deepslate", - "required": false - } + "minecraft:deepslate_redstone_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores_in_ground/netherrack.json b/src/generated/resources/data/c/tags/item/ores_in_ground/netherrack.json index 83b110ef9e5..090233bd460 100644 --- a/src/generated/resources/data/c/tags/item/ores_in_ground/netherrack.json +++ b/src/generated/resources/data/c/tags/item/ores_in_ground/netherrack.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:nether_gold_ore", - "minecraft:nether_quartz_ore", - { - "id": "#forge:ores_in_ground/netherrack", - "required": false - } + "minecraft:nether_quartz_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/ores_in_ground/stone.json b/src/generated/resources/data/c/tags/item/ores_in_ground/stone.json index 97b26721aeb..568fbe7cb67 100644 --- a/src/generated/resources/data/c/tags/item/ores_in_ground/stone.json +++ b/src/generated/resources/data/c/tags/item/ores_in_ground/stone.json @@ -7,10 +7,6 @@ "minecraft:gold_ore", "minecraft:iron_ore", "minecraft:lapis_ore", - "minecraft:redstone_ore", - { - "id": "#forge:ores_in_ground/stone", - "required": false - } + "minecraft:redstone_ore" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/raw_materials.json b/src/generated/resources/data/c/tags/item/raw_materials.json index de258a264bb..d0b9991efe9 100644 --- a/src/generated/resources/data/c/tags/item/raw_materials.json +++ b/src/generated/resources/data/c/tags/item/raw_materials.json @@ -2,10 +2,6 @@ "values": [ "#c:raw_materials/copper", "#c:raw_materials/gold", - "#c:raw_materials/iron", - { - "id": "#forge:raw_materials", - "required": false - } + "#c:raw_materials/iron" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/raw_materials/copper.json b/src/generated/resources/data/c/tags/item/raw_materials/copper.json index ce2a8c25b9c..3e03ab9ca8a 100644 --- a/src/generated/resources/data/c/tags/item/raw_materials/copper.json +++ b/src/generated/resources/data/c/tags/item/raw_materials/copper.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_copper", - { - "id": "#forge:raw_materials/copper", - "required": false - } + "minecraft:raw_copper" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/raw_materials/gold.json b/src/generated/resources/data/c/tags/item/raw_materials/gold.json index 555e2873582..3d1252e5f9d 100644 --- a/src/generated/resources/data/c/tags/item/raw_materials/gold.json +++ b/src/generated/resources/data/c/tags/item/raw_materials/gold.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_gold", - { - "id": "#forge:raw_materials/gold", - "required": false - } + "minecraft:raw_gold" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/raw_materials/iron.json b/src/generated/resources/data/c/tags/item/raw_materials/iron.json index def08c1dacc..8f9af48d8e1 100644 --- a/src/generated/resources/data/c/tags/item/raw_materials/iron.json +++ b/src/generated/resources/data/c/tags/item/raw_materials/iron.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_iron", - { - "id": "#forge:raw_materials/iron", - "required": false - } + "minecraft:raw_iron" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/rods.json b/src/generated/resources/data/c/tags/item/rods.json index 4bf89f59ff8..84ee8864fcf 100644 --- a/src/generated/resources/data/c/tags/item/rods.json +++ b/src/generated/resources/data/c/tags/item/rods.json @@ -2,10 +2,6 @@ "values": [ "#c:rods/wooden", "#c:rods/blaze", - "#c:rods/breeze", - { - "id": "#forge:rods", - "required": false - } + "#c:rods/breeze" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/rods/blaze.json b/src/generated/resources/data/c/tags/item/rods/blaze.json index cda6278df87..5d2eff8311d 100644 --- a/src/generated/resources/data/c/tags/item/rods/blaze.json +++ b/src/generated/resources/data/c/tags/item/rods/blaze.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:blaze_rod", - { - "id": "#forge:rods/blaze", - "required": false - } + "minecraft:blaze_rod" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/rods/wooden.json b/src/generated/resources/data/c/tags/item/rods/wooden.json index 348d18d33d3..019b63dd31d 100644 --- a/src/generated/resources/data/c/tags/item/rods/wooden.json +++ b/src/generated/resources/data/c/tags/item/rods/wooden.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:stick", - { - "id": "#forge:rods/wooden", - "required": false - } + "minecraft:stick" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/sands.json b/src/generated/resources/data/c/tags/item/sands.json index 43eaac83ae7..f4b6e6a7691 100644 --- a/src/generated/resources/data/c/tags/item/sands.json +++ b/src/generated/resources/data/c/tags/item/sands.json @@ -1,10 +1,6 @@ { "values": [ "#c:sands/colorless", - "#c:sands/red", - { - "id": "#forge:sand", - "required": false - } + "#c:sands/red" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/sands/colorless.json b/src/generated/resources/data/c/tags/item/sands/colorless.json index 93cdef191bc..af14f42f568 100644 --- a/src/generated/resources/data/c/tags/item/sands/colorless.json +++ b/src/generated/resources/data/c/tags/item/sands/colorless.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:sand", - { - "id": "#forge:sand/colorless", - "required": false - } + "minecraft:sand" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/sands/red.json b/src/generated/resources/data/c/tags/item/sands/red.json index 03eba73b127..9934cb5bbcf 100644 --- a/src/generated/resources/data/c/tags/item/sands/red.json +++ b/src/generated/resources/data/c/tags/item/sands/red.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:red_sand", - { - "id": "#forge:sand/red", - "required": false - } + "minecraft:red_sand" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/sandstone/blocks.json b/src/generated/resources/data/c/tags/item/sandstone/blocks.json index 5684db6caf7..df1b934e5c7 100644 --- a/src/generated/resources/data/c/tags/item/sandstone/blocks.json +++ b/src/generated/resources/data/c/tags/item/sandstone/blocks.json @@ -1,10 +1,6 @@ { "values": [ "#c:sandstone/red_blocks", - "#c:sandstone/uncolored_blocks", - { - "id": "#forge:sandstone", - "required": false - } + "#c:sandstone/uncolored_blocks" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/seeds.json b/src/generated/resources/data/c/tags/item/seeds.json index b8b91473ccb..d89379617e2 100644 --- a/src/generated/resources/data/c/tags/item/seeds.json +++ b/src/generated/resources/data/c/tags/item/seeds.json @@ -5,10 +5,6 @@ "#c:seeds/pumpkin", "#c:seeds/torchflower", "#c:seeds/pitcher_plant", - "#c:seeds/wheat", - { - "id": "#forge:seeds", - "required": false - } + "#c:seeds/wheat" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/seeds/beetroot.json b/src/generated/resources/data/c/tags/item/seeds/beetroot.json index 54ba42f3555..da5a4ab7eff 100644 --- a/src/generated/resources/data/c/tags/item/seeds/beetroot.json +++ b/src/generated/resources/data/c/tags/item/seeds/beetroot.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:beetroot_seeds", - { - "id": "#forge:seeds/beetroot", - "required": false - } + "minecraft:beetroot_seeds" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/seeds/melon.json b/src/generated/resources/data/c/tags/item/seeds/melon.json index 0def0ae263e..973c52ea124 100644 --- a/src/generated/resources/data/c/tags/item/seeds/melon.json +++ b/src/generated/resources/data/c/tags/item/seeds/melon.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:melon_seeds", - { - "id": "#forge:seeds/melon", - "required": false - } + "minecraft:melon_seeds" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/seeds/pumpkin.json b/src/generated/resources/data/c/tags/item/seeds/pumpkin.json index d0ab847b4af..264c06bf04f 100644 --- a/src/generated/resources/data/c/tags/item/seeds/pumpkin.json +++ b/src/generated/resources/data/c/tags/item/seeds/pumpkin.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:pumpkin_seeds", - { - "id": "#forge:seeds/pumpkin", - "required": false - } + "minecraft:pumpkin_seeds" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/seeds/wheat.json b/src/generated/resources/data/c/tags/item/seeds/wheat.json index 68fdea41a21..b90459c2910 100644 --- a/src/generated/resources/data/c/tags/item/seeds/wheat.json +++ b/src/generated/resources/data/c/tags/item/seeds/wheat.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:wheat_seeds", - { - "id": "#forge:seeds/wheat", - "required": false - } + "minecraft:wheat_seeds" ] } \ No newline at end of file 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 168a8c2a456..533c25d9163 100644 --- a/src/generated/resources/data/c/tags/item/slime_balls.json +++ b/src/generated/resources/data/c/tags/item/slime_balls.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:slime_ball", - { - "id": "#forge:slime_balls", - "required": false - } + "minecraft:slime_ball" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/stones.json b/src/generated/resources/data/c/tags/item/stones.json index 28489984599..c95195f10c8 100644 --- a/src/generated/resources/data/c/tags/item/stones.json +++ b/src/generated/resources/data/c/tags/item/stones.json @@ -5,10 +5,6 @@ "minecraft:granite", "minecraft:stone", "minecraft:deepslate", - "minecraft:tuff", - { - "id": "#forge:stone", - "required": false - } + "minecraft:tuff" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks.json b/src/generated/resources/data/c/tags/item/storage_blocks.json index a837ec688cf..bb0022c04fa 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks.json @@ -16,10 +16,6 @@ "#c:storage_blocks/redstone", "#c:storage_blocks/resin", "#c:storage_blocks/slime", - "#c:storage_blocks/wheat", - { - "id": "#forge:storage_blocks", - "required": false - } + "#c:storage_blocks/wheat" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/coal.json b/src/generated/resources/data/c/tags/item/storage_blocks/coal.json index b8479ced38e..4b7921705b6 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/coal.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/coal.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:coal_block", - { - "id": "#forge:storage_blocks/coal", - "required": false - } + "minecraft:coal_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/copper.json b/src/generated/resources/data/c/tags/item/storage_blocks/copper.json index acd2a6a7a48..015bec70c31 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/copper.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/copper.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:copper_block", - { - "id": "#forge:storage_blocks/copper", - "required": false - } + "minecraft:copper_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/diamond.json b/src/generated/resources/data/c/tags/item/storage_blocks/diamond.json index 76426ba425f..acd7f52de5e 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/diamond.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/diamond.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:diamond_block", - { - "id": "#forge:storage_blocks/diamond", - "required": false - } + "minecraft:diamond_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/emerald.json b/src/generated/resources/data/c/tags/item/storage_blocks/emerald.json index 7a41454d94d..152063ec6c6 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/emerald.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/emerald.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:emerald_block", - { - "id": "#forge:storage_blocks/emerald", - "required": false - } + "minecraft:emerald_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/gold.json b/src/generated/resources/data/c/tags/item/storage_blocks/gold.json index a4116fc77fd..546dde03c96 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/gold.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/gold.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:gold_block", - { - "id": "#forge:storage_blocks/gold", - "required": false - } + "minecraft:gold_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/iron.json b/src/generated/resources/data/c/tags/item/storage_blocks/iron.json index f0e9fcca1fe..01fb2965f2c 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/iron.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/iron.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:iron_block", - { - "id": "#forge:storage_blocks/iron", - "required": false - } + "minecraft:iron_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/lapis.json b/src/generated/resources/data/c/tags/item/storage_blocks/lapis.json index b5f41d8d4e7..f4ca82bbd4d 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/lapis.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/lapis.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:lapis_block", - { - "id": "#forge:storage_blocks/lapis", - "required": false - } + "minecraft:lapis_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/netherite.json b/src/generated/resources/data/c/tags/item/storage_blocks/netherite.json index a3dfe0d53c5..83433d44eb8 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/netherite.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/netherite.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:netherite_block", - { - "id": "#forge:storage_blocks/netherite", - "required": false - } + "minecraft:netherite_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/raw_copper.json b/src/generated/resources/data/c/tags/item/storage_blocks/raw_copper.json index 8f12fb63a74..1a21e230ef0 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/raw_copper.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/raw_copper.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_copper_block", - { - "id": "#forge:storage_blocks/raw_copper", - "required": false - } + "minecraft:raw_copper_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/raw_gold.json b/src/generated/resources/data/c/tags/item/storage_blocks/raw_gold.json index dcee1e225b1..80781ce6675 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/raw_gold.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/raw_gold.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_gold_block", - { - "id": "#forge:storage_blocks/raw_gold", - "required": false - } + "minecraft:raw_gold_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/raw_iron.json b/src/generated/resources/data/c/tags/item/storage_blocks/raw_iron.json index 3f0ecf27ad1..13ed9fc651b 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/raw_iron.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/raw_iron.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:raw_iron_block", - { - "id": "#forge:storage_blocks/raw_iron", - "required": false - } + "minecraft:raw_iron_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/redstone.json b/src/generated/resources/data/c/tags/item/storage_blocks/redstone.json index 49fa7a5a26a..f5fd89c5414 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks/redstone.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks/redstone.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:redstone_block", - { - "id": "#forge:storage_blocks/redstone", - "required": false - } + "minecraft:redstone_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/strings.json b/src/generated/resources/data/c/tags/item/strings.json index 89b40c31c5b..d018256cf83 100644 --- a/src/generated/resources/data/c/tags/item/strings.json +++ b/src/generated/resources/data/c/tags/item/strings.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:string", - { - "id": "#forge:strings", - "required": false - } + "minecraft:string" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools.json b/src/generated/resources/data/c/tags/item/tools.json index 6fd1f02c3a2..5f538b47dba 100644 --- a/src/generated/resources/data/c/tags/item/tools.json +++ b/src/generated/resources/data/c/tags/item/tools.json @@ -4,6 +4,7 @@ "#minecraft:hoes", "#minecraft:pickaxes", "#minecraft:shovels", + "#minecraft:spears", "#minecraft:swords", "#c:tools/bow", "#c:tools/brush", @@ -12,15 +13,11 @@ "#c:tools/igniter", "#c:tools/shear", "#c:tools/shield", - "#c:tools/spear", + "#c:tools/trident", "#c:tools/mace", "#c:tools/wrench", "#c:tools/mining_tool", "#c:tools/melee_weapon", - "#c:tools/ranged_weapon", - { - "id": "#forge:tools", - "required": false - } + "#c:tools/ranged_weapon" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/bow.json b/src/generated/resources/data/c/tags/item/tools/bow.json index 0e7a3eb3a23..a1c8a443dca 100644 --- a/src/generated/resources/data/c/tags/item/tools/bow.json +++ b/src/generated/resources/data/c/tags/item/tools/bow.json @@ -1,13 +1,5 @@ { "values": [ - "minecraft:bow", - { - "id": "#forge:tools/bows", - "required": false - }, - { - "id": "#c:tools/bows", - "required": false - } + "minecraft:bow" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/brush.json b/src/generated/resources/data/c/tags/item/tools/brush.json index bacde921223..8b2fb219eac 100644 --- a/src/generated/resources/data/c/tags/item/tools/brush.json +++ b/src/generated/resources/data/c/tags/item/tools/brush.json @@ -1,13 +1,5 @@ { "values": [ - "minecraft:brush", - { - "id": "#forge:tools/brushes", - "required": false - }, - { - "id": "#c:tools/brushes", - "required": false - } + "minecraft:brush" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/crossbow.json b/src/generated/resources/data/c/tags/item/tools/crossbow.json index 7f9c54c37f7..848f97bc22e 100644 --- a/src/generated/resources/data/c/tags/item/tools/crossbow.json +++ b/src/generated/resources/data/c/tags/item/tools/crossbow.json @@ -1,13 +1,5 @@ { "values": [ - "minecraft:crossbow", - { - "id": "#forge:tools/crossbows", - "required": false - }, - { - "id": "#c:tools/crossbows", - "required": false - } + "minecraft:crossbow" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/fishing_rod.json b/src/generated/resources/data/c/tags/item/tools/fishing_rod.json index 7b10f8bef7a..e97941e9dc3 100644 --- a/src/generated/resources/data/c/tags/item/tools/fishing_rod.json +++ b/src/generated/resources/data/c/tags/item/tools/fishing_rod.json @@ -1,13 +1,5 @@ { "values": [ - "minecraft:fishing_rod", - { - "id": "#forge:tools/fishing_rods", - "required": false - }, - { - "id": "#c:tools/fishing_rods", - "required": false - } + "minecraft:fishing_rod" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/melee_weapon.json b/src/generated/resources/data/c/tags/item/tools/melee_weapon.json index 2bb3c599d06..0f91924b7de 100644 --- a/src/generated/resources/data/c/tags/item/tools/melee_weapon.json +++ b/src/generated/resources/data/c/tags/item/tools/melee_weapon.json @@ -15,6 +15,13 @@ "minecraft:golden_axe", "minecraft:iron_axe", "minecraft:diamond_axe", - "minecraft:netherite_axe" + "minecraft:netherite_axe", + "minecraft:wooden_spear", + "minecraft:stone_spear", + "minecraft:copper_spear", + "minecraft:iron_spear", + "minecraft:golden_spear", + "minecraft:diamond_spear", + "minecraft:netherite_spear" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/shear.json b/src/generated/resources/data/c/tags/item/tools/shear.json index 4bfc43fa6b2..24000781662 100644 --- a/src/generated/resources/data/c/tags/item/tools/shear.json +++ b/src/generated/resources/data/c/tags/item/tools/shear.json @@ -1,17 +1,5 @@ { "values": [ - "minecraft:shears", - { - "id": "#forge:shears", - "required": false - }, - { - "id": "#forge:tools/shears", - "required": false - }, - { - "id": "#c:tools/shears", - "required": false - } + "minecraft:shears" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/shield.json b/src/generated/resources/data/c/tags/item/tools/shield.json index e7f561f3a04..0f2454ce043 100644 --- a/src/generated/resources/data/c/tags/item/tools/shield.json +++ b/src/generated/resources/data/c/tags/item/tools/shield.json @@ -1,13 +1,5 @@ { "values": [ - "minecraft:shield", - { - "id": "#forge:tools/shields", - "required": false - }, - { - "id": "#c:tools/shields", - "required": false - } + "minecraft:shield" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/spear.json b/src/generated/resources/data/c/tags/item/tools/spear.json deleted file mode 100644 index ec20a2fa831..00000000000 --- a/src/generated/resources/data/c/tags/item/tools/spear.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "values": [ - "minecraft:trident", - { - "id": "#forge:tools/tridents", - "required": false - }, - { - "id": "#forge:tools/tridents", - "required": false - }, - { - "id": "#c:tools/tridents", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/trident.json b/src/generated/resources/data/c/tags/item/tools/trident.json new file mode 100644 index 00000000000..7a2c450bc74 --- /dev/null +++ b/src/generated/resources/data/c/tags/item/tools/trident.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:trident" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_aquatic.json b/src/generated/resources/data/c/tags/worldgen/biome/is_aquatic.json index 77bf3cac1ae..0c764d624a0 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_aquatic.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_aquatic.json @@ -1,10 +1,6 @@ { "values": [ "#c:is_ocean", - "#c:is_river", - { - "id": "#forge:is_water", - "required": false - } + "#c:is_river" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_cave.json b/src/generated/resources/data/c/tags/worldgen/biome/is_cave.json index 14acf097edf..21a70cfeec4 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_cave.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_cave.json @@ -2,10 +2,6 @@ "values": [ "minecraft:lush_caves", "minecraft:dripstone_caves", - "minecraft:deep_dark", - { - "id": "#forge:is_cave", - "required": false - } + "minecraft:deep_dark" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_cold.json b/src/generated/resources/data/c/tags/worldgen/biome/is_cold.json index e072099767f..d58cc9f7744 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_cold.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_cold.json @@ -2,10 +2,6 @@ "values": [ "#c:is_cold/overworld", "#c:is_cold/nether", - "#c:is_cold/end", - { - "id": "#forge:is_cold", - "required": false - } + "#c:is_cold/end" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_cold/end.json b/src/generated/resources/data/c/tags/worldgen/biome/is_cold/end.json index 5598c65b7f7..73d3eff3b0e 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_cold/end.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_cold/end.json @@ -4,10 +4,6 @@ "minecraft:small_end_islands", "minecraft:end_midlands", "minecraft:end_highlands", - "minecraft:end_barrens", - { - "id": "#forge:is_cold/end", - "required": false - } + "minecraft:end_barrens" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_cold/nether.json b/src/generated/resources/data/c/tags/worldgen/biome/is_cold/nether.json index ba8ac392ff2..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_cold/nether.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_cold/nether.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_cold/nether", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_cold/overworld.json b/src/generated/resources/data/c/tags/worldgen/biome/is_cold/overworld.json index 67e6574044e..0a747bbcfee 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_cold/overworld.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_cold/overworld.json @@ -19,10 +19,6 @@ "minecraft:cold_ocean", "minecraft:frozen_ocean", "minecraft:deep_cold_ocean", - "minecraft:deep_frozen_ocean", - { - "id": "#forge:is_cold/overworld", - "required": false - } + "minecraft:deep_frozen_ocean" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dead.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dead.json index 019f7a17c71..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dead.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dead.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_dead", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation.json index 9681edafbf5..7d985655049 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation.json @@ -2,10 +2,6 @@ "values": [ "#c:is_dense_vegetation/overworld", "#c:is_dense_vegetation/nether", - "#c:is_dense_vegetation/end", - { - "id": "#forge:is_dense", - "required": false - } + "#c:is_dense_vegetation/end" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/end.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/end.json index 644b5739654..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/end.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/end.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_dense/end", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/nether.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/nether.json index 732488f87ae..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/nether.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/nether.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_dense/nether", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/overworld.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/overworld.json index 3af2bdd5e44..54f339aa4ca 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/overworld.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dense_vegetation/overworld.json @@ -5,10 +5,6 @@ "minecraft:old_growth_spruce_taiga", "minecraft:jungle", "minecraft:bamboo_jungle", - "minecraft:mangrove_swamp", - { - "id": "#forge:is_dense/overworld", - "required": false - } + "minecraft:mangrove_swamp" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_desert.json b/src/generated/resources/data/c/tags/worldgen/biome/is_desert.json index 7f6b11f3b43..f1a8ccb6429 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_desert.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_desert.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:desert", - { - "id": "#forge:is_desert", - "required": false - } + "minecraft:desert" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dry.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dry.json index d1e491ae50b..fb8b1f13095 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dry.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dry.json @@ -2,10 +2,6 @@ "values": [ "#c:is_dry/overworld", "#c:is_dry/nether", - "#c:is_dry/end", - { - "id": "#forge:is_dry", - "required": false - } + "#c:is_dry/end" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dry/end.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dry/end.json index ce1b28ee591..73d3eff3b0e 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dry/end.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dry/end.json @@ -4,10 +4,6 @@ "minecraft:small_end_islands", "minecraft:end_midlands", "minecraft:end_highlands", - "minecraft:end_barrens", - { - "id": "#forge:is_dry/end", - "required": false - } + "minecraft:end_barrens" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dry/nether.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dry/nether.json index c490dcb1afc..d8cf8f5e344 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dry/nether.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dry/nether.json @@ -4,10 +4,6 @@ "minecraft:crimson_forest", "minecraft:warped_forest", "minecraft:soul_sand_valley", - "minecraft:basalt_deltas", - { - "id": "#forge:is_dry/nether", - "required": false - } + "minecraft:basalt_deltas" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_dry/overworld.json b/src/generated/resources/data/c/tags/worldgen/biome/is_dry/overworld.json index 66049f89289..56ca6781dae 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_dry/overworld.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_dry/overworld.json @@ -6,10 +6,6 @@ "minecraft:eroded_badlands", "minecraft:savanna", "minecraft:savanna_plateau", - "minecraft:windswept_savanna", - { - "id": "#forge:is_dry/overworld", - "required": false - } + "minecraft:windswept_savanna" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_end.json b/src/generated/resources/data/c/tags/worldgen/biome/is_end.json index 2e43e7a97ba..3bbfe0bf59f 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_end.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_end.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:is_end", - { - "id": "#forge:is_end", - "required": false - } + "#minecraft:is_end" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_floral.json b/src/generated/resources/data/c/tags/worldgen/biome/is_floral.json index 32cfdbacc28..6b464cc9bbb 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_floral.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_floral.json @@ -3,10 +3,6 @@ "#c:is_flower_forest", "minecraft:sunflower_plains", "minecraft:cherry_grove", - "minecraft:meadow", - { - "id": "#forge:is_floral", - "required": false - } + "minecraft:meadow" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_hot.json b/src/generated/resources/data/c/tags/worldgen/biome/is_hot.json index 5948ff7b5cd..28dd24912a4 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_hot.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_hot.json @@ -2,10 +2,6 @@ "values": [ "#c:is_hot/overworld", "#c:is_hot/nether", - "#c:is_hot/end", - { - "id": "#forge:is_hot", - "required": false - } + "#c:is_hot/end" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_hot/end.json b/src/generated/resources/data/c/tags/worldgen/biome/is_hot/end.json index 384c64e8239..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_hot/end.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_hot/end.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_hot/end", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_hot/nether.json b/src/generated/resources/data/c/tags/worldgen/biome/is_hot/nether.json index 48cf5e7bec1..d8cf8f5e344 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_hot/nether.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_hot/nether.json @@ -4,10 +4,6 @@ "minecraft:crimson_forest", "minecraft:warped_forest", "minecraft:soul_sand_valley", - "minecraft:basalt_deltas", - { - "id": "#forge:is_hot/nether", - "required": false - } + "minecraft:basalt_deltas" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_hot/overworld.json b/src/generated/resources/data/c/tags/worldgen/biome/is_hot/overworld.json index 3fea45117ce..5161845da04 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_hot/overworld.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_hot/overworld.json @@ -12,10 +12,6 @@ "minecraft:windswept_savanna", "minecraft:stony_peaks", "minecraft:mushroom_fields", - "minecraft:warm_ocean", - { - "id": "#forge:is_hot/overworld", - "required": false - } + "minecraft:warm_ocean" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_lush.json b/src/generated/resources/data/c/tags/worldgen/biome/is_lush.json index 6d69742b221..14035f0a54d 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_lush.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_lush.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:lush_caves", - { - "id": "#forge:is_lush", - "required": false - } + "minecraft:lush_caves" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_magical.json b/src/generated/resources/data/c/tags/worldgen/biome/is_magical.json index 790536a079b..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_magical.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_magical.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_magical", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_mountain.json b/src/generated/resources/data/c/tags/worldgen/biome/is_mountain.json index 0ad5197c186..f6976e06700 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_mountain.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_mountain.json @@ -2,10 +2,6 @@ "values": [ "#minecraft:is_mountain", "#c:is_mountain/peak", - "#c:is_mountain/slope", - { - "id": "#forge:is_mountain", - "required": false - } + "#c:is_mountain/slope" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_mountain/peak.json b/src/generated/resources/data/c/tags/worldgen/biome/is_mountain/peak.json index 60454a4666e..c9597b86d04 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_mountain/peak.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_mountain/peak.json @@ -2,10 +2,6 @@ "values": [ "minecraft:jagged_peaks", "minecraft:frozen_peaks", - "minecraft:stony_peaks", - { - "id": "#forge:is_peak", - "required": false - } + "minecraft:stony_peaks" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_mountain/slope.json b/src/generated/resources/data/c/tags/worldgen/biome/is_mountain/slope.json index b5347839575..f3a1e55d57d 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_mountain/slope.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_mountain/slope.json @@ -3,10 +3,6 @@ "minecraft:snowy_slopes", "minecraft:meadow", "minecraft:grove", - "minecraft:cherry_grove", - { - "id": "#forge:is_slope", - "required": false - } + "minecraft:cherry_grove" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_mushroom.json b/src/generated/resources/data/c/tags/worldgen/biome/is_mushroom.json index e83f4e0c452..05d85d951d7 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_mushroom.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_mushroom.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:mushroom_fields", - { - "id": "#forge:is_mushroom", - "required": false - } + "minecraft:mushroom_fields" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_nether.json b/src/generated/resources/data/c/tags/worldgen/biome/is_nether.json index 8775f39f6f5..f7e672b8c87 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_nether.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_nether.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:is_nether", - { - "id": "#forge:is_nether", - "required": false - } + "#minecraft:is_nether" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_overworld.json b/src/generated/resources/data/c/tags/worldgen/biome/is_overworld.json index e1bd80c7544..d3152c5b09d 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_overworld.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_overworld.json @@ -1,9 +1,5 @@ { "values": [ - "#minecraft:is_overworld", - { - "id": "#forge:is_overworld", - "required": false - } + "#minecraft:is_overworld" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_plains.json b/src/generated/resources/data/c/tags/worldgen/biome/is_plains.json index 4e23e1e56f1..c88810bc13d 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_plains.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_plains.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:plains", - "minecraft:sunflower_plains", - { - "id": "#forge:is_plains", - "required": false - } + "minecraft:sunflower_plains" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_plateau.json b/src/generated/resources/data/c/tags/worldgen/biome/is_plateau.json index c7120844786..7228fbfd2b4 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_plateau.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_plateau.json @@ -3,10 +3,6 @@ "minecraft:wooded_badlands", "minecraft:savanna_plateau", "minecraft:cherry_grove", - "minecraft:meadow", - { - "id": "#forge:is_plateau", - "required": false - } + "minecraft:meadow" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_rare.json b/src/generated/resources/data/c/tags/worldgen/biome/is_rare.json index 9f2fa3a3325..77b3680e494 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_rare.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_rare.json @@ -13,10 +13,6 @@ "minecraft:windswept_gravelly_hills", "minecraft:pale_garden", "minecraft:mushroom_fields", - "minecraft:deep_dark", - { - "id": "#forge:is_rare", - "required": false - } + "minecraft:deep_dark" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_sandy.json b/src/generated/resources/data/c/tags/worldgen/biome/is_sandy.json index 5fad39f73bf..5380f1372e0 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_sandy.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_sandy.json @@ -4,10 +4,6 @@ "minecraft:badlands", "minecraft:wooded_badlands", "minecraft:eroded_badlands", - "minecraft:beach", - { - "id": "#forge:is_sandy", - "required": false - } + "minecraft:beach" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_snowy.json b/src/generated/resources/data/c/tags/worldgen/biome/is_snowy.json index 8d5168ef6ce..193255cf45a 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_snowy.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_snowy.json @@ -7,10 +7,6 @@ "minecraft:grove", "minecraft:snowy_slopes", "minecraft:jagged_peaks", - "minecraft:frozen_peaks", - { - "id": "#forge:is_snowy", - "required": false - } + "minecraft:frozen_peaks" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation.json b/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation.json index ef4f3fc90b0..3f05a1cd7ad 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation.json @@ -2,14 +2,6 @@ "values": [ "#c:is_sparse_vegetation/overworld", "#c:is_sparse_vegetation/nether", - "#c:is_sparse_vegetation/end", - { - "id": "#forge:is_sparse_vegetation", - "required": false - }, - { - "id": "#forge:is_sparse", - "required": false - } + "#c:is_sparse_vegetation/end" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/end.json b/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/end.json index 93863ce9c16..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/end.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/end.json @@ -1,12 +1,3 @@ { - "values": [ - { - "id": "#forge:is_sparse_vegetation/end", - "required": false - }, - { - "id": "#forge:is_sparse/end", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/nether.json b/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/nether.json index 70f6d7a9a00..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/nether.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/nether.json @@ -1,12 +1,3 @@ { - "values": [ - { - "id": "#forge:is_sparse_vegetation/nether", - "required": false - }, - { - "id": "#forge:is_sparse/nether", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/overworld.json b/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/overworld.json index 905b2bfe66f..50e66eff68f 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/overworld.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_sparse_vegetation/overworld.json @@ -10,14 +10,6 @@ "minecraft:windswept_gravelly_hills", "minecraft:snowy_slopes", "minecraft:jagged_peaks", - "minecraft:frozen_peaks", - { - "id": "#forge:is_sparse_vegetation/overworld", - "required": false - }, - { - "id": "#forge:is_sparse/overworld", - "required": false - } + "minecraft:frozen_peaks" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_spooky.json b/src/generated/resources/data/c/tags/worldgen/biome/is_spooky.json index 83ca2148992..db1aa63f728 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_spooky.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_spooky.json @@ -2,10 +2,6 @@ "values": [ "minecraft:dark_forest", "minecraft:pale_garden", - "minecraft:deep_dark", - { - "id": "#forge:is_spooky", - "required": false - } + "minecraft:deep_dark" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_swamp.json b/src/generated/resources/data/c/tags/worldgen/biome/is_swamp.json index 7f7d1c742b7..0f5eb22e0c7 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_swamp.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_swamp.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:swamp", - "minecraft:mangrove_swamp", - { - "id": "#forge:is_swamp", - "required": false - } + "minecraft:mangrove_swamp" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_tree/coniferous.json b/src/generated/resources/data/c/tags/worldgen/biome/is_tree/coniferous.json index 62d147cff9e..56f639f895b 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_tree/coniferous.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_tree/coniferous.json @@ -1,10 +1,6 @@ { "values": [ "#c:is_taiga", - "minecraft:grove", - { - "id": "#forge:is_tree/coniferous", - "required": false - } + "minecraft:grove" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_void.json b/src/generated/resources/data/c/tags/worldgen/biome/is_void.json index f6048857ff5..f55aea66711 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_void.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_void.json @@ -1,9 +1,5 @@ { "values": [ - "minecraft:the_void", - { - "id": "#forge:is_void", - "required": false - } + "minecraft:the_void" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_wasteland.json b/src/generated/resources/data/c/tags/worldgen/biome/is_wasteland.json index 6d11db61bc3..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_wasteland.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_wasteland.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_wasteland", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_wet.json b/src/generated/resources/data/c/tags/worldgen/biome/is_wet.json index 7ae0700ab44..c451f70640a 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_wet.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_wet.json @@ -2,10 +2,6 @@ "values": [ "#c:is_wet/overworld", "#c:is_wet/nether", - "#c:is_wet/end", - { - "id": "#forge:is_wet", - "required": false - } + "#c:is_wet/end" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_wet/end.json b/src/generated/resources/data/c/tags/worldgen/biome/is_wet/end.json index 6f6b6d1480b..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_wet/end.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_wet/end.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_wet/end", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_wet/nether.json b/src/generated/resources/data/c/tags/worldgen/biome/is_wet/nether.json index 90601e0731c..f72d209df78 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_wet/nether.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_wet/nether.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:is_wet/nether", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_wet/overworld.json b/src/generated/resources/data/c/tags/worldgen/biome/is_wet/overworld.json index 6bb610406d9..ee6eef27231 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_wet/overworld.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_wet/overworld.json @@ -7,10 +7,6 @@ "minecraft:sparse_jungle", "minecraft:beach", "minecraft:lush_caves", - "minecraft:dripstone_caves", - { - "id": "#forge:is_wet/overworld", - "required": false - } + "minecraft:dripstone_caves" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/advancement/adventure/lighten_up.json b/src/generated/resources/data/minecraft/advancement/adventure/lighten_up.json index e0bffbfecd4..62a300f10aa 100644 --- a/src/generated/resources/data/minecraft/advancement/adventure/lighten_up.json +++ b/src/generated/resources/data/minecraft/advancement/adventure/lighten_up.json @@ -40,7 +40,6 @@ "translate": "advancements.adventure.lighten_up.description" }, "icon": { - "count": 1, "id": "minecraft:copper_bulb" }, "title": { diff --git a/src/generated/resources/data/minecraft/advancement/adventure/throw_trident.json b/src/generated/resources/data/minecraft/advancement/adventure/throw_trident.json index 67305db54ab..9a65819871e 100644 --- a/src/generated/resources/data/minecraft/advancement/adventure/throw_trident.json +++ b/src/generated/resources/data/minecraft/advancement/adventure/throw_trident.json @@ -27,7 +27,6 @@ "translate": "advancements.adventure.throw_trident.description" }, "icon": { - "count": 1, "id": "minecraft:trident" }, "title": { diff --git a/src/generated/resources/data/minecraft/advancement/adventure/walk_on_powder_snow_with_leather_boots.json b/src/generated/resources/data/minecraft/advancement/adventure/walk_on_powder_snow_with_leather_boots.json index de026413232..a74cf1e85fa 100644 --- a/src/generated/resources/data/minecraft/advancement/adventure/walk_on_powder_snow_with_leather_boots.json +++ b/src/generated/resources/data/minecraft/advancement/adventure/walk_on_powder_snow_with_leather_boots.json @@ -28,7 +28,6 @@ "translate": "advancements.adventure.walk_on_powder_snow_with_leather_boots.description" }, "icon": { - "count": 1, "id": "minecraft:leather_boots" }, "title": { diff --git a/src/generated/resources/data/minecraft/advancement/husbandry/wax_off.json b/src/generated/resources/data/minecraft/advancement/husbandry/wax_off.json index f6240425372..310757df962 100644 --- a/src/generated/resources/data/minecraft/advancement/husbandry/wax_off.json +++ b/src/generated/resources/data/minecraft/advancement/husbandry/wax_off.json @@ -91,7 +91,6 @@ "translate": "advancements.husbandry.wax_off.description" }, "icon": { - "count": 1, "id": "minecraft:stone_axe" }, "title": { diff --git a/src/generated/resources/data/minecraft/advancement/nether/distract_piglin.json b/src/generated/resources/data/minecraft/advancement/nether/distract_piglin.json index d95c59aea86..edb35bf70bb 100644 --- a/src/generated/resources/data/minecraft/advancement/nether/distract_piglin.json +++ b/src/generated/resources/data/minecraft/advancement/nether/distract_piglin.json @@ -77,7 +77,6 @@ "translate": "advancements.nether.distract_piglin.description" }, "icon": { - "count": 1, "id": "minecraft:gold_ingot" }, "title": { diff --git a/src/generated/resources/data/minecraft/recipe/acacia_chest_boat.json b/src/generated/resources/data/minecraft/recipe/acacia_chest_boat.json index 745f8237baf..6edfbe37de7 100644 --- a/src/generated/resources/data/minecraft/recipe/acacia_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/acacia_chest_boat.json @@ -11,7 +11,6 @@ "minecraft:acacia_boat" ], "result": { - "count": 1, "id": "minecraft:acacia_chest_boat" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/acacia_fence_gate.json b/src/generated/resources/data/minecraft/recipe/acacia_fence_gate.json index af366bf3326..e685099595c 100644 --- a/src/generated/resources/data/minecraft/recipe/acacia_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/acacia_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:acacia_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/anvil.json b/src/generated/resources/data/minecraft/recipe/anvil.json index e50cd1febee..b6bbfbf8210 100644 --- a/src/generated/resources/data/minecraft/recipe/anvil.json +++ b/src/generated/resources/data/minecraft/recipe/anvil.json @@ -11,7 +11,6 @@ "iii" ], "result": { - "count": 1, "id": "minecraft:anvil" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/armor_stand.json b/src/generated/resources/data/minecraft/recipe/armor_stand.json index a3ad60d12c0..938c8d80c4c 100644 --- a/src/generated/resources/data/minecraft/recipe/armor_stand.json +++ b/src/generated/resources/data/minecraft/recipe/armor_stand.json @@ -11,7 +11,6 @@ "/_/" ], "result": { - "count": 1, "id": "minecraft:armor_stand" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/bamboo_chest_raft.json b/src/generated/resources/data/minecraft/recipe/bamboo_chest_raft.json index 0b97b7f4cf0..f2ab0a08758 100644 --- a/src/generated/resources/data/minecraft/recipe/bamboo_chest_raft.json +++ b/src/generated/resources/data/minecraft/recipe/bamboo_chest_raft.json @@ -11,7 +11,6 @@ "minecraft:bamboo_raft" ], "result": { - "count": 1, "id": "minecraft:bamboo_chest_raft" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/bamboo_fence_gate.json b/src/generated/resources/data/minecraft/recipe/bamboo_fence_gate.json index 444acda7bec..4156b7fec10 100644 --- a/src/generated/resources/data/minecraft/recipe/bamboo_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/bamboo_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:bamboo_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/birch_chest_boat.json b/src/generated/resources/data/minecraft/recipe/birch_chest_boat.json index 3043b2193a6..a2b23b0aab7 100644 --- a/src/generated/resources/data/minecraft/recipe/birch_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/birch_chest_boat.json @@ -11,7 +11,6 @@ "minecraft:birch_boat" ], "result": { - "count": 1, "id": "minecraft:birch_chest_boat" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/birch_fence_gate.json b/src/generated/resources/data/minecraft/recipe/birch_fence_gate.json index 55e6c5133a1..df4e8880cd5 100644 --- a/src/generated/resources/data/minecraft/recipe/birch_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/birch_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:birch_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/black_banner.json b/src/generated/resources/data/minecraft/recipe/black_banner.json index 7f676002169..20fa2d97376 100644 --- a/src/generated/resources/data/minecraft/recipe/black_banner.json +++ b/src/generated/resources/data/minecraft/recipe/black_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:black_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/black_candle.json b/src/generated/resources/data/minecraft/recipe/black_candle.json index 5d54b78d106..832c36e176b 100644 --- a/src/generated/resources/data/minecraft/recipe/black_candle.json +++ b/src/generated/resources/data/minecraft/recipe/black_candle.json @@ -7,7 +7,6 @@ "#c:dyes/black" ], "result": { - "count": 1, "id": "minecraft:black_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/blast_furnace.json b/src/generated/resources/data/minecraft/recipe/blast_furnace.json index eb2c292aacb..e6d456e1d3c 100644 --- a/src/generated/resources/data/minecraft/recipe/blast_furnace.json +++ b/src/generated/resources/data/minecraft/recipe/blast_furnace.json @@ -12,7 +12,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:blast_furnace" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/blue_banner.json b/src/generated/resources/data/minecraft/recipe/blue_banner.json index a98940c6b16..ef898a85863 100644 --- a/src/generated/resources/data/minecraft/recipe/blue_banner.json +++ b/src/generated/resources/data/minecraft/recipe/blue_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:blue_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/blue_candle.json b/src/generated/resources/data/minecraft/recipe/blue_candle.json index 34f58060150..b7b8e290661 100644 --- a/src/generated/resources/data/minecraft/recipe/blue_candle.json +++ b/src/generated/resources/data/minecraft/recipe/blue_candle.json @@ -7,7 +7,6 @@ "#c:dyes/blue" ], "result": { - "count": 1, "id": "minecraft:blue_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/bow.json b/src/generated/resources/data/minecraft/recipe/bow.json index 5831fc36f12..57e32ba264d 100644 --- a/src/generated/resources/data/minecraft/recipe/bow.json +++ b/src/generated/resources/data/minecraft/recipe/bow.json @@ -11,7 +11,6 @@ " #X" ], "result": { - "count": 1, "id": "minecraft:bow" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/brown_banner.json b/src/generated/resources/data/minecraft/recipe/brown_banner.json index 5394a3d33c1..4fe52af7689 100644 --- a/src/generated/resources/data/minecraft/recipe/brown_banner.json +++ b/src/generated/resources/data/minecraft/recipe/brown_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:brown_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/brown_candle.json b/src/generated/resources/data/minecraft/recipe/brown_candle.json index 730b80253db..06006de7b70 100644 --- a/src/generated/resources/data/minecraft/recipe/brown_candle.json +++ b/src/generated/resources/data/minecraft/recipe/brown_candle.json @@ -7,7 +7,6 @@ "#c:dyes/brown" ], "result": { - "count": 1, "id": "minecraft:brown_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/brush.json b/src/generated/resources/data/minecraft/recipe/brush.json index 4fc5863cee6..c66d1df5b6e 100644 --- a/src/generated/resources/data/minecraft/recipe/brush.json +++ b/src/generated/resources/data/minecraft/recipe/brush.json @@ -12,7 +12,6 @@ "I" ], "result": { - "count": 1, "id": "minecraft:brush" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/bucket.json b/src/generated/resources/data/minecraft/recipe/bucket.json index 692ea8b728b..98599240ceb 100644 --- a/src/generated/resources/data/minecraft/recipe/bucket.json +++ b/src/generated/resources/data/minecraft/recipe/bucket.json @@ -9,7 +9,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:bucket" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/bundle.json b/src/generated/resources/data/minecraft/recipe/bundle.json index fb9cad8657e..75cd4774598 100644 --- a/src/generated/resources/data/minecraft/recipe/bundle.json +++ b/src/generated/resources/data/minecraft/recipe/bundle.json @@ -10,7 +10,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:bundle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/calibrated_sculk_sensor.json b/src/generated/resources/data/minecraft/recipe/calibrated_sculk_sensor.json index 7b748c17a20..b1ceef8b504 100644 --- a/src/generated/resources/data/minecraft/recipe/calibrated_sculk_sensor.json +++ b/src/generated/resources/data/minecraft/recipe/calibrated_sculk_sensor.json @@ -10,7 +10,6 @@ "#X#" ], "result": { - "count": 1, "id": "minecraft:calibrated_sculk_sensor" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/campfire.json b/src/generated/resources/data/minecraft/recipe/campfire.json index fd2f3375236..93372c24ec0 100644 --- a/src/generated/resources/data/minecraft/recipe/campfire.json +++ b/src/generated/resources/data/minecraft/recipe/campfire.json @@ -12,7 +12,6 @@ "LLL" ], "result": { - "count": 1, "id": "minecraft:campfire" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/candle.json b/src/generated/resources/data/minecraft/recipe/candle.json index 6cb6864e6bc..953a6803591 100644 --- a/src/generated/resources/data/minecraft/recipe/candle.json +++ b/src/generated/resources/data/minecraft/recipe/candle.json @@ -10,7 +10,6 @@ "H" ], "result": { - "count": 1, "id": "minecraft:candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cauldron.json b/src/generated/resources/data/minecraft/recipe/cauldron.json index 101a0b54d69..936cc35ecb4 100644 --- a/src/generated/resources/data/minecraft/recipe/cauldron.json +++ b/src/generated/resources/data/minecraft/recipe/cauldron.json @@ -10,7 +10,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:cauldron" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cherry_chest_boat.json b/src/generated/resources/data/minecraft/recipe/cherry_chest_boat.json index 1a6fb591c08..4675663fdf3 100644 --- a/src/generated/resources/data/minecraft/recipe/cherry_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/cherry_chest_boat.json @@ -11,7 +11,6 @@ "minecraft:cherry_boat" ], "result": { - "count": 1, "id": "minecraft:cherry_chest_boat" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cherry_fence_gate.json b/src/generated/resources/data/minecraft/recipe/cherry_fence_gate.json index 7ad275d0129..22f74cc665b 100644 --- a/src/generated/resources/data/minecraft/recipe/cherry_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/cherry_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:cherry_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/chest_minecart.json b/src/generated/resources/data/minecraft/recipe/chest_minecart.json index 961f895291f..4fac9e95885 100644 --- a/src/generated/resources/data/minecraft/recipe/chest_minecart.json +++ b/src/generated/resources/data/minecraft/recipe/chest_minecart.json @@ -10,7 +10,6 @@ "minecraft:minecart" ], "result": { - "count": 1, "id": "minecraft:chest_minecart" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/clock.json b/src/generated/resources/data/minecraft/recipe/clock.json index 0ffa5dfe00b..d7130bdfffa 100644 --- a/src/generated/resources/data/minecraft/recipe/clock.json +++ b/src/generated/resources/data/minecraft/recipe/clock.json @@ -11,7 +11,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:clock" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/compass.json b/src/generated/resources/data/minecraft/recipe/compass.json index 89310bdf95c..5dc4cc7981d 100644 --- a/src/generated/resources/data/minecraft/recipe/compass.json +++ b/src/generated/resources/data/minecraft/recipe/compass.json @@ -11,7 +11,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:compass" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_axe.json b/src/generated/resources/data/minecraft/recipe/copper_axe.json index 98bae5923d9..e74f15829a9 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_axe.json +++ b/src/generated/resources/data/minecraft/recipe/copper_axe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:copper_axe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_boots.json b/src/generated/resources/data/minecraft/recipe/copper_boots.json index d6dede53eea..46363bf8da3 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_boots.json +++ b/src/generated/resources/data/minecraft/recipe/copper_boots.json @@ -9,7 +9,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:copper_boots" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_chain.json b/src/generated/resources/data/minecraft/recipe/copper_chain.json index 7b30fb11151..51909893cd5 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_chain.json +++ b/src/generated/resources/data/minecraft/recipe/copper_chain.json @@ -11,7 +11,6 @@ "N" ], "result": { - "count": 1, "id": "minecraft:copper_chain" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_chest.json b/src/generated/resources/data/minecraft/recipe/copper_chest.json index 6baaab1dba3..ce0402f2735 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_chest.json +++ b/src/generated/resources/data/minecraft/recipe/copper_chest.json @@ -15,7 +15,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:copper_chest" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_chestplate.json b/src/generated/resources/data/minecraft/recipe/copper_chestplate.json index 996c150fcf1..c0af2412598 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_chestplate.json +++ b/src/generated/resources/data/minecraft/recipe/copper_chestplate.json @@ -10,7 +10,6 @@ "XXX" ], "result": { - "count": 1, "id": "minecraft:copper_chestplate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_helmet.json b/src/generated/resources/data/minecraft/recipe/copper_helmet.json index fe31d6cacae..7db88051e7c 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_helmet.json +++ b/src/generated/resources/data/minecraft/recipe/copper_helmet.json @@ -9,7 +9,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:copper_helmet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_hoe.json b/src/generated/resources/data/minecraft/recipe/copper_hoe.json index 4eaf00f663a..8a16409b03a 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/copper_hoe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:copper_hoe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_leggings.json b/src/generated/resources/data/minecraft/recipe/copper_leggings.json index aa4cb1e52f4..fb2d240bd41 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_leggings.json +++ b/src/generated/resources/data/minecraft/recipe/copper_leggings.json @@ -10,7 +10,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:copper_leggings" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_pickaxe.json b/src/generated/resources/data/minecraft/recipe/copper_pickaxe.json index 2238f2cf5e0..ba3fa4e56af 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/copper_pickaxe.json @@ -11,7 +11,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:copper_pickaxe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_shovel.json b/src/generated/resources/data/minecraft/recipe/copper_shovel.json index 581a606f5d8..fddf9c90e75 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/copper_shovel.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:copper_shovel" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_spear.json b/src/generated/resources/data/minecraft/recipe/copper_spear.json index 6a3b1446a0a..833fdc4e619 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_spear.json +++ b/src/generated/resources/data/minecraft/recipe/copper_spear.json @@ -11,7 +11,6 @@ "# " ], "result": { - "count": 1, "id": "minecraft:copper_spear" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_sword.json b/src/generated/resources/data/minecraft/recipe/copper_sword.json index 123e70b648f..6d9608daaa3 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_sword.json +++ b/src/generated/resources/data/minecraft/recipe/copper_sword.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:copper_sword" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/copper_trapdoor.json b/src/generated/resources/data/minecraft/recipe/copper_trapdoor.json index 00b43cd5a3d..2128a384376 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_trapdoor.json +++ b/src/generated/resources/data/minecraft/recipe/copper_trapdoor.json @@ -9,7 +9,6 @@ "##" ], "result": { - "count": 1, "id": "minecraft:copper_trapdoor" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/crafter.json b/src/generated/resources/data/minecraft/recipe/crafter.json index 8db88e04665..96f30df7905 100644 --- a/src/generated/resources/data/minecraft/recipe/crafter.json +++ b/src/generated/resources/data/minecraft/recipe/crafter.json @@ -13,7 +13,6 @@ "RDR" ], "result": { - "count": 1, "id": "minecraft:crafter" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/crimson_fence_gate.json b/src/generated/resources/data/minecraft/recipe/crimson_fence_gate.json index fdbdfa0f4bd..2411d233015 100644 --- a/src/generated/resources/data/minecraft/recipe/crimson_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/crimson_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:crimson_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/crossbow.json b/src/generated/resources/data/minecraft/recipe/crossbow.json index 96364225e14..05ab180df46 100644 --- a/src/generated/resources/data/minecraft/recipe/crossbow.json +++ b/src/generated/resources/data/minecraft/recipe/crossbow.json @@ -13,7 +13,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:crossbow" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cyan_banner.json b/src/generated/resources/data/minecraft/recipe/cyan_banner.json index 2efc2367e51..39eab34e3e9 100644 --- a/src/generated/resources/data/minecraft/recipe/cyan_banner.json +++ b/src/generated/resources/data/minecraft/recipe/cyan_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:cyan_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cyan_candle.json b/src/generated/resources/data/minecraft/recipe/cyan_candle.json index 50c38c52c7a..b0490ad4ef6 100644 --- a/src/generated/resources/data/minecraft/recipe/cyan_candle.json +++ b/src/generated/resources/data/minecraft/recipe/cyan_candle.json @@ -7,7 +7,6 @@ "#c:dyes/cyan" ], "result": { - "count": 1, "id": "minecraft:cyan_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dark_oak_chest_boat.json b/src/generated/resources/data/minecraft/recipe/dark_oak_chest_boat.json index e7dd8b53d2b..3d791f3762b 100644 --- a/src/generated/resources/data/minecraft/recipe/dark_oak_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/dark_oak_chest_boat.json @@ -11,7 +11,6 @@ "minecraft:dark_oak_boat" ], "result": { - "count": 1, "id": "minecraft:dark_oak_chest_boat" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dark_oak_fence_gate.json b/src/generated/resources/data/minecraft/recipe/dark_oak_fence_gate.json index d7db1861f24..d43a8b50767 100644 --- a/src/generated/resources/data/minecraft/recipe/dark_oak_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/dark_oak_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:dark_oak_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dark_prismarine.json b/src/generated/resources/data/minecraft/recipe/dark_prismarine.json index c81c46bf21e..874c4e23b62 100644 --- a/src/generated/resources/data/minecraft/recipe/dark_prismarine.json +++ b/src/generated/resources/data/minecraft/recipe/dark_prismarine.json @@ -11,7 +11,6 @@ "SSS" ], "result": { - "count": 1, "id": "minecraft:dark_prismarine" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_axe.json b/src/generated/resources/data/minecraft/recipe/diamond_axe.json index 81cfd048796..bbf68047c10 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_axe.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_axe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:diamond_axe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_boots.json b/src/generated/resources/data/minecraft/recipe/diamond_boots.json index 38ea7f8e5d9..db05b155079 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_boots.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_boots.json @@ -9,7 +9,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:diamond_boots" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_chestplate.json b/src/generated/resources/data/minecraft/recipe/diamond_chestplate.json index bace9a7d21a..65ed426afc1 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_chestplate.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_chestplate.json @@ -10,7 +10,6 @@ "XXX" ], "result": { - "count": 1, "id": "minecraft:diamond_chestplate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_helmet.json b/src/generated/resources/data/minecraft/recipe/diamond_helmet.json index 59067194a0f..ae369acd28c 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_helmet.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_helmet.json @@ -9,7 +9,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:diamond_helmet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_hoe.json b/src/generated/resources/data/minecraft/recipe/diamond_hoe.json index 6a770c0452d..baabf3d6ce5 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_hoe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:diamond_hoe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_leggings.json b/src/generated/resources/data/minecraft/recipe/diamond_leggings.json index 7992a0d4786..8d6eba381ea 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_leggings.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_leggings.json @@ -10,7 +10,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:diamond_leggings" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_pickaxe.json b/src/generated/resources/data/minecraft/recipe/diamond_pickaxe.json index bc06ce4af19..fa25c310475 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_pickaxe.json @@ -11,7 +11,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:diamond_pickaxe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_shovel.json b/src/generated/resources/data/minecraft/recipe/diamond_shovel.json index ff947a6fd7b..f4b7f3cf242 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_shovel.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:diamond_shovel" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_spear.json b/src/generated/resources/data/minecraft/recipe/diamond_spear.json index 38d7aa93893..eb350b79651 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_spear.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_spear.json @@ -11,7 +11,6 @@ "# " ], "result": { - "count": 1, "id": "minecraft:diamond_spear" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/diamond_sword.json b/src/generated/resources/data/minecraft/recipe/diamond_sword.json index cb872879e70..f04f283eae5 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_sword.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_sword.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:diamond_sword" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dispenser.json b/src/generated/resources/data/minecraft/recipe/dispenser.json index 08d2b51f71c..4eedc72fcef 100644 --- a/src/generated/resources/data/minecraft/recipe/dispenser.json +++ b/src/generated/resources/data/minecraft/recipe/dispenser.json @@ -12,7 +12,6 @@ "#R#" ], "result": { - "count": 1, "id": "minecraft:dispenser" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dropper.json b/src/generated/resources/data/minecraft/recipe/dropper.json index a079f7c1930..9af6ef7b510 100644 --- a/src/generated/resources/data/minecraft/recipe/dropper.json +++ b/src/generated/resources/data/minecraft/recipe/dropper.json @@ -11,7 +11,6 @@ "#R#" ], "result": { - "count": 1, "id": "minecraft:dropper" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_black_bed.json b/src/generated/resources/data/minecraft/recipe/dye_black_bed.json index 990bd438281..ef903c56702 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_black_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_black_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:black_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_black_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_black_carpet.json index 78757447589..8ba3bf52811 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_black_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_black_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:black_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_black_harness.json b/src/generated/resources/data/minecraft/recipe/dye_black_harness.json index 94e9e262843..809c7b3148d 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_black_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_black_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:black_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_black_wool.json b/src/generated/resources/data/minecraft/recipe/dye_black_wool.json index 4b00f9de045..27bf6c9eefc 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_black_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_black_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:black_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_blue_bed.json b/src/generated/resources/data/minecraft/recipe/dye_blue_bed.json index 0699c9e9601..38196f5df01 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_blue_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_blue_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:blue_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_blue_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_blue_carpet.json index 60b100c5c1c..d63efc3a395 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_blue_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_blue_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:blue_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_blue_harness.json b/src/generated/resources/data/minecraft/recipe/dye_blue_harness.json index 69f427d77cf..b77b87633a4 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_blue_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_blue_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:blue_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_blue_wool.json b/src/generated/resources/data/minecraft/recipe/dye_blue_wool.json index 1e41106f6c2..a8f1c8a0258 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_blue_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_blue_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:blue_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_brown_bed.json b/src/generated/resources/data/minecraft/recipe/dye_brown_bed.json index 1abfc08b5aa..5a926babf28 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_brown_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_brown_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:brown_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_brown_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_brown_carpet.json index f44998120ca..054c0804a8a 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_brown_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_brown_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:brown_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_brown_harness.json b/src/generated/resources/data/minecraft/recipe/dye_brown_harness.json index c3d41bae046..5b38d3c833d 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_brown_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_brown_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:brown_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_brown_wool.json b/src/generated/resources/data/minecraft/recipe/dye_brown_wool.json index ce7255818fe..b84983037c9 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_brown_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_brown_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:brown_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_cyan_bed.json b/src/generated/resources/data/minecraft/recipe/dye_cyan_bed.json index 56db1f77c42..9f4b6a2c9ed 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_cyan_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_cyan_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:cyan_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_cyan_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_cyan_carpet.json index e1c0684658c..3b4fc272557 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_cyan_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_cyan_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:cyan_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_cyan_harness.json b/src/generated/resources/data/minecraft/recipe/dye_cyan_harness.json index 94976ffa6b6..3855ef911d9 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_cyan_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_cyan_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:cyan_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_cyan_wool.json b/src/generated/resources/data/minecraft/recipe/dye_cyan_wool.json index 3c6551327f8..912a634367a 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_cyan_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_cyan_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:cyan_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_gray_bed.json b/src/generated/resources/data/minecraft/recipe/dye_gray_bed.json index b3af84a7e73..00f1fb12d52 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_gray_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_gray_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:gray_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_gray_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_gray_carpet.json index 589145f8366..4584001a765 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_gray_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_gray_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:gray_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_gray_harness.json b/src/generated/resources/data/minecraft/recipe/dye_gray_harness.json index 65c20d603d3..a8022a58594 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_gray_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_gray_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:gray_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_gray_wool.json b/src/generated/resources/data/minecraft/recipe/dye_gray_wool.json index 54b7a841c23..a4158ac7dd9 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_gray_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_gray_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:gray_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_green_bed.json b/src/generated/resources/data/minecraft/recipe/dye_green_bed.json index a7078757e01..67d16511255 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_green_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_green_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:green_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_green_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_green_carpet.json index 3862dfcff05..62e7ce04418 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_green_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_green_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:green_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_green_harness.json b/src/generated/resources/data/minecraft/recipe/dye_green_harness.json index d92f76c33d5..03b7c49bd3e 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_green_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_green_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:green_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_green_wool.json b/src/generated/resources/data/minecraft/recipe/dye_green_wool.json index 63e86df341a..8e12bce0e88 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_green_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_green_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:green_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_blue_bed.json b/src/generated/resources/data/minecraft/recipe/dye_light_blue_bed.json index 61331d9d7cf..577e639ed17 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_light_blue_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_light_blue_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:light_blue_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_blue_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_light_blue_carpet.json index 2191f6c37b9..d918db03746 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_light_blue_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_light_blue_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:light_blue_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_blue_harness.json b/src/generated/resources/data/minecraft/recipe/dye_light_blue_harness.json index 526e054ec66..eeff31f8c1e 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_light_blue_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_light_blue_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:light_blue_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_blue_wool.json b/src/generated/resources/data/minecraft/recipe/dye_light_blue_wool.json index 9c97901ec96..c998e3f01a2 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_light_blue_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_light_blue_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:light_blue_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_gray_bed.json b/src/generated/resources/data/minecraft/recipe/dye_light_gray_bed.json index d1fd9b826dc..437cf3b3a57 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_light_gray_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_light_gray_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:light_gray_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_gray_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_light_gray_carpet.json index eaee1d6a727..abbea2b4a53 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_light_gray_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_light_gray_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:light_gray_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_gray_harness.json b/src/generated/resources/data/minecraft/recipe/dye_light_gray_harness.json index 3e612865dfa..5810a8f8af0 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_light_gray_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_light_gray_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:light_gray_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_gray_wool.json b/src/generated/resources/data/minecraft/recipe/dye_light_gray_wool.json index 701df4f96ea..00a76de1b6f 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_light_gray_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_light_gray_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:light_gray_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_lime_bed.json b/src/generated/resources/data/minecraft/recipe/dye_lime_bed.json index 0a39a227e32..0ce2dff7b8b 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_lime_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_lime_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:lime_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_lime_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_lime_carpet.json index 69beb904d0b..66fd2bbac11 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_lime_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_lime_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:lime_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_lime_harness.json b/src/generated/resources/data/minecraft/recipe/dye_lime_harness.json index fa99a344e34..e625d021e13 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_lime_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_lime_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:lime_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_lime_wool.json b/src/generated/resources/data/minecraft/recipe/dye_lime_wool.json index 9cfaecd17a1..dae1db4f47f 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_lime_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_lime_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:lime_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_magenta_bed.json b/src/generated/resources/data/minecraft/recipe/dye_magenta_bed.json index e7be3400fb1..a3c371ee585 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_magenta_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_magenta_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:magenta_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_magenta_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_magenta_carpet.json index e3974fb105b..0fc218a3e0d 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_magenta_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_magenta_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:magenta_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_magenta_harness.json b/src/generated/resources/data/minecraft/recipe/dye_magenta_harness.json index d3fa3590f14..3776162d5d7 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_magenta_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_magenta_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:magenta_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_magenta_wool.json b/src/generated/resources/data/minecraft/recipe/dye_magenta_wool.json index b5cb50c8c04..39d518f0598 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_magenta_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_magenta_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:magenta_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_orange_bed.json b/src/generated/resources/data/minecraft/recipe/dye_orange_bed.json index 831a0e288eb..0b632905562 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_orange_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_orange_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:orange_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_orange_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_orange_carpet.json index e39ceda176a..8a2a151c28f 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_orange_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_orange_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:orange_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_orange_harness.json b/src/generated/resources/data/minecraft/recipe/dye_orange_harness.json index c004a5c28ed..7e7bd04fff8 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_orange_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_orange_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:orange_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_orange_wool.json b/src/generated/resources/data/minecraft/recipe/dye_orange_wool.json index 0b89a2fe23b..0526e390b35 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_orange_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_orange_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:orange_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_pink_bed.json b/src/generated/resources/data/minecraft/recipe/dye_pink_bed.json index 9139061548d..9a92f9390a8 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_pink_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_pink_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:pink_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_pink_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_pink_carpet.json index 7973e480979..b74bcc744fe 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_pink_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_pink_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:pink_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_pink_harness.json b/src/generated/resources/data/minecraft/recipe/dye_pink_harness.json index 1f947d9ab5f..032c4b96a6a 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_pink_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_pink_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:pink_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_pink_wool.json b/src/generated/resources/data/minecraft/recipe/dye_pink_wool.json index bb15342a01f..d9a81644eb3 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_pink_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_pink_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:pink_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_purple_bed.json b/src/generated/resources/data/minecraft/recipe/dye_purple_bed.json index 161ecdccbe9..368ebb2d73c 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_purple_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_purple_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:purple_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_purple_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_purple_carpet.json index 6640c945160..6ba0782d196 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_purple_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_purple_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:purple_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_purple_harness.json b/src/generated/resources/data/minecraft/recipe/dye_purple_harness.json index ed84278be71..270b1cec038 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_purple_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_purple_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:purple_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_purple_wool.json b/src/generated/resources/data/minecraft/recipe/dye_purple_wool.json index 8d26252d275..498fe855b4c 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_purple_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_purple_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:purple_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_red_bed.json b/src/generated/resources/data/minecraft/recipe/dye_red_bed.json index b098d1be7a3..196f67ea77a 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_red_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_red_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:red_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_red_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_red_carpet.json index ad9bcb90483..839267a4e60 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_red_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_red_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:red_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_red_harness.json b/src/generated/resources/data/minecraft/recipe/dye_red_harness.json index a3656d53e49..6f410f2267a 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_red_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_red_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:red_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_red_wool.json b/src/generated/resources/data/minecraft/recipe/dye_red_wool.json index cfd0569b72b..66f2b1097ea 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_red_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_red_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:red_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_white_bed.json b/src/generated/resources/data/minecraft/recipe/dye_white_bed.json index d65f31e7f88..e3a51d1b622 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_white_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_white_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:white_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_white_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_white_carpet.json index c508f5781d4..c374409f7df 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_white_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_white_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:white_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_white_harness.json b/src/generated/resources/data/minecraft/recipe/dye_white_harness.json index 3bfface9997..ac4c0a35ecc 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_white_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_white_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:white_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_white_wool.json b/src/generated/resources/data/minecraft/recipe/dye_white_wool.json index f88f447f889..0e47b6a71fd 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_white_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_white_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:white_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_yellow_bed.json b/src/generated/resources/data/minecraft/recipe/dye_yellow_bed.json index 0419c2cde66..2e0c76087e5 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_yellow_bed.json +++ b/src/generated/resources/data/minecraft/recipe/dye_yellow_bed.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:yellow_bed" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_yellow_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_yellow_carpet.json index e2421ce795e..06754d8ffed 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_yellow_carpet.json +++ b/src/generated/resources/data/minecraft/recipe/dye_yellow_carpet.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:yellow_carpet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_yellow_harness.json b/src/generated/resources/data/minecraft/recipe/dye_yellow_harness.json index b20fd609b9e..09ef058d178 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_yellow_harness.json +++ b/src/generated/resources/data/minecraft/recipe/dye_yellow_harness.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:yellow_harness" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_yellow_wool.json b/src/generated/resources/data/minecraft/recipe/dye_yellow_wool.json index 7cb4a1f1ca7..1d9d634be63 100644 --- a/src/generated/resources/data/minecraft/recipe/dye_yellow_wool.json +++ b/src/generated/resources/data/minecraft/recipe/dye_yellow_wool.json @@ -23,7 +23,6 @@ ] ], "result": { - "count": 1, "id": "minecraft:yellow_wool" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/enchanting_table.json b/src/generated/resources/data/minecraft/recipe/enchanting_table.json index a18e62aa601..bfe6ac27709 100644 --- a/src/generated/resources/data/minecraft/recipe/enchanting_table.json +++ b/src/generated/resources/data/minecraft/recipe/enchanting_table.json @@ -12,7 +12,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:enchanting_table" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/fishing_rod.json b/src/generated/resources/data/minecraft/recipe/fishing_rod.json index 8308c1ef46e..c01dafa760c 100644 --- a/src/generated/resources/data/minecraft/recipe/fishing_rod.json +++ b/src/generated/resources/data/minecraft/recipe/fishing_rod.json @@ -11,7 +11,6 @@ "# X" ], "result": { - "count": 1, "id": "minecraft:fishing_rod" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/flint_and_steel.json b/src/generated/resources/data/minecraft/recipe/flint_and_steel.json index 291b18605ef..00ba34c7919 100644 --- a/src/generated/resources/data/minecraft/recipe/flint_and_steel.json +++ b/src/generated/resources/data/minecraft/recipe/flint_and_steel.json @@ -6,7 +6,6 @@ "minecraft:flint" ], "result": { - "count": 1, "id": "minecraft:flint_and_steel" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/glistering_melon_slice.json b/src/generated/resources/data/minecraft/recipe/glistering_melon_slice.json index d9f7cb56c0c..94b2d9ca215 100644 --- a/src/generated/resources/data/minecraft/recipe/glistering_melon_slice.json +++ b/src/generated/resources/data/minecraft/recipe/glistering_melon_slice.json @@ -11,7 +11,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:glistering_melon_slice" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/gold_ingot_from_nuggets.json b/src/generated/resources/data/minecraft/recipe/gold_ingot_from_nuggets.json index e1e752fdac5..e2376f5af57 100644 --- a/src/generated/resources/data/minecraft/recipe/gold_ingot_from_nuggets.json +++ b/src/generated/resources/data/minecraft/recipe/gold_ingot_from_nuggets.json @@ -11,7 +11,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:gold_ingot" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_apple.json b/src/generated/resources/data/minecraft/recipe/golden_apple.json index 0a029564aac..bc73ddf1405 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_apple.json +++ b/src/generated/resources/data/minecraft/recipe/golden_apple.json @@ -11,7 +11,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:golden_apple" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_axe.json b/src/generated/resources/data/minecraft/recipe/golden_axe.json index aad3355e766..0818c3cb61a 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_axe.json +++ b/src/generated/resources/data/minecraft/recipe/golden_axe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:golden_axe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_boots.json b/src/generated/resources/data/minecraft/recipe/golden_boots.json index baede9b2b03..5abe0af9200 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_boots.json +++ b/src/generated/resources/data/minecraft/recipe/golden_boots.json @@ -9,7 +9,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:golden_boots" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_carrot.json b/src/generated/resources/data/minecraft/recipe/golden_carrot.json index de1984305cd..c5e476626e4 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_carrot.json +++ b/src/generated/resources/data/minecraft/recipe/golden_carrot.json @@ -11,7 +11,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:golden_carrot" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_chestplate.json b/src/generated/resources/data/minecraft/recipe/golden_chestplate.json index 44610c5b756..7573b40a024 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_chestplate.json +++ b/src/generated/resources/data/minecraft/recipe/golden_chestplate.json @@ -10,7 +10,6 @@ "XXX" ], "result": { - "count": 1, "id": "minecraft:golden_chestplate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_helmet.json b/src/generated/resources/data/minecraft/recipe/golden_helmet.json index 77e0c12be82..a13d779537a 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_helmet.json +++ b/src/generated/resources/data/minecraft/recipe/golden_helmet.json @@ -9,7 +9,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:golden_helmet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_hoe.json b/src/generated/resources/data/minecraft/recipe/golden_hoe.json index 6a31db7ec1c..6b390024a96 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/golden_hoe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:golden_hoe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_leggings.json b/src/generated/resources/data/minecraft/recipe/golden_leggings.json index 6ffc3edd1c7..76ff024ef53 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_leggings.json +++ b/src/generated/resources/data/minecraft/recipe/golden_leggings.json @@ -10,7 +10,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:golden_leggings" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_pickaxe.json b/src/generated/resources/data/minecraft/recipe/golden_pickaxe.json index 7e88522f3e1..ef13a0f17a5 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/golden_pickaxe.json @@ -11,7 +11,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:golden_pickaxe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_shovel.json b/src/generated/resources/data/minecraft/recipe/golden_shovel.json index ed7b535236d..e4f71ef565d 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/golden_shovel.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:golden_shovel" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_spear.json b/src/generated/resources/data/minecraft/recipe/golden_spear.json index 477bbb3f6b5..bb65788d460 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_spear.json +++ b/src/generated/resources/data/minecraft/recipe/golden_spear.json @@ -11,7 +11,6 @@ "# " ], "result": { - "count": 1, "id": "minecraft:golden_spear" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/golden_sword.json b/src/generated/resources/data/minecraft/recipe/golden_sword.json index a400bb8117b..510d5fd8bda 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_sword.json +++ b/src/generated/resources/data/minecraft/recipe/golden_sword.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:golden_sword" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/gray_banner.json b/src/generated/resources/data/minecraft/recipe/gray_banner.json index 75e5ac3ebe8..5b383dfe154 100644 --- a/src/generated/resources/data/minecraft/recipe/gray_banner.json +++ b/src/generated/resources/data/minecraft/recipe/gray_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:gray_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/gray_candle.json b/src/generated/resources/data/minecraft/recipe/gray_candle.json index ef9a61dea24..212e0e1972f 100644 --- a/src/generated/resources/data/minecraft/recipe/gray_candle.json +++ b/src/generated/resources/data/minecraft/recipe/gray_candle.json @@ -7,7 +7,6 @@ "#c:dyes/gray" ], "result": { - "count": 1, "id": "minecraft:gray_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/green_banner.json b/src/generated/resources/data/minecraft/recipe/green_banner.json index e18d67a1f36..b39debf52e5 100644 --- a/src/generated/resources/data/minecraft/recipe/green_banner.json +++ b/src/generated/resources/data/minecraft/recipe/green_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:green_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/green_candle.json b/src/generated/resources/data/minecraft/recipe/green_candle.json index a95ce3d9d77..6bb9e072573 100644 --- a/src/generated/resources/data/minecraft/recipe/green_candle.json +++ b/src/generated/resources/data/minecraft/recipe/green_candle.json @@ -7,7 +7,6 @@ "#c:dyes/green" ], "result": { - "count": 1, "id": "minecraft:green_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/grindstone.json b/src/generated/resources/data/minecraft/recipe/grindstone.json index 5edf22f7502..7bfe1abe164 100644 --- a/src/generated/resources/data/minecraft/recipe/grindstone.json +++ b/src/generated/resources/data/minecraft/recipe/grindstone.json @@ -11,7 +11,6 @@ "# #" ], "result": { - "count": 1, "id": "minecraft:grindstone" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/heavy_weighted_pressure_plate.json b/src/generated/resources/data/minecraft/recipe/heavy_weighted_pressure_plate.json index e4c401e38e9..0400715a6b1 100644 --- a/src/generated/resources/data/minecraft/recipe/heavy_weighted_pressure_plate.json +++ b/src/generated/resources/data/minecraft/recipe/heavy_weighted_pressure_plate.json @@ -8,7 +8,6 @@ "##" ], "result": { - "count": 1, "id": "minecraft:heavy_weighted_pressure_plate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/hopper.json b/src/generated/resources/data/minecraft/recipe/hopper.json index 37560a9e85d..0775c3d0383 100644 --- a/src/generated/resources/data/minecraft/recipe/hopper.json +++ b/src/generated/resources/data/minecraft/recipe/hopper.json @@ -15,7 +15,6 @@ " I " ], "result": { - "count": 1, "id": "minecraft:hopper" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_axe.json b/src/generated/resources/data/minecraft/recipe/iron_axe.json index 535479a2bac..bb952031818 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_axe.json +++ b/src/generated/resources/data/minecraft/recipe/iron_axe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:iron_axe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_boots.json b/src/generated/resources/data/minecraft/recipe/iron_boots.json index 459f7533849..82ec93b74de 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_boots.json +++ b/src/generated/resources/data/minecraft/recipe/iron_boots.json @@ -9,7 +9,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:iron_boots" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_chain.json b/src/generated/resources/data/minecraft/recipe/iron_chain.json index af66cc2bd51..8ac993289af 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_chain.json +++ b/src/generated/resources/data/minecraft/recipe/iron_chain.json @@ -11,7 +11,6 @@ "N" ], "result": { - "count": 1, "id": "minecraft:iron_chain" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_chestplate.json b/src/generated/resources/data/minecraft/recipe/iron_chestplate.json index 42ac070a95d..c04281055a3 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_chestplate.json +++ b/src/generated/resources/data/minecraft/recipe/iron_chestplate.json @@ -10,7 +10,6 @@ "XXX" ], "result": { - "count": 1, "id": "minecraft:iron_chestplate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_helmet.json b/src/generated/resources/data/minecraft/recipe/iron_helmet.json index 67b4fa72290..227d97983b8 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_helmet.json +++ b/src/generated/resources/data/minecraft/recipe/iron_helmet.json @@ -9,7 +9,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:iron_helmet" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_hoe.json b/src/generated/resources/data/minecraft/recipe/iron_hoe.json index 65fb6202de8..be5921217f4 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/iron_hoe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:iron_hoe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_ingot_from_nuggets.json b/src/generated/resources/data/minecraft/recipe/iron_ingot_from_nuggets.json index 3880618510c..e8210eae29f 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_ingot_from_nuggets.json +++ b/src/generated/resources/data/minecraft/recipe/iron_ingot_from_nuggets.json @@ -11,7 +11,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:iron_ingot" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_leggings.json b/src/generated/resources/data/minecraft/recipe/iron_leggings.json index ca4c45bc62f..232ad3caded 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_leggings.json +++ b/src/generated/resources/data/minecraft/recipe/iron_leggings.json @@ -10,7 +10,6 @@ "X X" ], "result": { - "count": 1, "id": "minecraft:iron_leggings" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_pickaxe.json b/src/generated/resources/data/minecraft/recipe/iron_pickaxe.json index 169d8f70946..313311755fc 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/iron_pickaxe.json @@ -11,7 +11,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:iron_pickaxe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_shovel.json b/src/generated/resources/data/minecraft/recipe/iron_shovel.json index b4367667787..3074e560c34 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/iron_shovel.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:iron_shovel" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_spear.json b/src/generated/resources/data/minecraft/recipe/iron_spear.json index eca0174318b..4d4d17ea8ff 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_spear.json +++ b/src/generated/resources/data/minecraft/recipe/iron_spear.json @@ -11,7 +11,6 @@ "# " ], "result": { - "count": 1, "id": "minecraft:iron_spear" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_sword.json b/src/generated/resources/data/minecraft/recipe/iron_sword.json index 8c909bfa564..a676cd048cd 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_sword.json +++ b/src/generated/resources/data/minecraft/recipe/iron_sword.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:iron_sword" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/iron_trapdoor.json b/src/generated/resources/data/minecraft/recipe/iron_trapdoor.json index a64774b455a..ef32cfaa391 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_trapdoor.json +++ b/src/generated/resources/data/minecraft/recipe/iron_trapdoor.json @@ -9,7 +9,6 @@ "##" ], "result": { - "count": 1, "id": "minecraft:iron_trapdoor" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/item_frame.json b/src/generated/resources/data/minecraft/recipe/item_frame.json index 9daf39f512b..3cbb9b2183e 100644 --- a/src/generated/resources/data/minecraft/recipe/item_frame.json +++ b/src/generated/resources/data/minecraft/recipe/item_frame.json @@ -11,7 +11,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:item_frame" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/jukebox.json b/src/generated/resources/data/minecraft/recipe/jukebox.json index c7c109d95fd..389ac126c80 100644 --- a/src/generated/resources/data/minecraft/recipe/jukebox.json +++ b/src/generated/resources/data/minecraft/recipe/jukebox.json @@ -11,7 +11,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:jukebox" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/jungle_chest_boat.json b/src/generated/resources/data/minecraft/recipe/jungle_chest_boat.json index 4ce71a21b81..ea3f8ca2f77 100644 --- a/src/generated/resources/data/minecraft/recipe/jungle_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/jungle_chest_boat.json @@ -11,7 +11,6 @@ "minecraft:jungle_boat" ], "result": { - "count": 1, "id": "minecraft:jungle_chest_boat" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/jungle_fence_gate.json b/src/generated/resources/data/minecraft/recipe/jungle_fence_gate.json index 3f3ee533ed6..b94a81ea033 100644 --- a/src/generated/resources/data/minecraft/recipe/jungle_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/jungle_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:jungle_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lantern.json b/src/generated/resources/data/minecraft/recipe/lantern.json index 547cee52468..cf0017a0182 100644 --- a/src/generated/resources/data/minecraft/recipe/lantern.json +++ b/src/generated/resources/data/minecraft/recipe/lantern.json @@ -11,7 +11,6 @@ "XXX" ], "result": { - "count": 1, "id": "minecraft:lantern" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lever.json b/src/generated/resources/data/minecraft/recipe/lever.json index 25196040a9a..69f1f2f36d5 100644 --- a/src/generated/resources/data/minecraft/recipe/lever.json +++ b/src/generated/resources/data/minecraft/recipe/lever.json @@ -10,7 +10,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:lever" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_banner.json b/src/generated/resources/data/minecraft/recipe/light_blue_banner.json index b0fa0803662..94fa7b212c0 100644 --- a/src/generated/resources/data/minecraft/recipe/light_blue_banner.json +++ b/src/generated/resources/data/minecraft/recipe/light_blue_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:light_blue_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_candle.json b/src/generated/resources/data/minecraft/recipe/light_blue_candle.json index 43cbfe0211f..2b14ecbbad5 100644 --- a/src/generated/resources/data/minecraft/recipe/light_blue_candle.json +++ b/src/generated/resources/data/minecraft/recipe/light_blue_candle.json @@ -7,7 +7,6 @@ "#c:dyes/light_blue" ], "result": { - "count": 1, "id": "minecraft:light_blue_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_banner.json b/src/generated/resources/data/minecraft/recipe/light_gray_banner.json index 7a16563cc07..e1a2400e0b8 100644 --- a/src/generated/resources/data/minecraft/recipe/light_gray_banner.json +++ b/src/generated/resources/data/minecraft/recipe/light_gray_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:light_gray_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_candle.json b/src/generated/resources/data/minecraft/recipe/light_gray_candle.json index 5fbd4a55c67..fc4167f6c10 100644 --- a/src/generated/resources/data/minecraft/recipe/light_gray_candle.json +++ b/src/generated/resources/data/minecraft/recipe/light_gray_candle.json @@ -7,7 +7,6 @@ "#c:dyes/light_gray" ], "result": { - "count": 1, "id": "minecraft:light_gray_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_weighted_pressure_plate.json b/src/generated/resources/data/minecraft/recipe/light_weighted_pressure_plate.json index ef08a13e3fd..ebff2fb7aa9 100644 --- a/src/generated/resources/data/minecraft/recipe/light_weighted_pressure_plate.json +++ b/src/generated/resources/data/minecraft/recipe/light_weighted_pressure_plate.json @@ -8,7 +8,6 @@ "##" ], "result": { - "count": 1, "id": "minecraft:light_weighted_pressure_plate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lightning_rod.json b/src/generated/resources/data/minecraft/recipe/lightning_rod.json index 614ed2737ef..92b7699ca02 100644 --- a/src/generated/resources/data/minecraft/recipe/lightning_rod.json +++ b/src/generated/resources/data/minecraft/recipe/lightning_rod.json @@ -10,7 +10,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:lightning_rod" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lime_banner.json b/src/generated/resources/data/minecraft/recipe/lime_banner.json index 49b26aba099..828ccfcb501 100644 --- a/src/generated/resources/data/minecraft/recipe/lime_banner.json +++ b/src/generated/resources/data/minecraft/recipe/lime_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:lime_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lime_candle.json b/src/generated/resources/data/minecraft/recipe/lime_candle.json index f38b4cd3c5d..a7324505d78 100644 --- a/src/generated/resources/data/minecraft/recipe/lime_candle.json +++ b/src/generated/resources/data/minecraft/recipe/lime_candle.json @@ -7,7 +7,6 @@ "#c:dyes/lime" ], "result": { - "count": 1, "id": "minecraft:lime_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lodestone.json b/src/generated/resources/data/minecraft/recipe/lodestone.json index 56532f2eede..8b353b45046 100644 --- a/src/generated/resources/data/minecraft/recipe/lodestone.json +++ b/src/generated/resources/data/minecraft/recipe/lodestone.json @@ -11,7 +11,6 @@ "SSS" ], "result": { - "count": 1, "id": "minecraft:lodestone" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/loom.json b/src/generated/resources/data/minecraft/recipe/loom.json index 9b25eeb36fa..21b2fa928a8 100644 --- a/src/generated/resources/data/minecraft/recipe/loom.json +++ b/src/generated/resources/data/minecraft/recipe/loom.json @@ -10,7 +10,6 @@ "##" ], "result": { - "count": 1, "id": "minecraft:loom" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_banner.json b/src/generated/resources/data/minecraft/recipe/magenta_banner.json index f09624c2ac9..b0fee202d57 100644 --- a/src/generated/resources/data/minecraft/recipe/magenta_banner.json +++ b/src/generated/resources/data/minecraft/recipe/magenta_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:magenta_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_candle.json b/src/generated/resources/data/minecraft/recipe/magenta_candle.json index a424f2970c8..f72fc1dd147 100644 --- a/src/generated/resources/data/minecraft/recipe/magenta_candle.json +++ b/src/generated/resources/data/minecraft/recipe/magenta_candle.json @@ -7,7 +7,6 @@ "#c:dyes/magenta" ], "result": { - "count": 1, "id": "minecraft:magenta_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/mangrove_chest_boat.json b/src/generated/resources/data/minecraft/recipe/mangrove_chest_boat.json index 66a4dacf451..33253974400 100644 --- a/src/generated/resources/data/minecraft/recipe/mangrove_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/mangrove_chest_boat.json @@ -11,7 +11,6 @@ "minecraft:mangrove_boat" ], "result": { - "count": 1, "id": "minecraft:mangrove_chest_boat" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/mangrove_fence_gate.json b/src/generated/resources/data/minecraft/recipe/mangrove_fence_gate.json index 8510a15d3fe..a2814dee245 100644 --- a/src/generated/resources/data/minecraft/recipe/mangrove_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/mangrove_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:mangrove_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/minecart.json b/src/generated/resources/data/minecraft/recipe/minecart.json index 3a407b046e1..1ba76533874 100644 --- a/src/generated/resources/data/minecraft/recipe/minecart.json +++ b/src/generated/resources/data/minecraft/recipe/minecart.json @@ -9,7 +9,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:minecart" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_moss_block.json b/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_moss_block.json index 0600f034315..b2d83bde406 100644 --- a/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_moss_block.json +++ b/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_moss_block.json @@ -7,7 +7,6 @@ "minecraft:moss_block" ], "result": { - "count": 1, "id": "minecraft:mossy_cobblestone" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_vine.json b/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_vine.json index fb39076601e..4ee78421da9 100644 --- a/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_vine.json +++ b/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_vine.json @@ -7,7 +7,6 @@ "minecraft:vine" ], "result": { - "count": 1, "id": "minecraft:mossy_cobblestone" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/netherite_ingot.json b/src/generated/resources/data/minecraft/recipe/netherite_ingot.json index 839b4ad4f58..b99430fe502 100644 --- a/src/generated/resources/data/minecraft/recipe/netherite_ingot.json +++ b/src/generated/resources/data/minecraft/recipe/netherite_ingot.json @@ -13,7 +13,6 @@ "#c:ingots/gold" ], "result": { - "count": 1, "id": "minecraft:netherite_ingot" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/oak_chest_boat.json b/src/generated/resources/data/minecraft/recipe/oak_chest_boat.json index 76a88f4aa3d..6e91f8b2907 100644 --- a/src/generated/resources/data/minecraft/recipe/oak_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/oak_chest_boat.json @@ -11,7 +11,6 @@ "minecraft:oak_boat" ], "result": { - "count": 1, "id": "minecraft:oak_chest_boat" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/oak_fence_gate.json b/src/generated/resources/data/minecraft/recipe/oak_fence_gate.json index 36941138d7b..8d1ab67ec04 100644 --- a/src/generated/resources/data/minecraft/recipe/oak_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/oak_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:oak_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/observer.json b/src/generated/resources/data/minecraft/recipe/observer.json index f29722af98d..2287dea5fdc 100644 --- a/src/generated/resources/data/minecraft/recipe/observer.json +++ b/src/generated/resources/data/minecraft/recipe/observer.json @@ -12,7 +12,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:observer" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/orange_banner.json b/src/generated/resources/data/minecraft/recipe/orange_banner.json index 8bbc0dbf426..22de227ea50 100644 --- a/src/generated/resources/data/minecraft/recipe/orange_banner.json +++ b/src/generated/resources/data/minecraft/recipe/orange_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:orange_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/orange_candle.json b/src/generated/resources/data/minecraft/recipe/orange_candle.json index 9708bbc215d..acc8bc7ea4e 100644 --- a/src/generated/resources/data/minecraft/recipe/orange_candle.json +++ b/src/generated/resources/data/minecraft/recipe/orange_candle.json @@ -7,7 +7,6 @@ "#c:dyes/orange" ], "result": { - "count": 1, "id": "minecraft:orange_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/painting.json b/src/generated/resources/data/minecraft/recipe/painting.json index 64b32014dc1..b8497c2de4e 100644 --- a/src/generated/resources/data/minecraft/recipe/painting.json +++ b/src/generated/resources/data/minecraft/recipe/painting.json @@ -11,7 +11,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:painting" } } \ 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 index 8339b115b16..107f028562e 100644 --- a/src/generated/resources/data/minecraft/recipe/pale_oak_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/pale_oak_chest_boat.json @@ -11,7 +11,6 @@ "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_gate.json b/src/generated/resources/data/minecraft/recipe/pale_oak_fence_gate.json index b09f87fa2b7..ae5182f114d 100644 --- a/src/generated/resources/data/minecraft/recipe/pale_oak_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/pale_oak_fence_gate.json @@ -11,7 +11,6 @@ "#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/pink_banner.json b/src/generated/resources/data/minecraft/recipe/pink_banner.json index 4fd7901e5de..b0640cb8efd 100644 --- a/src/generated/resources/data/minecraft/recipe/pink_banner.json +++ b/src/generated/resources/data/minecraft/recipe/pink_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:pink_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pink_candle.json b/src/generated/resources/data/minecraft/recipe/pink_candle.json index d62dd117247..4afecd75b71 100644 --- a/src/generated/resources/data/minecraft/recipe/pink_candle.json +++ b/src/generated/resources/data/minecraft/recipe/pink_candle.json @@ -7,7 +7,6 @@ "#c:dyes/pink" ], "result": { - "count": 1, "id": "minecraft:pink_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/piston.json b/src/generated/resources/data/minecraft/recipe/piston.json index 84593e660cb..432146eef5c 100644 --- a/src/generated/resources/data/minecraft/recipe/piston.json +++ b/src/generated/resources/data/minecraft/recipe/piston.json @@ -13,7 +13,6 @@ "#R#" ], "result": { - "count": 1, "id": "minecraft:piston" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/purple_banner.json b/src/generated/resources/data/minecraft/recipe/purple_banner.json index ed4b36c1367..8f1b072de3a 100644 --- a/src/generated/resources/data/minecraft/recipe/purple_banner.json +++ b/src/generated/resources/data/minecraft/recipe/purple_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:purple_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/purple_candle.json b/src/generated/resources/data/minecraft/recipe/purple_candle.json index 7f5ddcf289b..b93072c3770 100644 --- a/src/generated/resources/data/minecraft/recipe/purple_candle.json +++ b/src/generated/resources/data/minecraft/recipe/purple_candle.json @@ -7,7 +7,6 @@ "#c:dyes/purple" ], "result": { - "count": 1, "id": "minecraft:purple_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/red_banner.json b/src/generated/resources/data/minecraft/recipe/red_banner.json index 9b0643110e7..16e01ce497b 100644 --- a/src/generated/resources/data/minecraft/recipe/red_banner.json +++ b/src/generated/resources/data/minecraft/recipe/red_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:red_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/red_candle.json b/src/generated/resources/data/minecraft/recipe/red_candle.json index f658efa5d32..0517423b4b5 100644 --- a/src/generated/resources/data/minecraft/recipe/red_candle.json +++ b/src/generated/resources/data/minecraft/recipe/red_candle.json @@ -7,7 +7,6 @@ "#c:dyes/red" ], "result": { - "count": 1, "id": "minecraft:red_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/redstone_torch.json b/src/generated/resources/data/minecraft/recipe/redstone_torch.json index ea402cb6e47..ed035e7db20 100644 --- a/src/generated/resources/data/minecraft/recipe/redstone_torch.json +++ b/src/generated/resources/data/minecraft/recipe/redstone_torch.json @@ -10,7 +10,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:redstone_torch" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/saddle.json b/src/generated/resources/data/minecraft/recipe/saddle.json index 38171a6054f..7aa4f316717 100644 --- a/src/generated/resources/data/minecraft/recipe/saddle.json +++ b/src/generated/resources/data/minecraft/recipe/saddle.json @@ -10,7 +10,6 @@ "X#X" ], "result": { - "count": 1, "id": "minecraft:saddle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/shears.json b/src/generated/resources/data/minecraft/recipe/shears.json index ca02dfb8aaf..08fc67bbe1d 100644 --- a/src/generated/resources/data/minecraft/recipe/shears.json +++ b/src/generated/resources/data/minecraft/recipe/shears.json @@ -9,7 +9,6 @@ "# " ], "result": { - "count": 1, "id": "minecraft:shears" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/shield.json b/src/generated/resources/data/minecraft/recipe/shield.json index e0cc4be9a4d..6dc818bc94e 100644 --- a/src/generated/resources/data/minecraft/recipe/shield.json +++ b/src/generated/resources/data/minecraft/recipe/shield.json @@ -11,7 +11,6 @@ " W " ], "result": { - "count": 1, "id": "minecraft:shield" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/shulker_box.json b/src/generated/resources/data/minecraft/recipe/shulker_box.json index 6b74b70a579..21ba12c7100 100644 --- a/src/generated/resources/data/minecraft/recipe/shulker_box.json +++ b/src/generated/resources/data/minecraft/recipe/shulker_box.json @@ -15,7 +15,6 @@ "-" ], "result": { - "count": 1, "id": "minecraft:shulker_box" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/smithing_table.json b/src/generated/resources/data/minecraft/recipe/smithing_table.json index cdf474dfc52..46420666344 100644 --- a/src/generated/resources/data/minecraft/recipe/smithing_table.json +++ b/src/generated/resources/data/minecraft/recipe/smithing_table.json @@ -11,7 +11,6 @@ "##" ], "result": { - "count": 1, "id": "minecraft:smithing_table" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/soul_campfire.json b/src/generated/resources/data/minecraft/recipe/soul_campfire.json index 8daec84a100..a5630fbfe5a 100644 --- a/src/generated/resources/data/minecraft/recipe/soul_campfire.json +++ b/src/generated/resources/data/minecraft/recipe/soul_campfire.json @@ -12,7 +12,6 @@ "LLL" ], "result": { - "count": 1, "id": "minecraft:soul_campfire" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/soul_lantern.json b/src/generated/resources/data/minecraft/recipe/soul_lantern.json index 3d06fd51d16..ee40d893cef 100644 --- a/src/generated/resources/data/minecraft/recipe/soul_lantern.json +++ b/src/generated/resources/data/minecraft/recipe/soul_lantern.json @@ -11,7 +11,6 @@ "XXX" ], "result": { - "count": 1, "id": "minecraft:soul_lantern" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/spruce_chest_boat.json b/src/generated/resources/data/minecraft/recipe/spruce_chest_boat.json index b1c05471809..66f20401843 100644 --- a/src/generated/resources/data/minecraft/recipe/spruce_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/spruce_chest_boat.json @@ -11,7 +11,6 @@ "minecraft:spruce_boat" ], "result": { - "count": 1, "id": "minecraft:spruce_chest_boat" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/spruce_fence_gate.json b/src/generated/resources/data/minecraft/recipe/spruce_fence_gate.json index ea1f612c1f2..3a7d27c4ec2 100644 --- a/src/generated/resources/data/minecraft/recipe/spruce_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/spruce_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:spruce_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/spyglass.json b/src/generated/resources/data/minecraft/recipe/spyglass.json index d2caaad3623..b7e83ec9602 100644 --- a/src/generated/resources/data/minecraft/recipe/spyglass.json +++ b/src/generated/resources/data/minecraft/recipe/spyglass.json @@ -11,7 +11,6 @@ " X " ], "result": { - "count": 1, "id": "minecraft:spyglass" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/stone_axe.json b/src/generated/resources/data/minecraft/recipe/stone_axe.json index 8d557557d6a..e3113ba751a 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_axe.json +++ b/src/generated/resources/data/minecraft/recipe/stone_axe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:stone_axe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/stone_hoe.json b/src/generated/resources/data/minecraft/recipe/stone_hoe.json index 8ed74421deb..c8cf52f38d8 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/stone_hoe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:stone_hoe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/stone_pickaxe.json b/src/generated/resources/data/minecraft/recipe/stone_pickaxe.json index cd245c22c4b..0be8cd1618b 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/stone_pickaxe.json @@ -11,7 +11,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:stone_pickaxe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/stone_shovel.json b/src/generated/resources/data/minecraft/recipe/stone_shovel.json index bde9b0a8be3..98f9b03920c 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/stone_shovel.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:stone_shovel" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/stone_spear.json b/src/generated/resources/data/minecraft/recipe/stone_spear.json index c0f703f53d6..f2fa6012088 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_spear.json +++ b/src/generated/resources/data/minecraft/recipe/stone_spear.json @@ -11,7 +11,6 @@ "# " ], "result": { - "count": 1, "id": "minecraft:stone_spear" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/stone_sword.json b/src/generated/resources/data/minecraft/recipe/stone_sword.json index cdff3bf44e6..9e5d6978961 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_sword.json +++ b/src/generated/resources/data/minecraft/recipe/stone_sword.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:stone_sword" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/stonecutter.json b/src/generated/resources/data/minecraft/recipe/stonecutter.json index e2f95eecf43..1d1c6a2e349 100644 --- a/src/generated/resources/data/minecraft/recipe/stonecutter.json +++ b/src/generated/resources/data/minecraft/recipe/stonecutter.json @@ -10,7 +10,6 @@ "###" ], "result": { - "count": 1, "id": "minecraft:stonecutter" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/trapped_chest.json b/src/generated/resources/data/minecraft/recipe/trapped_chest.json index bd85e9bcad6..92486e31773 100644 --- a/src/generated/resources/data/minecraft/recipe/trapped_chest.json +++ b/src/generated/resources/data/minecraft/recipe/trapped_chest.json @@ -10,7 +10,6 @@ "minecraft:tripwire_hook" ], "result": { - "count": 1, "id": "minecraft:trapped_chest" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/warped_fence_gate.json b/src/generated/resources/data/minecraft/recipe/warped_fence_gate.json index bd500ac0898..aae3e2aeb40 100644 --- a/src/generated/resources/data/minecraft/recipe/warped_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/warped_fence_gate.json @@ -11,7 +11,6 @@ "#W#" ], "result": { - "count": 1, "id": "minecraft:warped_fence_gate" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/white_banner.json b/src/generated/resources/data/minecraft/recipe/white_banner.json index 0f87a1e878c..fcae720d405 100644 --- a/src/generated/resources/data/minecraft/recipe/white_banner.json +++ b/src/generated/resources/data/minecraft/recipe/white_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:white_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/white_candle.json b/src/generated/resources/data/minecraft/recipe/white_candle.json index 45b193d9996..a4946bbe842 100644 --- a/src/generated/resources/data/minecraft/recipe/white_candle.json +++ b/src/generated/resources/data/minecraft/recipe/white_candle.json @@ -7,7 +7,6 @@ "#c:dyes/white" ], "result": { - "count": 1, "id": "minecraft:white_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/wooden_axe.json b/src/generated/resources/data/minecraft/recipe/wooden_axe.json index 05fdaaad7e7..dc068310651 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_axe.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_axe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:wooden_axe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/wooden_hoe.json b/src/generated/resources/data/minecraft/recipe/wooden_hoe.json index 6fd2085dda4..bff2385c5a5 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_hoe.json @@ -11,7 +11,6 @@ " #" ], "result": { - "count": 1, "id": "minecraft:wooden_hoe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/wooden_pickaxe.json b/src/generated/resources/data/minecraft/recipe/wooden_pickaxe.json index ff84e265b6c..1981ea719a1 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_pickaxe.json @@ -11,7 +11,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:wooden_pickaxe" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/wooden_shovel.json b/src/generated/resources/data/minecraft/recipe/wooden_shovel.json index 3aac8226a55..43c48e78c10 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_shovel.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:wooden_shovel" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/wooden_spear.json b/src/generated/resources/data/minecraft/recipe/wooden_spear.json index 6c9f4220e03..cc7dbe09af7 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_spear.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_spear.json @@ -11,7 +11,6 @@ "# " ], "result": { - "count": 1, "id": "minecraft:wooden_spear" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/wooden_sword.json b/src/generated/resources/data/minecraft/recipe/wooden_sword.json index 35a7a42140e..ca80932c0ad 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_sword.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_sword.json @@ -11,7 +11,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:wooden_sword" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/yellow_banner.json b/src/generated/resources/data/minecraft/recipe/yellow_banner.json index 6228650872a..6b72a8f64a5 100644 --- a/src/generated/resources/data/minecraft/recipe/yellow_banner.json +++ b/src/generated/resources/data/minecraft/recipe/yellow_banner.json @@ -12,7 +12,6 @@ " | " ], "result": { - "count": 1, "id": "minecraft:yellow_banner" } } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/yellow_candle.json b/src/generated/resources/data/minecraft/recipe/yellow_candle.json index a3decc14aee..3085d2794c9 100644 --- a/src/generated/resources/data/minecraft/recipe/yellow_candle.json +++ b/src/generated/resources/data/minecraft/recipe/yellow_candle.json @@ -7,7 +7,6 @@ "#c:dyes/yellow" ], "result": { - "count": 1, "id": "minecraft:yellow_candle" } } \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/block/enderman_place_on_blacklist.json b/src/generated/resources/data/neoforge/tags/block/enderman_place_on_blacklist.json index fb75bfe2788..f72d209df78 100644 --- a/src/generated/resources/data/neoforge/tags/block/enderman_place_on_blacklist.json +++ b/src/generated/resources/data/neoforge/tags/block/enderman_place_on_blacklist.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:enderman_place_on_blacklist", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_environment.json b/src/generated/resources/data/neoforge/tags/damage_type/is_environment.json index e351503a5ca..77b995dd5e5 100644 --- a/src/generated/resources/data/neoforge/tags/damage_type/is_environment.json +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_environment.json @@ -17,10 +17,6 @@ "minecraft:cramming", "minecraft:fly_into_wall", "minecraft:sweet_berry_bush", - "minecraft:in_wall", - { - "id": "#forge:is_environment", - "required": false - } + "minecraft:in_wall" ] } \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json b/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json index 09c4487b295..fa7b122f296 100644 --- a/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json @@ -5,10 +5,6 @@ "minecraft:thorns", "minecraft:dragon_breath", "#neoforge:is_poison", - "#neoforge:is_wither", - { - "id": "#forge:is_magic", - "required": false - } + "#neoforge:is_wither" ] } \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_physical.json b/src/generated/resources/data/neoforge/tags/damage_type/is_physical.json index 3073b3807b7..ed7aa2f6e72 100644 --- a/src/generated/resources/data/neoforge/tags/damage_type/is_physical.json +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_physical.json @@ -19,10 +19,6 @@ "minecraft:mob_projectile", "minecraft:sonic_boom", "minecraft:in_wall", - "minecraft:generic", - { - "id": "#forge:is_physical", - "required": false - } + "minecraft:generic" ] } \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_poison.json b/src/generated/resources/data/neoforge/tags/damage_type/is_poison.json index 45ecffa2ef9..15884f836b1 100644 --- a/src/generated/resources/data/neoforge/tags/damage_type/is_poison.json +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_poison.json @@ -3,10 +3,6 @@ { "id": "neoforge:poison", "required": false - }, - { - "id": "#forge:is_poison", - "required": false } ] } \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_technical.json b/src/generated/resources/data/neoforge/tags/damage_type/is_technical.json index f14aee1e663..5d723926e6d 100644 --- a/src/generated/resources/data/neoforge/tags/damage_type/is_technical.json +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_technical.json @@ -2,10 +2,6 @@ "values": [ "minecraft:generic_kill", "minecraft:outside_border", - "minecraft:out_of_world", - { - "id": "#forge:is_technical", - "required": false - } + "minecraft:out_of_world" ] } \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_wither.json b/src/generated/resources/data/neoforge/tags/damage_type/is_wither.json index 178bad95f4b..33f6ff3bd05 100644 --- a/src/generated/resources/data/neoforge/tags/damage_type/is_wither.json +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_wither.json @@ -1,10 +1,6 @@ { "values": [ "minecraft:wither", - "minecraft:wither_skull", - { - "id": "#forge:is_wither", - "required": false - } + "minecraft:wither_skull" ] } \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/no_flinch.json b/src/generated/resources/data/neoforge/tags/damage_type/no_flinch.json index cf630670d5e..f72d209df78 100644 --- a/src/generated/resources/data/neoforge/tags/damage_type/no_flinch.json +++ b/src/generated/resources/data/neoforge/tags/damage_type/no_flinch.json @@ -1,8 +1,3 @@ { - "values": [ - { - "id": "#forge:no_flinch", - "required": false - } - ] + "values": [] } \ No newline at end of file diff --git a/src/generated/resources/pack.mcmeta b/src/generated/resources/pack.mcmeta index 6ecac684a88..b4ee75edcf2 100644 --- a/src/generated/resources/pack.mcmeta +++ b/src/generated/resources/pack.mcmeta @@ -4,11 +4,11 @@ "translate": "pack.neoforge.description" }, "max_format": [ - 94, + 97, 1 ], "min_format": [ - 94, + 97, 1 ] } diff --git a/src/main/java/net/neoforged/neoforge/attachment/AttachmentSync.java b/src/main/java/net/neoforged/neoforge/attachment/AttachmentSync.java index e37eccf2c2c..116d51973c0 100644 --- a/src/main/java/net/neoforged/neoforge/attachment/AttachmentSync.java +++ b/src/main/java/net/neoforged/neoforge/attachment/AttachmentSync.java @@ -20,7 +20,6 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; @@ -111,11 +110,18 @@ private static void syncUpdate(AttachmentHolder holder, AttachmentType ty } } - public static void syncBlockEntityUpdate(BlockEntity blockEntity, AttachmentType type) { - if (type.syncHandler == null || !(blockEntity.getLevel() instanceof ServerLevel serverLevel)) { + public static void syncBlockEntityUpdates(BlockEntity blockEntity, List players) { + var toSync = blockEntity.getAndClearAttachmentTypesToSync(); + if (toSync == null) { return; } - syncUpdate(blockEntity, type, serverLevel.getChunkSource().chunkMap.getPlayers(new ChunkPos(blockEntity.getBlockPos()), false)); + // For now, we send one packet per attachment type. In the future, consider bundling all the updates in a single packet. + for (var type : toSync) { + if (type.syncHandler == null) { + continue; + } + syncUpdate(blockEntity, type, players); + } } public static void syncChunkUpdate(LevelChunk chunk, AttachmentHolder.AsField holder, AttachmentType type) { diff --git a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java index d94861033c0..7bc6ca4ff43 100644 --- a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java +++ b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java @@ -28,6 +28,7 @@ import net.neoforged.neoforge.transfer.CombinedResourceHandler; import net.neoforged.neoforge.transfer.ResourceHandler; import net.neoforged.neoforge.transfer.fluid.BucketResourceHandler; +import net.neoforged.neoforge.transfer.item.BundleItemHandler; import net.neoforged.neoforge.transfer.item.ComposterWrapper; import net.neoforged.neoforge.transfer.item.ItemAccessItemHandler; import net.neoforged.neoforge.transfer.item.ItemResource; @@ -84,7 +85,17 @@ public static void registerVanillaProviders(RegisterCapabilitiesEvent event) { event.registerBlock(Capabilities.Item.BLOCK, (level, pos, state, blockEntity, side) -> { return ((ChestBlock) state.getBlock()).combine(state, level, pos, true).apply(CHEST_COMBINER_HANDLER); - }, Blocks.CHEST, Blocks.TRAPPED_CHEST); + }, + Blocks.CHEST, + Blocks.TRAPPED_CHEST, + Blocks.COPPER_CHEST, + Blocks.EXPOSED_COPPER_CHEST, + Blocks.WEATHERED_COPPER_CHEST, + Blocks.OXIDIZED_COPPER_CHEST, + Blocks.WAXED_COPPER_CHEST, + Blocks.WAXED_EXPOSED_COPPER_CHEST, + Blocks.WAXED_WEATHERED_COPPER_CHEST, + Blocks.WAXED_OXIDIZED_COPPER_CHEST); var sidedVanillaContainers = List.of( BlockEntityType.BLAST_FURNACE, @@ -104,7 +115,8 @@ public static void registerVanillaProviders(RegisterCapabilitiesEvent event) { BlockEntityType.HOPPER, BlockEntityType.JUKEBOX, BlockEntityType.CRAFTER, - BlockEntityType.DECORATED_POT); + BlockEntityType.DECORATED_POT, + BlockEntityType.SHELF); for (var type : nonSidedVanillaContainers) { event.registerBlockEntity(Capabilities.Item.BLOCK, type, (container, side) -> VanillaContainerWrapper.of(container)); } @@ -148,6 +160,24 @@ public static void registerVanillaProviders(RegisterCapabilitiesEvent event) { Items.RED_SHULKER_BOX, Items.WHITE_SHULKER_BOX, Items.YELLOW_SHULKER_BOX); + event.registerItem(Capabilities.Item.ITEM, (stack, access) -> new BundleItemHandler(access, DataComponents.BUNDLE_CONTENTS), + Items.BUNDLE, + Items.BLACK_BUNDLE, + Items.BLUE_BUNDLE, + Items.BROWN_BUNDLE, + Items.CYAN_BUNDLE, + Items.GRAY_BUNDLE, + Items.GREEN_BUNDLE, + Items.LIGHT_BLUE_BUNDLE, + Items.LIGHT_GRAY_BUNDLE, + Items.LIME_BUNDLE, + Items.MAGENTA_BUNDLE, + Items.ORANGE_BUNDLE, + Items.PINK_BUNDLE, + Items.PURPLE_BUNDLE, + Items.RED_BUNDLE, + Items.WHITE_BUNDLE, + Items.YELLOW_BUNDLE); } public static void registerFallbackVanillaProviders(RegisterCapabilitiesEvent event) { diff --git a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityListenerHolder.java b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityListenerHolder.java index 69cf58b33ab..e4fcfc79589 100644 --- a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityListenerHolder.java +++ b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityListenerHolder.java @@ -39,7 +39,7 @@ public class CapabilityListenerHolder { */ public void addListener(BlockPos pos, ICapabilityInvalidationListener listener) { pos = pos.immutable(); - var chunkHolder = byChunkThenBlock.computeIfAbsent(ChunkPos.asLong(pos), l -> new Long2ReferenceOpenHashMap<>()); + var chunkHolder = byChunkThenBlock.computeIfAbsent(ChunkPos.pack(pos), l -> new Long2ReferenceOpenHashMap<>()); var listenersSet = chunkHolder.computeIfAbsent(pos.asLong(), l -> new ObjectOpenHashSet<>()); var reference = new ListenerReference(queue, pos, listener); @@ -53,7 +53,7 @@ public void addListener(BlockPos pos, ICapabilityInvalidationListener listener) * Invalidates listeners at a specific block position. */ public void invalidatePos(BlockPos pos) { - var chunkHolder = byChunkThenBlock.get(ChunkPos.asLong(pos)); + var chunkHolder = byChunkThenBlock.get(ChunkPos.pack(pos)); if (chunkHolder != null) { var caches = chunkHolder.get(pos.asLong()); if (caches != null) @@ -65,7 +65,7 @@ public void invalidatePos(BlockPos pos) { * Invalidates listeners at a specific chunk position. */ public void invalidateChunk(ChunkPos chunkPos) { - var chunkHolder = byChunkThenBlock.get(chunkPos.toLong()); + var chunkHolder = byChunkThenBlock.get(chunkPos.pack()); if (chunkHolder != null) { for (var caches : chunkHolder.values()) invalidateList(caches); @@ -88,7 +88,7 @@ public void clean() { if (ref == null) return; - var chunkHolder = byChunkThenBlock.get(ChunkPos.asLong(ref.pos)); + var chunkHolder = byChunkThenBlock.get(ChunkPos.pack(ref.pos)); if (chunkHolder == null) continue; @@ -103,7 +103,7 @@ public void clean() { if (removed && set.isEmpty()) { chunkHolder.remove(ref.pos.asLong()); if (chunkHolder.isEmpty()) { - byChunkThenBlock.remove(ChunkPos.asLong(ref.pos)); + byChunkThenBlock.remove(ChunkPos.pack(ref.pos)); } } } diff --git a/src/main/java/net/neoforged/neoforge/common/BasicItemListing.java b/src/main/java/net/neoforged/neoforge/common/BasicItemListing.java deleted file mode 100644 index 36725e7f366..00000000000 --- a/src/main/java/net/neoforged/neoforge/common/BasicItemListing.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common; - -import java.util.Optional; -import net.minecraft.core.component.DataComponentExactPredicate; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.util.RandomSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.npc.villager.VillagerTrades.ItemListing; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.trading.ItemCost; -import net.minecraft.world.item.trading.MerchantOffer; -import org.jspecify.annotations.Nullable; - -/** - * A default, exposed implementation of ITrade. All of the other implementations of ITrade (in VillagerTrades) are not public. - * This class contains everything needed to make a MerchantOffer, the actual "trade" object shown in trading guis. - */ -public class BasicItemListing implements ItemListing { - protected final ItemStack price; - protected final ItemStack price2; - protected final ItemStack forSale; - protected final int maxTrades; - protected final int xp; - protected final float priceMult; - - public BasicItemListing(ItemStack price, ItemStack price2, ItemStack forSale, int maxTrades, int xp, float priceMult) { - this.price = price; - this.price2 = price2; - this.forSale = forSale; - this.maxTrades = maxTrades; - this.xp = xp; - this.priceMult = priceMult; - } - - public BasicItemListing(ItemStack price, ItemStack forSale, int maxTrades, int xp, float priceMult) { - this(price, ItemStack.EMPTY, forSale, maxTrades, xp, priceMult); - } - - public BasicItemListing(int emeralds, ItemStack forSale, int maxTrades, int xp, float mult) { - this(new ItemStack(Items.EMERALD, emeralds), forSale, maxTrades, xp, mult); - } - - public BasicItemListing(int emeralds, ItemStack forSale, int maxTrades, int xp) { - this(new ItemStack(Items.EMERALD, emeralds), forSale, maxTrades, xp, 1); - } - - @Nullable - @Override - public MerchantOffer getOffer(ServerLevel level, Entity p_219693_, RandomSource p_219694_) { - ItemCost cost = new ItemCost(price.getItemHolder(), price.getCount(), DataComponentExactPredicate.EMPTY, price); // TODO: Porting 1.20.5 do something proper for the components here - Optional optionalSecondCost = price2.isEmpty() ? Optional.empty() : Optional.of(new ItemCost(price2.getItemHolder(), price2.getCount(), DataComponentExactPredicate.EMPTY, price2)); - return new MerchantOffer(cost, optionalSecondCost, forSale, maxTrades, xp, priceMult); - } -} diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index e7e733b4c30..abada77f64e 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -803,15 +803,6 @@ public static Player getCraftingPlayer() { return craftingPlayer.get(); } - public static ItemStack getCraftingRemainder(ItemStack stack) { - stack = stack.getCraftingRemainder(); - if (!stack.isEmpty() && stack.isDamageableItem() && stack.getDamageValue() > stack.getMaxDamage()) { - EventHooks.onPlayerDestroyItem(craftingPlayer.get(), stack, null); - return ItemStack.EMPTY; - } - return stack; - } - public static boolean onPlayerAttackTarget(Player player, Entity target) { if (NeoForge.EVENT_BUS.post(new AttackEntityEvent(player, target)).isCanceled()) return false; diff --git a/src/main/java/net/neoforged/neoforge/common/FarmlandWaterManager.java b/src/main/java/net/neoforged/neoforge/common/FarmlandWaterManager.java index 3549ebddd27..86b5c3917c7 100644 --- a/src/main/java/net/neoforged/neoforge/common/FarmlandWaterManager.java +++ b/src/main/java/net/neoforged/neoforge/common/FarmlandWaterManager.java @@ -73,8 +73,8 @@ public static AABBTicket addAABBTicket(Level level, AABB aabb) { ChunkPos leftUp = new ChunkPos(((int) aabb.minX) >> 4, ((int) aabb.minZ) >> 4); ChunkPos rightDown = new ChunkPos(((int) aabb.maxX) >> 4, ((int) aabb.maxZ) >> 4); Set posSet = new HashSet<>(); - for (int x = leftUp.x; x <= rightDown.x; x++) { - for (int z = leftUp.z; z <= rightDown.z; z++) { + for (int x = leftUp.x(); x <= rightDown.x(); x++) { + for (int z = leftUp.z(); z <= rightDown.z(); z++) { posSet.add(new ChunkPos(x, z)); } } @@ -98,15 +98,15 @@ public static AABBTicket addAABBTicket(Level level, AABB aabb) { private static double getDistanceSq(ChunkPos pos, Vec3 vec3d) { //See ChunkPos#getDistanceSq - double d0 = (double) (pos.x * 16 + 8); - double d1 = (double) (pos.z * 16 + 8); + double d0 = (double) (pos.x() * 16 + 8); + double d1 = (double) (pos.z() * 16 + 8); double d2 = d0 - vec3d.x; double d3 = d1 - vec3d.z; return d2 * d2 + d3 * d3; } /** - * Tests if a block is in a region that is watered by blocks. This does not check vanilla water, see {@code net.minecraft.level.level.block.FarmBlock#isNearWater(LevelReader, BlockPos)} + * Tests if a block is in a region that is watered by blocks. This does not check vanilla water, see {@code net.minecraft.level.level.block.FarmlandBlock#isNearWater(LevelReader, BlockPos)} * * @return true if there is a ticket with an AABB that includes your block */ diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index 70f3ec36646..dbf27911ed1 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -25,6 +25,7 @@ import net.minecraft.core.RegistryCodecs; import net.minecraft.core.component.predicates.DataComponentPredicate; import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; @@ -48,6 +49,7 @@ import net.minecraft.world.entity.ai.attributes.Attribute.Sentiment; import net.minecraft.world.entity.ai.attributes.RangedAttribute; import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.item.crafting.display.SlotDisplay; @@ -128,6 +130,7 @@ import net.neoforged.neoforge.common.world.StructureModifier; import net.neoforged.neoforge.common.world.StructureModifiers; import net.neoforged.neoforge.data.loading.DatagenModLoader; +import net.neoforged.neoforge.event.DefaultDataComponentsBoundEvent; import net.neoforged.neoforge.event.server.ServerStoppingEvent; import net.neoforged.neoforge.fluids.BaseFlowingFluid; import net.neoforged.neoforge.fluids.CauldronFluidContent; @@ -591,13 +594,11 @@ public NeoForgeMod(IEventBus modEventBus, Dist dist, ModContainer container) { NeoForgeRegistriesSetup.setup(modEventBus); StartupNotificationManager.addModMessage("NeoForge version " + NeoForgeVersion.getVersion()); - NeoForge.EVENT_BUS.addListener(VillagerTradingManager::loadTrades); NeoForge.EVENT_BUS.register(new NeoForgeEventHandler()); NeoForge.EVENT_BUS.addListener(this::registerPermissionNodes); UsernameCache.load(); DualStackUtils.initialise(); - TagConventionLogWarning.init(); modEventBus.addListener(EventPriority.HIGH, CapabilityHooks::markProxyableCapabilities); modEventBus.addListener(CapabilityHooks::registerVanillaProviders); @@ -610,6 +611,13 @@ public NeoForgeMod(IEventBus modEventBus, Dist dist, ModContainer container) { NeoForge.EVENT_BUS.addListener(DataMapHooks::onDataMapsUpdated); + // When the components are bound, we have to reset the default resources too + NeoForge.EVENT_BUS.addListener(DefaultDataComponentsBoundEvent.class, event -> { + if (event.shouldUpdateStaticData()) { + BuiltInRegistries.ITEM.forEach(Item::resetDefaultResource); + } + }); + modEventBus.register(NeoForgeDataMaps.class); modEventBus.register(SpawnEggItem.class); // Registers dispenser behaviour for eggs @@ -664,8 +672,8 @@ public void registerLootData(RegisterEvent event) { if (!event.getRegistryKey().equals(Registries.LOOT_CONDITION_TYPE)) return; - event.register(Registries.LOOT_CONDITION_TYPE, Identifier.fromNamespaceAndPath("neoforge", "loot_table_id"), () -> LootTableIdCondition.LOOT_TABLE_ID); - event.register(Registries.LOOT_CONDITION_TYPE, Identifier.fromNamespaceAndPath("neoforge", "can_item_perform_ability"), () -> CanItemPerformAbility.LOOT_CONDITION_TYPE); + event.register(Registries.LOOT_CONDITION_TYPE, Identifier.fromNamespaceAndPath("neoforge", "loot_table_id"), () -> LootTableIdCondition.CODEC); + event.register(Registries.LOOT_CONDITION_TYPE, Identifier.fromNamespaceAndPath("neoforge", "can_item_perform_ability"), () -> CanItemPerformAbility.CODEC); } private static void onConfigLoad(final ModConfigEvent.Loading configEvent) { diff --git a/src/main/java/net/neoforged/neoforge/common/SpecialPlantable.java b/src/main/java/net/neoforged/neoforge/common/SpecialPlantable.java index ffff78a8ba3..ee6735b6f16 100644 --- a/src/main/java/net/neoforged/neoforge/common/SpecialPlantable.java +++ b/src/main/java/net/neoforged/neoforge/common/SpecialPlantable.java @@ -38,7 +38,7 @@ public interface SpecialPlantable { void spawnPlantAtPosition(ItemStack itemStack, LevelAccessor level, BlockPos pos, @Nullable Direction direction); /** - * Whether Villagers can pick up this item and plant it down on any block that extends FarmBlock. + * Whether Villagers can pick up this item and plant it down on any block that extends FarmlandBlock. */ default boolean villagerCanPlantItem(Villager villager) { return false; diff --git a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java deleted file mode 100644 index 363c71e2dab..00000000000 --- a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import java.util.AbstractMap; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import net.minecraft.core.HolderSet; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.Identifier; -import net.minecraft.resources.ResourceKey; -import net.minecraft.tags.ItemTags; -import net.minecraft.tags.TagKey; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.loading.FMLEnvironment; -import net.neoforged.neoforge.common.config.NeoForgeCommonConfig; -import net.neoforged.neoforge.event.server.ServerStartingEvent; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public final class TagConventionLogWarning { - private TagConventionLogWarning() {} - - public enum LogWarningMode { - SILENCED, - DEV_SHORT, - DEV_VERBOSE, - PROD_SHORT, - PROD_VERBOSE - } - - private static final Logger LOGGER = LogManager.getLogger(); - - /** - * Old `forge` tags that we migrated to a new tag under a new convention. - * May also contain commonly used `forge` tags that are not following convention. - */ - private static final Map, String> LEGACY_FORGE_TAGS = Map., String>ofEntries( - createForgeMapEntry(Registries.BLOCK, "enderman_place_on_blacklist", Tags.Blocks.ENDERMAN_PLACE_ON_BLACKLIST), - createForgeMapEntry(Registries.BLOCK, "needs_wood_tool", Tags.Blocks.NEEDS_WOOD_TOOL), - createForgeMapEntry(Registries.BLOCK, "needs_gold_tool", Tags.Blocks.NEEDS_GOLD_TOOL), - createForgeMapEntry(Registries.BLOCK, "needs_netherite_tool", Tags.Blocks.NEEDS_NETHERITE_TOOL), - - createForgeMapEntry(Registries.BLOCK, "barrels", Tags.Blocks.BARRELS), - createForgeMapEntry(Registries.BLOCK, "barrels/wooden", Tags.Blocks.BARRELS_WOODEN), - createForgeMapEntry(Registries.BLOCK, "bookshelves", Tags.Blocks.BOOKSHELVES), - createForgeMapEntry(Registries.BLOCK, "chests", Tags.Blocks.CHESTS), - createForgeMapEntry(Registries.BLOCK, "chests/ender", Tags.Blocks.CHESTS_ENDER), - createForgeMapEntry(Registries.BLOCK, "chests/trapped", Tags.Blocks.CHESTS_TRAPPED), - createForgeMapEntry(Registries.BLOCK, "chests/wooden", Tags.Blocks.CHESTS_WOODEN), - createForgeMapEntry(Registries.BLOCK, "cobblestone", Tags.Blocks.COBBLESTONES), - createForgeMapEntry(Registries.BLOCK, "cobblestone/normal", Tags.Blocks.COBBLESTONES_NORMAL), - createForgeMapEntry(Registries.BLOCK, "cobblestone/infested", Tags.Blocks.COBBLESTONES_INFESTED), - createForgeMapEntry(Registries.BLOCK, "cobblestone/mossy", Tags.Blocks.COBBLESTONES_MOSSY), - createForgeMapEntry(Registries.BLOCK, "cobblestone/deepslate", Tags.Blocks.COBBLESTONES_DEEPSLATE), - createForgeMapEntry(Registries.BLOCK, "crafting_table", Tags.Blocks.PLAYER_WORKSTATIONS_CRAFTING_TABLES), - createForgeMapEntry(Registries.BLOCK, "crafting_tables", Tags.Blocks.PLAYER_WORKSTATIONS_CRAFTING_TABLES), - createForgeMapEntry(Registries.BLOCK, "workbench", Tags.Blocks.PLAYER_WORKSTATIONS_CRAFTING_TABLES), - createForgeMapEntry(Registries.BLOCK, "workbenches", Tags.Blocks.PLAYER_WORKSTATIONS_CRAFTING_TABLES), - createForgeMapEntry(Registries.BLOCK, "end_stones", Tags.Blocks.END_STONES), - createForgeMapEntry(Registries.BLOCK, "fence_gates", Tags.Blocks.FENCE_GATES), - createForgeMapEntry(Registries.BLOCK, "fence_gates/wooden", Tags.Blocks.FENCE_GATES_WOODEN), - createForgeMapEntry(Registries.BLOCK, "fences", Tags.Blocks.FENCES), - createForgeMapEntry(Registries.BLOCK, "fences/nether_brick", Tags.Blocks.FENCES_NETHER_BRICK), - createForgeMapEntry(Registries.BLOCK, "fences/wooden", Tags.Blocks.FENCES_WOODEN), - createMapEntry(Registries.BLOCK, "minecraft", "tall_flowers", Tags.Blocks.FLOWERS_TALL), - createForgeMapEntry(Registries.BLOCK, "furnace", Tags.Blocks.PLAYER_WORKSTATIONS_FURNACES), - createForgeMapEntry(Registries.BLOCK, "furnaces", Tags.Blocks.PLAYER_WORKSTATIONS_FURNACES), - createForgeMapEntry(Registries.BLOCK, "glass", Tags.Blocks.GLASS_BLOCKS), - createMapEntry(Registries.BLOCK, "forge", "stained_glass", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED), - createMapEntry(Registries.BLOCK, "forge", "glass/black", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_BLACK), - createMapEntry(Registries.BLOCK, "forge", "glass/blue", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_BLUE), - createMapEntry(Registries.BLOCK, "forge", "glass/brown", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_BROWN), - createMapEntry(Registries.BLOCK, "forge", "glass/cyan", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_CYAN), - createMapEntry(Registries.BLOCK, "forge", "glass/gray", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_GRAY), - createMapEntry(Registries.BLOCK, "forge", "glass/green", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_GREEN), - createMapEntry(Registries.BLOCK, "forge", "glass/light_blue", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_LIGHT_BLUE), - createMapEntry(Registries.BLOCK, "forge", "glass/light_gray", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_LIGHT_GRAY), - createMapEntry(Registries.BLOCK, "forge", "glass/lime", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_LIME), - createMapEntry(Registries.BLOCK, "forge", "glass/magenta", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_MAGENTA), - createMapEntry(Registries.BLOCK, "forge", "glass/orange", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_ORANGE), - createMapEntry(Registries.BLOCK, "forge", "glass/pink", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_PINK), - createMapEntry(Registries.BLOCK, "forge", "glass/purple", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_PURPLE), - createMapEntry(Registries.BLOCK, "forge", "glass/red", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_RED), - createMapEntry(Registries.BLOCK, "forge", "glass/white", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_WHITE), - createMapEntry(Registries.BLOCK, "forge", "glass/yellow", Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.DYED_YELLOW), - createForgeMapEntry(Registries.BLOCK, "glass/colorless", Tags.Blocks.GLASS_BLOCKS_COLORLESS), - createForgeMapEntry(Registries.BLOCK, "glass/silica", Tags.Blocks.GLASS_BLOCKS_CHEAP), - createForgeMapEntry(Registries.BLOCK, "glass/tinted", Tags.Blocks.GLASS_BLOCKS_TINTED), - createForgeMapEntry(Registries.BLOCK, "glass_panes", Tags.Blocks.GLASS_PANES), - createMapEntry(Registries.BLOCK, "forge", "stained_glass_panes", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/black", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_BLACK), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/blue", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_BLUE), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/brown", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_BROWN), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/cyan", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_CYAN), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/gray", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_GRAY), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/green", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_GREEN), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/light_blue", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_LIGHT_BLUE), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/light_gray", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_LIGHT_GRAY), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/lime", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_LIME), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/magenta", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_MAGENTA), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/orange", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_ORANGE), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/pink", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_PINK), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/purple", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_PURPLE), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/red", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_RED), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/white", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_WHITE), - createMapEntry(Registries.BLOCK, "forge", "glass_panes/yellow", Tags.Blocks.GLASS_PANES, Tags.Blocks.DYED_YELLOW), - createForgeMapEntry(Registries.BLOCK, "glass_panes/colorless", Tags.Blocks.GLASS_PANES_COLORLESS), - createForgeMapEntry(Registries.BLOCK, "gravel", Tags.Blocks.GRAVELS), - createMapEntry(Registries.BLOCK, "c", "gravel", Tags.Blocks.GRAVELS), - createForgeMapEntry(Registries.BLOCK, "heads", Tags.Blocks.SKULLS), - createForgeMapEntry(Registries.BLOCK, "skulls", Tags.Blocks.SKULLS), - createForgeMapEntry(Registries.BLOCK, "netherrack", Tags.Blocks.NETHERRACKS), - createMapEntry(Registries.BLOCK, "c", "netherrack", Tags.Blocks.NETHERRACKS), - createForgeMapEntry(Registries.BLOCK, "obsidian", Tags.Blocks.OBSIDIANS), - createForgeMapEntry(Registries.BLOCK, "ore_bearing_ground/deepslate", Tags.Blocks.ORE_BEARING_GROUND_DEEPSLATE), - createForgeMapEntry(Registries.BLOCK, "ore_bearing_ground/netherrack", Tags.Blocks.ORE_BEARING_GROUND_NETHERRACK), - createForgeMapEntry(Registries.BLOCK, "ore_bearing_ground/stone", Tags.Blocks.ORE_BEARING_GROUND_STONE), - createForgeMapEntry(Registries.BLOCK, "ore_rates/dense", Tags.Blocks.ORE_RATES_DENSE), - createForgeMapEntry(Registries.BLOCK, "ore_rates/singular", Tags.Blocks.ORE_RATES_SINGULAR), - createForgeMapEntry(Registries.BLOCK, "ore_rates/sparse", Tags.Blocks.ORE_RATES_SPARSE), - createForgeMapEntry(Registries.BLOCK, "ores", Tags.Blocks.ORES), - createForgeMapEntry(Registries.BLOCK, "ores/coal", Tags.Blocks.ORES_COAL), - createForgeMapEntry(Registries.BLOCK, "ores/copper", Tags.Blocks.ORES_COPPER), - createForgeMapEntry(Registries.BLOCK, "ores/diamond", Tags.Blocks.ORES_DIAMOND), - createForgeMapEntry(Registries.BLOCK, "ores/emerald", Tags.Blocks.ORES_EMERALD), - createForgeMapEntry(Registries.BLOCK, "ores/gold", Tags.Blocks.ORES_GOLD), - createForgeMapEntry(Registries.BLOCK, "ores/iron", Tags.Blocks.ORES_IRON), - createForgeMapEntry(Registries.BLOCK, "ores/lapis", Tags.Blocks.ORES_LAPIS), - createForgeMapEntry(Registries.BLOCK, "ores/netherite_scrap", Tags.Blocks.ORES_NETHERITE_SCRAP), - createForgeMapEntry(Registries.BLOCK, "ores/quartz", Tags.Blocks.ORES_QUARTZ), - createForgeMapEntry(Registries.BLOCK, "ores/redstone", Tags.Blocks.ORES_REDSTONE), - createForgeMapEntry(Registries.BLOCK, "ores_in_ground/deepslate", Tags.Blocks.ORES_IN_GROUND_DEEPSLATE), - createForgeMapEntry(Registries.BLOCK, "ores_in_ground/netherrack", Tags.Blocks.ORES_IN_GROUND_NETHERRACK), - createForgeMapEntry(Registries.BLOCK, "ores_in_ground/stone", Tags.Blocks.ORES_IN_GROUND_STONE), - createForgeMapEntry(Registries.BLOCK, "sand", Tags.Blocks.SANDS), - createForgeMapEntry(Registries.BLOCK, "sand/colorless", Tags.Blocks.SANDS_COLORLESS), - createForgeMapEntry(Registries.BLOCK, "sand/red", Tags.Blocks.SANDS_RED), - createForgeMapEntry(Registries.BLOCK, "sandstone", Tags.Blocks.SANDSTONE_BLOCKS), - createForgeMapEntry(Registries.BLOCK, "stone", Tags.Blocks.STONES), - createForgeMapEntry(Registries.BLOCK, "storage_blocks", Tags.Blocks.STORAGE_BLOCKS), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/amethyst", "storage_blocks/amethyst"), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/coal", Tags.Blocks.STORAGE_BLOCKS_COAL), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/copper", Tags.Blocks.STORAGE_BLOCKS_COPPER), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/diamond", Tags.Blocks.STORAGE_BLOCKS_DIAMOND), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/emerald", Tags.Blocks.STORAGE_BLOCKS_EMERALD), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/gold", Tags.Blocks.STORAGE_BLOCKS_GOLD), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/iron", Tags.Blocks.STORAGE_BLOCKS_IRON), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/lapis", Tags.Blocks.STORAGE_BLOCKS_LAPIS), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/netherite", Tags.Blocks.STORAGE_BLOCKS_NETHERITE), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/quartz", "storage_blocks/quartz"), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/raw_copper", Tags.Blocks.STORAGE_BLOCKS_RAW_COPPER), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/raw_gold", Tags.Blocks.STORAGE_BLOCKS_RAW_GOLD), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/raw_iron", Tags.Blocks.STORAGE_BLOCKS_RAW_IRON), - createForgeMapEntry(Registries.BLOCK, "storage_blocks/redstone", Tags.Blocks.STORAGE_BLOCKS_REDSTONE), - - createForgeMapEntry(Registries.BLOCK, "relocation_not_supported", Tags.Blocks.RELOCATION_NOT_SUPPORTED), - createForgeMapEntry(Registries.BLOCK, "immovable", Tags.Blocks.RELOCATION_NOT_SUPPORTED), - createForgeMapEntry(Registries.BLOCK_PREDICATE_TYPE, "relocation_not_supported", Tags.Blocks.RELOCATION_NOT_SUPPORTED), - createForgeMapEntry(Registries.BLOCK_PREDICATE_TYPE, "immovable", Tags.Blocks.RELOCATION_NOT_SUPPORTED), - - createForgeMapEntry(Registries.ENTITY_TYPE, "bosses", Tags.EntityTypes.BOSSES), - - createForgeMapEntry(Registries.ITEM, "barrels", Tags.Items.BARRELS), - createForgeMapEntry(Registries.ITEM, "barrels/wooden", Tags.Items.BARRELS_WOODEN), - createForgeMapEntry(Registries.ITEM, "bones", Tags.Items.BONES), - createForgeMapEntry(Registries.ITEM, "bookshelves", Tags.Items.BOOKSHELVES), - createForgeMapEntry(Registries.ITEM, "bucket", Tags.Items.BUCKETS), - createForgeMapEntry(Registries.ITEM, "chests", Tags.Items.CHESTS), - createForgeMapEntry(Registries.ITEM, "chests/ender", Tags.Items.CHESTS_ENDER), - createForgeMapEntry(Registries.ITEM, "chests/trapped", Tags.Items.CHESTS_TRAPPED), - createForgeMapEntry(Registries.ITEM, "chests/wooden", Tags.Items.CHESTS_WOODEN), - createForgeMapEntry(Registries.ITEM, "cobblestone", Tags.Items.COBBLESTONES), - createForgeMapEntry(Registries.ITEM, "cobblestone/normal", Tags.Items.COBBLESTONES_NORMAL), - createForgeMapEntry(Registries.ITEM, "cobblestone/infested", Tags.Items.COBBLESTONES_INFESTED), - createForgeMapEntry(Registries.ITEM, "cobblestone/mossy", Tags.Items.COBBLESTONES_MOSSY), - createForgeMapEntry(Registries.ITEM, "cobblestone/deepslate", Tags.Items.COBBLESTONES_DEEPSLATE), - createForgeMapEntry(Registries.ITEM, "crafting_table", Tags.Items.PLAYER_WORKSTATIONS_CRAFTING_TABLES), - createForgeMapEntry(Registries.ITEM, "crafting_tables", Tags.Items.PLAYER_WORKSTATIONS_CRAFTING_TABLES), - createForgeMapEntry(Registries.ITEM, "workbench", Tags.Items.PLAYER_WORKSTATIONS_CRAFTING_TABLES), - createForgeMapEntry(Registries.ITEM, "workbenches", Tags.Items.PLAYER_WORKSTATIONS_CRAFTING_TABLES), - createForgeMapEntry(Registries.ITEM, "crops", Tags.Items.CROPS), - createForgeMapEntry(Registries.ITEM, "crops/beetroot", Tags.Items.CROPS_BEETROOT), - createForgeMapEntry(Registries.ITEM, "crops/carrot", Tags.Items.CROPS_CARROT), - createForgeMapEntry(Registries.ITEM, "crops/nether_wart", Tags.Items.CROPS_NETHER_WART), - createForgeMapEntry(Registries.ITEM, "crops/potato", Tags.Items.CROPS_POTATO), - createForgeMapEntry(Registries.ITEM, "crops/wheat", Tags.Items.CROPS_WHEAT), - createForgeMapEntry(Registries.ITEM, "dusts", Tags.Items.DUSTS), - createForgeMapEntry(Registries.ITEM, "dusts/redstone", Tags.Items.DUSTS_REDSTONE), - createForgeMapEntry(Registries.ITEM, "dusts/glowstone", Tags.Items.DUSTS_GLOWSTONE), - createForgeMapEntry(Registries.ITEM, "dyes", Tags.Items.DYES), - createForgeMapEntry(Registries.ITEM, "dyes/black", Tags.Items.DYES_BLACK), - createForgeMapEntry(Registries.ITEM, "dyes/red", Tags.Items.DYES_RED), - createForgeMapEntry(Registries.ITEM, "dyes/green", Tags.Items.DYES_GREEN), - createForgeMapEntry(Registries.ITEM, "dyes/brown", Tags.Items.DYES_BROWN), - createForgeMapEntry(Registries.ITEM, "dyes/blue", Tags.Items.DYES_BLUE), - createForgeMapEntry(Registries.ITEM, "dyes/purple", Tags.Items.DYES_PURPLE), - createForgeMapEntry(Registries.ITEM, "dyes/cyan", Tags.Items.DYES_CYAN), - createForgeMapEntry(Registries.ITEM, "dyes/light_gray", Tags.Items.DYES_LIGHT_GRAY), - createForgeMapEntry(Registries.ITEM, "dyes/gray", Tags.Items.DYES_GRAY), - createForgeMapEntry(Registries.ITEM, "dyes/pink", Tags.Items.DYES_PINK), - createForgeMapEntry(Registries.ITEM, "dyes/lime", Tags.Items.DYES_LIME), - createForgeMapEntry(Registries.ITEM, "dyes/yellow", Tags.Items.DYES_YELLOW), - createForgeMapEntry(Registries.ITEM, "dyes/light_blue", Tags.Items.DYES_LIGHT_BLUE), - createForgeMapEntry(Registries.ITEM, "dyes/magenta", Tags.Items.DYES_MAGENTA), - createForgeMapEntry(Registries.ITEM, "dyes/orange", Tags.Items.DYES_ORANGE), - createForgeMapEntry(Registries.ITEM, "dyes/white", Tags.Items.DYES_WHITE), - createForgeMapEntry(Registries.ITEM, "eggs", Tags.Items.EGGS), - createForgeMapEntry(Registries.ITEM, "enchanting_fuels", Tags.Items.ENCHANTING_FUELS), - createForgeMapEntry(Registries.ITEM, "end_stones", Tags.Items.END_STONES), - createForgeMapEntry(Registries.ITEM, "ender_pearls", Tags.Items.ENDER_PEARLS), - createForgeMapEntry(Registries.ITEM, "feathers", Tags.Items.FEATHERS), - createForgeMapEntry(Registries.ITEM, "fence_gates", Tags.Items.FENCE_GATES), - createForgeMapEntry(Registries.ITEM, "fence_gates/wooden", Tags.Items.FENCE_GATES_WOODEN), - createForgeMapEntry(Registries.ITEM, "fences", Tags.Items.FENCES), - createForgeMapEntry(Registries.ITEM, "fences/nether_brick", Tags.Items.FENCES_NETHER_BRICK), - createForgeMapEntry(Registries.ITEM, "fences/wooden", Tags.Items.FENCES_WOODEN), - createMapEntry(Registries.ITEM, "minecraft", "tall_flowers", Tags.Items.FLOWERS_TALL), - createForgeMapEntry(Registries.ITEM, "furnace", Tags.Items.PLAYER_WORKSTATIONS_FURNACES), - createForgeMapEntry(Registries.ITEM, "furnaces", Tags.Items.PLAYER_WORKSTATIONS_FURNACES), - createForgeMapEntry(Registries.ITEM, "gems", Tags.Items.GEMS), - createForgeMapEntry(Registries.ITEM, "gems/diamond", Tags.Items.GEMS_DIAMOND), - createForgeMapEntry(Registries.ITEM, "gems/emerald", Tags.Items.GEMS_EMERALD), - createForgeMapEntry(Registries.ITEM, "gems/amethyst", Tags.Items.GEMS_AMETHYST), - createForgeMapEntry(Registries.ITEM, "gems/lapis", Tags.Items.GEMS_LAPIS), - createForgeMapEntry(Registries.ITEM, "gems/prismarine", Tags.Items.GEMS_PRISMARINE), - createForgeMapEntry(Registries.ITEM, "gems/quartz", Tags.Items.GEMS_QUARTZ), - createForgeMapEntry(Registries.ITEM, "glass", Tags.Items.GLASS_BLOCKS), - createMapEntry(Registries.ITEM, "forge", "stained_glass", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED), - createMapEntry(Registries.ITEM, "forge", "glass/black", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_BLACK), - createMapEntry(Registries.ITEM, "forge", "glass/blue", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_BLUE), - createMapEntry(Registries.ITEM, "forge", "glass/brown", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_BROWN), - createMapEntry(Registries.ITEM, "forge", "glass/cyan", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_CYAN), - createMapEntry(Registries.ITEM, "forge", "glass/gray", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_GRAY), - createMapEntry(Registries.ITEM, "forge", "glass/green", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_GREEN), - createMapEntry(Registries.ITEM, "forge", "glass/light_blue", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_LIGHT_BLUE), - createMapEntry(Registries.ITEM, "forge", "glass/light_gray", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_LIGHT_GRAY), - createMapEntry(Registries.ITEM, "forge", "glass/lime", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_LIME), - createMapEntry(Registries.ITEM, "forge", "glass/magenta", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_MAGENTA), - createMapEntry(Registries.ITEM, "forge", "glass/orange", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_ORANGE), - createMapEntry(Registries.ITEM, "forge", "glass/pink", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_PINK), - createMapEntry(Registries.ITEM, "forge", "glass/purple", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_PURPLE), - createMapEntry(Registries.ITEM, "forge", "glass/red", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_RED), - createMapEntry(Registries.ITEM, "forge", "glass/white", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_WHITE), - createMapEntry(Registries.ITEM, "forge", "glass/yellow", Tags.Items.GLASS_BLOCKS, Tags.Items.DYED_YELLOW), - createForgeMapEntry(Registries.ITEM, "glass/colorless", Tags.Items.GLASS_BLOCKS_COLORLESS), - createForgeMapEntry(Registries.ITEM, "glass/silica", Tags.Items.GLASS_BLOCKS_CHEAP), - createForgeMapEntry(Registries.ITEM, "glass/tinted", Tags.Items.GLASS_BLOCKS_TINTED), - createForgeMapEntry(Registries.ITEM, "glass_panes", Tags.Items.GLASS_PANES), - createMapEntry(Registries.ITEM, "forge", "stained_glass_panes", Tags.Items.GLASS_PANES, Tags.Items.DYED), - createMapEntry(Registries.ITEM, "forge", "glass_panes/black", Tags.Items.GLASS_PANES, Tags.Items.DYED_BLACK), - createMapEntry(Registries.ITEM, "forge", "glass_panes/blue", Tags.Items.GLASS_PANES, Tags.Items.DYED_BLUE), - createMapEntry(Registries.ITEM, "forge", "glass_panes/brown", Tags.Items.GLASS_PANES, Tags.Items.DYED_BROWN), - createMapEntry(Registries.ITEM, "forge", "glass_panes/cyan", Tags.Items.GLASS_PANES, Tags.Items.DYED_CYAN), - createMapEntry(Registries.ITEM, "forge", "glass_panes/gray", Tags.Items.GLASS_PANES, Tags.Items.DYED_GRAY), - createMapEntry(Registries.ITEM, "forge", "glass_panes/green", Tags.Items.GLASS_PANES, Tags.Items.DYED_GREEN), - createMapEntry(Registries.ITEM, "forge", "glass_panes/light_blue", Tags.Items.GLASS_PANES, Tags.Items.DYED_LIGHT_BLUE), - createMapEntry(Registries.ITEM, "forge", "glass_panes/light_gray", Tags.Items.GLASS_PANES, Tags.Items.DYED_LIGHT_GRAY), - createMapEntry(Registries.ITEM, "forge", "glass_panes/lime", Tags.Items.GLASS_PANES, Tags.Items.DYED_LIME), - createMapEntry(Registries.ITEM, "forge", "glass_panes/magenta", Tags.Items.GLASS_PANES, Tags.Items.DYED_MAGENTA), - createMapEntry(Registries.ITEM, "forge", "glass_panes/orange", Tags.Items.GLASS_PANES, Tags.Items.DYED_ORANGE), - createMapEntry(Registries.ITEM, "forge", "glass_panes/pink", Tags.Items.GLASS_PANES, Tags.Items.DYED_PINK), - createMapEntry(Registries.ITEM, "forge", "glass_panes/purple", Tags.Items.GLASS_PANES, Tags.Items.DYED_PURPLE), - createMapEntry(Registries.ITEM, "forge", "glass_panes/red", Tags.Items.GLASS_PANES, Tags.Items.DYED_RED), - createMapEntry(Registries.ITEM, "forge", "glass_panes/white", Tags.Items.GLASS_PANES, Tags.Items.DYED_WHITE), - createMapEntry(Registries.ITEM, "forge", "glass_panes/yellow", Tags.Items.GLASS_PANES, Tags.Items.DYED_YELLOW), - createForgeMapEntry(Registries.ITEM, "glass_panes/colorless", Tags.Items.GLASS_PANES_COLORLESS), - createForgeMapEntry(Registries.ITEM, "gravel", Tags.Items.GRAVELS), - createMapEntry(Registries.ITEM, "c", "gravel", Tags.Items.GRAVELS), - createForgeMapEntry(Registries.ITEM, "gunpowder", Tags.Items.GUNPOWDERS), - createMapEntry(Registries.ITEM, "c", "gunpowder", Tags.Items.GUNPOWDERS), - createForgeMapEntry(Registries.ITEM, "ingots", Tags.Items.INGOTS), - createForgeMapEntry(Registries.ITEM, "ingots/brick", Tags.Items.BRICKS_NORMAL), - createForgeMapEntry(Registries.ITEM, "ingots/copper", Tags.Items.INGOTS_COPPER), - createForgeMapEntry(Registries.ITEM, "ingots/gold", Tags.Items.INGOTS_GOLD), - createForgeMapEntry(Registries.ITEM, "ingots/iron", Tags.Items.INGOTS_IRON), - createForgeMapEntry(Registries.ITEM, "ingots/netherite", Tags.Items.INGOTS_NETHERITE), - createForgeMapEntry(Registries.ITEM, "ingots/nether_brick", Tags.Items.BRICKS_NETHER), - createForgeMapEntry(Registries.ITEM, "leather", Tags.Items.LEATHERS), - createMapEntry(Registries.ITEM, "c", "leather", Tags.Items.LEATHERS), - createForgeMapEntry(Registries.ITEM, "mushrooms", Tags.Items.MUSHROOMS), - createForgeMapEntry(Registries.ITEM, "nether_stars", Tags.Items.NETHER_STARS), - createForgeMapEntry(Registries.ITEM, "netherrack", Tags.Items.NETHERRACKS), - createMapEntry(Registries.ITEM, "c", "netherrack", Tags.Items.NETHERRACKS), - createForgeMapEntry(Registries.ITEM, "nuggets", Tags.Items.NUGGETS), - createForgeMapEntry(Registries.ITEM, "nuggets/gold", Tags.Items.NUGGETS_GOLD), - createForgeMapEntry(Registries.ITEM, "nuggets/iron", Tags.Items.NUGGETS_IRON), - createForgeMapEntry(Registries.ITEM, "obsidian", Tags.Items.OBSIDIANS), - createForgeMapEntry(Registries.ITEM, "ore_bearing_ground/deepslate", Tags.Items.ORE_BEARING_GROUND_DEEPSLATE), - createForgeMapEntry(Registries.ITEM, "ore_bearing_ground/netherrack", Tags.Items.ORE_BEARING_GROUND_NETHERRACK), - createForgeMapEntry(Registries.ITEM, "ore_bearing_ground/stone", Tags.Items.ORE_BEARING_GROUND_STONE), - createForgeMapEntry(Registries.ITEM, "ore_rates/dense", Tags.Items.ORE_RATES_DENSE), - createForgeMapEntry(Registries.ITEM, "ore_rates/singular", Tags.Items.ORE_RATES_SINGULAR), - createForgeMapEntry(Registries.ITEM, "ore_rates/sparse", Tags.Items.ORE_RATES_SPARSE), - createForgeMapEntry(Registries.ITEM, "ores", Tags.Items.ORES), - createForgeMapEntry(Registries.ITEM, "ores/coal", Tags.Items.ORES_COAL), - createForgeMapEntry(Registries.ITEM, "ores/copper", Tags.Items.ORES_COPPER), - createForgeMapEntry(Registries.ITEM, "ores/diamond", Tags.Items.ORES_DIAMOND), - createForgeMapEntry(Registries.ITEM, "ores/emerald", Tags.Items.ORES_EMERALD), - createForgeMapEntry(Registries.ITEM, "ores/gold", Tags.Items.ORES_GOLD), - createForgeMapEntry(Registries.ITEM, "ores/iron", Tags.Items.ORES_IRON), - createForgeMapEntry(Registries.ITEM, "ores/lapis", Tags.Items.ORES_LAPIS), - createForgeMapEntry(Registries.ITEM, "ores/netherite_scrap", Tags.Items.ORES_NETHERITE_SCRAP), - createForgeMapEntry(Registries.ITEM, "ores/quartz", Tags.Items.ORES_QUARTZ), - createForgeMapEntry(Registries.ITEM, "ores/redstone", Tags.Items.ORES_REDSTONE), - createForgeMapEntry(Registries.ITEM, "ores_in_ground/deepslate", Tags.Items.ORES_IN_GROUND_DEEPSLATE), - createForgeMapEntry(Registries.ITEM, "ores_in_ground/netherrack", Tags.Items.ORES_IN_GROUND_NETHERRACK), - createForgeMapEntry(Registries.ITEM, "ores_in_ground/stone", Tags.Items.ORES_IN_GROUND_STONE), - createMapEntry(Registries.ITEM, "c", "raw_blocks", Tags.Items.STORAGE_BLOCKS), - createMapEntry(Registries.ITEM, "c", "raw_blocks/copper", Tags.Items.STORAGE_BLOCKS_COPPER), - createMapEntry(Registries.ITEM, "c", "raw_blocks/gold", Tags.Items.STORAGE_BLOCKS_GOLD), - createMapEntry(Registries.ITEM, "c", "raw_blocks/iron", Tags.Items.STORAGE_BLOCKS_IRON), - createForgeMapEntry(Registries.ITEM, "raw_materials", Tags.Items.RAW_MATERIALS), - createForgeMapEntry(Registries.ITEM, "raw_materials/copper", Tags.Items.RAW_MATERIALS_COPPER), - createForgeMapEntry(Registries.ITEM, "raw_materials/gold", Tags.Items.RAW_MATERIALS_GOLD), - createForgeMapEntry(Registries.ITEM, "raw_materials/iron", Tags.Items.RAW_MATERIALS_IRON), - createForgeMapEntry(Registries.ITEM, "rods", Tags.Items.RODS), - createForgeMapEntry(Registries.ITEM, "rods/blaze", Tags.Items.RODS_BLAZE), - createForgeMapEntry(Registries.ITEM, "rods/wooden", Tags.Items.RODS_WOODEN), - createForgeMapEntry(Registries.ITEM, "rope", Tags.Items.ROPES), - createForgeMapEntry(Registries.ITEM, "sand", Tags.Items.SANDS), - createForgeMapEntry(Registries.ITEM, "sand/colorless", Tags.Items.SANDS_COLORLESS), - createForgeMapEntry(Registries.ITEM, "sand/red", Tags.Items.SANDS_RED), - createForgeMapEntry(Registries.ITEM, "sandstone", Tags.Items.SANDSTONE_BLOCKS), - createForgeMapEntry(Registries.ITEM, "seeds", Tags.Items.SEEDS), - createForgeMapEntry(Registries.ITEM, "seeds/beetroot", Tags.Items.SEEDS_BEETROOT), - createForgeMapEntry(Registries.ITEM, "seeds/melon", Tags.Items.SEEDS_MELON), - createForgeMapEntry(Registries.ITEM, "seeds/pumpkin", Tags.Items.SEEDS_PUMPKIN), - createForgeMapEntry(Registries.ITEM, "seeds/wheat", Tags.Items.SEEDS_WHEAT), - createForgeMapEntry(Registries.ITEM, "shears", Tags.Items.TOOLS_SHEAR), - createForgeMapEntry(Registries.ITEM, "slimeballs", Tags.Items.SLIME_BALLS), - createForgeMapEntry(Registries.ITEM, "stone", Tags.Items.STONES), - createForgeMapEntry(Registries.ITEM, "storage_blocks", Tags.Items.STORAGE_BLOCKS), - createForgeMapEntry(Registries.ITEM, "storage_blocks/amethyst", "storage_blocks/amethyst"), - createForgeMapEntry(Registries.ITEM, "storage_blocks/coal", Tags.Items.STORAGE_BLOCKS_COAL), - createForgeMapEntry(Registries.ITEM, "storage_blocks/copper", Tags.Items.STORAGE_BLOCKS_COPPER), - createForgeMapEntry(Registries.ITEM, "storage_blocks/diamond", Tags.Items.STORAGE_BLOCKS_DIAMOND), - createForgeMapEntry(Registries.ITEM, "storage_blocks/emerald", Tags.Items.STORAGE_BLOCKS_EMERALD), - createForgeMapEntry(Registries.ITEM, "storage_blocks/gold", Tags.Items.STORAGE_BLOCKS_GOLD), - createForgeMapEntry(Registries.ITEM, "storage_blocks/iron", Tags.Items.STORAGE_BLOCKS_IRON), - createForgeMapEntry(Registries.ITEM, "storage_blocks/lapis", Tags.Items.STORAGE_BLOCKS_LAPIS), - createForgeMapEntry(Registries.ITEM, "storage_blocks/netherite", Tags.Items.STORAGE_BLOCKS_NETHERITE), - createForgeMapEntry(Registries.ITEM, "storage_blocks/quartz", "storage_blocks/quartz"), - createForgeMapEntry(Registries.ITEM, "storage_blocks/raw_copper", Tags.Items.STORAGE_BLOCKS_RAW_COPPER), - createForgeMapEntry(Registries.ITEM, "storage_blocks/raw_gold", Tags.Items.STORAGE_BLOCKS_RAW_GOLD), - createForgeMapEntry(Registries.ITEM, "storage_blocks/raw_iron", Tags.Items.STORAGE_BLOCKS_RAW_IRON), - createForgeMapEntry(Registries.ITEM, "storage_blocks/redstone", Tags.Items.STORAGE_BLOCKS_REDSTONE), - createForgeMapEntry(Registries.ITEM, "string", Tags.Items.STRINGS), - createForgeMapEntry(Registries.ITEM, "tools", Tags.Items.TOOLS), - createForgeMapEntry(Registries.ITEM, "tools/shields", Tags.Items.TOOLS_SHIELD), - createForgeMapEntry(Registries.ITEM, "tools/bows", Tags.Items.TOOLS_BOW), - createForgeMapEntry(Registries.ITEM, "tools/crossbows", Tags.Items.TOOLS_CROSSBOW), - createForgeMapEntry(Registries.ITEM, "tools/fishing_rods", Tags.Items.TOOLS_FISHING_ROD), - createForgeMapEntry(Registries.ITEM, "tools/tridents", Tags.Items.TOOLS_SPEAR), - createForgeMapEntry(Registries.ITEM, "tools/brushes", Tags.Items.TOOLS_BRUSH), - createMapEntry(Registries.ITEM, "c", "tools/shields", Tags.Items.TOOLS_SHIELD), - createMapEntry(Registries.ITEM, "c", "tools/bows", Tags.Items.TOOLS_BOW), - createMapEntry(Registries.ITEM, "c", "tools/brushes", Tags.Items.TOOLS_BRUSH), - createMapEntry(Registries.ITEM, "c", "tools/crossbows", Tags.Items.TOOLS_CROSSBOW), - createMapEntry(Registries.ITEM, "c", "tools/fishing_rods", Tags.Items.TOOLS_FISHING_ROD), - createMapEntry(Registries.ITEM, "c", "tools/shears", Tags.Items.TOOLS_SHEAR), - createMapEntry(Registries.ITEM, "c", "tools/tridents", Tags.Items.TOOLS_SPEAR), - createForgeMapEntry(Registries.ITEM, "armors", Tags.Items.ARMORS), - createForgeMapEntry(Registries.ITEM, "armors/helmets", ItemTags.HEAD_ARMOR), - createForgeMapEntry(Registries.ITEM, "armors/chestplates", ItemTags.CHEST_ARMOR), - createForgeMapEntry(Registries.ITEM, "armors/leggings", ItemTags.LEG_ARMOR), - createForgeMapEntry(Registries.ITEM, "armors/boots", ItemTags.FOOT_ARMOR), - createForgeMapEntry(Registries.ITEM, "wrench", Tags.Items.TOOLS_WRENCH), - createForgeMapEntry(Registries.ITEM, "wrenches", Tags.Items.TOOLS_WRENCH), - createForgeMapEntry(Registries.ITEM, "tools/wrench", Tags.Items.TOOLS_WRENCH), - createForgeMapEntry(Registries.ITEM, "tools/wrenches", Tags.Items.TOOLS_WRENCH), - createMapEntry(Registries.ITEM, "c", "tools/wrenches", Tags.Items.TOOLS_WRENCH), - createForgeMapEntry(Registries.ITEM, "food", Tags.Items.FOODS), - createForgeMapEntry(Registries.ITEM, "foods", Tags.Items.FOODS), - createForgeMapEntry(Registries.ITEM, "fruit", Tags.Items.FOODS_FRUIT), - createForgeMapEntry(Registries.ITEM, "fruits", Tags.Items.FOODS_FRUIT), - createMapEntry(Registries.ITEM, "c", "foods/fruits", Tags.Items.FOODS_FRUIT), - createForgeMapEntry(Registries.ITEM, "vegetable", Tags.Items.FOODS_VEGETABLE), - createForgeMapEntry(Registries.ITEM, "vegetables", Tags.Items.FOODS_VEGETABLE), - createMapEntry(Registries.ITEM, "c", "foods/vegetables", Tags.Items.FOODS_VEGETABLE), - createForgeMapEntry(Registries.ITEM, "berry", Tags.Items.FOODS_BERRY), - createForgeMapEntry(Registries.ITEM, "berries", Tags.Items.FOODS_BERRY), - createMapEntry(Registries.ITEM, "c", "foods/berries", Tags.Items.FOODS_BERRY), - createForgeMapEntry(Registries.ITEM, "bread", Tags.Items.FOODS_BREAD), - createForgeMapEntry(Registries.ITEM, "breads", Tags.Items.FOODS_BREAD), - createMapEntry(Registries.ITEM, "c", "foods/breads", Tags.Items.FOODS_BREAD), - createForgeMapEntry(Registries.ITEM, "cookie", Tags.Items.FOODS_COOKIE), - createForgeMapEntry(Registries.ITEM, "cookies", Tags.Items.FOODS_COOKIE), - createMapEntry(Registries.ITEM, "c", "foods/cookies", Tags.Items.FOODS_COOKIE), - createForgeMapEntry(Registries.ITEM, "raw_meat", Tags.Items.FOODS_RAW_MEAT), - createForgeMapEntry(Registries.ITEM, "raw_meats", Tags.Items.FOODS_RAW_MEAT), - createMapEntry(Registries.ITEM, "c", "foods/raw_meats", Tags.Items.FOODS_RAW_MEAT), - createForgeMapEntry(Registries.ITEM, "raw_fish", Tags.Items.FOODS_RAW_FISH), - createForgeMapEntry(Registries.ITEM, "raw_fishes", Tags.Items.FOODS_RAW_FISH), - createMapEntry(Registries.ITEM, "c", "foods/raw_fishes", Tags.Items.FOODS_RAW_FISH), - createForgeMapEntry(Registries.ITEM, "cooked_meat", Tags.Items.FOODS_COOKED_MEAT), - createForgeMapEntry(Registries.ITEM, "cooked_meats", Tags.Items.FOODS_COOKED_MEAT), - createMapEntry(Registries.ITEM, "c", "foods/cooked_meats", Tags.Items.FOODS_COOKED_MEAT), - createForgeMapEntry(Registries.ITEM, "cooked_fish", Tags.Items.FOODS_COOKED_FISH), - createForgeMapEntry(Registries.ITEM, "cooked_fishes", Tags.Items.FOODS_COOKED_FISH), - createMapEntry(Registries.ITEM, "c", "foods/cooked_fishes", Tags.Items.FOODS_COOKED_FISH), - createForgeMapEntry(Registries.ITEM, "soup", Tags.Items.FOODS_SOUP), - createForgeMapEntry(Registries.ITEM, "soups", Tags.Items.FOODS_SOUP), - createMapEntry(Registries.ITEM, "c", "foods/soups", Tags.Items.FOODS_SOUP), - createForgeMapEntry(Registries.ITEM, "stew", Tags.Items.FOODS_SOUP), - createForgeMapEntry(Registries.ITEM, "stews", Tags.Items.FOODS_SOUP), - createForgeMapEntry(Registries.ITEM, "candy", Tags.Items.FOODS_CANDY), - createForgeMapEntry(Registries.ITEM, "candies", Tags.Items.FOODS_CANDY), - createMapEntry(Registries.ITEM, "c", "foods/candies", Tags.Items.FOODS_CANDY), - createForgeMapEntry(Registries.ITEM, "pie", Tags.Items.FOODS_PIE), - createForgeMapEntry(Registries.ITEM, "pies", Tags.Items.FOODS_PIE), - createMapEntry(Registries.ITEM, "c", "foods/pies", Tags.Items.FOODS_PIE), - - createForgeMapEntry(Registries.FLUID, "water", Tags.Fluids.WATER), - createForgeMapEntry(Registries.FLUID, "lava", Tags.Fluids.LAVA), - createForgeMapEntry(Registries.FLUID, "milk", Tags.Fluids.MILK), - createForgeMapEntry(Registries.FLUID, "gaseous", Tags.Fluids.GASEOUS), - createForgeMapEntry(Registries.FLUID, "honey", Tags.Fluids.HONEY), - createForgeMapEntry(Registries.FLUID, "xp", Tags.Fluids.EXPERIENCE), - createForgeMapEntry(Registries.FLUID, "experience", Tags.Fluids.EXPERIENCE), - createForgeMapEntry(Registries.FLUID, "potion", Tags.Fluids.POTION), - createForgeMapEntry(Registries.FLUID, "plantoil", "plant_oil"), - - createForgeMapEntry(Registries.BIOME, "is_hot", Tags.Biomes.IS_HOT), - createForgeMapEntry(Registries.BIOME, "is_hot/overworld", Tags.Biomes.IS_HOT_OVERWORLD), - createForgeMapEntry(Registries.BIOME, "is_hot/nether", Tags.Biomes.IS_HOT_NETHER), - createForgeMapEntry(Registries.BIOME, "is_hot/end", Tags.Biomes.IS_HOT_END), - createForgeMapEntry(Registries.BIOME, "is_cold", Tags.Biomes.IS_COLD), - createForgeMapEntry(Registries.BIOME, "is_cold/overworld", Tags.Biomes.IS_COLD_OVERWORLD), - createForgeMapEntry(Registries.BIOME, "is_cold/nether", Tags.Biomes.IS_COLD_NETHER), - createForgeMapEntry(Registries.BIOME, "is_cold/end", Tags.Biomes.IS_COLD_END), - createForgeMapEntry(Registries.BIOME, "is_sparse", Tags.Biomes.IS_SPARSE_VEGETATION), - createForgeMapEntry(Registries.BIOME, "is_sparse/overworld", Tags.Biomes.IS_SPARSE_VEGETATION_OVERWORLD), - createForgeMapEntry(Registries.BIOME, "is_sparse/nether", Tags.Biomes.IS_SPARSE_VEGETATION_NETHER), - createForgeMapEntry(Registries.BIOME, "is_sparse/end", Tags.Biomes.IS_SPARSE_VEGETATION_END), - createForgeMapEntry(Registries.BIOME, "is_dense", Tags.Biomes.IS_DENSE_VEGETATION), - createForgeMapEntry(Registries.BIOME, "is_dense/overworld", Tags.Biomes.IS_DENSE_VEGETATION_OVERWORLD), - createForgeMapEntry(Registries.BIOME, "is_dense/nether", Tags.Biomes.IS_DENSE_VEGETATION_NETHER), - createForgeMapEntry(Registries.BIOME, "is_dense/end", Tags.Biomes.IS_DENSE_VEGETATION_END), - createForgeMapEntry(Registries.BIOME, "is_wet", Tags.Biomes.IS_WET), - createForgeMapEntry(Registries.BIOME, "is_wet/overworld", Tags.Biomes.IS_WET_OVERWORLD), - createForgeMapEntry(Registries.BIOME, "is_wet/nether", Tags.Biomes.IS_WET_NETHER), - createForgeMapEntry(Registries.BIOME, "is_wet/end", Tags.Biomes.IS_WET_END), - createForgeMapEntry(Registries.BIOME, "is_dry", Tags.Biomes.IS_DRY), - createForgeMapEntry(Registries.BIOME, "is_dry/overworld", Tags.Biomes.IS_DRY_OVERWORLD), - createForgeMapEntry(Registries.BIOME, "is_dry/nether", Tags.Biomes.IS_DRY_NETHER), - createForgeMapEntry(Registries.BIOME, "is_dry/end", Tags.Biomes.IS_DRY_END), - createForgeMapEntry(Registries.BIOME, "is_coniferous", Tags.Biomes.IS_CONIFEROUS_TREE), - createForgeMapEntry(Registries.BIOME, "is_savanna", Tags.Biomes.IS_SAVANNA_TREE), - createForgeMapEntry(Registries.BIOME, "is_jungle", Tags.Biomes.IS_JUNGLE_TREE), - createForgeMapEntry(Registries.BIOME, "is_deciduous", Tags.Biomes.IS_DECIDUOUS_TREE), - createForgeMapEntry(Registries.BIOME, "is_spooky", Tags.Biomes.IS_SPOOKY), - createForgeMapEntry(Registries.BIOME, "is_dead", Tags.Biomes.IS_DEAD), - createForgeMapEntry(Registries.BIOME, "is_lush", Tags.Biomes.IS_LUSH), - createForgeMapEntry(Registries.BIOME, "is_mushroom", Tags.Biomes.IS_MUSHROOM), - createForgeMapEntry(Registries.BIOME, "is_magical", Tags.Biomes.IS_MAGICAL), - createForgeMapEntry(Registries.BIOME, "is_rare", Tags.Biomes.IS_RARE), - createForgeMapEntry(Registries.BIOME, "is_plateau", Tags.Biomes.IS_PLATEAU), - createForgeMapEntry(Registries.BIOME, "is_water", Tags.Biomes.IS_AQUATIC), - createForgeMapEntry(Registries.BIOME, "is_desert", Tags.Biomes.IS_DESERT), - createForgeMapEntry(Registries.BIOME, "is_plains", Tags.Biomes.IS_PLAINS), - createForgeMapEntry(Registries.BIOME, "is_swamp", Tags.Biomes.IS_SWAMP), - createForgeMapEntry(Registries.BIOME, "is_sandy", Tags.Biomes.IS_SANDY), - createForgeMapEntry(Registries.BIOME, "is_snowy", Tags.Biomes.IS_SNOWY), - createForgeMapEntry(Registries.BIOME, "is_wasteland", Tags.Biomes.IS_WASTELAND), - createForgeMapEntry(Registries.BIOME, "is_void", Tags.Biomes.IS_VOID), - createForgeMapEntry(Registries.BIOME, "is_underground", Tags.Biomes.IS_UNDERGROUND), - createForgeMapEntry(Registries.BIOME, "is_cave", Tags.Biomes.IS_CAVE), - createForgeMapEntry(Registries.BIOME, "is_peak", Tags.Biomes.IS_MOUNTAIN_PEAK), - createForgeMapEntry(Registries.BIOME, "is_slope", Tags.Biomes.IS_MOUNTAIN_SLOPE), - createForgeMapEntry(Registries.BIOME, "is_mountain", Tags.Biomes.IS_MOUNTAIN), - createForgeMapEntry(Registries.BIOME, "is_end", Tags.Biomes.IS_END), - createForgeMapEntry(Registries.BIOME, "is_nether", Tags.Biomes.IS_NETHER), - createForgeMapEntry(Registries.BIOME, "is_overworld", Tags.Biomes.IS_OVERWORLD), - createForgeMapEntry(Registries.BIOME, "no_default_monsters", Tags.Biomes.NO_DEFAULT_MONSTERS)); - - /*package private*/ - static void init() { - IEventBus forgeBus = NeoForge.EVENT_BUS; - - setupLegacyTagWarning(forgeBus); - } - - // Remove in 1.22 - private static void setupLegacyTagWarning(IEventBus forgeBus) { - // Log tags that are still using legacy 'forge' namespace - forgeBus.addListener((ServerStartingEvent serverStartingEvent) -> { - // We have to wait for server start to read the server config. - LogWarningMode legacyTagWarningMode = NeoForgeCommonConfig.INSTANCE.logLegacyTagWarnings.get(); - if (legacyTagWarningMode != LogWarningMode.SILENCED) { - boolean isConfigSetToDev = legacyTagWarningMode == LogWarningMode.DEV_SHORT || - legacyTagWarningMode == LogWarningMode.DEV_VERBOSE; - - if (!FMLEnvironment.isProduction() == isConfigSetToDev) { - List> legacyTags = new ObjectArrayList<>(); - RegistryAccess.Frozen registryAccess = serverStartingEvent.getServer().registryAccess(); - - // We only care about vanilla registries - registryAccess.registries().forEach(registryEntry -> { - if (registryEntry.key().identifier().getNamespace().equals("minecraft")) { - registryEntry.value().getTags().map(HolderSet.Named::key).forEach(tagKey -> { - // Grab tags under 'forge' namespace - if (LEGACY_FORGE_TAGS.containsKey(tagKey) || tagKey.location().getNamespace().equals("forge")) { - legacyTags.add(tagKey); - } - }); - } - }); - - if (!legacyTags.isEmpty()) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(""" - \n Dev warning - Legacy Tags detected. Please migrate your 'forge' namespace tags to the 'c' namespace! See net.neoforged.neoforge.common.Tags.java for all tags. - NOTE: Many tags have been moved around or renamed. Some new ones were added so please review the new tags. - And make sure you follow tag conventions for new tags! The convention is `c` with nouns generally being plural and adjectives being singular. - You can disable this message in NeoForge's common config by setting `logLegacyTagWarnings` to "SILENCED" or see individual tags with "DEV_VERBOSE". - """); - - // Print out all legacy tags when desired. - boolean isConfigSetToVerbose = legacyTagWarningMode == LogWarningMode.DEV_VERBOSE || - legacyTagWarningMode == LogWarningMode.PROD_VERBOSE; - - if (isConfigSetToVerbose) { - stringBuilder.append("\nLegacy tags:"); - for (TagKey tagKey : legacyTags) { - if (LEGACY_FORGE_TAGS.containsKey(tagKey)) { - String replacementMessage = LEGACY_FORGE_TAGS.get(tagKey); - stringBuilder.append("\n ").append(tagKey).append(" -> ").append(replacementMessage); - } else { - stringBuilder.append("\n ").append(tagKey).append(" -> ").append("See similar `c` tags in NeoForge's Tags class"); - } - } - } - - LOGGER.warn(stringBuilder); - } - } - } - }); - } - - private static AbstractMap.SimpleEntry, String> createForgeMapEntry(ResourceKey> registryKey, String tagId1, String tagId2) { - return new AbstractMap.SimpleEntry<>(createTagKey(registryKey, "forge", tagId1), "c:" + tagId2); - } - - private static AbstractMap.SimpleEntry, String> createForgeMapEntry(ResourceKey> registryKey, String tagId1, TagKey tag2) { - return new AbstractMap.SimpleEntry<>(createTagKey(registryKey, "forge", tagId1), tag2.toString()); - } - - private static AbstractMap.SimpleEntry, String> createMapEntry(ResourceKey> registryKey, String tagNamespace1, String tagId1, TagKey tag2) { - return new AbstractMap.SimpleEntry<>(createTagKey(registryKey, tagNamespace1, tagId1), tag2.toString()); - } - - private static AbstractMap.SimpleEntry, String> createMapEntry(ResourceKey> registryKey, String tagNamespace1, String tagId1, TagKey... replacementTags) { - return new AbstractMap.SimpleEntry<>(createTagKey(registryKey, tagNamespace1, tagId1), String.join(" and ", Arrays.stream(replacementTags).map(TagKey::toString).toList())); - } - - private static TagKey createTagKey(ResourceKey> registryKey, String namespace, String tagId) { - return TagKey.create(registryKey, Identifier.fromNamespaceAndPath(namespace, tagId)); - } -} diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index 435758cc08f..85103bcd0c9 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -901,15 +901,16 @@ public static class Items { */ public static final TagKey TOOLS_FISHING_ROD = tag("tools/fishing_rod"); /** - * A tag containing all existing spears. Other tools such as throwing knives or boomerangs - * should not be put into this tag and should be put into their own tool tags. + * A tag containing all existing throwable stick-like weapons like tridents. + * Other tools such as throwing knives or boomerangs should not be put into + * this tag and should be put into their own tool tags. * Do not use this tag for determining a tool's behavior. * Please use {@link ItemAbilities} instead for what action a tool can do. * * @see ItemAbility * @see ItemAbilities */ - public static final TagKey TOOLS_SPEAR = tag("tools/spear"); + public static final TagKey TOOLS_TRIDENT = tag("tools/trident"); /** * A tag containing all existing shears. Do not use this tag for determining a tool's behavior. * Please use {@link ItemAbilities} instead for what action a tool can do. diff --git a/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java b/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java deleted file mode 100644 index d9393a73ed0..00000000000 --- a/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common; - -import com.google.common.collect.ImmutableList; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import net.minecraft.core.HolderLookup; -import net.minecraft.core.NonNullList; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.entity.npc.villager.VillagerProfession; -import net.minecraft.world.entity.npc.villager.VillagerTrades; -import net.minecraft.world.entity.npc.villager.VillagerTrades.ItemListing; -import net.neoforged.neoforge.event.TagsUpdatedEvent; -import net.neoforged.neoforge.event.village.VillagerTradesEvent; -import net.neoforged.neoforge.event.village.WandererTradesEvent; -import org.apache.commons.lang3.tuple.Pair; - -public class VillagerTradingManager { - private static final Map, Int2ObjectMap> VANILLA_TRADES = new HashMap<>(); - private static final List> WANDERER_TRADES = new ArrayList<>(); - - static { - VillagerTrades.TRADES.entrySet().forEach(e -> { - Int2ObjectMap copy = new Int2ObjectOpenHashMap<>(); - e.getValue().int2ObjectEntrySet().forEach(ent -> copy.put(ent.getIntKey(), Arrays.copyOf(ent.getValue(), ent.getValue().length))); - VANILLA_TRADES.put(e.getKey(), copy); - }); - VillagerTrades.WANDERING_TRADER_TRADES.forEach(e -> WANDERER_TRADES.add(Pair.of(Arrays.copyOf(e.getLeft(), e.getLeft().length), e.getRight()))); - } - - static void loadTrades(TagsUpdatedEvent e) { - if (e.getUpdateCause() == TagsUpdatedEvent.UpdateCause.SERVER_DATA_LOAD) { - postWandererEvent(e.getLookupProvider()); - postVillagerEvents(e.getLookupProvider()); - } - } - - /** - * Posts the WandererTradesEvent. - */ - private static void postWandererEvent(HolderLookup.Provider registries) { - List buying = NonNullList.create(); - List rare = NonNullList.create(); - List generic = NonNullList.create(); - Arrays.stream(WANDERER_TRADES.get(0).getLeft()).forEach(buying::add); - Arrays.stream(WANDERER_TRADES.get(1).getLeft()).forEach(rare::add); - Arrays.stream(WANDERER_TRADES.get(2).getLeft()).forEach(generic::add); - int buyingAmount = WANDERER_TRADES.get(0).getRight(); - int rareAmount = WANDERER_TRADES.get(1).getRight(); - int genericAmount = WANDERER_TRADES.get(2).getRight(); - List, Integer>> additional = new ArrayList<>(); - - WandererTradesEvent event = new WandererTradesEvent(buying, buyingAmount, rare, rareAmount, generic, genericAmount, additional, registries); - NeoForge.EVENT_BUS.post(event); - - VillagerTrades.WANDERING_TRADER_TRADES = ImmutableList.>builder() - .add(Pair.of(buying.toArray(ItemListing[]::new), event.getBuyingAmount())) - .add(Pair.of(rare.toArray(ItemListing[]::new), event.getRareAmount())) - .add(Pair.of(generic.toArray(ItemListing[]::new), event.getGenericAmount())) - .addAll(additional.stream().map(pair -> Pair.of(pair.getLeft().toArray(ItemListing[]::new), pair.getRight())).toList()) - .build(); - } - - /** - * Posts a VillagerTradesEvent for each registered profession. - */ - private static void postVillagerEvents(HolderLookup.Provider registries) { - for (var entry : BuiltInRegistries.VILLAGER_PROFESSION.entrySet()) { - var prof = entry.getKey(); - Int2ObjectMap trades = VANILLA_TRADES.getOrDefault(prof, new Int2ObjectOpenHashMap<>()); - Int2ObjectMap> mutableTrades = new Int2ObjectOpenHashMap<>(); - for (int i = 1; i < 6; i++) { - mutableTrades.put(i, NonNullList.create()); - } - trades.int2ObjectEntrySet().forEach(e -> { - Arrays.stream(e.getValue()).forEach(mutableTrades.get(e.getIntKey())::add); - }); - NeoForge.EVENT_BUS.post(new VillagerTradesEvent(mutableTrades, prof, registries)); - Int2ObjectMap newTrades = new Int2ObjectOpenHashMap<>(); - mutableTrades.int2ObjectEntrySet().forEach(e -> newTrades.put(e.getIntKey(), e.getValue().toArray(new ItemListing[0]))); - VillagerTrades.TRADES.put(prof, newTrades); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/common/config/NeoForgeCommonConfig.java b/src/main/java/net/neoforged/neoforge/common/config/NeoForgeCommonConfig.java index a9df9a1614d..eb5f9a6c2de 100644 --- a/src/main/java/net/neoforged/neoforge/common/config/NeoForgeCommonConfig.java +++ b/src/main/java/net/neoforged/neoforge/common/config/NeoForgeCommonConfig.java @@ -6,7 +6,6 @@ package net.neoforged.neoforge.common.config; import net.neoforged.neoforge.common.ModConfigSpec; -import net.neoforged.neoforge.common.TagConventionLogWarning; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; @@ -18,23 +17,9 @@ public final class NeoForgeCommonConfig { public static final ModConfigSpec SPEC; public static final NeoForgeCommonConfig INSTANCE; - public final ModConfigSpec.EnumValue logUntranslatedItemTagWarnings; - - public final ModConfigSpec.EnumValue logLegacyTagWarnings; - public final ModConfigSpec.BooleanValue attributeAdvancedTooltipDebugInfo; private NeoForgeCommonConfig(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.") - .translation("neoforge.configgui.logUntranslatedItemTagWarnings") - .defineEnum("logUntranslatedItemTagWarnings", TagConventionLogWarning.LogWarningMode.SILENCED); - - logLegacyTagWarnings = builder - .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") diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/BlockTagIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/BlockTagIngredient.java index 6afb6fcc634..6570171f786 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/BlockTagIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/BlockTagIngredient.java @@ -68,7 +68,7 @@ public boolean test(@Nullable ItemStack stack) { if (stack == null) return false; - return dissolve().contains(stack.getItemHolder()); + return dissolve().contains(stack.typeHolder()); } public TagKey getTag() { diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/DataComponentIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/DataComponentIngredient.java index 0d96e9a9848..6aabf1fa1cd 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/DataComponentIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/DataComponentIngredient.java @@ -13,21 +13,23 @@ import java.util.stream.Stream; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; -import net.minecraft.core.component.DataComponentExactPredicate; +import net.minecraft.core.component.DataComponentGetter; import net.minecraft.core.component.DataComponentMap; +import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponentType; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.resources.HolderSetCodec; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.display.SlotDisplay; import net.minecraft.world.level.ItemLike; import net.neoforged.neoforge.common.NeoForgeMod; /** - * Ingredient that matches the given items, performing either a {@link DataComponentIngredient#isStrict() strict} or a partial NBT test. + * Ingredient that matches the given items, and components as defined by a {@link DataComponentPatch}. *

* Strict NBT ingredients will only match items that have exactly the provided tag, while partial ones will * match if the item's tags contain all of the elements of the provided one, while allowing for additional elements to exist. @@ -37,34 +39,45 @@ public class DataComponentIngredient implements ICustomIngredient { builder -> builder .group( HolderSetCodec.create(Registries.ITEM, BuiltInRegistries.ITEM.holderByNameCodec(), false).fieldOf("items").forGetter(DataComponentIngredient::itemSet), - DataComponentExactPredicate.CODEC.fieldOf("components").forGetter(DataComponentIngredient::components), - Codec.BOOL.optionalFieldOf("strict", false).forGetter(DataComponentIngredient::isStrict)) + DataComponentPatch.CODEC.fieldOf("components").forGetter(DataComponentIngredient::components), + Codec.BOOL.optionalFieldOf("strict", false).forGetter(DataComponentIngredient::componentsExhaustive)) .apply(builder, DataComponentIngredient::new)); private final HolderSet items; - private final DataComponentExactPredicate components; - private final boolean strict; - private final ItemStack[] stacks; + private final DataComponentPatch components; + private final boolean exhaustive; - public DataComponentIngredient(HolderSet items, DataComponentExactPredicate components, boolean strict) { + public DataComponentIngredient(HolderSet items, DataComponentPatch components, boolean exhaustive) { this.items = items; this.components = components; - this.strict = strict; - this.stacks = items.stream() - .map(i -> new ItemStack(i, 1, components.asPatch())) - .toArray(ItemStack[]::new); + this.exhaustive = exhaustive; } @Override public boolean test(ItemStack stack) { - if (strict) { - for (ItemStack stack2 : this.stacks) { - if (ItemStack.isSameItemSameComponents(stack, stack2)) return true; - } + if (!this.items.contains(stack.typeHolder()) || !testComponents(stack)) { return false; - } else { - return this.items.contains(stack.getItemHolder()) && this.components.test(stack); } + + if (exhaustive) { + for (var type : stack.getComponents().keySet()) { + if (components.getPatch(type) == null) { + return false; // Patch does not list the component + } + } + } + return true; + } + + private boolean testComponents(DataComponentGetter getter) { + for (var entry : components.entrySet()) { + var type = entry.getKey(); + var value = entry.getValue(); + if (value.isEmpty() && getter.has(type) || value.isPresent() && !value.get().equals(getter.get(type))) { + return false; // One of the patch entries doesn't match + } + } + return true; // Empty patch always matches } @Override @@ -84,11 +97,12 @@ public IngredientType getType() { @Override public SlotDisplay display() { - return new SlotDisplay.Composite(Stream.of(stacks) - .map(stack -> { - SlotDisplay display = new SlotDisplay.ItemStackSlotDisplay(stack); - ItemStack remainder = stack.getCraftingRemainder(); - if (!remainder.isEmpty()) { + return new SlotDisplay.Composite(items.stream() + .map(item -> { + var template = new ItemStackTemplate(item, 1, components); + var display = new SlotDisplay.ItemStackSlotDisplay(template); + var remainder = item.value().getCraftingRemainder(template); + if (remainder != null) { SlotDisplay remainderDisplay = new SlotDisplay.ItemStackSlotDisplay(remainder); return new SlotDisplay.WithRemainder(display, remainderDisplay); } else { @@ -102,76 +116,117 @@ public HolderSet itemSet() { return items; } - public DataComponentExactPredicate components() { + public DataComponentPatch components() { return components; } + /** + * {@return true if item stacks that have any component not listed in the components of this ingredient will fail to match} + */ + public boolean componentsExhaustive() { + return exhaustive; + } + + @Deprecated(forRemoval = true) public boolean isStrict() { - return strict; + return exhaustive; + } + + /** + * Creates a new ingredient matching the given item, containing the given components + */ + public static Ingredient of(boolean exhaustive, ItemStack stack) { + return of(exhaustive, stack.getComponents(), stack.getItem()); } /** * Creates a new ingredient matching the given item, containing the given components */ - public static Ingredient of(boolean strict, ItemStack stack) { - return of(strict, stack.getComponents(), stack.getItem()); + public static Ingredient of(boolean exhaustive, ItemStackTemplate stack) { + return of(exhaustive, stack.components(), stack.item()); + } + + /** + * Creates a new ingredient matching any item from the list, containing the given components + */ + public static Ingredient of(DataComponentType type, T value, ItemLike... items) { + return of(false, DataComponentPatch.builder().set(type, value).build(), items); } /** * Creates a new ingredient matching any item from the list, containing the given components */ - public static Ingredient of(boolean strict, DataComponentType type, T value, ItemLike... items) { - return of(strict, DataComponentExactPredicate.builder().expect(type, value).build(), items); + public static Ingredient of(boolean exhaustive, DataComponentType type, T value, ItemLike... items) { + return of(exhaustive, DataComponentPatch.builder().set(type, value).build(), items); } /** * Creates a new ingredient matching any item from the list, containing the given components */ - public static Ingredient of(boolean strict, Supplier> type, T value, ItemLike... items) { - return of(strict, type.get(), value, items); + public static Ingredient of(boolean exhaustive, Supplier> type, T value, ItemLike... items) { + return of(exhaustive, type.get(), value, items); } /** * Creates a new ingredient matching any item from the list, containing the given components */ - public static Ingredient of(boolean strict, DataComponentMap map, ItemLike... items) { - return of(strict, DataComponentExactPredicate.allOf(map), items); + public static Ingredient of(boolean exhaustive, DataComponentMap map, ItemLike... items) { + return of(exhaustive, asPatch(map), items); } /** * Creates a new ingredient matching any item from the list, containing the given components */ @SafeVarargs - public static Ingredient of(boolean strict, DataComponentMap map, Holder... items) { - return of(strict, DataComponentExactPredicate.allOf(map), items); + public static Ingredient of(boolean exhaustive, DataComponentMap map, Holder... items) { + return of(exhaustive, asPatch(map), items); } /** * Creates a new ingredient matching any item from the list, containing the given components */ - public static Ingredient of(boolean strict, DataComponentMap map, HolderSet items) { - return of(strict, DataComponentExactPredicate.allOf(map), items); + public static Ingredient of(boolean exhaustive, DataComponentMap map, HolderSet items) { + return of(exhaustive, asPatch(map), items); + } + + private static DataComponentPatch asPatch(DataComponentMap map) { + var builder = DataComponentPatch.builder(); + for (var type : map) { + builder.set(type); + } + return builder.build(); } /** * Creates a new ingredient matching any item from the list, containing the given components */ @SafeVarargs - public static Ingredient of(boolean strict, DataComponentExactPredicate predicate, Holder... items) { - return of(strict, predicate, HolderSet.direct(items)); + public static Ingredient of(boolean exhaustive, DataComponentPatch predicate, Holder... items) { + return of(exhaustive, predicate, HolderSet.direct(items)); } /** - * Creates a new ingredient matching any item from the list, containing the given components + * Creates a new ingredient matching any item from the list, that contains the components set on the given patch + * and that does not contain the components removed by the given patch. + */ + public static Ingredient of(DataComponentPatch predicate, ItemLike... items) { + return of(false, predicate, HolderSet.direct(Arrays.stream(items).map(ItemLike::asItem).map(Item::builtInRegistryHolder).toList())); + } + + /** + * Creates a new ingredient matching any item from the list, that contains the components set on the given patch + * and that does not contain the components removed by the given patch. + * + * @param exhaustive If true, no other components besides the components set on the patch are allowed on an item to match. */ - public static Ingredient of(boolean strict, DataComponentExactPredicate predicate, ItemLike... items) { - return of(strict, predicate, HolderSet.direct(Arrays.stream(items).map(ItemLike::asItem).map(Item::builtInRegistryHolder).toList())); + public static Ingredient of(boolean exhaustive, DataComponentPatch predicate, ItemLike... items) { + return of(exhaustive, predicate, HolderSet.direct(Arrays.stream(items).map(ItemLike::asItem).map(Item::builtInRegistryHolder).toList())); } /** * Creates a new ingredient matching any item from the list, containing the given components */ - public static Ingredient of(boolean strict, DataComponentExactPredicate predicate, HolderSet items) { - return new DataComponentIngredient(items, predicate, strict).toVanilla(); + public static Ingredient of(boolean exhaustive, DataComponentPatch predicate, HolderSet items) { + return new DataComponentIngredient(items, predicate, exhaustive).toVanilla(); } } diff --git a/src/main/java/net/neoforged/neoforge/common/damagesource/DamageContainer.java b/src/main/java/net/neoforged/neoforge/common/damagesource/DamageContainer.java index fc1659e1217..ac3750b271f 100644 --- a/src/main/java/net/neoforged/neoforge/common/damagesource/DamageContainer.java +++ b/src/main/java/net/neoforged/neoforge/common/damagesource/DamageContainer.java @@ -95,7 +95,7 @@ public float getNewDamage() { * Adds a callback modifier to the vanilla damage reductions. Each function will be performed in sequence * on the vanilla value at the time the {@link DamageContainer.Reduction} type is set by vanilla. *

    - *
  • only the {@link LivingIncomingDamageEvent EntityPreDamageEvent} + *
  • only the {@link LivingIncomingDamageEvent} * happens early enough in the sequence for this method to have any effect.
  • *
  • if the vanilla reduction is not triggered, the reduction function will not execute.
  • *
diff --git a/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java index 09759fff568..4bc950cc075 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java @@ -5,7 +5,10 @@ package net.neoforged.neoforge.common.data; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; import java.nio.file.Path; import java.util.Map; import java.util.TreeMap; @@ -14,6 +17,8 @@ import net.minecraft.data.CachedOutput; import net.minecraft.data.DataProvider; import net.minecraft.data.PackOutput; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; import net.minecraft.world.effect.MobEffect; @@ -27,7 +32,9 @@ import net.neoforged.neoforge.common.extensions.ILevelExtension; public abstract class LanguageProvider implements DataProvider { - private final Map data = new TreeMap<>(); + private static final Codec> CODEC = Codec.unboundedMap(Codec.STRING, ComponentSerialization.CODEC); + + private final Map data = new TreeMap<>(); private final PackOutput output; private final String modid; private final String locale; @@ -56,9 +63,7 @@ public String getName() { } private CompletableFuture save(CachedOutput cache, Path target) { - JsonObject json = new JsonObject(); - this.data.forEach(json::addProperty); - + final JsonElement json = CODEC.encode(this.data, JsonOps.INSTANCE, new JsonObject()).getOrThrow(); return DataProvider.saveStable(cache, json, target); } @@ -111,8 +116,13 @@ public void add(TagKey tagKey, String name) { } public void add(String key, String value) { - if (data.put(key, value) != null) + add(key, Component.literal(value)); // Literals are serialized as strings directly by the codec + } + + public void add(String key, Component value) { + if (data.put(key, value) != null) { throw new IllegalStateException("Duplicate translation key " + key); + } } public void addDimension(ResourceKey dimension, String value) { diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeAdvancementProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeAdvancementProvider.java index 7f52c589f64..50ea1140afc 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeAdvancementProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeAdvancementProvider.java @@ -379,7 +379,7 @@ public EntityPredicateReplacementHelper(EntityPredicate source) { } public boolean clearTypeIfMatches(EntityType type) { - if (entityType.isPresent() && entityType.get().matches(type)) { + if (entityType.isPresent() && entityType.get().matches(type.builtInRegistryHolder())) { entityType = Optional.empty(); return true; } diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBiomeTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBiomeTagsProvider.java index 1b012fd59d6..7c3879c81d4 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBiomeTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBiomeTagsProvider.java @@ -7,11 +7,8 @@ import java.util.concurrent.CompletableFuture; import net.minecraft.core.HolderLookup; -import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; import net.minecraft.data.tags.BiomeTagsProvider; -import net.minecraft.data.tags.TagAppender; -import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.BiomeTags; import net.minecraft.tags.TagKey; @@ -249,10 +246,12 @@ protected void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Biomes.IS_OLD_GROWTH).add(Biomes.OLD_GROWTH_BIRCH_FOREST, Biomes.OLD_GROWTH_PINE_TAIGA, Biomes.OLD_GROWTH_SPRUCE_TAIGA); tag(Tags.Biomes.IS_LUSH).add(Biomes.LUSH_CAVES); tag(Tags.Biomes.IS_SANDY).add(Biomes.DESERT, Biomes.BADLANDS, Biomes.WOODED_BADLANDS, Biomes.ERODED_BADLANDS, Biomes.BEACH); + tag(Tags.Biomes.IS_MAGICAL); tag(Tags.Biomes.IS_MUSHROOM).add(Biomes.MUSHROOM_FIELDS); tag(Tags.Biomes.IS_PLATEAU).add(Biomes.WOODED_BADLANDS, Biomes.SAVANNA_PLATEAU, Biomes.CHERRY_GROVE, Biomes.MEADOW); tag(Tags.Biomes.IS_SPOOKY).add(Biomes.DARK_FOREST, Biomes.PALE_GARDEN, Biomes.DEEP_DARK); tag(Tags.Biomes.IS_WASTELAND); + tag(Tags.Biomes.IS_DEAD); tag(Tags.Biomes.IS_RARE).add(Biomes.SUNFLOWER_PLAINS, Biomes.FLOWER_FOREST, Biomes.OLD_GROWTH_BIRCH_FOREST, Biomes.OLD_GROWTH_SPRUCE_TAIGA, Biomes.BAMBOO_JUNGLE, Biomes.SPARSE_JUNGLE, Biomes.ERODED_BADLANDS, Biomes.SAVANNA_PLATEAU, Biomes.WINDSWEPT_SAVANNA, Biomes.ICE_SPIKES, Biomes.WINDSWEPT_GRAVELLY_HILLS, Biomes.PALE_GARDEN, Biomes.MUSHROOM_FIELDS, Biomes.DEEP_DARK); tag(Tags.Biomes.IS_RIVER).addTags(BiomeTags.IS_RIVER); @@ -267,61 +266,6 @@ protected void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Biomes.IS_NETHER_FOREST).add(Biomes.CRIMSON_FOREST, Biomes.WARPED_FOREST); tag(Tags.Biomes.IS_OUTER_END_ISLAND).add(Biomes.END_HIGHLANDS, Biomes.END_MIDLANDS, Biomes.END_BARRENS); - - // 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 - tag(Tags.Biomes.IS_MOUNTAIN_SLOPE).addOptionalTag(forge("is_slope")); - tag(Tags.Biomes.IS_MOUNTAIN_PEAK).addOptionalTag(forge("is_peak")); - tagWithOptionalLegacy(Tags.Biomes.IS_MOUNTAIN); - tagWithOptionalLegacy(Tags.Biomes.IS_HOT_OVERWORLD); - tagWithOptionalLegacy(Tags.Biomes.IS_HOT_NETHER); - tagWithOptionalLegacy(Tags.Biomes.IS_HOT_END); - tagWithOptionalLegacy(Tags.Biomes.IS_HOT); - tagWithOptionalLegacy(Tags.Biomes.IS_COLD_OVERWORLD); - tagWithOptionalLegacy(Tags.Biomes.IS_COLD_NETHER); - tagWithOptionalLegacy(Tags.Biomes.IS_COLD_END); - tagWithOptionalLegacy(Tags.Biomes.IS_COLD); - tagWithOptionalLegacy(Tags.Biomes.IS_SPARSE_VEGETATION_OVERWORLD); - tagWithOptionalLegacy(Tags.Biomes.IS_SPARSE_VEGETATION_NETHER); - tagWithOptionalLegacy(Tags.Biomes.IS_SPARSE_VEGETATION_END); - tagWithOptionalLegacy(Tags.Biomes.IS_SPARSE_VEGETATION); - tag(Tags.Biomes.IS_SPARSE_VEGETATION_OVERWORLD).addOptionalTag(forge("is_sparse/overworld")); - tag(Tags.Biomes.IS_SPARSE_VEGETATION_NETHER).addOptionalTag(forge("is_sparse/nether")); - tag(Tags.Biomes.IS_SPARSE_VEGETATION_END).addOptionalTag(forge("is_sparse/end")); - tag(Tags.Biomes.IS_SPARSE_VEGETATION).addOptionalTag(forge("is_sparse")); - tag(Tags.Biomes.IS_DENSE_VEGETATION_OVERWORLD).addOptionalTag(forge("is_dense/overworld")); - tag(Tags.Biomes.IS_DENSE_VEGETATION_NETHER).addOptionalTag(forge("is_dense/nether")); - tag(Tags.Biomes.IS_DENSE_VEGETATION_END).addOptionalTag(forge("is_dense/end")); - tag(Tags.Biomes.IS_DENSE_VEGETATION).addOptionalTag(forge("is_dense")); - tagWithOptionalLegacy(Tags.Biomes.IS_WET_OVERWORLD); - tagWithOptionalLegacy(Tags.Biomes.IS_WET_NETHER); - tagWithOptionalLegacy(Tags.Biomes.IS_WET_END); - tagWithOptionalLegacy(Tags.Biomes.IS_WET); - tagWithOptionalLegacy(Tags.Biomes.IS_DRY_OVERWORLD); - tagWithOptionalLegacy(Tags.Biomes.IS_DRY_NETHER); - tagWithOptionalLegacy(Tags.Biomes.IS_DRY_END); - tagWithOptionalLegacy(Tags.Biomes.IS_DRY); - tagWithOptionalLegacy(Tags.Biomes.IS_CONIFEROUS_TREE); - tagWithOptionalLegacy(Tags.Biomes.IS_SPOOKY); - tagWithOptionalLegacy(Tags.Biomes.IS_DEAD); - tagWithOptionalLegacy(Tags.Biomes.IS_LUSH); - tagWithOptionalLegacy(Tags.Biomes.IS_MUSHROOM); - tagWithOptionalLegacy(Tags.Biomes.IS_MAGICAL); - tagWithOptionalLegacy(Tags.Biomes.IS_RARE); - tagWithOptionalLegacy(Tags.Biomes.IS_PLATEAU); - tagWithOptionalLegacy(Tags.Biomes.IS_FLORAL); - tag(Tags.Biomes.IS_AQUATIC).addOptionalTag(forge("is_water")); - tagWithOptionalLegacy(Tags.Biomes.IS_DESERT); - tagWithOptionalLegacy(Tags.Biomes.IS_PLAINS); - tagWithOptionalLegacy(Tags.Biomes.IS_SWAMP); - tagWithOptionalLegacy(Tags.Biomes.IS_SANDY); - tagWithOptionalLegacy(Tags.Biomes.IS_SNOWY); - tagWithOptionalLegacy(Tags.Biomes.IS_WASTELAND); - tagWithOptionalLegacy(Tags.Biomes.IS_VOID); - tagWithOptionalLegacy(Tags.Biomes.IS_CAVE); - tagWithOptionalLegacy(Tags.Biomes.IS_END); - tagWithOptionalLegacy(Tags.Biomes.IS_NETHER); - tagWithOptionalLegacy(Tags.Biomes.IS_OVERWORLD); } @SafeVarargs @@ -331,14 +275,6 @@ private void tag(ResourceKey biome, TagKey... tags) { } } - private TagAppender, Biome> tagWithOptionalLegacy(TagKey tag) { - return tag(tag).addOptionalTag(forge(tag.location().getPath())); - } - - private TagKey forge(String id) { - return TagKey.create(Registries.BIOME, Identifier.fromNamespaceAndPath("forge", id)); - } - @Override public String getName() { return "NeoForge Biome Tags"; 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 abdea9cd6c1..6d48c653d7a 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 @@ -10,9 +10,7 @@ import java.util.function.Consumer; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; -import net.minecraft.data.tags.TagAppender; import net.minecraft.resources.Identifier; import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; @@ -188,134 +186,6 @@ public void addTags(HolderLookup.Provider registries) { 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); - tagWithOptionalLegacy(Tags.Blocks.BARRELS_WOODEN); - tagWithOptionalLegacy(Tags.Blocks.BOOKSHELVES); - tagWithOptionalLegacy(Tags.Blocks.CHESTS); - tagWithOptionalLegacy(Tags.Blocks.CHESTS_ENDER); - tagWithOptionalLegacy(Tags.Blocks.CHESTS_TRAPPED); - tagWithOptionalLegacy(Tags.Blocks.CHESTS_WOODEN); - tag(Tags.Blocks.COBBLESTONES).addOptionalTag(forge("cobblestone")); - tag(Tags.Blocks.COBBLESTONES_NORMAL).addOptionalTag(forge("cobblestone/normal")); - tag(Tags.Blocks.COBBLESTONES_INFESTED).addOptionalTag(forge("cobblestone/infested")); - tag(Tags.Blocks.COBBLESTONES_MOSSY).addOptionalTag(forge("cobblestone/mossy")); - tag(Tags.Blocks.COBBLESTONES_DEEPSLATE).addOptionalTag(forge("cobblestone/deepslate")); - tag(Tags.Blocks.DYED_BLACK) - .addOptionalTag(forge("glass/black")) - .addOptionalTag(forge("stained_glass/black")); - tag(Tags.Blocks.DYED_BLUE) - .addOptionalTag(forge("glass/blue")) - .addOptionalTag(forge("stained_glass/blue")); - tag(Tags.Blocks.DYED_BROWN) - .addOptionalTag(forge("glass/brown")) - .addOptionalTag(forge("stained_glass/brown")); - tag(Tags.Blocks.DYED_CYAN) - .addOptionalTag(forge("glass/cyan")) - .addOptionalTag(forge("stained_glass/cyan")); - tag(Tags.Blocks.DYED_GRAY) - .addOptionalTag(forge("glass/gray")) - .addOptionalTag(forge("stained_glass/gray")); - tag(Tags.Blocks.DYED_GREEN) - .addOptionalTag(forge("glass/green")) - .addOptionalTag(forge("stained_glass/green")); - tag(Tags.Blocks.DYED_LIGHT_BLUE) - .addOptionalTag(forge("glass/light_blue")) - .addOptionalTag(forge("stained_glass/light_blue")); - tag(Tags.Blocks.DYED_LIGHT_GRAY) - .addOptionalTag(forge("glass/light_gray")) - .addOptionalTag(forge("stained_glass/light_gray")); - tag(Tags.Blocks.DYED_LIME) - .addOptionalTag(forge("glass/lime")) - .addOptionalTag(forge("stained_glass/lime")); - tag(Tags.Blocks.DYED_MAGENTA) - .addOptionalTag(forge("glass/magenta")) - .addOptionalTag(forge("stained_glass/magenta")); - tag(Tags.Blocks.DYED_MAGENTA) - .addOptionalTag(forge("glass/magenta")) - .addOptionalTag(forge("stained_glass/magenta")); - tag(Tags.Blocks.DYED_ORANGE) - .addOptionalTag(forge("glass/orange")) - .addOptionalTag(forge("stained_glass/orange")); - tag(Tags.Blocks.DYED_PINK) - .addOptionalTag(forge("glass/pink")) - .addOptionalTag(forge("stained_glass/pink")); - tag(Tags.Blocks.DYED_PURPLE) - .addOptionalTag(forge("glass/purple")) - .addOptionalTag(forge("stained_glass/purple")); - tag(Tags.Blocks.DYED_RED) - .addOptionalTag(forge("glass/red")) - .addOptionalTag(forge("stained_glass/red")); - tag(Tags.Blocks.DYED_WHITE) - .addOptionalTag(forge("glass/white")) - .addOptionalTag(forge("stained_glass/white")); - tag(Tags.Blocks.DYED_YELLOW) - .addOptionalTag(forge("glass/yellow")) - .addOptionalTag(forge("stained_glass/yellow")); - tagWithOptionalLegacy(Tags.Blocks.END_STONES); - tagWithOptionalLegacy(Tags.Blocks.ENDERMAN_PLACE_ON_BLACKLIST); - tagWithOptionalLegacy(Tags.Blocks.FENCE_GATES); - tagWithOptionalLegacy(Tags.Blocks.FENCE_GATES_WOODEN); - tagWithOptionalLegacy(Tags.Blocks.FENCES); - tagWithOptionalLegacy(Tags.Blocks.FENCES_NETHER_BRICK); - tagWithOptionalLegacy(Tags.Blocks.FENCES_WOODEN); - tag(Tags.Blocks.GRAVELS).addOptionalTag(forge("gravel")); - tag(Tags.Blocks.GLASS_BLOCKS).addOptionalTag(forge("glass")); - tag(Tags.Blocks.GLASS_BLOCKS_COLORLESS).addOptionalTag(forge("glass_colorless")); - tag(Tags.Blocks.GLASS_BLOCKS_CHEAP).addOptionalTag(forge("glass_silica")); - tag(Tags.Blocks.GLASS_BLOCKS_TINTED).addOptionalTag(forge("glass_tinted")); - tag(Tags.Blocks.GLASS_PANES_COLORLESS).addOptionalTag(forge("glass_panes_colorless")); - tag(Tags.Blocks.NETHERRACKS).addOptionalTag(forge("netherrack")); - tag(Tags.Blocks.OBSIDIANS).addOptionalTag(forge("obsidian")); - tagWithOptionalLegacy(Tags.Blocks.ORE_BEARING_GROUND_DEEPSLATE); - tagWithOptionalLegacy(Tags.Blocks.ORE_BEARING_GROUND_NETHERRACK); - tagWithOptionalLegacy(Tags.Blocks.ORE_BEARING_GROUND_STONE); - tagWithOptionalLegacy(Tags.Blocks.ORE_RATES_DENSE); - tagWithOptionalLegacy(Tags.Blocks.ORE_RATES_SINGULAR); - tagWithOptionalLegacy(Tags.Blocks.ORE_RATES_SPARSE); - tagWithOptionalLegacy(Tags.Blocks.ORES); - tagWithOptionalLegacy(Tags.Blocks.ORES_COAL); - tagWithOptionalLegacy(Tags.Blocks.ORES_COPPER); - tagWithOptionalLegacy(Tags.Blocks.ORES_DIAMOND); - tagWithOptionalLegacy(Tags.Blocks.ORES_EMERALD); - tagWithOptionalLegacy(Tags.Blocks.ORES_GOLD); - tagWithOptionalLegacy(Tags.Blocks.ORES_IRON); - tagWithOptionalLegacy(Tags.Blocks.ORES_LAPIS); - tagWithOptionalLegacy(Tags.Blocks.ORES_QUARTZ); - tagWithOptionalLegacy(Tags.Blocks.ORES_REDSTONE); - tagWithOptionalLegacy(Tags.Blocks.ORES_NETHERITE_SCRAP); - tagWithOptionalLegacy(Tags.Blocks.ORES_IN_GROUND_DEEPSLATE); - tagWithOptionalLegacy(Tags.Blocks.ORES_IN_GROUND_NETHERRACK); - tagWithOptionalLegacy(Tags.Blocks.ORES_IN_GROUND_STONE); - tag(Tags.Blocks.STONES).addOptionalTag(forge("stone")); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_COAL); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_COPPER); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_DIAMOND); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_EMERALD); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_GOLD); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_IRON); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_LAPIS); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_RAW_COPPER); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_RAW_GOLD); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_RAW_IRON); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_REDSTONE); - tagWithOptionalLegacy(Tags.Blocks.STORAGE_BLOCKS_NETHERITE); - tag(Tags.Blocks.RELOCATION_NOT_SUPPORTED) - .addOptionalTag(forge("relocation_not_supported")) - .addOptionalTag(forge("immovable")); - tag(Tags.Blocks.SANDSTONE_BLOCKS).addOptionalTag(forge("sandstone")); - tag(Tags.Blocks.SANDS).addOptionalTag(forge("sand")); - tag(Tags.Blocks.SANDS_COLORLESS).addOptionalTag(forge("sand/colorless")); - tag(Tags.Blocks.SANDS_RED).addOptionalTag(forge("sand/red")); - } - - private TagAppender tagWithOptionalLegacy(TagKey tag) { - TagAppender tagAppender = tag(tag); - tagAppender.addOptionalTag(forge(tag.location().getPath())); - return tagAppender; } private void addColored(TagKey group, String pattern) { @@ -347,8 +217,4 @@ private TagKey getForgeTag(String name) { throw new IllegalStateException(Tags.Blocks.class.getName() + " is missing tag name: " + name); } } - - private TagKey forge(String id) { - return TagKey.create(Registries.BLOCK, Identifier.fromNamespaceAndPath("forge", id)); - } } diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDamageTypeTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDamageTypeTagsProvider.java index c5eb1b8a3f5..2705186450e 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDamageTypeTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDamageTypeTagsProvider.java @@ -107,16 +107,6 @@ protected void addTags(HolderLookup.Provider lookupProvider) { tag(DamageTypes.OUTSIDE_BORDER, Tags.DamageTypes.IS_TECHNICAL); tag(DamageTypes.FELL_OUT_OF_WORLD, Tags.DamageTypes.IS_TECHNICAL); tag(Tags.DamageTypes.NO_FLINCH); - - // 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.DamageTypes.IS_POISON); - tagWithOptionalLegacy(Tags.DamageTypes.IS_WITHER); - tagWithOptionalLegacy(Tags.DamageTypes.IS_MAGIC); - tagWithOptionalLegacy(Tags.DamageTypes.IS_ENVIRONMENT); - tagWithOptionalLegacy(Tags.DamageTypes.IS_PHYSICAL); - tagWithOptionalLegacy(Tags.DamageTypes.IS_TECHNICAL); - tagWithOptionalLegacy(Tags.DamageTypes.NO_FLINCH); } /** {@return an appender for vanilla tags that contain the given entry directly} */ diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeEntityTypeTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeEntityTypeTagsProvider.java index b48409e7ca8..a6655ce9a05 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeEntityTypeTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeEntityTypeTagsProvider.java @@ -7,12 +7,9 @@ import java.util.concurrent.CompletableFuture; import net.minecraft.core.HolderLookup; -import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; import net.minecraft.data.tags.EntityTypeTagsProvider; -import net.minecraft.resources.Identifier; import net.minecraft.tags.EntityTypeTags; -import net.minecraft.tags.TagKey; import net.minecraft.world.entity.EntityType; import net.neoforged.neoforge.common.Tags; @@ -39,15 +36,5 @@ public void addTags(HolderLookup.Provider lookupProvider) { EntityType.BAMBOO_CHEST_RAFT); tag(Tags.EntityTypes.CAPTURING_NOT_SUPPORTED); tag(Tags.EntityTypes.TELEPORTING_NOT_SUPPORTED); - - // 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 - tag(Tags.EntityTypes.BOSSES).addOptionalTag(forge("bosses")); - tag(Tags.EntityTypes.MINECARTS).addOptionalTag(forge("minecarts")); - tag(Tags.EntityTypes.BOATS).addOptionalTag(forge("boats")); - } - - private TagKey> forge(String id) { - return TagKey.create(Registries.ENTITY_TYPE, Identifier.fromNamespaceAndPath("forge", id)); } } diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeFluidTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeFluidTagsProvider.java index d90a036db4f..f177e9ef177 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeFluidTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeFluidTagsProvider.java @@ -36,17 +36,6 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Fluids.RABBIT_STEW); tag(Fluids.BEETROOT_SOUP); tag(Fluids.HIDDEN_FROM_RECIPE_VIEWERS); - - // 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(Fluids.MILK); - tagWithOptionalLegacy(Fluids.GASEOUS); - tagWithOptionalLegacy(Fluids.HONEY); - tagWithOptionalLegacy(Fluids.POTION); - tagWithOptionalLegacy(Fluids.SUSPICIOUS_STEW); - tagWithOptionalLegacy(Fluids.MUSHROOM_STEW); - tagWithOptionalLegacy(Fluids.RABBIT_STEW); - tagWithOptionalLegacy(Fluids.BEETROOT_SOUP); } private TagAppender tagWithOptionalLegacy(TagKey tag) { 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 0fcd96eaec9..1a5063e91fb 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 @@ -10,9 +10,7 @@ import java.util.function.Consumer; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; -import net.minecraft.data.tags.TagAppender; import net.minecraft.resources.Identifier; import net.minecraft.tags.ItemTags; import net.minecraft.tags.TagKey; @@ -299,19 +297,20 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Items.TOOLS_CROSSBOW).add(Items.CROSSBOW); tag(Tags.Items.TOOLS_FISHING_ROD).add(Items.FISHING_ROD); tag(Tags.Items.TOOLS_SHEAR).add(Items.SHEARS); - tag(Tags.Items.TOOLS_SPEAR).add(Items.TRIDENT); + tag(Tags.Items.TOOLS_TRIDENT).add(Items.TRIDENT); tag(Tags.Items.TOOLS_IGNITER).add(Items.FLINT_AND_STEEL); tag(Tags.Items.TOOLS_WRENCH); tag(Tags.Items.MINING_TOOL_TOOLS).add(Items.WOODEN_PICKAXE, Items.STONE_PICKAXE, Items.COPPER_PICKAXE, Items.GOLDEN_PICKAXE, Items.IRON_PICKAXE, Items.DIAMOND_PICKAXE, Items.NETHERITE_PICKAXE); tag(Tags.Items.MELEE_WEAPON_TOOLS).add( Items.MACE, Items.TRIDENT, Items.WOODEN_SWORD, Items.STONE_SWORD, Items.COPPER_SWORD, Items.GOLDEN_SWORD, Items.IRON_SWORD, Items.DIAMOND_SWORD, Items.NETHERITE_SWORD, - Items.WOODEN_AXE, Items.STONE_AXE, Items.COPPER_AXE, Items.GOLDEN_AXE, Items.IRON_AXE, Items.DIAMOND_AXE, Items.NETHERITE_AXE); + Items.WOODEN_AXE, Items.STONE_AXE, Items.COPPER_AXE, Items.GOLDEN_AXE, Items.IRON_AXE, Items.DIAMOND_AXE, Items.NETHERITE_AXE, + Items.WOODEN_SPEAR, Items.STONE_SPEAR, Items.COPPER_SPEAR, Items.IRON_SPEAR, Items.GOLDEN_SPEAR, Items.DIAMOND_SPEAR, Items.NETHERITE_SPEAR); tag(Tags.Items.RANGED_WEAPON_TOOLS).add(Items.BOW, Items.CROSSBOW, Items.TRIDENT); tag(Tags.Items.TOOLS) - .addTags(ItemTags.AXES, ItemTags.HOES, ItemTags.PICKAXES, ItemTags.SHOVELS, ItemTags.SWORDS) + .addTags(ItemTags.AXES, ItemTags.HOES, ItemTags.PICKAXES, ItemTags.SHOVELS, ItemTags.SPEARS, ItemTags.SWORDS) .addTags(Tags.Items.TOOLS_BOW, Tags.Items.TOOLS_BRUSH, Tags.Items.TOOLS_CROSSBOW, Tags.Items.TOOLS_FISHING_ROD, - Tags.Items.TOOLS_IGNITER, Tags.Items.TOOLS_SHEAR, Tags.Items.TOOLS_SHIELD, Tags.Items.TOOLS_SPEAR, + Tags.Items.TOOLS_IGNITER, Tags.Items.TOOLS_SHEAR, Tags.Items.TOOLS_SHIELD, Tags.Items.TOOLS_TRIDENT, Tags.Items.TOOLS_MACE, Tags.Items.TOOLS_WRENCH, Tags.Items.MINING_TOOL_TOOLS, Tags.Items.MELEE_WEAPON_TOOLS, Tags.Items.RANGED_WEAPON_TOOLS); tag(Tags.Items.ARMORS) @@ -342,151 +341,6 @@ public void addTags(HolderLookup.Provider lookupProvider) { .addTags(ItemTags.HEAD_ARMOR, ItemTags.CHEST_ARMOR, ItemTags.LEG_ARMOR, ItemTags.FOOT_ARMOR); tag(Tags.Items.ENCHANTABLES).addTags(ItemTags.ARMOR_ENCHANTABLE, ItemTags.EQUIPPABLE_ENCHANTABLE, ItemTags.WEAPON_ENCHANTABLE, ItemTags.MELEE_WEAPON_ENCHANTABLE, ItemTags.SHARP_WEAPON_ENCHANTABLE, ItemTags.SWEEPING_ENCHANTABLE, ItemTags.MINING_ENCHANTABLE, ItemTags.MINING_LOOT_ENCHANTABLE, ItemTags.FISHING_ENCHANTABLE, ItemTags.TRIDENT_ENCHANTABLE, ItemTags.BOW_ENCHANTABLE, ItemTags.CROSSBOW_ENCHANTABLE, ItemTags.MACE_ENCHANTABLE, ItemTags.FIRE_ASPECT_ENCHANTABLE, ItemTags.DURABILITY_ENCHANTABLE, ItemTags.VANISHING_ENCHANTABLE); - - // 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.Items.BONES); - tag(Tags.Items.BRICKS_NORMAL).addOptionalTag(forge("ingots/brick")); - tag(Tags.Items.BRICKS_NETHER).addOptionalTag(forge("ingots/nether_brick")); - tagWithOptionalLegacy(Tags.Items.CROPS); - tagWithOptionalLegacy(Tags.Items.CROPS_BEETROOT); - tagWithOptionalLegacy(Tags.Items.CROPS_CARROT); - tagWithOptionalLegacy(Tags.Items.CROPS_NETHER_WART); - tagWithOptionalLegacy(Tags.Items.CROPS_POTATO); - tagWithOptionalLegacy(Tags.Items.CROPS_WHEAT); - tagWithOptionalLegacy(Tags.Items.DUSTS); - tagWithOptionalLegacy(Tags.Items.DUSTS_GLOWSTONE); - tagWithOptionalLegacy(Tags.Items.DUSTS_REDSTONE); - tagColoredWithOptionalLegacy(Tags.Items.DYES); - tag(Tags.Items.DYED_BLACK) - .addOptionalTag(forge("glass/black")) - .addOptionalTag(forge("stained_glass/black")); - tag(Tags.Items.DYED_BLUE) - .addOptionalTag(forge("glass/blue")) - .addOptionalTag(forge("stained_glass/blue")); - tag(Tags.Items.DYED_BROWN) - .addOptionalTag(forge("glass/brown")) - .addOptionalTag(forge("stained_glass/brown")); - tag(Tags.Items.DYED_CYAN) - .addOptionalTag(forge("glass/cyan")) - .addOptionalTag(forge("stained_glass/cyan")); - tag(Tags.Items.DYED_GRAY) - .addOptionalTag(forge("glass/gray")) - .addOptionalTag(forge("stained_glass/gray")); - tag(Tags.Items.DYED_GREEN) - .addOptionalTag(forge("glass/green")) - .addOptionalTag(forge("stained_glass/green")); - tag(Tags.Items.DYED_LIGHT_BLUE) - .addOptionalTag(forge("glass/light_blue")) - .addOptionalTag(forge("stained_glass/light_blue")); - tag(Tags.Items.DYED_LIGHT_GRAY) - .addOptionalTag(forge("glass/light_gray")) - .addOptionalTag(forge("stained_glass/light_gray")); - tag(Tags.Items.DYED_LIME) - .addOptionalTag(forge("glass/lime")) - .addOptionalTag(forge("stained_glass/lime")); - tag(Tags.Items.DYED_MAGENTA) - .addOptionalTag(forge("glass/magenta")) - .addOptionalTag(forge("stained_glass/magenta")); - tag(Tags.Items.DYED_MAGENTA) - .addOptionalTag(forge("glass/magenta")) - .addOptionalTag(forge("stained_glass/magenta")); - tag(Tags.Items.DYED_ORANGE) - .addOptionalTag(forge("glass/orange")) - .addOptionalTag(forge("stained_glass/orange")); - tag(Tags.Items.DYED_PINK) - .addOptionalTag(forge("glass/pink")) - .addOptionalTag(forge("stained_glass/pink")); - tag(Tags.Items.DYED_PURPLE) - .addOptionalTag(forge("glass/purple")) - .addOptionalTag(forge("stained_glass/purple")); - tag(Tags.Items.DYED_RED) - .addOptionalTag(forge("glass/red")) - .addOptionalTag(forge("stained_glass/red")); - tag(Tags.Items.DYED_WHITE) - .addOptionalTag(forge("glass/white")) - .addOptionalTag(forge("stained_glass/white")); - tag(Tags.Items.DYED_YELLOW) - .addOptionalTag(forge("glass/yellow")) - .addOptionalTag(forge("stained_glass/yellow")); - tagWithOptionalLegacy(Tags.Items.ENDER_PEARLS); - tagWithOptionalLegacy(Tags.Items.FEATHERS); - tagWithOptionalLegacy(Tags.Items.GEMS); - tagWithOptionalLegacy(Tags.Items.GEMS_AMETHYST); - tagWithOptionalLegacy(Tags.Items.GEMS_DIAMOND); - tagWithOptionalLegacy(Tags.Items.GEMS_EMERALD); - tagWithOptionalLegacy(Tags.Items.GEMS_LAPIS); - tagWithOptionalLegacy(Tags.Items.GEMS_PRISMARINE); - tagWithOptionalLegacy(Tags.Items.GEMS_QUARTZ); - tag(Tags.Items.GUNPOWDERS).addOptionalTag(forge("gunpowder")); - tagWithOptionalLegacy(Tags.Items.INGOTS); - tagWithOptionalLegacy(Tags.Items.INGOTS_COPPER); - tagWithOptionalLegacy(Tags.Items.INGOTS_GOLD); - tagWithOptionalLegacy(Tags.Items.INGOTS_IRON); - tagWithOptionalLegacy(Tags.Items.INGOTS_NETHERITE); - tag(Tags.Items.LEATHERS).addOptionalTag(forge("leather")); - tagWithOptionalLegacy(Tags.Items.MUSHROOMS); - tagWithOptionalLegacy(Tags.Items.NETHER_STARS); - tagWithOptionalLegacy(Tags.Items.NUGGETS); - tagWithOptionalLegacy(Tags.Items.NUGGETS_IRON); - tagWithOptionalLegacy(Tags.Items.NUGGETS_GOLD); - tagWithOptionalLegacy(Tags.Items.RAW_MATERIALS); - tagWithOptionalLegacy(Tags.Items.RAW_MATERIALS_COPPER); - tagWithOptionalLegacy(Tags.Items.RAW_MATERIALS_GOLD); - tagWithOptionalLegacy(Tags.Items.RAW_MATERIALS_IRON); - tagWithOptionalLegacy(Tags.Items.RODS); - tagWithOptionalLegacy(Tags.Items.RODS_BLAZE); - tagWithOptionalLegacy(Tags.Items.RODS_WOODEN); - tagWithOptionalLegacy(Tags.Items.SEEDS); - tagWithOptionalLegacy(Tags.Items.SEEDS_BEETROOT); - tagWithOptionalLegacy(Tags.Items.SEEDS_MELON); - tagWithOptionalLegacy(Tags.Items.SEEDS_PUMPKIN); - tagWithOptionalLegacy(Tags.Items.SEEDS_WHEAT); - tagWithOptionalLegacy(Tags.Items.SLIME_BALLS); - tagWithOptionalLegacy(Tags.Items.STRINGS); - tag(Tags.Items.TOOLS_SHEAR).addOptionalTag(forge("shears")); - tag(Tags.Items.TOOLS_SPEAR).addOptionalTag(forge("tools/tridents")); - tagWithOptionalLegacy(Tags.Items.TOOLS); - tagWithOptionalLegacy(Tags.Items.ARMORS); - tag(Tags.Items.TOOLS_SHIELD).addOptionalTag(forge("tools/shields")); - tag(Tags.Items.TOOLS_BOW).addOptionalTag(forge("tools/bows")); - tag(Tags.Items.TOOLS_BRUSH).addOptionalTag(forge("tools/brushes")); - tag(Tags.Items.TOOLS_CROSSBOW).addOptionalTag(forge("tools/crossbows")); - tag(Tags.Items.TOOLS_FISHING_ROD).addOptionalTag(forge("tools/fishing_rods")); - tag(Tags.Items.TOOLS_SHEAR).addOptionalTag(forge("tools/shears")); - tag(Tags.Items.TOOLS_SPEAR).addOptionalTag(forge("tools/tridents")); - tag(Tags.Items.TOOLS_SHIELD).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools/shields"))); - tag(Tags.Items.TOOLS_BOW).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools/bows"))); - tag(Tags.Items.TOOLS_BRUSH).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools/brushes"))); - tag(Tags.Items.TOOLS_CROSSBOW).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools/crossbows"))); - tag(Tags.Items.TOOLS_FISHING_ROD).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools/fishing_rods"))); - tag(Tags.Items.TOOLS_SHEAR).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools/shears"))); - tag(Tags.Items.TOOLS_SPEAR).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools/tridents"))); - tag(Tags.Items.FOODS_FRUIT).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/fruits"))); - tag(Tags.Items.FOODS_VEGETABLE).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/vegetables"))); - tag(Tags.Items.FOODS_BERRY).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/berries"))); - tag(Tags.Items.FOODS_BREAD).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/breads"))); - tag(Tags.Items.FOODS_COOKIE).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/cookies"))); - tag(Tags.Items.FOODS_RAW_MEAT).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/raw_meats"))); - tag(Tags.Items.FOODS_COOKED_MEAT).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/cooked_meats"))); - tag(Tags.Items.FOODS_RAW_FISH).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/raw_fishes"))); - tag(Tags.Items.FOODS_COOKED_FISH).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/cooked_fishes"))); - tag(Tags.Items.FOODS_SOUP).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/soups"))); - tag(Tags.Items.FOODS_CANDY).addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "foods/candies"))); - } - - private TagAppender tagWithOptionalLegacy(TagKey tag) { - var tagAppender = tag(tag); - tagAppender.addOptionalTag(forge(tag.location().getPath())); - return tagAppender; - } - - private void tagColoredWithOptionalLegacy(TagKey group) { - String prefix = group.location().getPath().toUpperCase(Locale.ENGLISH) + '_'; - for (DyeColor color : DyeColor.values()) { - TagKey tag = getForgeItemTag(prefix + color.getName()); - tagWithOptionalLegacy(tag); - } } private void addColored(TagKey group, String pattern) { @@ -529,10 +383,6 @@ private TagKey getForgeItemTag(String name) { } } - private static TagKey forge(String name) { - return TagKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath("forge", name)); - } - @Override public String getName() { return "NeoForge Item Tags"; 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 097661b8d0c..d9e6ce6cfc4 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 @@ -378,7 +378,7 @@ protected void addTranslations() { add(Tags.Items.TOOLS_FISHING_ROD, "Fishing Rods"); add(Tags.Items.TOOLS_BRUSH, "Brushes"); add(Tags.Items.TOOLS_MACE, "Maces"); - add(Tags.Items.TOOLS_SPEAR, "Spears"); + add(Tags.Items.TOOLS_TRIDENT, "Tridents"); add(Tags.Items.TOOLS_IGNITER, "Igniters"); add(Tags.Items.TOOLS_WRENCH, "Wrenches"); add(Tags.Items.MELEE_WEAPON_TOOLS, "Melee Weapons"); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLootTableProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLootTableProvider.java index 52b8164d4db..8a8f35b4741 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLootTableProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLootTableProvider.java @@ -30,7 +30,7 @@ import net.minecraft.world.item.Items; import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.LootTable; -import net.minecraft.world.level.storage.loot.ValidationContext; +import net.minecraft.world.level.storage.loot.ValidationContextSource; import net.minecraft.world.level.storage.loot.entries.AlternativesEntry; import net.minecraft.world.level.storage.loot.entries.CompositeEntryBase; import net.minecraft.world.level.storage.loot.entries.DynamicLoot; @@ -65,7 +65,7 @@ public NeoForgeLootTableProvider(PackOutput packOutput, CompletableFuture tables, ValidationContext validationContext, ProblemReporter.Collector problems) { + protected void validate(WritableRegistry tables, ValidationContextSource validationContext, ProblemReporter.Collector problems) { // Do not validate against all registered loot tables } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/GameTestHelperExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/GameTestHelperExtension.java new file mode 100644 index 00000000000..b80835a8058 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/extensions/GameTestHelperExtension.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.extensions; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.Entity; +import net.neoforged.neoforge.capabilities.BlockCapability; +import org.jspecify.annotations.Nullable; + +/** + * Additional functionality for {@link net.minecraft.gametest.framework.GameTestHelper} + */ +public interface GameTestHelperExtension { + private GameTestHelper self() { + return (GameTestHelper) this; + } + + /** + * Same as {@link GameTestHelper#fail(Component, BlockPos)}, but for untranslated messages. + */ + default void fail(String message, BlockPos pos) { + self().fail(Component.literal(message), pos); + } + + /** + * Same as {@link GameTestHelper#fail(Component, Entity)}, but for untranslated messages. + */ + default void fail(String message, Entity entity) { + self().fail(Component.literal(message), entity); + } + + /** + * Gets a capability from the given relative position with the given context. + */ + @Nullable + default T getCapability(BlockCapability cap, BlockPos pos, C context) { + return self().getLevel().getCapability(cap, self().absolutePos(pos), context); + } + + /** + * Gets a capability from the given relative position and fails the test, if it does not exist. + */ + default T requireCapability(BlockCapability cap, BlockPos pos, C context) { + var capability = getCapability(cap, pos, context); + if (capability == null) { + throw self().assertionException(pos, "Expected capability %s but there was none", cap); + } + return capability; + } +} 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 3c063b8074b..4cbb1d4ca95 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java @@ -47,7 +47,7 @@ import net.minecraft.world.level.block.CampfireBlock; import net.minecraft.world.level.block.CandleBlock; import net.minecraft.world.level.block.CandleCakeBlock; -import net.minecraft.world.level.block.FarmBlock; +import net.minecraft.world.level.block.FarmlandBlock; import net.minecraft.world.level.block.FenceGateBlock; import net.minecraft.world.level.block.FireBlock; import net.minecraft.world.level.block.GrowingPlantHeadBlock; @@ -457,8 +457,8 @@ default boolean onTreeGrow(BlockState state, LevelReader level, BiConsumer 0; + if (state.getBlock() instanceof FarmlandBlock) + return state.getValue(FarmlandBlock.MOISTURE) > 0; return false; } @@ -1049,16 +1049,16 @@ default boolean isEmpty(BlockState state) { /** * Determines if this block can spawn Bubble Columns and if so, what direction the column flows. *

- * NOTE: The block itself will still need to call {@link net.minecraft.world.level.block.BubbleColumnBlock#updateColumn(LevelAccessor, BlockPos, BlockState)} in their tick method and schedule a block tick in the block's onPlace. + * NOTE: The block itself will still need to call {@link net.minecraft.world.level.block.BubbleColumnBlock#updateColumn(Block, LevelAccessor, BlockPos, BlockState)} in their tick method and schedule a block tick in the block's onPlace. * Also, schedule a fluid tick in updateShape method if update direction is up. Both are needed in order to get the Bubble Columns to function properly. See {@link net.minecraft.world.level.block.SoulSandBlock} and {@link net.minecraft.world.level.block.MagmaBlock} for example. * * @param state The current state * @return BubbleColumnDirection.NONE for no Bubble Column. Otherwise, will spawn Bubble Column flowing with specified direction */ default BubbleColumnDirection getBubbleColumnDirection(BlockState state) { - if (state.is(Blocks.SOUL_SAND)) { + if (state.is(BlockTags.ENABLES_BUBBLE_COLUMN_PUSH_UP)) { return BubbleColumnDirection.UPWARD; - } else if (state.is(Blocks.MAGMA_BLOCK)) { + } else if (state.is(BlockTags.ENABLES_BUBBLE_COLUMN_DRAG_DOWN)) { return BubbleColumnDirection.DOWNWARD; } else { return BubbleColumnDirection.NONE; diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockGetterExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockGetterExtension.java index 904e37673db..e4856a84c7c 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockGetterExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockGetterExtension.java @@ -33,7 +33,7 @@ public interface IBlockGetterExtension { @Nullable @ApiStatus.NonExtendable default AuxiliaryLightManager getAuxLightManager(BlockPos pos) { - return getAuxLightManager(new ChunkPos(pos)); + return getAuxLightManager(ChunkPos.containing(pos)); } /** @@ -50,7 +50,7 @@ default AuxiliaryLightManager getAuxLightManager(BlockPos pos) { @Nullable default AuxiliaryLightManager getAuxLightManager(ChunkPos pos) { if (this instanceof LevelAccessor level) { - LightChunk chunk = level.getChunkSource().getChunkForLighting(pos.x, pos.z); + LightChunk chunk = level.getChunkSource().getChunkForLighting(pos.x(), pos.z()); return chunk != null ? chunk.getAuxLightManager(pos) : null; } else if (this instanceof ImposterProtoChunk chunk) { return chunk.getWrapped().getAuxLightManager(pos); diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IDataComponentHolderExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IDataComponentHolderExtension.java index f66b04af639..73cf8a3b982 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IDataComponentHolderExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IDataComponentHolderExtension.java @@ -12,6 +12,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.item.Item; import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; import net.minecraft.world.item.component.TooltipProvider; public interface IDataComponentHolderExtension { @@ -19,14 +20,15 @@ private DataComponentHolder self() { return (DataComponentHolder) this; } - default void addToTooltip(DataComponentType type, Item.TooltipContext context, Consumer adder, TooltipFlag flag) { + default void addToTooltip(DataComponentType type, Item.TooltipContext context, TooltipDisplay display, Consumer adder, TooltipFlag flag) { var value = self().get(type); - if (value != null) + if (value != null && display.shows(type)) { value.addToTooltip(context, adder, flag, self()); + } } - default void addToTooltip(Supplier> type, Item.TooltipContext context, Consumer adder, TooltipFlag flag) { - addToTooltip(type.get(), context, adder, flag); + default void addToTooltip(Supplier> type, Item.TooltipContext context, TooltipDisplay display, Consumer adder, TooltipFlag flag) { + addToTooltip(type.get(), context, display, adder, flag); } } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IFluidExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IFluidExtension.java index e66f06a1167..b2ff02f13c0 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IFluidExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IFluidExtension.java @@ -5,11 +5,16 @@ package net.neoforged.neoforge.common.extensions; +import java.util.function.Consumer; import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.vehicle.boat.AbstractBoat; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.block.state.BlockState; @@ -17,6 +22,7 @@ import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.pathfinder.PathType; import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidType; import org.jspecify.annotations.Nullable; @@ -154,4 +160,22 @@ default boolean canHydrate(FluidState state, BlockGetter getter, BlockPos pos, B default boolean canExtinguish(FluidState state, BlockGetter getter, BlockPos pos) { return getFluidType().canExtinguish(state, getter, pos); } + + /** + * Adds additional tooltip components for the given {@link FluidStack}. + * + *

This method is invoked when building the fluid's tooltip and allows + * fluids to contribute custom informational lines (for example temperature, + * effects, or mod-specific data).

+ * + *

Implementations should emit tooltip components via the provided + * {@code builder} consumer.

+ * + * @param fluidStack the fluid stack being rendered + * @param context the tooltip context + * @param display controls which tooltip elements should be displayed + * @param builder consumer used to append tooltip components + * @param tooltipFlag controls tooltip verbosity and advanced information + */ + default void appendHoverText(FluidStack fluidStack, Item.TooltipContext context, TooltipDisplay display, Consumer builder, TooltipFlag tooltipFlag) {} } 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 477565a6706..2b496456fba 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java @@ -35,7 +35,9 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemInstance; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; import net.minecraft.world.item.Items; import net.minecraft.world.item.component.ItemAttributeModifiers; import net.minecraft.world.item.context.UseOnContext; @@ -176,11 +178,10 @@ default boolean onLeftClickEntity(ItemStack stack, Player player, Entity entity) * ItemStack sensitive version of {@link Item#getCraftingRemainder()} ()}. * Returns a full ItemStack instance of the result. * - * @param itemStack The current ItemStack + * @param instance The current ItemStack * @return The resulting ItemStack */ - @SuppressWarnings("deprecation") - default ItemStack getCraftingRemainder(ItemStack itemStack) { + default @Nullable ItemStackTemplate getCraftingRemainder(ItemInstance instance) { return self().getCraftingRemainder(); } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java index 249d073f3ab..c39fe8163af 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java @@ -25,6 +25,7 @@ import net.minecraft.world.item.AdventureModePredicate; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; import net.minecraft.world.item.component.ItemAttributeModifiers; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.crafting.RecipeType; @@ -58,7 +59,7 @@ private ItemStack self() { * * @return The resulting ItemStack */ - default ItemStack getCraftingRemainder() { + default @Nullable ItemStackTemplate getCraftingRemainder() { return self().getItem().getCraftingRemainder(self()); } diff --git a/src/main/java/net/neoforged/neoforge/common/loot/CanItemPerformAbility.java b/src/main/java/net/neoforged/neoforge/common/loot/CanItemPerformAbility.java index 925ded4a79d..b9faefa25fc 100644 --- a/src/main/java/net/neoforged/neoforge/common/loot/CanItemPerformAbility.java +++ b/src/main/java/net/neoforged/neoforge/common/loot/CanItemPerformAbility.java @@ -14,7 +14,6 @@ import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; import net.neoforged.neoforge.common.ItemAbility; /** @@ -27,16 +26,15 @@ public class CanItemPerformAbility implements LootItemCondition { ItemAbility.CODEC.fieldOf("ability").forGetter(action -> action.ability)) .apply(builder, CanItemPerformAbility::new)); - public static final LootItemConditionType LOOT_CONDITION_TYPE = new LootItemConditionType(CODEC); - final ItemAbility ability; public CanItemPerformAbility(ItemAbility ability) { this.ability = ability; } - public LootItemConditionType getType() { - return LOOT_CONDITION_TYPE; + @Override + public MapCodec codec() { + return CODEC; } public Set> getReferencedContextParams() { diff --git a/src/main/java/net/neoforged/neoforge/common/loot/LootTableIdCondition.java b/src/main/java/net/neoforged/neoforge/common/loot/LootTableIdCondition.java index 278b701d359..920f001241b 100644 --- a/src/main/java/net/neoforged/neoforge/common/loot/LootTableIdCondition.java +++ b/src/main/java/net/neoforged/neoforge/common/loot/LootTableIdCondition.java @@ -10,7 +10,6 @@ import net.minecraft.resources.Identifier; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; public class LootTableIdCondition implements LootItemCondition { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( @@ -18,7 +17,6 @@ public class LootTableIdCondition implements LootItemCondition { .group( Identifier.CODEC.fieldOf("loot_table_id").forGetter(idCondition -> idCondition.targetLootTableId)) .apply(builder, LootTableIdCondition::new)); - public static final LootItemConditionType LOOT_TABLE_ID = new LootItemConditionType(CODEC); public static final Identifier UNKNOWN_LOOT_TABLE = Identifier.fromNamespaceAndPath("neoforge", "unknown_loot_table"); private final Identifier targetLootTableId; @@ -28,8 +26,8 @@ private LootTableIdCondition(final Identifier targetLootTableId) { } @Override - public LootItemConditionType getType() { - return LOOT_TABLE_ID; + public MapCodec codec() { + return CODEC; } @Override diff --git a/src/main/java/net/neoforged/neoforge/common/util/CenterChunkPosComparator.java b/src/main/java/net/neoforged/neoforge/common/util/CenterChunkPosComparator.java index 29db1ddc098..5cb33e7ab2d 100644 --- a/src/main/java/net/neoforged/neoforge/common/util/CenterChunkPosComparator.java +++ b/src/main/java/net/neoforged/neoforge/common/util/CenterChunkPosComparator.java @@ -25,10 +25,10 @@ public int compare(ChunkPos a, ChunkPos b) { } // Subtract current position to set center point - int ax = a.x - this.x; - int az = a.z - this.z; - int bx = b.x - this.x; - int bz = b.z - this.z; + int ax = a.x() - this.x; + int az = a.z() - this.z; + int bx = b.x() - this.x; + int bz = b.z() - this.z; int result = ((ax - bx) * (ax + bx)) + ((az - bz) * (az + bz)); if (result != 0) { diff --git a/src/main/java/net/neoforged/neoforge/common/util/ClockAdjustment.java b/src/main/java/net/neoforged/neoforge/common/util/ClockAdjustment.java new file mode 100644 index 00000000000..b0df21b2df8 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/util/ClockAdjustment.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.util; + +import java.util.Objects; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.clock.ClockTimeMarker; +import net.minecraft.world.clock.ServerClockManager; +import net.minecraft.world.clock.WorldClock; + +/** + * This models how the current time of a {@linkplain net.minecraft.world.clock.ClockManager clock} is to be adjusted. + *

It's used in events to express the desired adjustment as a data model so other event listeners can inspect + * and further change it. + */ +public sealed interface ClockAdjustment { + void apply(ServerClockManager clockManager, Holder clock); + + record Absolute(long ticks) implements ClockAdjustment { + @Override + public void apply(ServerClockManager clockManager, Holder clock) { + clockManager.setTotalTicks(clock, ticks); + } + } + + record Relative(long ticks) implements ClockAdjustment { + @Override + public void apply(ServerClockManager clockManager, Holder clock) { + var currentTicks = clockManager.getTotalTicks(clock); + var newTicks = currentTicks + ticks; + clockManager.setTotalTicks(clock, newTicks); + } + } + + record Marker(ResourceKey marker) implements ClockAdjustment { + public Marker { + Objects.requireNonNull(marker); + } + + @Override + public void apply(ServerClockManager clockManager, Holder clock) { + clockManager.skipToTimeMarker(clock, marker); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/world/chunk/ForcedChunkManager.java b/src/main/java/net/neoforged/neoforge/common/world/chunk/ForcedChunkManager.java index 3d9f19c3b3a..30f2e4761fe 100644 --- a/src/main/java/net/neoforged/neoforge/common/world/chunk/ForcedChunkManager.java +++ b/src/main/java/net/neoforged/neoforge/common/world/chunk/ForcedChunkManager.java @@ -88,7 +88,7 @@ static > boolean forceChunk(ServerLevel level, I TicketStorage saveData = level.getDataStorage().computeIfAbsent(TicketStorage.TYPE); ChunkPos pos = new ChunkPos(chunkX, chunkZ); - long chunk = pos.toLong(); + long chunk = pos.pack(); TicketTracker tickets = ticketGetter.apply(saveData); TicketOwner ticketOwner = new TicketOwner<>(id, owner); if (add) { 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 817b09229e5..7b22a9f0395 100644 --- a/src/main/java/net/neoforged/neoforge/data/event/GatherDataEvent.java +++ b/src/main/java/net/neoforged/neoforge/data/event/GatherDataEvent.java @@ -171,7 +171,7 @@ public boolean isFlat() { } public DataGenerator makeGenerator(final Function pathEnhancer) { - final DataGenerator generator = new DataGenerator(pathEnhancer.apply(path), DetectedVersion.tryDetectVersion(), true); + final DataGenerator generator = new DataGenerator.Cached(pathEnhancer.apply(path), DetectedVersion.tryDetectVersion(), true); generators.add(generator); return generator; } 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 801df77d439..7822858b36d 100644 --- a/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java +++ b/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java @@ -20,7 +20,6 @@ import net.neoforged.fml.ModList; import net.neoforged.neoforge.data.event.GatherDataEvent; import net.neoforged.neoforge.internal.CommonModLoader; -import net.neoforged.neoforge.internal.RegistrationEvents; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.ApiStatus; @@ -54,8 +53,6 @@ public static void begin( runningDataGen = true; Bootstrap.bootStrap(); begin(() -> {}, true); - // 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, devToolGenerators, reportsGenerator, structureValidator, flat, vanillaGenerator, existingPacks, vanillaClientAssets); setup.run(); diff --git a/src/main/java/net/neoforged/neoforge/event/DefaultDataComponentsBoundEvent.java b/src/main/java/net/neoforged/neoforge/event/DefaultDataComponentsBoundEvent.java new file mode 100644 index 00000000000..06d777cd367 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/DefaultDataComponentsBoundEvent.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event; + +import net.minecraft.core.Holder; +import net.neoforged.bus.api.Event; +import org.jetbrains.annotations.ApiStatus; + +/** + * This event is emitted after data components have been bound to holders in a registry. + *

This can occur on the server when datapacks are reloaded or when the client receives this data upon joining a world. + *

This event signals when {@link Holder#areComponentsBound()} becomes true. + */ +public class DefaultDataComponentsBoundEvent extends Event { + private final UpdateCause updateCause; + private final boolean integratedServer; + + @ApiStatus.Internal + public DefaultDataComponentsBoundEvent(boolean fromClientPacket, boolean isIntegratedServerConnection) { + this.updateCause = fromClientPacket ? UpdateCause.CLIENT_PACKET_RECEIVED : UpdateCause.SERVER_DATA_LOAD; + this.integratedServer = isIntegratedServerConnection; + } + + /** + * @return the cause for binding the default data components + */ + public UpdateCause getUpdateCause() { + return updateCause; + } + + /** + * Whether static data (which in single player is shared between server and client thread) should be updated as a + * result of this event. Effectively this means that in single player only the server-side updates this data. + */ + public boolean shouldUpdateStaticData() { + return updateCause == UpdateCause.SERVER_DATA_LOAD || !integratedServer; + } + + /** + * Represents the cause for binding the default data components. + */ + public enum UpdateCause { + /** + * The default data components were bound due to the server loading datapack data. Note that in single player this still happens + * on the client thread. + */ + SERVER_DATA_LOAD, + /** + * The default data components were bound due to the client receiving the datapack data from the server. + */ + CLIENT_PACKET_RECEIVED + } +} diff --git a/src/main/java/net/neoforged/neoforge/event/DifficultyChangeEvent.java b/src/main/java/net/neoforged/neoforge/event/DifficultyChangeEvent.java index 75d0d6e20c3..b8342c189a7 100644 --- a/src/main/java/net/neoforged/neoforge/event/DifficultyChangeEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/DifficultyChangeEvent.java @@ -15,8 +15,6 @@ *
* This event is fired via the {@link CommonHooks#onDifficultyChange(Difficulty, Difficulty)}.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class DifficultyChangeEvent extends Event { diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index 191d4002061..721276a688a 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -27,6 +27,7 @@ import net.minecraft.core.HolderLookup.RegistryLookup; import net.minecraft.core.NonNullList; import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; @@ -93,6 +94,7 @@ import net.minecraft.world.level.block.entity.FuelValues; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.gamerules.GameRule; import net.minecraft.world.level.gamerules.GameRules; import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; @@ -112,6 +114,7 @@ import net.neoforged.neoforge.common.extensions.IFluidStateExtension; import net.neoforged.neoforge.common.extensions.IOwnedSpawner; import net.neoforged.neoforge.common.util.BlockSnapshot; +import net.neoforged.neoforge.common.util.ClockAdjustment; import net.neoforged.neoforge.common.util.InsertableLinkedOpenCustomHashSet; import net.neoforged.neoforge.event.brewing.PlayerBrewedPotionEvent; import net.neoforged.neoforge.event.brewing.PotionBrewEvent; @@ -145,6 +148,7 @@ import net.neoforged.neoforge.event.entity.player.BonemealEvent; import net.neoforged.neoforge.event.entity.player.CanContinueSleepingEvent; import net.neoforged.neoforge.event.entity.player.CanPlayerSleepEvent; +import net.neoforged.neoforge.event.entity.player.FluidTooltipEvent; import net.neoforged.neoforge.event.entity.player.ItemEntityPickupEvent; import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent; import net.neoforged.neoforge.event.entity.player.PermissionsChangedEvent; @@ -168,6 +172,7 @@ import net.neoforged.neoforge.event.level.ChunkWatchEvent; import net.neoforged.neoforge.event.level.ExplosionEvent; import net.neoforged.neoforge.event.level.ExplosionKnockbackEvent; +import net.neoforged.neoforge.event.level.GameRuleChangedEvent; import net.neoforged.neoforge.event.level.LevelEvent; import net.neoforged.neoforge.event.level.ModifyCustomSpawnersEvent; import net.neoforged.neoforge.event.level.PistonEvent; @@ -177,6 +182,7 @@ import net.neoforged.neoforge.event.tick.LevelTickEvent; import net.neoforged.neoforge.event.tick.PlayerTickEvent; import net.neoforged.neoforge.event.tick.ServerTickEvent; +import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.resource.ReloadListenerSort; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.Nullable; @@ -364,7 +370,7 @@ public static FinalizeSpawnEvent finalizeMobSpawnSpawner(Mob mob, ServerLevelAcc */ public static PlayerSpawnPhantomsEvent firePlayerSpawnPhantoms(ServerPlayer player, ServerLevel level, BlockPos pos) { Difficulty difficulty = level.getCurrentDifficultyAt(pos).getDifficulty(); - var event = new PlayerSpawnPhantomsEvent(player, 1 + level.random.nextInt(difficulty.getId() + 1)); + var event = new PlayerSpawnPhantomsEvent(player, 1 + level.getRandom().nextInt(difficulty.getId() + 1)); NeoForge.EVENT_BUS.post(event); return event; } @@ -441,6 +447,12 @@ public static ItemTooltipEvent onItemTooltip(ItemStack itemStack, @Nullable Play return event; } + public static FluidTooltipEvent onFluidTooltip(FluidStack fluidStack, @Nullable Player entityPlayer, List list, TooltipFlag flags, Item.TooltipContext context) { + FluidTooltipEvent event = new FluidTooltipEvent(fluidStack, entityPlayer, list, flags, context); + NeoForge.EVENT_BUS.post(event); + return event; + } + public static boolean onEntityStruckByLightning(Entity entity, LightningBolt bolt) { return NeoForge.EVENT_BUS.post(new EntityStruckByLightningEvent(entity, bolt)).isCanceled(); } @@ -787,10 +799,14 @@ public static void onPistonMovePost(Level level, BlockPos pos, Direction directi NeoForge.EVENT_BUS.post(new PistonEvent.Post(level, pos, direction, extending ? PistonEvent.PistonMoveType.EXTEND : PistonEvent.PistonMoveType.RETRACT)); } - public static long onSleepFinished(ServerLevel level, long newTime, long minTime) { - SleepFinishedTimeEvent event = new SleepFinishedTimeEvent(level, newTime, minTime); + @Nullable + public static ClockAdjustment onSleepFinished(ServerLevel level, ClockAdjustment defaultAdjustment) { + SleepFinishedTimeEvent event = new SleepFinishedTimeEvent(level, defaultAdjustment); NeoForge.EVENT_BUS.post(event); - return event.getNewTime(); + if (event.isCanceled()) { + return null; + } + return event.getAdjustment(); } /** @@ -1069,14 +1085,15 @@ public static ItemEnchantments getAllEnchantmentLevels(ItemEnchantments enchantm * Fires the {@link BuildCreativeModeTabContentsEvent}. * * @param tab The tab that contents are being collected for. - * @param tabKey The resource key of the tab. * @param originalGenerator The display items generator that populates vanilla entries. * @param params Display parameters, controlling if certain items are hidden. * @param output The output acceptor. * @apiNote Call via {@link CreativeModeTab#buildContents(CreativeModeTab.ItemDisplayParameters)} */ @ApiStatus.Internal - public static void onCreativeModeTabBuildContents(CreativeModeTab tab, ResourceKey tabKey, CreativeModeTab.DisplayItemsGenerator originalGenerator, CreativeModeTab.ItemDisplayParameters params, CreativeModeTab.Output output) { + public static void onCreativeModeTabBuildContents(CreativeModeTab tab, CreativeModeTab.DisplayItemsGenerator originalGenerator, CreativeModeTab.ItemDisplayParameters params, CreativeModeTab.Output output) { + var tabKey = BuiltInRegistries.CREATIVE_MODE_TAB.getResourceKey(tab).orElseThrow(); + final var parentEntries = new InsertableLinkedOpenCustomHashSet(ItemStackLinkedSet.TYPE_AND_TAG); final var searchEntries = new InsertableLinkedOpenCustomHashSet(ItemStackLinkedSet.TYPE_AND_TAG); @@ -1129,4 +1146,8 @@ public static List getCustomSpawners(ServerLevel serverLevel, Lis NeoForge.EVENT_BUS.post(event); return event.getCustomSpawners(); } + + public static void onGameRuleChanged(MinecraftServer server, GameRule gameRule, T newValue) { + NeoForge.EVENT_BUS.post(new GameRuleChangedEvent(server, gameRule, newValue)); + } } diff --git a/src/main/java/net/neoforged/neoforge/event/ModifyDefaultComponentsEvent.java b/src/main/java/net/neoforged/neoforge/event/ModifyDefaultComponentsEvent.java index 68146cf5c2d..5f98f3f53f3 100644 --- a/src/main/java/net/neoforged/neoforge/event/ModifyDefaultComponentsEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/ModifyDefaultComponentsEvent.java @@ -5,11 +5,12 @@ package net.neoforged.neoforge.event; +import com.mojang.datafixers.util.Pair; +import java.util.List; +import java.util.Map; import java.util.function.Consumer; import java.util.function.Predicate; -import java.util.stream.Stream; -import net.minecraft.core.component.DataComponentPatch; -import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.component.DataComponentMap; import net.minecraft.world.item.Item; import net.minecraft.world.level.ItemLike; import net.neoforged.bus.api.Event; @@ -43,8 +44,15 @@ * } */ public final class ModifyDefaultComponentsEvent extends Event implements IModBusEvent { + private final Map> modifiersByItem; + private final List, Consumer>> modifiersByPredicate; + @ApiStatus.Internal - public ModifyDefaultComponentsEvent() {} + public ModifyDefaultComponentsEvent(Map> modifiersByItem, + List, Consumer>> modifiersByPredicate) { + this.modifiersByItem = modifiersByItem; + this.modifiersByPredicate = modifiersByPredicate; + } /** * Patches the default components of the given {@code item}. @@ -52,13 +60,8 @@ public ModifyDefaultComponentsEvent() {} * @param item the item to modify the default components for * @param patch the patch to apply */ - public void modify(ItemLike item, Consumer patch) { - var builder = DataComponentPatch.builder(); - patch.accept(builder); - var compPatch = builder.build(); - if (!compPatch.isEmpty()) { - item.asItem().modifyDefaultComponentsFrom(builder.build()); - } + public void modify(ItemLike item, Consumer patch) { + modifiersByItem.merge(item.asItem(), patch, Consumer::andThen); } /** @@ -71,14 +74,7 @@ public void modify(ItemLike item, Consumer patch) { * @param predicate the item filter * @param patch the patch to apply */ - public void modifyMatching(Predicate predicate, Consumer patch) { - getAllItems().filter(predicate).forEach(item -> modify(item, patch)); - } - - /** - * {@return all registered items} - */ - public Stream getAllItems() { - return BuiltInRegistries.ITEM.stream(); + public void modifyMatching(Predicate predicate, Consumer patch) { + modifiersByPredicate.add(Pair.of(predicate, patch)); } } diff --git a/src/main/java/net/neoforged/neoforge/event/RegisterGameRuleCategoryEvent.java b/src/main/java/net/neoforged/neoforge/event/RegisterGameRuleCategoryEvent.java new file mode 100644 index 00000000000..3340e251695 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/RegisterGameRuleCategoryEvent.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event; + +import java.util.function.Consumer; +import net.minecraft.world.level.gamerules.GameRuleCategory; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Fired to allow modders to register custom {@link GameRuleCategory gamerule categories}. + *

+ * This event is fired on the mod-specific event bus. + */ +public final class RegisterGameRuleCategoryEvent extends Event implements IModBusEvent { + private final Consumer registrar; + + @ApiStatus.Internal + public RegisterGameRuleCategoryEvent(Consumer registrar) { + this.registrar = registrar; + } + + public void register(GameRuleCategory category) { + registrar.accept(category); + } +} diff --git a/src/main/java/net/neoforged/neoforge/event/RegisterGameTestsEvent.java b/src/main/java/net/neoforged/neoforge/event/RegisterGameTestsEvent.java index 1b012280fd7..87baca92160 100644 --- a/src/main/java/net/neoforged/neoforge/event/RegisterGameTestsEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/RegisterGameTestsEvent.java @@ -23,30 +23,30 @@ /** * Game tests are registered on client or server startup. - * It is run in {@link net.minecraft.resources.RegistryDataLoader#load(ResourceManager, List, List)} if {@link GameTestHooks#isGametestEnabled} returns true. + * It is run in {@link net.minecraft.resources.RegistryDataLoader#load(ResourceManager, List, List, java.util.concurrent.Executor)} if {@link GameTestHooks#isGametestEnabled} returns true. *

* Fired on the Mod bus, see {@link IModBusEvent}. */ public class RegisterGameTestsEvent extends Event implements IModBusEvent { - private final WritableRegistry environmentsRegistry; + private final WritableRegistry> environmentsRegistry; private final WritableRegistry testsRegistry; - public RegisterGameTestsEvent(WritableRegistry environmentsRegistry, WritableRegistry testsRegistry) { + public RegisterGameTestsEvent(WritableRegistry> environmentsRegistry, WritableRegistry testsRegistry) { this.environmentsRegistry = environmentsRegistry; this.testsRegistry = testsRegistry; } - public Holder registerEnvironment(Identifier name, TestEnvironmentDefinition... definitions) { + public Holder> registerEnvironment(Identifier name, TestEnvironmentDefinition... definitions) { return registerEnvironment(name, new TestEnvironmentDefinition.AllOf(definitions)); } - public Holder registerEnvironment(Identifier name, TestEnvironmentDefinition definition) { + public Holder> registerEnvironment(Identifier name, TestEnvironmentDefinition definition) { return environmentsRegistry.register( ResourceKey.create(Registries.TEST_ENVIRONMENT, name), definition, RegistrationInfo.BUILT_IN); } - public void registerTest(Identifier name, Function>, GameTestInstance> factory, TestData> testData) { + public void registerTest(Identifier name, Function>>, GameTestInstance> factory, TestData>> testData) { registerTest(name, factory.apply(testData)); } diff --git a/src/main/java/net/neoforged/neoforge/event/brewing/PotionBrewEvent.java b/src/main/java/net/neoforged/neoforge/event/brewing/PotionBrewEvent.java index 8f74534646d..3114fa5bca4 100644 --- a/src/main/java/net/neoforged/neoforge/event/brewing/PotionBrewEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/brewing/PotionBrewEvent.java @@ -44,8 +44,6 @@ public int getLength() { * This event is {@link net.neoforged.bus.api.ICancellableEvent}.
* If the event is not canceled, the vanilla brewing will take place instead of modded brewing. *
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*
* If this event is canceled, and items have been modified, PotionBrewEvent.Post will automatically be fired. @@ -65,8 +63,6 @@ public Pre(NonNullList stacks) { *
* This event is not {@link net.neoforged.bus.api.ICancellableEvent}.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
**/ public static class Post extends PotionBrewEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/EntityEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/EntityEvent.java index 20b956e4971..1b6a62e62b9 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/EntityEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/EntityEvent.java @@ -13,13 +13,12 @@ import net.neoforged.neoforge.common.NeoForge; /** - * EntityEvent is fired when an event involving any Entity occurs.
- * If a method utilizes this {@link net.neoforged.bus.api.Event} as its parameter, the method will - * receive every child event of this class.
- *
- * {@link #entity} contains the entity that caused this event to occur.
- *
- * All children of this event are fired on the {@link NeoForge#EVENT_BUS}.
+ * Base class of the events involving entities. + *

+ * + * @see EntityEvent.EntityConstructing + * @see EntityEvent.EnteringSection + * @see EntityEvent.Size **/ public abstract class EntityEvent extends Event { private final Entity entity; @@ -33,14 +32,13 @@ public Entity getEntity() { } /** - * EntityConstructing is fired when an Entity is being created.
- * This event is fired within the constructor of the Entity.
- *
- * This event is not {@link net.neoforged.bus.api.ICancellableEvent}.
- *
- * This event does not have a result. {@link HasResult}
- *
- * This event is fired on the {@link NeoForge#EVENT_BUS}.
+ * EntityConstructing is fired when an Entity is being created. + * This event is fired within the constructor of the Entity. + *

+ *

  • {@link #getEntity} contains the entity that caused this event to occur.
+ *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. **/ public static class EntityConstructing extends EntityEvent { public EntityConstructing(Entity entity) { @@ -49,16 +47,16 @@ public EntityConstructing(Entity entity) { } /** - * This event is fired on server and client after an Entity has entered a different section.
- * Sections are 16x16x16 block grids of the world.
+ * This event is fired on server and client after an Entity has entered a different section. + * Sections are 16x16x16 block grids of the world. + *

* This event does not fire when a new entity is spawned, only when an entity moves from one section to another one. * Use {@link EntityJoinLevelEvent} to detect new entities joining the world. - *
- * This event is not {@link net.neoforged.bus.api.ICancellableEvent}.
- *
- * This event does not have a result. {@link HasResult} - *
- * This event is fired on the {@link NeoForge#EVENT_BUS}.
+ *

+ *

  • {@link #getEntity} contains the entity that caused this event to occur.
+ *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. **/ public static class EnteringSection extends EntityEvent { private final long packedOldPos; @@ -119,8 +117,10 @@ public boolean didChunkChange() { *

Note: This event is fired from the {@code Entity} constructor, and therefore the entity instance * might not be fully initialized. Be cautious in using methods and fields from the instance, and check * {@link Entity#isAddedToLevel()} or {@link Entity#firstTick}. - * - *

This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + *

+ *

  • {@link #getEntity} contains the entity that caused this event to occur.
+ *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the * {@linkplain NeoForge#EVENT_BUS game event bus}. **/ public static class Size extends EntityEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/EntityMountEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/EntityMountEvent.java index 038e24785bf..ab61961211d 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/EntityMountEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/EntityMountEvent.java @@ -18,8 +18,6 @@ * This event is {@link net.neoforged.bus.api.ICancellableEvent}.
* If this event is canceled, the entity does not mount/dismount the other entity.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. * */ diff --git a/src/main/java/net/neoforged/neoforge/event/entity/EntityStruckByLightningEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/EntityStruckByLightningEvent.java index 87b89831dd9..8b6e26158d6 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/EntityStruckByLightningEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/EntityStruckByLightningEvent.java @@ -21,8 +21,6 @@ * This event is {@link ICancellableEvent}.
* If this event is canceled, the Entity is not struck by the lightening.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
**/ public class EntityStruckByLightningEvent extends EntityEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/EntityTeleportEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/EntityTeleportEvent.java index bfacb3f580f..1983acc671c 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/EntityTeleportEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/EntityTeleportEvent.java @@ -92,8 +92,6 @@ public Vec3 getPrev() { * This event is {@link ICancellableEvent}.
* If the event is not canceled, the entity will be teleported. *
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*
* This event is only fired on the {@link LogicalSide#SERVER} side.
@@ -113,8 +111,6 @@ public TeleportCommand(Entity entity, double targetX, double targetY, double tar * This event is {@link ICancellableEvent}.
* If the event is not canceled, the entity will be teleported. *
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*
* This event is only fired on the {@link LogicalSide#SERVER} side.
@@ -133,8 +129,6 @@ public SpreadPlayersCommand(Entity entity, double targetX, double targetY, doubl * This event is {@link ICancellableEvent}.
* If the event is not canceled, the entity will be teleported. *
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*
* This event is only fired on the {@link LogicalSide#SERVER} side.
@@ -160,8 +154,6 @@ public LivingEntity getEntityLiving() { * This event is {@link ICancellableEvent}.
* If the event is not canceled, the entity will be teleported. *
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*
* This event is only fired on the {@link LogicalSide#SERVER} side.
@@ -211,8 +203,6 @@ public void setAttackDamage(float attackDamage) { * This event is {@link ICancellableEvent}.
* If the event is not canceled, the entity will be teleported. *
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*
* This event is only fired on the {@link LogicalSide#SERVER} side.
diff --git a/src/main/java/net/neoforged/neoforge/event/entity/EntityTravelToDimensionEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/EntityTravelToDimensionEvent.java index 0dda3efc151..9547c15a289 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/EntityTravelToDimensionEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/EntityTravelToDimensionEvent.java @@ -19,8 +19,6 @@ * This event is {@link net.neoforged.bus.api.ICancellableEvent}.
* If this event is canceled, the Entity does not travel to the dimension.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}.
**/ public class EntityTravelToDimensionEvent extends EntityEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/BabyEntitySpawnEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/BabyEntitySpawnEvent.java index 54f2df0e032..4cb7339a98e 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/BabyEntitySpawnEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/BabyEntitySpawnEvent.java @@ -31,8 +31,6 @@ * If this event is canceled, the child Entity is not added to the world, and the parents
* will no longer attempt to mate. *
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class BabyEntitySpawnEvent extends net.neoforged.bus.api.Event implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingBreatheEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingBreatheEvent.java index 06b11769a6d..088fe8c5608 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingBreatheEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingBreatheEvent.java @@ -6,6 +6,7 @@ package net.neoforged.neoforge.event.entity.living; import net.minecraft.world.entity.LivingEntity; +import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.common.CommonHooks; import net.neoforged.neoforge.common.NeoForge; @@ -16,8 +17,6 @@ *
* This event is not {@link ICancellableEvent}.
*
- * This event does not have a result. {@link HasResult} - *
* This event is fired on {@link NeoForge#EVENT_BUS} */ public class LivingBreatheEvent extends LivingEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingChangeTargetEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingChangeTargetEvent.java index 411e97c1933..08f1fb9d247 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingChangeTargetEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingChangeTargetEvent.java @@ -8,31 +8,26 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.behavior.StartAttacking; -import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.common.CommonHooks; import net.neoforged.neoforge.common.NeoForge; import org.jspecify.annotations.Nullable; /** - * This event allows you to change the target an entity has.
- * This event is fired before {@link LivingSetAttackTargetEvent}.
- *
- * This event is fired via the {@link CommonHooks#onLivingChangeTarget(LivingEntity, LivingEntity, ILivingTargetType)}
- *
- * {@link #getOriginalAboutToBeSetTarget()} returns the target that should originally be set. - * The return value cannot be affected by calling {@link #setNewAboutToBeSetTarget(LivingEntity)}.
- * {@link #getNewAboutToBeSetTarget()} returns the new target that this entity will have. - * The return value can be affected by calling {@link #setNewAboutToBeSetTarget(LivingEntity)}.
- * {@link #getTargetType()} returns the target type that caused the change of targets.
- *
- * This event is {@link net.neoforged.bus.api.ICancellableEvent}.
- *
- * If you cancel this event, the target will not be changed and it will stay the same. - * Cancelling this event will prevent {@link LivingSetAttackTargetEvent} from being posted.
- *
- * This event does not have a result. {@link Event.HasResult}
- *
+ * This event allows you to change what target an entity is about to have. + *

+ * This event is fired via the {@link CommonHooks#onLivingChangeTarget(LivingEntity, LivingEntity, ILivingTargetType)} + *

    + *
  • {@link #getOriginalAboutToBeSetTarget()} returns the target that should originally be set. + * The return value cannot be changed.
  • + *
  • {@link #getNewAboutToBeSetTarget()} returns the new target that this entity will have. + * The return value can be affected by calling {@link #setNewAboutToBeSetTarget(LivingEntity)}.
  • + *
  • {@link #getTargetType()} returns the target type that caused the change of targets.
  • + *
+ * This event is {@link net.neoforged.bus.api.ICancellableEvent}. + *

+ * If you cancel this event, the target will stay the same to what the entity already is targeting and not be changed. + *

* This event is fired on the {@link NeoForge#EVENT_BUS}. */ public class LivingChangeTargetEvent extends LivingEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDeathEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDeathEvent.java index e9a29ac54f0..7febf0b30b1 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDeathEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDeathEvent.java @@ -27,8 +27,6 @@ * This event is {@link ICancellableEvent}.
* If this event is canceled, the Entity does not die.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class LivingDeathEvent extends LivingEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDestroyBlockEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDestroyBlockEvent.java index 726fc58ccd2..09ed19ede2e 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDestroyBlockEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDestroyBlockEvent.java @@ -20,8 +20,6 @@ * This event is {@link ICancellableEvent}.
* If this event is canceled, the block will not be destroyed.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class LivingDestroyBlockEvent extends LivingEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDropsEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDropsEvent.java index a1df6a12007..05b7de0d2e5 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDropsEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingDropsEvent.java @@ -28,8 +28,6 @@ * This event is {@link ICancellableEvent}.
* If this event is canceled, the Entity does not drop anything.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class LivingDropsEvent extends LivingEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEquipmentChangeEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEquipmentChangeEvent.java index b0430e4bb64..87de70fd1c1 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEquipmentChangeEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEquipmentChangeEvent.java @@ -8,6 +8,7 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; +import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.common.NeoForge; /** @@ -22,8 +23,6 @@ *
* This event is not {@link ICancellableEvent}.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class LivingEquipmentChangeEvent extends LivingEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEvent.java index 5f52ef9a388..1db9b1e6b28 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEvent.java @@ -7,19 +7,16 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; -import net.neoforged.bus.api.Event; -import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.common.CommonHooks; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.entity.EntityEvent; import org.jspecify.annotations.Nullable; /** - * LivingEvent is fired whenever an event involving a {@link LivingEntity} occurs.
- * If a method utilizes this {@link Event} as its parameter, the method will - * receive every child event of this class.
- *
- * All children of this event are fired on the {@link NeoForge#EVENT_BUS}.
+ * Base class of the events specific to LivingEntities. + * + * @see LivingEvent.LivingJumpEvent + * @see LivingEvent.LivingVisibilityEvent **/ public abstract class LivingEvent extends EntityEvent { private final LivingEntity livingEntity; @@ -35,19 +32,19 @@ public LivingEntity getEntity() { } /** - * LivingJumpEvent is fired when an Entity jumps.
- * This event is fired whenever an Entity jumps in + * LivingJumpEvent is fired when a LivingEntity jumps. + *

+ * This event is fired whenever a LivingEntity jumps in * {@code LivingEntity#jumpFromGround()}, {@code MagmaCube#jumpFromGround()}, * {@code Slime#jumpFromGround()}, {@code Camel#executeRidersJump()}, - * and {@code AbstractHorse#executeRidersJump()}.
- *
- * This event is fired via the {@link CommonHooks#onLivingJump(LivingEntity)}.
- *
- * This event is not {@link ICancellableEvent}.
- *
- * This event does not have a result. {@link HasResult}
- *
- * This event is fired on the {@link NeoForge#EVENT_BUS}. + * and {@code AbstractHorse#executeRidersJump()}. + *

+ * This event is fired via the {@link CommonHooks#onLivingJump(LivingEntity)}. + *

+ *

  • {@link #getEntity} contains the entity that caused this event to occur.
+ *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. **/ public static class LivingJumpEvent extends LivingEvent { public LivingJumpEvent(LivingEntity e) { @@ -55,6 +52,18 @@ public LivingJumpEvent(LivingEntity e) { } } + /** + * LivingVisibilityEvent is fired when an LivingEntity's visibility is queried. + *

+ * This event is fired whenever {@code LivingEntity#getVisibilityPercent()} is called. + *

+ * This event is fired via the {@link CommonHooks#getEntityVisibilityMultiplier(LivingEntity, Entity, double)}. + *

+ *

  • {@link #getEntity} contains the entity that caused this event to occur.
+ *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. + **/ public static class LivingVisibilityEvent extends LivingEvent { private double visibilityModifier; @Nullable diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingGetProjectileEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingGetProjectileEvent.java index 42fea25d920..953080e54d9 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingGetProjectileEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingGetProjectileEvent.java @@ -18,8 +18,6 @@ *

* This event is not {@link net.neoforged.bus.api.ICancellableEvent}. *

- * This event does not have a result. {@link net.neoforged.bus.api.Event.HasResult} - *

* This event is fired on the {@link NeoForge#EVENT_BUS}. */ public class LivingGetProjectileEvent extends LivingEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingHealEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingHealEvent.java index 46b5dbf34f4..c25971487ea 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingHealEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingHealEvent.java @@ -21,8 +21,6 @@ * This event is {@link net.neoforged.bus.api.ICancellableEvent}.
* If this event is canceled, the Entity is not healed.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class LivingHealEvent extends LivingEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingKnockBackEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingKnockBackEvent.java index 16665fe6409..4f597a6e62e 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingKnockBackEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingKnockBackEvent.java @@ -31,8 +31,6 @@ * This event is {@link ICancellableEvent}.
* If this event is canceled, the entity is not knocked back.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class LivingKnockBackEvent extends LivingEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/ArrowLooseEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/ArrowLooseEvent.java index 3c923b23494..3269a48ba52 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/player/ArrowLooseEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/ArrowLooseEvent.java @@ -10,7 +10,6 @@ import net.minecraft.world.item.BowItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; -import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.common.NeoForge; @@ -26,8 +25,6 @@ * If this event is canceled, the player does not stop using the bow.
* For crossbows, the charge will always be 1; Set it to -1 in order to prevent firing the arrow.
*
- * This event does not have a result. {@link Event.HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class ArrowLooseEvent extends PlayerEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/AttackEntityEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/AttackEntityEvent.java index 6e764cd6c1b..49e61975e02 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/player/AttackEntityEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/AttackEntityEvent.java @@ -20,8 +20,6 @@ * This event is {@link ICancellableEvent}.
* If this event is canceled, the player does not attack the Entity.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public class AttackEntityEvent extends PlayerEvent implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/FluidTooltipEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/FluidTooltipEvent.java new file mode 100644 index 00000000000..badd2549012 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/FluidTooltipEvent.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.entity.player; + +import java.util.List; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item.TooltipContext; +import net.minecraft.world.item.TooltipFlag; +import net.neoforged.neoforge.fluids.FluidStack; +import org.jspecify.annotations.Nullable; + +public class FluidTooltipEvent extends PlayerEvent { + private final TooltipFlag flags; + private final FluidStack fluidStack; + private final List toolTip; + private final TooltipContext context; + + /** + * This event is fired in {@link FluidStack#getTooltipLines(TooltipContext, Player, TooltipFlag)}, which in turn is called from its respective modded GUI. + * Tooltips may also be gathered with a null player during startup by other mods. + */ + public FluidTooltipEvent(FluidStack fluidStack, @Nullable Player player, List list, TooltipFlag flags, TooltipContext context) { + super(player); + this.fluidStack = fluidStack; + this.toolTip = list; + this.flags = flags; + this.context = context; + } + + /** + * Use to determine if the advanced information on fluid tooltips is being shown, toggled by F3+H. + */ + public TooltipFlag getFlags() { + return flags; + } + + /** + * The {@link FluidStack} with the tooltip. + */ + public FluidStack getFluidStack() { + return fluidStack; + } + + /** + * The {@link FluidStack} tooltip. + */ + public List getToolTip() { + return toolTip; + } + + /** + * This event is fired with a null player during startup when populating search trees for tooltips. + */ + @Override + @Nullable + public Player getEntity() { + return super.getEntity(); + } + + /** + * The {@link TooltipContext tooltip context}. + */ + public TooltipContext getContext() { + return context; + } +} diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerDestroyItemEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerDestroyItemEvent.java index 679b424195a..1b07f413eeb 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerDestroyItemEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerDestroyItemEvent.java @@ -38,8 +38,6 @@ *
* This event is not {@link ICancellableEvent}.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired from {@link EventHooks#onPlayerDestroyItem(Player, ItemStack, InteractionHand)}.
* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEvent.java index 4b64505d302..bf94b3a56a5 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEvent.java @@ -8,9 +8,12 @@ import java.io.File; import java.util.Optional; import net.minecraft.core.BlockPos; +import net.minecraft.network.Connection; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.CommonListenerCookie; +import net.minecraft.server.players.PlayerList; import net.minecraft.world.Container; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -19,7 +22,7 @@ import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.bus.api.Event; +import net.minecraft.world.level.portal.TeleportTransition; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.EventHooks; @@ -27,11 +30,24 @@ import org.jspecify.annotations.Nullable; /** - * PlayerEvent is fired whenever an event involving a {@link Player} occurs.
- * If a method utilizes this {@link net.neoforged.bus.api.Event} as its parameter, the method will - * receive every child event of this class.
- *
- * All children of this event are fired on the {@link NeoForge#EVENT_BUS}. + * Base class of the events specific to Players. + * + * @see PlayerEvent.HarvestCheck + * @see PlayerEvent.BreakSpeed + * @see PlayerEvent.NameFormat + * @see PlayerEvent.TabListNameFormat + * @see PlayerEvent.Clone + * @see PlayerEvent.StartTracking + * @see PlayerEvent.StopTracking + * @see PlayerEvent.LoadFromFile + * @see PlayerEvent.SaveToFile + * @see PlayerEvent.ItemCraftedEvent + * @see PlayerEvent.ItemSmeltedEvent + * @see PlayerEvent.PlayerLoggedInEvent + * @see PlayerEvent.PlayerLoggedOutEvent + * @see PlayerEvent.PlayerRespawnEvent + * @see PlayerEvent.PlayerChangedDimensionEvent + * @see PlayerEvent.PlayerChangeGameModeEvent **/ public abstract class PlayerEvent extends LivingEvent { private final Player player; @@ -47,20 +63,19 @@ public Player getEntity() { } /** - * HarvestCheck is fired when a player attempts to harvest a block.
+ * HarvestCheck is fired when a player attempts to harvest a block. + *

* This event is fired whenever a player attempts to harvest a block in - * {@link Player#hasCorrectToolForDrops(BlockState)}.
- *
- * This event is fired via the {@link EventHooks#doPlayerHarvestCheck(Player, BlockState, BlockGetter, BlockPos)}.
- *
- * {@link #state} contains the {@link BlockState} that is being checked for harvesting.
- * {@link #success} contains the boolean value for whether the Block will be successfully harvested.
- *
- * This event is not {@link net.neoforged.bus.api.ICancellableEvent}.
- *
- * This event does not have a result. {@link Event.HasResult}
- *
- * This event is fired on the {@link NeoForge#EVENT_BUS}. + * {@link Player#hasCorrectToolForDrops(BlockState)}. + *

+ * This event is fired via the {@link EventHooks#doPlayerHarvestCheck(Player, BlockState, BlockGetter, BlockPos)}. + *

    + *
  • {@link #state} contains the {@link BlockState} that is being checked for harvesting.
  • + *
  • {@link #success} contains the boolean value for whether the Block will be successfully harvested.
  • + *
  • {@link #getEntity} contains the player that caused this event to occur.
  • + *
+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. **/ public static class HarvestCheck extends PlayerEvent { private final BlockState state; @@ -98,22 +113,22 @@ public void setCanHarvest(boolean success) { } /** - * BreakSpeed is fired when a player attempts to harvest a block.
+ * BreakSpeed is fired when a player attempts to harvest a block. + *

* This event is fired whenever a player attempts to harvest a block in - * {@link Player#getDigSpeed(BlockState, BlockPos)}.
- *
- * This event is fired via the {@link EventHooks#getBreakSpeed(Player, BlockState, float, BlockPos)}.
- *
- * {@link #state} contains the block being broken.
- * {@link #originalSpeed} contains the original speed at which the player broke the block.
- * {@link #newSpeed} contains the newSpeed at which the player will break the block.
- * {@link #pos} contains the coordinates at which this event is occurring. Optional value.
- *
- * This event is {@link net.neoforged.bus.api.ICancellableEvent}.
- * If it is canceled, the player is unable to break the block.
- *
- * This event does not have a result. {@link Event.HasResult}
- *
+ * {@link Player#getDigSpeed(BlockState, BlockPos)}. + *

+ * This event is fired via the {@link EventHooks#getBreakSpeed(Player, BlockState, float, BlockPos)}. + *

    + *
  • {@link #state} contains the block being broken.
  • + *
  • {@link #originalSpeed} contains the original speed at which the player broke the block.
  • + *
  • {@link #newSpeed} contains the newSpeed at which the player will break the block.
  • + *
  • {@link #pos} contains the coordinates at which this event is occurring. Optional value.
  • + *
  • {@link #getEntity} contains the player that caused this event to occur.
  • + *
+ * This event is {@link net.neoforged.bus.api.ICancellableEvent}. + * If it is canceled, the player is unable to break the block. + *

* This event is fired on the {@link NeoForge#EVENT_BUS}. **/ public static class BreakSpeed extends PlayerEvent implements ICancellableEvent { @@ -153,20 +168,18 @@ public Optional getPosition() { } /** - * NameFormat is fired when a player's display name is retrieved.
+ * NameFormat is fired when a player's display name is retrieved. + *

* This event is fired whenever a player's name is retrieved in - * {@link Player#getDisplayName()} or {@link Player#refreshDisplayName()}.
- *
- * This event is fired via the {@link EventHooks#getPlayerDisplayName(Player, Component)}.
- *
- * {@link #username} contains the username of the player. - * {@link #displayname} contains the display name of the player. - *
- * This event is not {@link net.neoforged.bus.api.ICancellableEvent}. - *
- * This event does not have a result. {@link Event.HasResult} - *
- * This event is fired on the {@link NeoForge#EVENT_BUS}. + * {@link Player#getDisplayName()} or {@link Player#refreshDisplayName()}. + *

+ * This event is fired via the {@link EventHooks#getPlayerDisplayName(Player, Component)}. + *

    + *
  • {@link #username} contains the username of the player.
  • + *
  • {@link #displayname} contains the display name of the player.
  • + *
+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. **/ public static class NameFormat extends PlayerEvent { private final Component username; @@ -192,19 +205,17 @@ public void setDisplayname(Component displayname) { } /** - * TabListNameFormat is fired when a player's display name for the tablist is retrieved.
+ * TabListNameFormat is fired when a player's display name for the tablist is retrieved. + *

* This event is fired whenever a player's display name for the tablist is retrieved in - * {@link ServerPlayer#getTabListDisplayName()} or {@link ServerPlayer#refreshTabListName()}.
- *
- * This event is fired via the {@link EventHooks#getPlayerTabListDisplayName(Player)}.
- *
+ * {@link ServerPlayer#getTabListDisplayName()} or {@link ServerPlayer#refreshTabListName()}. + *

+ * This event is fired via the {@link EventHooks#getPlayerTabListDisplayName(Player)}. + *

* {@link #getDisplayName()} contains the display name of the player or null if the client should determine the display name itself. - *
- * This event is not {@link net.neoforged.bus.api.ICancellableEvent}. - *
- * This event does not have a result. {@link Event.HasResult} - *
- * This event is fired on the {@link NeoForge#EVENT_BUS}. + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. **/ public static class TabListNameFormat extends PlayerEvent { @Nullable @@ -225,8 +236,11 @@ public void setDisplayName(@Nullable Component displayName) { } /** - * Fired when the EntityPlayer is cloned, typically caused by the impl sending a RESPAWN_PLAYER event. + * Fired when the player is cloned, typically caused by the impl sending a RESPAWN_PLAYER event. * Either caused by death, or by traveling from the End to the overworld. + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. */ public static class Clone extends PlayerEvent { private final Player original; @@ -239,7 +253,7 @@ public Clone(Player _new, Player oldPlayer, boolean wasDeath) { } /** - * The old EntityPlayer that this new entity is a clone of. + * The old Player that this new entity is a clone of. */ public Player getOriginal() { return original; @@ -256,7 +270,9 @@ public boolean isWasDeath() { /** * Fired when an Entity is started to be "tracked" by this player (the player receives updates about this entity, e.g. motion). - * + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. */ public static class StartTracking extends PlayerEvent { private final Entity target; @@ -276,7 +292,9 @@ public Entity getTarget() { /** * Fired when an Entity is stopped to be "tracked" by this player (the player no longer receives updates about this entity, e.g. motion). - * + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. */ public static class StopTracking extends PlayerEvent { private final Entity target; @@ -295,10 +313,14 @@ public Entity getTarget() { } /** - * The player is being loaded from the world save. Note that the - * player won't have been added to the world yet. Intended to + * The player is being loaded from the world save. + *

+ * Note: The player won't have been added to the world yet. Intended to * allow mods to load an additional file from the players directory * containing additional mod related player data. + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. */ public static class LoadFromFile extends PlayerEvent { private final File playerDirectory; @@ -312,7 +334,7 @@ public LoadFromFile(Player player, File originDirectory, String playerUUID) { /** * Construct and return a recommended file for the supplied suffix - * + * * @param suffix The suffix to use. */ public File getPlayerFile(String suffix) { @@ -338,17 +360,21 @@ public String getPlayerUUID() { } /** - * The player is being saved to the world store. Note that the - * player may be in the process of logging out or otherwise departing - * from the world. Don't assume it's association with the world. + * The player is being saved to the world store. + *

+ * Note: The player may be in the process of logging out or otherwise + * departing from the world. Don't assume its association with the world. + *

* This allows mods to load an additional file from the players directory * containing additional mod related player data. - *
+ *

* Use this event to save the additional mod related player data to the world. - * - *
+ *

* WARNING: Do not overwrite the player's .dat file here. You will * corrupt the world state. + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. */ public static class SaveToFile extends PlayerEvent { private final File playerDirectory; @@ -406,6 +432,14 @@ public Container getInventory() { } } + /** + * Fired when a player takes the resultant ItemStack from a furnace-like block. + *

+ * This event is fired via the {@link EventHooks#firePlayerSmeltedEvent(Player, ItemStack, int)}. + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. + */ public static class ItemSmeltedEvent extends PlayerEvent { private final ItemStack smelting; private final int amountRemoved; @@ -425,18 +459,37 @@ public int getAmountRemoved() { } } + /** + * Fired when the player is placed into the server via {@link PlayerList#placeNewPlayer(Connection, ServerPlayer, CommonListenerCookie)} + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. + */ public static class PlayerLoggedInEvent extends PlayerEvent { public PlayerLoggedInEvent(Player player) { super(player); } } + /** + * Fired when the player is removed from the server via {@link PlayerList#remove(ServerPlayer)} + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. + */ public static class PlayerLoggedOutEvent extends PlayerEvent { public PlayerLoggedOutEvent(Player player) { super(player); } } + /** + * Fired when the player is respawned via {@link PlayerList#respawn(ServerPlayer, boolean)} + * after creating and initializing the new {@link ServerPlayer}. + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. + */ public static class PlayerRespawnEvent extends PlayerEvent { private final boolean endConquered; @@ -455,6 +508,12 @@ public boolean isEndConquered() { } } + /** + * Fired when the player is teleported to a new dimension via {@link ServerPlayer#teleport(TeleportTransition)} + *

+ * This event is not {@linkplain net.neoforged.bus.api.ICancellableEvent cancellable}, and is fired on the + * {@linkplain NeoForge#EVENT_BUS game event bus}. + */ public static class PlayerChangedDimensionEvent extends PlayerEvent { private final ResourceKey fromDim; private final ResourceKey toDim; @@ -476,7 +535,10 @@ public ResourceKey getTo() { /** * Fired when the game type of a server player is changed to a different value than what it was previously. Eg Creative to Survival, not Survival to Survival. + *

* If the event is cancelled the game mode of the player is not changed and the value of newGameMode is ignored. + *

+ * This event is fired on the {@link NeoForge#EVENT_BUS}. */ public static class PlayerChangeGameModeEvent extends PlayerEvent implements ICancellableEvent { private final GameType currentGameMode; diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerXpEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerXpEvent.java index 1027c464b3c..28993f47533 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerXpEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerXpEvent.java @@ -11,11 +11,12 @@ import net.neoforged.neoforge.common.NeoForge; /** - * PlayerXpEvent is fired whenever an event involving player experience occurs.
- * If a method utilizes this {@link net.neoforged.bus.api.Event} as its parameter, the method will - * receive every child event of this class.
- *
- * All children of this event are fired on the {@link NeoForge#EVENT_BUS}. + * Base class of events involving player experience. + *

+ * + * @see PlayerXpEvent.PickupXp + * @see PlayerXpEvent.XpChange + * @see PlayerXpEvent.LevelChange */ public abstract class PlayerXpEvent extends PlayerEvent { public PlayerXpEvent(Player player) { @@ -24,7 +25,10 @@ public PlayerXpEvent(Player player) { /** * This event is fired after the player collides with an experience orb, but before the player has been given the experience. + *

* It can be cancelled, and no further processing will be done. + *

+ * This event is fired on the {@link NeoForge#EVENT_BUS}. */ public static class PickupXp extends PlayerXpEvent implements ICancellableEvent { private final ExperienceOrb orb; @@ -41,7 +45,10 @@ public ExperienceOrb getOrb() { /** * This event is fired when the player's experience changes through the {@link Player#giveExperiencePoints(int)} method. + *

* It can be cancelled, and no further processing will be done. + *

+ * This event is fired on the {@link NeoForge#EVENT_BUS}. */ public static class XpChange extends PlayerXpEvent implements ICancellableEvent { private int amount; @@ -62,7 +69,10 @@ public void setAmount(int amount) { /** * This event is fired when the player's experience level changes through the {@link Player#giveExperienceLevels(int)} method. + *

* It can be cancelled, and no further processing will be done. + *

+ * This event is fired on the {@link NeoForge#EVENT_BUS}. */ public static class LevelChange extends PlayerXpEvent implements ICancellableEvent { private int levels; diff --git a/src/main/java/net/neoforged/neoforge/event/level/ExplosionEvent.java b/src/main/java/net/neoforged/neoforge/event/level/ExplosionEvent.java index 34118e37908..f5dac69cdaf 100644 --- a/src/main/java/net/neoforged/neoforge/event/level/ExplosionEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/level/ExplosionEvent.java @@ -22,7 +22,6 @@ *
* ExplosionEvent.Start is {@link ICancellableEvent}.
* ExplosionEvent.Detonate can modify the affected blocks and entities.
- * Children do not use {@link HasResult}.
* Children of this event are fired on the {@link NeoForge#EVENT_BUS}.
*/ public abstract class ExplosionEvent extends Event { @@ -46,7 +45,6 @@ public ServerExplosion getExplosion() { * ExplosionEvent.Start is fired before the explosion actually occurs. Canceling this event will stop the explosion.
*
* This event is {@link ICancellableEvent}.
- * This event does not use {@link HasResult}.
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*/ public static class Start extends ExplosionEvent implements ICancellableEvent { @@ -59,7 +57,6 @@ public Start(Level level, ServerExplosion explosion) { * ExplosionEvent.Detonate is fired once the explosion has a list of affected blocks and entities. These lists can be modified to change the outcome.
*
* This event is not {@link ICancellableEvent}.
- * This event does not use {@link HasResult}.
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*/ public static class Detonate extends ExplosionEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/level/ExplosionKnockbackEvent.java b/src/main/java/net/neoforged/neoforge/event/level/ExplosionKnockbackEvent.java index 321e30f49ee..97cb94d06b7 100644 --- a/src/main/java/net/neoforged/neoforge/event/level/ExplosionKnockbackEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/level/ExplosionKnockbackEvent.java @@ -18,7 +18,6 @@ * ExplosionKnockbackEvent is fired once the explosion has calculated the knockback velocity to add to the entity caught in blast.
*
* This event is not {@link ICancellableEvent}.
- * This event does not use {@link HasResult}.
* This event is fired on the {@link NeoForge#EVENT_BUS}.
*/ public class ExplosionKnockbackEvent extends ExplosionEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/level/GameRuleChangedEvent.java b/src/main/java/net/neoforged/neoforge/event/level/GameRuleChangedEvent.java new file mode 100644 index 00000000000..72a3f993360 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/level/GameRuleChangedEvent.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.level; + +import java.util.function.Consumer; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.gamerules.GameRule; +import net.minecraft.world.level.gamerules.GameRules; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.LogicalSide; +import net.neoforged.neoforge.common.NeoForge; +import org.jetbrains.annotations.ApiStatus; + +/** + * Event which is fired when ever a {@link GameRule} is updated. + *

+ * This event is fired on the {@link NeoForge#EVENT_BUS main NeoForge event bus}, only on the {@linkplain LogicalSide#SERVER logical server}. + */ +public final class GameRuleChangedEvent extends Event { + private final MinecraftServer server; + private final GameRule gameRule; + private final Object newValue; + + @ApiStatus.Internal + public GameRuleChangedEvent(MinecraftServer server, GameRule gameRule, T newValue) { + this.server = server; + this.gameRule = gameRule; + this.newValue = newValue; + } + + public MinecraftServer getServer() { + return server; + } + + public GameRules getGameRules() { + return server.getWorldData().getGameRules(); + } + + public GameRule getGameRule() { + return gameRule; + } + + public Object getNewValue() { + return newValue; + } + + /** + * Executes the given {@code action} if the updated {@link GameRule} matches {@code gameRule}. + * + * @param gameRule {@link GameRule} to validate aganst. + * @param action Action to be invoked if the updated game rule matches, passing in the updated value. + * @param Game rule data type. + */ + @SuppressWarnings("unchecked") + public void runIfMatching(GameRule gameRule, Consumer action) { + if (this.gameRule == gameRule) { + action.accept((T) newValue); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/event/level/SleepFinishedTimeEvent.java b/src/main/java/net/neoforged/neoforge/event/level/SleepFinishedTimeEvent.java index 3c0dea54a6d..2bfe663bde6 100644 --- a/src/main/java/net/neoforged/neoforge/event/level/SleepFinishedTimeEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/level/SleepFinishedTimeEvent.java @@ -6,39 +6,33 @@ package net.neoforged.neoforge.event.level; import net.minecraft.server.level.ServerLevel; +import net.neoforged.bus.api.ICancellableEvent; +import net.neoforged.neoforge.common.util.ClockAdjustment; /** - * This event is fired when all players are asleep and the time should be set to day.
- * - * setWakeUpTime(wakeUpTime) sets a new time that will be added to the dayTime.
+ * This event is fired to adjust the clock of a level after sleep. */ -public class SleepFinishedTimeEvent extends LevelEvent { - private long newTime; - private final long minTime; +public class SleepFinishedTimeEvent extends LevelEvent implements ICancellableEvent { + private ClockAdjustment adjustment; - public SleepFinishedTimeEvent(ServerLevel level, long newTime, long minTime) { + public SleepFinishedTimeEvent(ServerLevel level, ClockAdjustment defaultAdjustment) { super(level); - this.newTime = newTime; - this.minTime = minTime; + this.adjustment = defaultAdjustment; } /** - * @return the new time + * {@return the adjustment that will be made to the clock when the event is not canceled} */ - public long getNewTime() { - return newTime; + public ClockAdjustment getAdjustment() { + return adjustment; } /** * Sets the new time which should be set when all players wake up - * - * @param newTimeIn The new time at wakeup - * @return {@code false} if newTimeIn was lower than current time + * + * @param adjustment The adjustment that should be made to the levels clock when this event isn't canceled. */ - public boolean setTimeAddition(long newTimeIn) { - if (minTime > newTimeIn) - return false; - this.newTime = newTimeIn; - return true; + public void setAdjustment(ClockAdjustment adjustment) { + this.adjustment = adjustment; } } diff --git a/src/main/java/net/neoforged/neoforge/event/village/VillageSiegeEvent.java b/src/main/java/net/neoforged/neoforge/event/village/VillageSiegeEvent.java index bda92decade..7d8f78c3557 100644 --- a/src/main/java/net/neoforged/neoforge/event/village/VillageSiegeEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/village/VillageSiegeEvent.java @@ -19,8 +19,6 @@ *
* This event is {@link ICancellableEvent}; canceling stops the siege.
*
- * This event does not have a result. {@link HasResult}
- *
* This event is fired on the {@link NeoForge#EVENT_BUS}. */ public class VillageSiegeEvent extends Event implements ICancellableEvent { diff --git a/src/main/java/net/neoforged/neoforge/event/village/VillagerTradesEvent.java b/src/main/java/net/neoforged/neoforge/event/village/VillagerTradesEvent.java deleted file mode 100644 index 0f75acf5972..00000000000 --- a/src/main/java/net/neoforged/neoforge/event/village/VillagerTradesEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.event.village; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import java.util.List; -import net.minecraft.core.HolderLookup; -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.entity.npc.villager.VillagerData; -import net.minecraft.world.entity.npc.villager.VillagerProfession; -import net.minecraft.world.entity.npc.villager.VillagerTrades.ItemListing; -import net.neoforged.bus.api.Event; -import net.neoforged.neoforge.common.BasicItemListing; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.TagsUpdatedEvent; -import org.jetbrains.annotations.ApiStatus; - -/** - * VillagerTradesEvent is fired during reload by {@link TagsUpdatedEvent}. It is used to gather the trade lists for each profession. - * It is fired on the {@link NeoForge#EVENT_BUS}. - * It is fired once for each registered villager profession. - * Villagers pick two trades from their trade map, based on their level. - * Villager level is increased by successful trades. - * The map is populated for levels 1-5 (inclusive), so Map#get will never return null for those keys. - * Levels outside of this range do nothing, as specified by {@link VillagerData#canLevelUp(int)} which is called before attempting to level up. - * To add trades to the merchant, simply add new trades to the list. {@link BasicItemListing} provides a default implementation. - */ -public class VillagerTradesEvent extends Event { - protected Int2ObjectMap> trades; - protected ResourceKey type; - private final HolderLookup.Provider registries; - - @ApiStatus.Internal - public VillagerTradesEvent(Int2ObjectMap> trades, ResourceKey type, HolderLookup.Provider registries) { - this.trades = trades; - this.type = type; - this.registries = registries; - } - - public Int2ObjectMap> getTrades() { - return trades; - } - - public ResourceKey getType() { - return type; - } - - public HolderLookup.Provider getRegistries() { - return registries; - } -} diff --git a/src/main/java/net/neoforged/neoforge/event/village/WandererTradesEvent.java b/src/main/java/net/neoforged/neoforge/event/village/WandererTradesEvent.java deleted file mode 100644 index 888cb5f1d3c..00000000000 --- a/src/main/java/net/neoforged/neoforge/event/village/WandererTradesEvent.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.event.village; - -import java.util.List; -import net.minecraft.core.HolderLookup; -import net.minecraft.core.HolderLookup.Provider; -import net.minecraft.world.entity.npc.villager.VillagerTrades.ItemListing; -import net.neoforged.bus.api.Event; -import net.neoforged.neoforge.common.BasicItemListing; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.TagsUpdatedEvent; -import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.ApiStatus; - -/** - * WandererTradesEvent is fired during reload by {@link TagsUpdatedEvent}. It is used to gather the trade lists for the wandering merchant. - * It is fired on the {@link NeoForge#EVENT_BUS}. - * For each set of trades the wandering merchant picks the specified amount of trades from the corresponding list. - * To add trades to the merchant, simply add new trades to the list. {@link BasicItemListing} provides a default implementation. - */ -public class WandererTradesEvent extends Event { - protected List buying; - protected int buyingAmount; - protected List rare; - protected int rareAmount; - protected List generic; - protected int genericAmount; - protected List, Integer>> additionalTrades; - private final HolderLookup.Provider registries; - - @ApiStatus.Internal - public WandererTradesEvent(List buying, int buyingAmount, List rare, int rareAmount, List generic, int genericAmount, List, Integer>> additionalTrades, Provider registries) { - this.buying = buying; - this.buyingAmount = buyingAmount; - this.rare = rare; - this.rareAmount = rareAmount; - this.generic = generic; - this.genericAmount = genericAmount; - this.additionalTrades = additionalTrades; - this.registries = registries; - } - - public List getBuyingTrades() { - return buying; - } - - public int getBuyingAmount() { - return buyingAmount; - } - - public void setBuyingAmount(int amount) { - buyingAmount = amount; - } - - public List getRareTrades() { - return rare; - } - - public int getRareAmount() { - return rareAmount; - } - - public void setRareAmount(int amount) { - rareAmount = amount; - } - - public List getGenericTrades() { - return generic; - } - - public int getGenericAmount() { - return genericAmount; - } - - public void setGenericAmount(int amount) { - genericAmount = amount; - } - - public void addTrades(List trades, int amount) { - additionalTrades.add(Pair.of(trades, amount)); - } - - public HolderLookup.Provider getRegistries() { - return registries; - } -} diff --git a/src/main/java/net/neoforged/neoforge/fluids/FluidStack.java b/src/main/java/net/neoforged/neoforge/fluids/FluidStack.java index 0e1e4452f53..29f5c4ff12c 100644 --- a/src/main/java/net/neoforged/neoforge/fluids/FluidStack.java +++ b/src/main/java/net/neoforged/neoforge/fluids/FluidStack.java @@ -5,6 +5,7 @@ package net.neoforged.neoforge.fluids; +import com.google.common.collect.Lists; import com.mojang.logging.LogUtils; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; @@ -12,15 +13,17 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.EncoderException; +import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.function.Predicate; -import java.util.stream.Stream; +import net.minecraft.ChatFormatting; import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; +import net.minecraft.core.TypedInstance; import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.PatchedDataComponentMap; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; @@ -28,12 +31,16 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; -import net.minecraft.tags.TagKey; import net.minecraft.util.ExtraCodecs; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; import net.neoforged.neoforge.common.MutableDataComponentHolder; +import net.neoforged.neoforge.event.EventHooks; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -44,7 +51,7 @@ * *

Most methods in this class are adapted from {@link ItemStack}. */ -public final class FluidStack implements MutableDataComponentHolder { +public final class FluidStack implements MutableDataComponentHolder, TypedInstance { public static final Codec> FLUID_NON_EMPTY_CODEC = BuiltInRegistries.FLUID.holderByNameCodec().validate(holder -> { return holder.is(Fluids.EMPTY.builtInRegistryHolder()) ? DataResult.error(() -> { return "Fluid must not be minecraft:empty"; @@ -57,7 +64,7 @@ public final class FluidStack implements MutableDataComponentHolder { "FluidStack", c -> RecordCodecBuilder.mapCodec( instance -> instance.group( - FLUID_NON_EMPTY_CODEC.fieldOf("id").forGetter(FluidStack::getFluidHolder), + FLUID_NON_EMPTY_CODEC.fieldOf("id").forGetter(FluidStack::typeHolder), ExtraCodecs.POSITIVE_INT.fieldOf("amount").forGetter(FluidStack::getAmount), // note: no .orElse(1) compared to ItemStack DataComponentPatch.CODEC.optionalFieldOf("components", DataComponentPatch.EMPTY) .forGetter(stack -> stack.components.asPatch())) @@ -77,7 +84,7 @@ public static Codec fixedAmountCodec(int amount) { return Codec.lazyInitialized( () -> RecordCodecBuilder.create( instance -> instance.group( - FLUID_NON_EMPTY_CODEC.fieldOf("id").forGetter(FluidStack::getFluidHolder), + FLUID_NON_EMPTY_CODEC.fieldOf("id").forGetter(FluidStack::typeHolder), DataComponentPatch.CODEC.optionalFieldOf("components", DataComponentPatch.EMPTY) .forGetter(stack -> stack.components.asPatch())) .apply(instance, (holder, patch) -> new FluidStack(holder, amount, patch)))); @@ -112,7 +119,7 @@ public void encode(RegistryFriendlyByteBuf buf, FluidStack stack) { buf.writeVarInt(0); } else { buf.writeVarInt(stack.getAmount()); - FLUID_STREAM_CODEC.encode(buf, stack.getFluidHolder()); + FLUID_STREAM_CODEC.encode(buf, stack.typeHolder()); DataComponentPatch.STREAM_CODEC.encode(buf, stack.components.asPatch()); } } @@ -227,32 +234,13 @@ public Fluid getFluid() { return this.isEmpty() ? Fluids.EMPTY : this.fluid; } - public Holder getFluidHolder() { + @Override + public Holder typeHolder() { return this.getFluid().builtInRegistryHolder(); } - public boolean is(TagKey tag) { - return this.getFluid().builtInRegistryHolder().is(tag); - } - - public boolean is(Fluid fluid) { - return this.getFluid() == fluid; - } - public boolean is(Predicate> holderPredicate) { - return holderPredicate.test(this.getFluidHolder()); - } - - public boolean is(Holder holder) { - return is(holder.value()); - } - - public boolean is(HolderSet holderSet) { - return holderSet.contains(this.getFluidHolder()); - } - - public Stream> getTags() { - return this.getFluid().builtInRegistryHolder().tags(); + return holderPredicate.test(this.typeHolder()); } /** @@ -343,6 +331,52 @@ public String toString() { return this.getAmount() + " " + this.getFluid(); } + /** + * Builds the tooltip lines for this fluid stack, intended for use by mods + * rendering fluids in GUIs. + * + *

This mirrors the behavior of + * {@link ItemStack#getTooltipLines(Item.TooltipContext, Player, TooltipFlag)} + * as closely as possible for fluids.

+ * + *

The tooltip consists of: + *

    + *
  • The styled hover name
  • + *
  • Additional lines provided by the fluid itself
  • + *
  • Lines added by {@link EventHooks#onFluidTooltip}
  • + *
  • The registry name when advanced tooltips are enabled
  • + *
+ *

+ * + *

If tooltips are hidden via {@link TooltipDisplay} and the tooltip is not + * being rendered in creative mode, an empty list is returned.

+ * + * @param context the tooltip context + * @param player the player viewing the tooltip, or {@code null} + * @param flag controls tooltip verbosity and advanced information + * @return a list of tooltip components, possibly empty + */ + public List getTooltipLines(Item.TooltipContext context, @Nullable Player player, TooltipFlag flag) { + TooltipDisplay tooltipDisplay = this.getOrDefault(DataComponents.TOOLTIP_DISPLAY, TooltipDisplay.DEFAULT); + if (!flag.isCreative() && tooltipDisplay.hideTooltip()) { + return List.of(); + } else { + Fluid fluid = getFluid(); + List list = Lists.newArrayList(); + list.add(this.getHoverName()); + fluid.appendHoverText(this, context, tooltipDisplay, list::add, flag); + EventHooks.onFluidTooltip(this, player, list, flag, context); + if (flag.isAdvanced()) { + list.add(Component.literal(BuiltInRegistries.FLUID.getKey(fluid).toString()).withStyle(ChatFormatting.DARK_GRAY)); + int componentCount = this.components.size(); + if (componentCount > 0) { + list.add(Component.translatable("item.components", componentCount).withStyle(ChatFormatting.DARK_GRAY)); + } + } + return list; + } + } + /** * Sets a data component. */ diff --git a/src/main/java/net/neoforged/neoforge/fluids/FluidType.java b/src/main/java/net/neoforged/neoforge/fluids/FluidType.java index 4eac8bc4159..7397ee8c95d 100644 --- a/src/main/java/net/neoforged/neoforge/fluids/FluidType.java +++ b/src/main/java/net/neoforged/neoforge/fluids/FluidType.java @@ -841,7 +841,7 @@ public boolean isVaporizedOnPlacement(Level level, BlockPos pos, FluidStack stac */ public void onVaporize(@Nullable LivingEntity entity, Level level, BlockPos pos, FluidStack stack) { SoundEvent sound = this.getSound(entity, level, pos, SoundActions.FLUID_VAPORIZE); - level.playSound(entity, pos, sound != null ? sound : SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (level.random.nextFloat() - level.random.nextFloat()) * 0.8F); + level.playSound(entity, pos, sound != null ? sound : SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (level.getRandom().nextFloat() - level.getRandom().nextFloat()) * 0.8F); for (int l = 0; l < 8; ++l) level.addAlwaysVisibleParticle(ParticleTypes.LARGE_SMOKE, (double) pos.getX() + Math.random(), (double) pos.getY() + Math.random(), (double) pos.getZ() + Math.random(), 0.0D, 0.0D, 0.0D); diff --git a/src/main/java/net/neoforged/neoforge/fluids/SimpleFluidContent.java b/src/main/java/net/neoforged/neoforge/fluids/SimpleFluidContent.java index 163293d06be..82eeb43e8fd 100644 --- a/src/main/java/net/neoforged/neoforge/fluids/SimpleFluidContent.java +++ b/src/main/java/net/neoforged/neoforge/fluids/SimpleFluidContent.java @@ -52,7 +52,7 @@ public Fluid getFluid() { } public Holder getFluidHolder() { - return fluidStack.getFluidHolder(); + return fluidStack.typeHolder(); } public boolean is(TagKey tag) { diff --git a/src/main/java/net/neoforged/neoforge/fluids/crafting/DataComponentFluidIngredient.java b/src/main/java/net/neoforged/neoforge/fluids/crafting/DataComponentFluidIngredient.java index 3462298aac5..520ea8110a3 100644 --- a/src/main/java/net/neoforged/neoforge/fluids/crafting/DataComponentFluidIngredient.java +++ b/src/main/java/net/neoforged/neoforge/fluids/crafting/DataComponentFluidIngredient.java @@ -68,7 +68,7 @@ public boolean test(FluidStack stack) { } return false; } else { - return this.fluids.contains(stack.getFluidHolder()) && this.components.test(stack); + return this.fluids.contains(stack.typeHolder()) && this.components.test(stack); } } diff --git a/src/main/java/net/neoforged/neoforge/fluids/crafting/SimpleFluidIngredient.java b/src/main/java/net/neoforged/neoforge/fluids/crafting/SimpleFluidIngredient.java index bb1f6d08297..c840f4057b7 100644 --- a/src/main/java/net/neoforged/neoforge/fluids/crafting/SimpleFluidIngredient.java +++ b/src/main/java/net/neoforged/neoforge/fluids/crafting/SimpleFluidIngredient.java @@ -54,7 +54,7 @@ public SimpleFluidIngredient(HolderSet values) { @Override public boolean test(FluidStack fluidStack) { - return values.contains(fluidStack.getFluidHolder()); + return values.contains(fluidStack.typeHolder()); } @Override diff --git a/src/main/java/net/neoforged/neoforge/internal/RegistrationEvents.java b/src/main/java/net/neoforged/neoforge/internal/RegistrationEvents.java index 32b8dfa8dc1..664edd75968 100644 --- a/src/main/java/net/neoforged/neoforge/internal/RegistrationEvents.java +++ b/src/main/java/net/neoforged/neoforge/internal/RegistrationEvents.java @@ -5,6 +5,15 @@ package net.neoforged.neoforge.internal; +import com.mojang.datafixers.util.Pair; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Predicate; +import net.minecraft.core.component.DataComponentMap; +import net.minecraft.world.item.Item; import net.neoforged.fml.ModLoader; import net.neoforged.neoforge.capabilities.CapabilityHooks; import net.neoforged.neoforge.common.world.chunk.ForcedChunkManager; @@ -14,24 +23,23 @@ import net.neoforged.neoforge.registries.RegistryManager; public class RegistrationEvents { + // TODO 26.1: Find a better solution than this + public static Map> componentModifiersByItem; + // TODO 26.1: Find a better solution than this + public static List, Consumer>> componentModifiersByPredicate; + static void init() { CauldronFluidContent.init(); // must be before capability event CapabilityHooks.init(); // must be after cauldron event ForcedChunkManager.init(); RegistryManager.initDataMaps(); - modifyComponents(); + collectComponentModifiers(); PoiTypeExtender.extendPoiTypes(); } - private static boolean canModifyComponents; - - public static void modifyComponents() { - canModifyComponents = true; - ModLoader.postEvent(new ModifyDefaultComponentsEvent()); - canModifyComponents = false; - } - - public static boolean canModifyComponents() { - return canModifyComponents; + public static void collectComponentModifiers() { + componentModifiersByItem = new HashMap<>(); + componentModifiersByPredicate = new ArrayList<>(); + ModLoader.postEvent(new ModifyDefaultComponentsEvent(componentModifiersByItem, componentModifiersByPredicate)); } } diff --git a/src/main/java/net/neoforged/neoforge/items/ItemHandlerHelper.java b/src/main/java/net/neoforged/neoforge/items/ItemHandlerHelper.java index b36b8d6c161..254e3427b08 100644 --- a/src/main/java/net/neoforged/neoforge/items/ItemHandlerHelper.java +++ b/src/main/java/net/neoforged/neoforge/items/ItemHandlerHelper.java @@ -133,7 +133,7 @@ public static void giveItemToPlayer(Player player, ItemStack stack, int preferre // play sound if something got picked up if (remainder.isEmpty() || remainder.getCount() != stack.getCount()) { level.playSound(null, player.getX(), player.getY() + 0.5, player.getZ(), - SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, 0.2F, ((level.random.nextFloat() - level.random.nextFloat()) * 0.7F + 1.0F) * 2.0F); + SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, 0.2F, ((level.getRandom().nextFloat() - level.getRandom().nextFloat()) * 0.7F + 1.0F) * 2.0F); } // drop remaining itemstack into the level diff --git a/src/main/java/net/neoforged/neoforge/model/data/ModelDataManager.java b/src/main/java/net/neoforged/neoforge/model/data/ModelDataManager.java index 70209c48ff1..9cfb2dd05e6 100644 --- a/src/main/java/net/neoforged/neoforge/model/data/ModelDataManager.java +++ b/src/main/java/net/neoforged/neoforge/model/data/ModelDataManager.java @@ -17,7 +17,6 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; @@ -132,7 +131,7 @@ private void refreshAt(long section) { // Sanity check so that mods cannot cause impossible-to-trace NPEs in other code later //noinspection ConstantValue if (newData == null) { - throw new NullPointerException("Null ModelData provided by " + BlockEntityType.getKey(toUpdate.getType()) + " @ " + pos); + throw new NullPointerException("Null ModelData provided by " + toUpdate.typeHolder().getRegisteredName() + " @ " + pos); } } // Make sure we don't bother storing empty data in the map @@ -164,7 +163,7 @@ public static void onChunkUnload(ChunkEvent.Unload event) { ChunkPos chunk = event.getChunk().getPos(); int maxSection = level.getMaxSectionY(); for (int y = level.getMinSectionY(); y < maxSection; y++) { - long section = SectionPos.asLong(chunk.x, y, chunk.z); + long section = SectionPos.asLong(chunk.x(), y, chunk.z()); modelDataManager.needModelDataRefresh.remove(section); modelDataManager.modelDataCache.remove(section); } diff --git a/src/main/java/net/neoforged/neoforge/network/NetworkInitialization.java b/src/main/java/net/neoforged/neoforge/network/NetworkInitialization.java index a4f2cf87665..347586b2749 100644 --- a/src/main/java/net/neoforged/neoforge/network/NetworkInitialization.java +++ b/src/main/java/net/neoforged/neoforge/network/NetworkInitialization.java @@ -16,7 +16,6 @@ import net.neoforged.neoforge.network.payload.AdvancedContainerSetDataPayload; import net.neoforged.neoforge.network.payload.AdvancedOpenScreenPayload; import net.neoforged.neoforge.network.payload.AuxiliaryLightDataPayload; -import net.neoforged.neoforge.network.payload.ClientboundCustomSetTimePayload; import net.neoforged.neoforge.network.payload.ConfigFilePayload; import net.neoforged.neoforge.network.payload.ExtensibleEnumAcknowledgePayload; import net.neoforged.neoforge.network.payload.ExtensibleEnumDataPayload; @@ -94,9 +93,6 @@ private static void register(final RegisterPayloadHandlersEvent event) { RegistryDataMapSyncPayload.STREAM_CODEC) .playToClient(AdvancedContainerSetDataPayload.TYPE, AdvancedContainerSetDataPayload.STREAM_CODEC) - .playToClient( - ClientboundCustomSetTimePayload.TYPE, - ClientboundCustomSetTimePayload.STREAM_CODEC) .playToClient( RecipeContentPayload.TYPE, RecipeContentPayload.STREAM_CODEC) diff --git a/src/main/java/net/neoforged/neoforge/network/payload/ClientboundCustomSetTimePayload.java b/src/main/java/net/neoforged/neoforge/network/payload/ClientboundCustomSetTimePayload.java deleted file mode 100644 index fd5d28c0de9..00000000000 --- a/src/main/java/net/neoforged/neoforge/network/payload/ClientboundCustomSetTimePayload.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.network.payload; - -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.Identifier; -import net.neoforged.neoforge.common.NeoForgeMod; -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public record ClientboundCustomSetTimePayload(long gameTime, long dayTime, boolean gameRule, float dayTimeFraction, float dayTimePerTick) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(Identifier.fromNamespaceAndPath(NeoForgeMod.MOD_ID, "custom_time_packet")); - - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.VAR_LONG, ClientboundCustomSetTimePayload::gameTime, - ByteBufCodecs.VAR_LONG, ClientboundCustomSetTimePayload::dayTime, - ByteBufCodecs.BOOL, ClientboundCustomSetTimePayload::gameRule, - ByteBufCodecs.FLOAT, ClientboundCustomSetTimePayload::dayTimeFraction, - ByteBufCodecs.FLOAT, ClientboundCustomSetTimePayload::dayTimePerTick, - ClientboundCustomSetTimePayload::new); - - @Override - public Type type() { - return TYPE; - } -} diff --git a/src/main/java/net/neoforged/neoforge/registries/DataPackRegistriesHooks.java b/src/main/java/net/neoforged/neoforge/registries/DataPackRegistriesHooks.java index 9464a393a89..2be91b809e1 100644 --- a/src/main/java/net/neoforged/neoforge/registries/DataPackRegistriesHooks.java +++ b/src/main/java/net/neoforged/neoforge/registries/DataPackRegistriesHooks.java @@ -13,6 +13,7 @@ import java.util.stream.Stream; import net.minecraft.core.Registry; import net.minecraft.resources.RegistryDataLoader; +import net.minecraft.resources.RegistryValidator; import net.minecraft.resources.ResourceKey; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.Nullable; @@ -44,7 +45,7 @@ static void addRegistryCodec(DataPackRegistryEvent.DataPackRegistryData d DATA_PACK_REGISTRIES.add(loaderData); if (data.networkCodec() != null) { SYNCED_CUSTOM_REGISTRIES.add(loaderData.key()); - NETWORKABLE_REGISTRIES.add(new RegistryDataLoader.RegistryData(loaderData.key(), data.networkCodec(), false)); + NETWORKABLE_REGISTRIES.add(new RegistryDataLoader.RegistryData(loaderData.key(), data.networkCodec(), RegistryValidator.none())); } } diff --git a/src/main/java/net/neoforged/neoforge/registries/DataPackRegistryEvent.java b/src/main/java/net/neoforged/neoforge/registries/DataPackRegistryEvent.java index 1a94965a443..0c8b808cb65 100644 --- a/src/main/java/net/neoforged/neoforge/registries/DataPackRegistryEvent.java +++ b/src/main/java/net/neoforged/neoforge/registries/DataPackRegistryEvent.java @@ -11,6 +11,7 @@ import java.util.function.Consumer; import net.minecraft.core.Registry; import net.minecraft.resources.RegistryDataLoader; +import net.minecraft.resources.RegistryValidator; import net.minecraft.resources.ResourceKey; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; @@ -71,7 +72,7 @@ public void dataPackRegistry(ResourceKey> registryKey, Codec * @see #dataPackRegistry(ResourceKey, Codec) */ public void dataPackRegistry(ResourceKey> registryKey, Codec codec, @Nullable Codec networkCodec) { - this.registryDataList.add(new DataPackRegistryData<>(new RegistryDataLoader.RegistryData<>(registryKey, codec, false), networkCodec)); + this.registryDataList.add(new DataPackRegistryData<>(new RegistryDataLoader.RegistryData<>(registryKey, codec, RegistryValidator.none()), networkCodec)); } /** @@ -94,7 +95,7 @@ public void dataPackRegistry(ResourceKey> registryKey, Codec * @see #dataPackRegistry(ResourceKey, Codec, Codec) */ public void dataPackRegistry(ResourceKey> registryKey, Codec codec, @Nullable Codec networkCodec, Consumer> consumer) { - this.registryDataList.add(new DataPackRegistryData<>(new RegistryDataLoader.RegistryData<>(registryKey, codec, false, consumer), networkCodec)); + this.registryDataList.add(new DataPackRegistryData<>(new RegistryDataLoader.RegistryData<>(registryKey, codec, RegistryValidator.none(), consumer), networkCodec)); } void process() { diff --git a/src/main/java/net/neoforged/neoforge/registries/DeferredHolder.java b/src/main/java/net/neoforged/neoforge/registries/DeferredHolder.java index f34acca1644..719dea0d718 100644 --- a/src/main/java/net/neoforged/neoforge/registries/DeferredHolder.java +++ b/src/main/java/net/neoforged/neoforge/registries/DeferredHolder.java @@ -15,6 +15,7 @@ import net.minecraft.core.Holder; import net.minecraft.core.HolderOwner; import net.minecraft.core.Registry; +import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; @@ -199,6 +200,18 @@ public boolean isBound() { return this.holder != null && this.holder.isBound(); } + @Override + public boolean areComponentsBound() { + bind(false); + return this.holder != null && this.holder.areComponentsBound(); + } + + @Override + public DataComponentMap components() { + bind(true); + return this.holder != null ? this.holder.components() : DataComponentMap.EMPTY; + } + /** * {@return true if the passed Identifier is the same as the ID of the target object} */ diff --git a/src/main/java/net/neoforged/neoforge/registries/GameData.java b/src/main/java/net/neoforged/neoforge/registries/GameData.java index 0b2707de65d..2d82f19e9bb 100644 --- a/src/main/java/net/neoforged/neoforge/registries/GameData.java +++ b/src/main/java/net/neoforged/neoforge/registries/GameData.java @@ -23,6 +23,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gamerules.GameRuleCategory; import net.neoforged.fml.ModLoader; import net.neoforged.fml.loading.progress.StartupNotificationManager; import net.neoforged.neoforge.common.CommonHooks; @@ -101,6 +102,7 @@ public static void postRegisterEvents() { SpawnPlacements.fireSpawnPlacementEvent(); ModLoader.postEvent(new BlockEntityTypeAddBlocksEvent()); CreativeModeTabRegistry.sortTabs(); + GameRuleCategory.registerModdedCategories(); } } diff --git a/src/main/java/net/neoforged/neoforge/server/command/DataComponentCommand.java b/src/main/java/net/neoforged/neoforge/server/command/DataComponentCommand.java index a91b024c27e..94ad3013c10 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/DataComponentCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/DataComponentCommand.java @@ -51,7 +51,7 @@ private static int listComponents(CommandContext ctx) throws DataComponentMap prototype = stack.getPrototype(); DataComponentPatch patch = stack.getComponentsPatch(); prototype.forEach(component -> { - Optional optData = patch.get(component.type()); + Optional optData = patch.getPatch(component.type()); if (optData == null) { // Component is default Component tooltip = CommandUtils.makeTranslatableWithFallback( "commands.neoforge.data_components.list.tooltip.default", diff --git a/src/main/java/net/neoforged/neoforge/server/command/EntityCommand.java b/src/main/java/net/neoforged/neoforge/server/command/EntityCommand.java index 7c92d37b30c..17b057aeb03 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/EntityCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/EntityCommand.java @@ -68,7 +68,7 @@ private static int execute(CommandSourceStack sender, String filter, ResourceKey Map>> list = Maps.newHashMap(); level.getEntities().getAll().forEach(e -> { MutablePair> info = list.computeIfAbsent(BuiltInRegistries.ENTITY_TYPE.getKey(e.getType()), k -> MutablePair.of(0, Maps.newHashMap())); - ChunkPos chunk = new ChunkPos(e.blockPosition()); + ChunkPos chunk = ChunkPos.containing(e.blockPosition()); info.left++; info.right.put(chunk, info.right.getOrDefault(chunk, 0) + 1); }); @@ -92,7 +92,7 @@ private static int execute(CommandSourceStack sender, String filter, ResourceKey long limit = 10; for (Map.Entry e : toSort) { if (limit-- == 0) break; - sender.sendSuccess(() -> Component.literal(" " + e.getValue() + ": " + e.getKey().x + ", " + e.getKey().z), false); + sender.sendSuccess(() -> Component.literal(" " + e.getValue() + ": " + e.getKey().x() + ", " + e.getKey().z()), false); } return toSort.size(); } else { diff --git a/src/main/java/net/neoforged/neoforge/server/command/GenerateCommand.java b/src/main/java/net/neoforged/neoforge/server/command/GenerateCommand.java index 2c1a59a6ce4..7cab864ac6f 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/GenerateCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/GenerateCommand.java @@ -64,9 +64,9 @@ private static int executeGeneration(CommandSourceStack source, BlockPos pos, in return Command.SINGLE_SUCCESS; } - ChunkPos origin = new ChunkPos(pos); + ChunkPos origin = ChunkPos.containing(pos); - activeTask = new GenerationTask(source.getLevel(), origin.x, origin.z, chunkRadius); + activeTask = new GenerationTask(source.getLevel(), origin.x(), origin.z(), chunkRadius); int diameter = chunkRadius * 2 + 1; if (progressBar) { diff --git a/src/main/java/net/neoforged/neoforge/server/command/TimeSpeedCommand.java b/src/main/java/net/neoforged/neoforge/server/command/TimeSpeedCommand.java index a60d49d7da1..36d2d40ca59 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/TimeSpeedCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/TimeSpeedCommand.java @@ -33,8 +33,15 @@ class TimeSpeedCommand { } private static int query(CommandSourceStack source) { - final float speed = source.getLevel().getDayTimePerTick(); - if (speed < 0) { + var clockManager = source.getLevel().clockManager(); + var defaultClock = source.getLevel().dimensionType().defaultClock().orElse(null); + if (defaultClock == null) { + source.sendFailure(CommandUtils.makeTranslatableWithFallback("commands.neoforge.timespeed.query.no_default_clock", levelName(source))); + return Command.SINGLE_SUCCESS; + } + + final float speed = clockManager.getSpeed(defaultClock); + if (speed == 1) { source.sendSuccess(() -> CommandUtils.makeTranslatableWithFallback("commands.neoforge.timespeed.query.default", levelName(source)), true); } else { source.sendSuccess(() -> CommandUtils.makeTranslatableWithFallback("commands.neoforge.timespeed.query", levelName(source), speed, minutes(speed)), true); @@ -61,7 +68,15 @@ private static int setSpeed(CommandSourceStack source, float speed) { source.sendSuccess(() -> CommandUtils.makeTranslatableWithFallback("commands.gamerule.set", GameRules.ADVANCE_TIME.id(), gameRules.getAsString(GameRules.ADVANCE_TIME)), true); return Command.SINGLE_SUCCESS; } - source.getLevel().setDayTimePerTick(speed); + + var clockManager = source.getLevel().clockManager(); + var defaultClock = source.getLevel().dimensionType().defaultClock().orElse(null); + if (defaultClock == null) { + source.sendFailure(CommandUtils.makeTranslatableWithFallback("commands.neoforge.timespeed.query.no_default_clock", levelName(source))); + return Command.SINGLE_SUCCESS; + } + + clockManager.setSpeed(defaultClock, speed); source.sendSuccess(() -> CommandUtils.makeTranslatableWithFallback("commands.neoforge.timespeed.set", levelName(source), speed, minutes(speed)), true); return Command.SINGLE_SUCCESS; } @@ -74,7 +89,14 @@ private static int setDaylength(CommandSourceStack source, int minutes) { } private static int setDefault(CommandSourceStack source) { - source.getLevel().setDayTimePerTick(-1f); + var clockManager = source.getLevel().clockManager(); + var defaultClock = source.getLevel().dimensionType().defaultClock().orElse(null); + if (defaultClock == null) { + source.sendFailure(CommandUtils.makeTranslatableWithFallback("commands.neoforge.timespeed.query.no_default_clock", levelName(source))); + return Command.SINGLE_SUCCESS; + } + + clockManager.setSpeed(defaultClock, 1); source.sendSuccess(() -> CommandUtils.makeTranslatableWithFallback("commands.neoforge.timespeed.set.default", levelName(source)), true); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/net/neoforged/neoforge/server/command/generation/CoarseOnionIterator.java b/src/main/java/net/neoforged/neoforge/server/command/generation/CoarseOnionIterator.java index 1cf4b7bbc05..ec4d0b1cfc2 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/generation/CoarseOnionIterator.java +++ b/src/main/java/net/neoforged/neoforge/server/command/generation/CoarseOnionIterator.java @@ -48,8 +48,8 @@ private CellIterator createCellIterator(ChunkPos pos) { int size = this.cellSize; int radius = this.radius; - int x0 = pos.x * size; - int z0 = pos.z * size; + int x0 = pos.x() * size; + int z0 = pos.z() * size; int x1 = x0 + size - 1; int z1 = z0 + size - 1; return new CellIterator( diff --git a/src/main/java/net/neoforged/neoforge/server/command/generation/GenerationTask.java b/src/main/java/net/neoforged/neoforge/server/command/generation/GenerationTask.java index 55b597b602d..a1cec71ffb8 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/generation/GenerationTask.java +++ b/src/main/java/net/neoforged/neoforge/server/command/generation/GenerationTask.java @@ -201,7 +201,7 @@ private LongList collectChunks(int count) { continue; } - chunks.add(ChunkPos.asLong(chunkPosInLocalSpace.x + this.x, chunkPosInLocalSpace.z + this.z)); + chunks.add(ChunkPos.pack(chunkPosInLocalSpace.x() + this.x, chunkPosInLocalSpace.z() + this.z)); i++; } @@ -209,17 +209,17 @@ private LongList collectChunks(int count) { } private void acquireChunk(long chunk) { - ChunkPos pos = new ChunkPos(chunk); + ChunkPos pos = ChunkPos.unpack(chunk); this.chunkSource.addTicketWithRadius(NeoForgeMod.GENERATE_FORCED_TICKET.value(), pos, 0); } private void releaseChunk(long chunk) { - ChunkPos pos = new ChunkPos(chunk); + ChunkPos pos = ChunkPos.unpack(chunk); this.chunkSource.removeTicketWithRadius(NeoForgeMod.GENERATE_FORCED_TICKET.value(), pos, 0); } private boolean isChunkFullyGenerated(ChunkPos chunkPosInLocalSpace) { - ChunkPos chunkPosInWorldSpace = new ChunkPos(chunkPosInLocalSpace.x + this.x, chunkPosInLocalSpace.z + this.z); + ChunkPos chunkPosInWorldSpace = new ChunkPos(chunkPosInLocalSpace.x() + this.x, chunkPosInLocalSpace.z() + this.z); CollectFields collectFields = new CollectFields(new FieldSelector(StringTag.TYPE, "Status")); this.chunkSource.chunkMap.chunkScanner().scanChunk(chunkPosInWorldSpace, collectFields).join(); diff --git a/src/main/java/net/neoforged/neoforge/transfer/ResourceHandlerUtil.java b/src/main/java/net/neoforged/neoforge/transfer/ResourceHandlerUtil.java index 3833dd9fa3d..c55621fdfb9 100644 --- a/src/main/java/net/neoforged/neoforge/transfer/ResourceHandlerUtil.java +++ b/src/main/java/net/neoforged/neoforge/transfer/ResourceHandlerUtil.java @@ -255,6 +255,28 @@ public static int move( Predicate filter, int amount, @Nullable TransactionContext transaction) { + return moveInternal(from, to, filter, amount, false, transaction); + } + + /** + * Same as {@link #move}, but uses {@link #insertStacking} for inserting resources. + */ + public static int moveStacking( + @Nullable ResourceHandler from, + @Nullable ResourceHandler to, + Predicate filter, + int amount, + @Nullable TransactionContext transaction) { + return moveInternal(from, to, filter, amount, true, transaction); + } + + private static int moveInternal( + @Nullable ResourceHandler from, + @Nullable ResourceHandler to, + Predicate filter, + int amount, + boolean stacking, + @Nullable TransactionContext transaction) { Objects.requireNonNull(filter, "Filter may not be null"); TransferPreconditions.checkNonNegative(amount); if (from == null || to == null || amount == 0) return 0; @@ -277,7 +299,12 @@ public static int move( try (Transaction transferTransaction = Transaction.open(subTransaction)) { // check how much can be inserted - int inserted = to.insert(fromResource, maxExtracted, transferTransaction); + int inserted; + if (stacking) { + inserted = insertStacking(to, fromResource, maxExtracted, transferTransaction); + } else { + inserted = to.insert(fromResource, maxExtracted, transferTransaction); + } // extract it, or rollback if we cannot actually extract the amount we inserted // this can happen even for a well-behaving handler if it only supports extracting the exact @@ -332,6 +359,30 @@ public static ResourceStack moveFirst( Predicate filter, int amount, @Nullable TransactionContext transaction) { + return moveFirstInternal(from, to, filter, amount, false, transaction); + } + + /** + * Same as {@link #moveFirst}, but uses {@link #insertStacking} for inserting resources. + */ + @Nullable + public static ResourceStack moveFirstStacking( + @Nullable ResourceHandler from, + @Nullable ResourceHandler to, + Predicate filter, + int amount, + @Nullable TransactionContext transaction) { + return moveFirstInternal(from, to, filter, amount, true, transaction); + } + + @Nullable + private static ResourceStack moveFirstInternal( + @Nullable ResourceHandler from, + @Nullable ResourceHandler to, + Predicate filter, + int amount, + boolean stacking, + @Nullable TransactionContext transaction) { Objects.requireNonNull(filter, "Filter may not be null"); TransferPreconditions.checkNonNegative(amount); if (from == null || to == null || amount == 0) @@ -362,7 +413,12 @@ public static ResourceStack moveFirst( try (Transaction transferTransaction = Transaction.open(transaction)) { // check how much can be inserted - int inserted = to.insert(fromResource, extracted, transferTransaction); + int inserted; + if (stacking) { + inserted = insertStacking(to, fromResource, extracted, transferTransaction); + } else { + inserted = to.insert(fromResource, extracted, transferTransaction); + } // The target might not accept the resource at all, or might be full if (inserted == 0) continue; diff --git a/src/main/java/net/neoforged/neoforge/transfer/StacksResourceHandler.java b/src/main/java/net/neoforged/neoforge/transfer/StacksResourceHandler.java index 60c294a2bcb..6a95cc2c365 100644 --- a/src/main/java/net/neoforged/neoforge/transfer/StacksResourceHandler.java +++ b/src/main/java/net/neoforged/neoforge/transfer/StacksResourceHandler.java @@ -8,7 +8,6 @@ import com.mojang.serialization.Codec; import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Objects; import java.util.function.Function; import net.minecraft.core.NonNullList; @@ -53,7 +52,7 @@ public abstract class StacksResourceHandler implements Re protected NonNullList stacks; protected final Codec> codec; - private final List snapshotJournals; + private final ArrayList snapshotJournals; protected StacksResourceHandler(int size, S emptyStack, Codec stackCodec) { this(NonNullList.withSize(size, emptyStack), emptyStack, stackCodec); @@ -65,9 +64,7 @@ protected StacksResourceHandler(NonNullList stacks, S emptyStack, Codec st // Don't use NonNullList.codecOf because it creates an unmodifiable list this.codec = stackCodec.listOf().xmap(this::mutableCopyOf, Function.identity()); this.snapshotJournals = new ArrayList<>(this.stacks.size()); - for (int i = 0; i < this.stacks.size(); i++) { - snapshotJournals.add(new StackJournal(i)); - } + updateStacksSize(); } /** @@ -77,6 +74,28 @@ private NonNullList mutableCopyOf(Collection list) { return NonNullList.of(emptyStack, (S[]) list.toArray(Object[]::new)); } + /** + * Changes the list of stacks. Can change the size of the handler. + * + * @param stacks The new list of stacks. A shallow copy will be made. + */ + protected void setStacks(NonNullList stacks) { + this.stacks = mutableCopyOf(stacks); + updateStacksSize(); + } + + private void updateStacksSize() { + snapshotJournals.ensureCapacity(stacks.size()); + // Add missing entries + while (snapshotJournals.size() < stacks.size()) { + snapshotJournals.add(new StackJournal(snapshotJournals.size())); + } + // Remove superfluous entries + if (snapshotJournals.size() > stacks.size()) { + snapshotJournals.subList(stacks.size(), snapshotJournals.size()).clear(); + } + } + @Override public void serialize(ValueOutput output) { output.store(VALUE_IO_KEY, codec, stacks); @@ -86,6 +105,7 @@ public void serialize(ValueOutput output) { public void deserialize(ValueInput input) { input.read(VALUE_IO_KEY, codec).ifPresent(l -> { stacks = l; + updateStacksSize(); }); } diff --git a/src/main/java/net/neoforged/neoforge/transfer/fluid/FluidResource.java b/src/main/java/net/neoforged/neoforge/transfer/fluid/FluidResource.java index f03a82d1381..3c3d992bdf8 100644 --- a/src/main/java/net/neoforged/neoforge/transfer/fluid/FluidResource.java +++ b/src/main/java/net/neoforged/neoforge/transfer/fluid/FluidResource.java @@ -55,7 +55,7 @@ public final class FluidResource implements DataComponentHolderResource { * Stream codec for a fluid resource. Accepts empty resources. */ public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.holderRegistry(Registries.FLUID), FluidResource::getHolder, + ByteBufCodecs.holderRegistry(Registries.FLUID), FluidResource::typeHolder, DataComponentPatch.STREAM_CODEC, FluidResource::getComponentsPatch, FluidResource::of); @@ -148,8 +148,8 @@ public Fluid getFluid() { * @return the fluid holder of this resource */ @Override - public Holder getHolder() { - return innerStack.getFluidHolder(); + public Holder typeHolder() { + return innerStack.typeHolder(); } /** diff --git a/src/main/java/net/neoforged/neoforge/transfer/fluid/FluidUtil.java b/src/main/java/net/neoforged/neoforge/transfer/fluid/FluidUtil.java index e7cd17d32a8..a7e1a7fa1e7 100644 --- a/src/main/java/net/neoforged/neoforge/transfer/fluid/FluidUtil.java +++ b/src/main/java/net/neoforged/neoforge/transfer/fluid/FluidUtil.java @@ -10,7 +10,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.LivingEntity; @@ -35,6 +34,7 @@ import net.neoforged.neoforge.transfer.ResourceHandler; import net.neoforged.neoforge.transfer.ResourceHandlerUtil; import net.neoforged.neoforge.transfer.access.ItemAccess; +import net.neoforged.neoforge.transfer.resource.ResourceStack; import net.neoforged.neoforge.transfer.transaction.Transaction; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -64,8 +64,13 @@ public static FluidStack getStack(ResourceHandler handler, int in * *

The contents from the first non-empty index are returned. * As such the returned contents might not be extractable, and the stack might contain additional contents. + * + *

{@link FluidStack#EMPTY} is returned if the given stack is {@linkplain ItemStack#EMPTY empty}. */ public static FluidStack getFirstStackContained(ItemStack stack) { + if (stack.isEmpty()) { + return FluidStack.EMPTY; + } var handler = ItemAccess.forStack(stack).oneByOne().getCapability(Capabilities.Fluid.ITEM); if (handler == null) { return FluidStack.EMPTY; @@ -120,26 +125,24 @@ public static boolean interactWithFluidHandler(Player player, InteractionHand ha return false; } - return !moveWithSound(handler, handHandler, player.level(), pos, player, true).isEmpty() - || !moveWithSound(handHandler, handler, player.level(), pos, player, false).isEmpty(); + return moveWithSound(handler, handHandler, player.level(), pos, player, true) != null + || moveWithSound(handHandler, handler, player.level(), pos, player, false) != null; } - private static FluidStack moveWithSound(ResourceHandler from, ResourceHandler to, Level level, @Nullable BlockPos pos, @Nullable Player player, boolean pickup) { + @Nullable + private static ResourceStack moveWithSound(ResourceHandler from, ResourceHandler to, Level level, @Nullable BlockPos pos, @Nullable Player player, boolean pickup) { if (player == null && pos == null) { throw new IllegalArgumentException("Either player or pos must be provided."); } var moved = ResourceHandlerUtil.moveFirst(from, to, fr -> true, Integer.MAX_VALUE, null); - if (moved == null) { - return FluidStack.EMPTY; + if (moved != null) { + playSoundAndGameEvent(moved.resource(), level, pos, player, pickup); } - - var stack = moved.resource().toStack(moved.amount()); - playSoundAndGameEvent(stack, level, pos, player, pickup); - return stack; + return moved; } - private static void playSoundAndGameEvent(FluidStack stack, Level level, @Nullable BlockPos blockPos, @Nullable Player player, boolean pickup) { + private static void playSoundAndGameEvent(FluidResource resource, Level level, @Nullable BlockPos blockPos, @Nullable Player player, boolean pickup) { if (player == null && blockPos == null) { throw new IllegalArgumentException("Either player or blockPos must be provided."); } @@ -147,7 +150,21 @@ private static void playSoundAndGameEvent(FluidStack stack, Level level, @Nullab // Prioritize block position, use player position as a fallback Vec3 position = blockPos != null ? Vec3.atCenterOf(blockPos) : new Vec3(player.getX(), player.getY() + 0.5, player.getZ()); - SoundEvent soundEvent = stack.getFluidType().getSound(stack, pickup ? SoundActions.BUCKET_FILL : SoundActions.BUCKET_EMPTY); + triggerSoundAndGameEvent(resource, level, position, player, pickup); + } + + /** + * Triggers the appropriate sound effect and game event for an interaction with a fluid handler. + * + * @param resource The resource that was moved during the interaction. + * @param level The level the interaction occurred in. + * @param position Where the interaction occurred at. The sound and game event will trigger here. + * @param player The player that caused the interaction (optional). The game event will be attributed to them. + * @param pickup True if the fluid was extracted from the handler, false if it was inserted. + */ + public static void triggerSoundAndGameEvent(FluidResource resource, Level level, Vec3 position, @Nullable Player player, boolean pickup) { + var stack = resource.toStack(FluidType.BUCKET_VOLUME); + var soundEvent = resource.getFluidType().getSound(stack, pickup ? SoundActions.BUCKET_FILL : SoundActions.BUCKET_EMPTY); if (soundEvent != null) { level.playSound(null, position.x, position.y, position.z, soundEvent, SoundSource.BLOCKS, 1.0F, 1.0F); } @@ -209,7 +226,7 @@ public static FluidStack tryPickupFluid(@Nullable ResourceHandler return FluidStack.EMPTY; } tx.commit(); - playSoundAndGameEvent(extracted, level, pos, player, true); + playSoundAndGameEvent(resource, level, pos, player, true); return extracted; } } else { @@ -217,7 +234,8 @@ public static FluidStack tryPickupFluid(@Nullable ResourceHandler if (fluidHandler == null) { return FluidStack.EMPTY; } - return moveWithSound(fluidHandler, destination, level, pos, player, true); + var moved = moveWithSound(fluidHandler, destination, level, pos, player, true); + return moved != null ? moved.resource().toStack(moved.amount()) : FluidStack.EMPTY; } } @@ -315,7 +333,7 @@ public static boolean tryPlaceFluid(FluidResource resource, @Nullable Player pla var state = fluidType.getBlockForFluidState(level, pos, resource.getFluid().defaultFluidState()); level.setBlock(pos, state, Block.UPDATE_ALL_IMMEDIATE); } - playSoundAndGameEvent(stack, level, pos, player, false); + playSoundAndGameEvent(resource, level, pos, player, false); return true; } } diff --git a/src/main/java/net/neoforged/neoforge/transfer/item/BundleItemHandler.java b/src/main/java/net/neoforged/neoforge/transfer/item/BundleItemHandler.java new file mode 100644 index 00000000000..0e69b8b85c9 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/transfer/item/BundleItemHandler.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.transfer.item; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import java.util.List; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStackTemplate; +import net.minecraft.world.item.component.BundleContents; +import net.neoforged.neoforge.capabilities.ICapabilityProvider; +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; +import net.neoforged.neoforge.transfer.ResourceHandler; +import net.neoforged.neoforge.transfer.TransferPreconditions; +import net.neoforged.neoforge.transfer.access.ItemAccess; +import net.neoforged.neoforge.transfer.transaction.TransactionContext; +import org.apache.commons.lang3.math.Fraction; +import org.jspecify.annotations.Nullable; + +/** + * Item {@link ResourceHandler} backed by an {@link ItemAccess} for use with bundle-like items. + * The stacks are stored in a {@link BundleContents} data component. + *

+ * To use this class, register a new {@link DataComponentType} which holds an {@link BundleContents} for your item. + * Then reference that component from your {@link ICapabilityProvider} passed to {@link RegisterCapabilitiesEvent#registerItem} to create an instance of this class. + */ +public class BundleItemHandler implements ResourceHandler { + protected final ItemAccess itemAccess; + protected final Item validItem; + protected final DataComponentType component; + + public BundleItemHandler(ItemAccess itemAccess, DataComponentType component) { + this.itemAccess = itemAccess; + this.validItem = itemAccess.getResource().getItem(); + this.component = component; + } + + @Override + public int size() { + BundleContents contents = itemAccess.getResource().get(component); + if (contents == null) return 0; + var weight = contents.weight().result().orElse(Fraction.ZERO); + return contents.size() + (weight.intValue() < 1 ? 1 : 0); + } + + protected @Nullable ItemStackTemplate getStack(int index) { + BundleContents contents = itemAccess.getResource().get(component); + if (contents == null || index >= contents.size()) return null; + return contents.items().get(index); + } + + @Override + public ItemResource getResource(int index) { + if (itemAccess.getResource().is(validItem)) { + return ItemResource.of(getStack(index)); + } else { + return ItemResource.EMPTY; + } + } + + @Override + public long getAmountAsLong(int index) { + if (itemAccess.getResource().is(validItem)) { + var stack = getStack(index); + return stack == null ? 0 : (long) itemAccess.getAmount() * stack.count(); + } else { + return 0; + } + } + + @Override + public long getCapacityAsLong(int index, ItemResource resource) { + if (isValid(index, resource)) { + return (long) itemAccess.getAmount() * (resource.isEmpty() ? Item.ABSOLUTE_MAX_STACK_SIZE : Math.min(resource.getMaxStackSize(), Item.ABSOLUTE_MAX_STACK_SIZE)); + } else { + return 0; + } + } + + @Override + public boolean isValid(int index, ItemResource resource) { + return itemAccess.getResource().is(validItem) && BundleContents.canItemBeInBundle(resource.toStack()); + } + + // TODO: We should potentially refuse the insertion if the bundle contains the item already + @Override + public int insert(int index, ItemResource resource, int amount, TransactionContext transaction) { + TransferPreconditions.checkNonEmptyNonNegative(resource, amount); + TransferPreconditions.checkNonNegative(index); + + int accessAmount = itemAccess.getAmount(); + if (accessAmount == 0) + return 0; + int extractedPerItem = amount / accessAmount; + + ItemResource accessResource = itemAccess.getResource(); + BundleContents contents = accessResource.get(component); + if (contents == null || index > contents.size()) return 0; + + BundleContents.Mutable mutable = new BundleContents.Mutable(contents); + int inserted = 0; + + if (index == contents.size()) { + inserted = mutable.tryInsert(resource.toStack(extractedPerItem)); + } else { + ItemStackTemplate existing = contents.items().get(index); + if (resource.matches(existing)) { + inserted += mutable.tryInsert(resource.toStack(extractedPerItem)); + } else { + return 0; + } + } + + return inserted * itemAccess.exchange(accessResource.with(component, mutable.toImmutable()), accessAmount, transaction); + } + + @Override + public int extract(int index, ItemResource resource, int amount, TransactionContext transaction) { + TransferPreconditions.checkNonEmptyNonNegative(resource, amount); + TransferPreconditions.checkNonNegative(index); + + int accessAmount = itemAccess.getAmount(); + if (accessAmount == 0) + return 0; + int extractedPerItem = amount / accessAmount; + + ItemResource accessResource = itemAccess.getResource(); + BundleContents contents = accessResource.get(component); + if (contents == null || index >= contents.size()) return 0; + + ItemStackTemplate stack = contents.items().get(index); + if (!resource.matches(stack)) return 0; + + int toExtract = Math.min(extractedPerItem, stack.count()); + if (toExtract <= 0) return 0; + + List items = new ObjectArrayList<>(contents.items()); + + if (toExtract == stack.count()) { + items.remove(index); + } else { + items.set(index, new ItemStackTemplate(stack.item(), stack.count() - toExtract, stack.components())); + } + + return toExtract * itemAccess.exchange(accessResource.with(component, new BundleContents(items)), accessAmount, transaction); + } +} diff --git a/src/main/java/net/neoforged/neoforge/transfer/item/ItemResource.java b/src/main/java/net/neoforged/neoforge/transfer/item/ItemResource.java index 048ebe156cc..676e6702f69 100644 --- a/src/main/java/net/neoforged/neoforge/transfer/item/ItemResource.java +++ b/src/main/java/net/neoforged/neoforge/transfer/item/ItemResource.java @@ -6,6 +6,7 @@ package net.neoforged.neoforge.transfer.item; import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Objects; import java.util.Optional; import java.util.function.Predicate; @@ -22,10 +23,12 @@ import net.minecraft.util.ExtraCodecs; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; import net.minecraft.world.item.Items; import net.minecraft.world.level.ItemLike; import net.neoforged.neoforge.transfer.TransferPreconditions; import net.neoforged.neoforge.transfer.resource.DataComponentHolderResource; +import org.jspecify.annotations.Nullable; /** * Immutable combination of an {@link Item} and data components. @@ -39,10 +42,14 @@ public final class ItemResource implements DataComponentHolderResource { /** * Codec for an item resource. - * Same format as {@link ItemStack#SINGLE_ITEM_CODEC}. * Does not accept empty resources. */ - public static final Codec CODEC = ItemStack.SINGLE_ITEM_CODEC.xmap(ItemResource::of, ItemResource::toStack); + public static final Codec CODEC = Codec.lazyInitialized( + () -> RecordCodecBuilder.create( + i -> i.group( + Item.CODEC.fieldOf("id").forGetter(ItemResource::typeHolder), + DataComponentPatch.CODEC.optionalFieldOf("components", DataComponentPatch.EMPTY).forGetter(ItemResource::getComponentsPatch)) + .apply(i, ItemResource::of))); /** * Codec for an item resource. Same format as {@link #CODEC}, and also accepts empty resources. @@ -55,7 +62,7 @@ public final class ItemResource implements DataComponentHolderResource { * Stream codec for an item resource. Accepts empty resources. */ public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.holderRegistry(Registries.ITEM), ItemResource::getHolder, + ByteBufCodecs.holderRegistry(Registries.ITEM), ItemResource::typeHolder, DataComponentPatch.STREAM_CODEC, ItemResource::getComponentsPatch, ItemResource::of); @@ -72,6 +79,23 @@ public static ItemResource of(ItemStack stack) { return new ItemResource(stack.copyWithCount(1)); } + /** + * Creates an ItemResource using the default or copy of the passed in item stack. Note the count is lost. + * + * @param template stack to copy with a size of 1 + * @return If null was given, an empty resource is returned. + * If there were no patches on the stack's data components, the item's default resource will be returned, otherwise a new instance with the copied stack. + */ + public static ItemResource of(@Nullable ItemStackTemplate template) { + if (template == null) { + return EMPTY; + } + if (template.components().isEmpty()) { + return of(template.item()); + } + return new ItemResource(new ItemStack(template.item(), 1, template.components())); + } + /** * Note: This cannot be called before your item is registered * @@ -146,8 +170,8 @@ public Item getItem() { } @Override - public Holder getHolder() { - return innerStack.getItemHolder(); + public Holder typeHolder() { + return innerStack.typeHolder(); } @Override @@ -164,6 +188,15 @@ public boolean matches(ItemStack stack) { return ItemStack.isSameItemSameComponents(stack, innerStack); } + /** + * {@return true if this resource matches the item and components of the passed template} + * + * @param template the item stack template to check + */ + public boolean matches(@Nullable ItemStackTemplate template) { + return ItemStack.isSameItemSameComponents(innerStack, template); + } + /** * {@return true if the item instance matches the backing instance value} * diff --git a/src/main/java/net/neoforged/neoforge/transfer/item/VanillaInventoryCodeHooks.java b/src/main/java/net/neoforged/neoforge/transfer/item/VanillaInventoryCodeHooks.java index f903a247f13..68076d38ece 100644 --- a/src/main/java/net/neoforged/neoforge/transfer/item/VanillaInventoryCodeHooks.java +++ b/src/main/java/net/neoforged/neoforge/transfer/item/VanillaInventoryCodeHooks.java @@ -107,7 +107,7 @@ public static ContainerOrHandler getEntityContainerOrHandler(Level level, double return entity instanceof Container || entity.getCapability(Capabilities.Item.ENTITY_AUTOMATION, side) != null; }); if (!list.isEmpty()) { - var entity = list.get(level.random.nextInt(list.size())); + var entity = list.get(level.getRandom().nextInt(list.size())); if (entity instanceof Container container) { return new ContainerOrHandler(container, null); } diff --git a/src/main/java/net/neoforged/neoforge/transfer/resource/RegisteredResource.java b/src/main/java/net/neoforged/neoforge/transfer/resource/RegisteredResource.java index 7a4236e342c..a823e6a8be9 100644 --- a/src/main/java/net/neoforged/neoforge/transfer/resource/RegisteredResource.java +++ b/src/main/java/net/neoforged/neoforge/transfer/resource/RegisteredResource.java @@ -7,8 +7,7 @@ import java.util.function.Predicate; import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; -import net.minecraft.tags.TagKey; +import net.minecraft.core.TypedInstance; import org.jetbrains.annotations.ApiStatus; /** @@ -16,59 +15,18 @@ * * @param The type of the backing registry entry. */ -public interface RegisteredResource extends Resource { +public interface RegisteredResource extends Resource, TypedInstance { /** * {@return the backing instance of the resource} */ T value(); - /** - * {@return The registered holder of the backing resource} - */ - Holder getHolder(); - - /** - * @param tag Tag to check - * @return {@code true} if the holder from {@link #getHolder()} is in the specified tag - */ - @ApiStatus.NonExtendable - default boolean is(TagKey tag) { - return getHolder().is(tag); - } - - /** - * @param instance the instance to compare - * @return {@code true} if an exact equality comparison ('==') between the instance provided and the value from {@link #value()} is {@code true} - */ - @ApiStatus.NonExtendable - default boolean is(T instance) { - return instance == value(); - } - /** * @param predicate The predicate to perform the test. - * @return {@code true} if the predicate's test returns {@code true} for the holder from {@link #getHolder()}. + * @return {@code true} if the predicate's test returns {@code true} for the holder from {@link #typeHolder()}. */ @ApiStatus.NonExtendable default boolean is(Predicate> predicate) { - return predicate.test(getHolder()); - } - - /** - * @param holder the holder to check - * @return {@code true} if the holder's value is the instance value from {@link #value()} - */ - @ApiStatus.NonExtendable - default boolean is(Holder holder) { - return is(holder.value()); - } - - /** - * @param holders Set of holders to check - * @return {@code true} if the holder set contains the holder provided from {@link #getHolder()} - */ - @ApiStatus.NonExtendable - default boolean is(HolderSet holders) { - return holders.contains(getHolder()); + return predicate.test(typeHolder()); } } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 9fb51337020..23a41ac3978 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -44,7 +44,6 @@ public net.minecraft.client.renderer.block.ModelBlockRenderer$AdjacencyInfo public net.minecraft.client.renderer.block.ModelBlockRenderer$AdjacencyInfo corners public net.minecraft.client.renderer.block.ModelBlockRenderer$AmbientOcclusionRenderStorage protected net.minecraft.client.renderer.block.ModelBlockRenderer$AmbientOcclusionRenderStorage faceShape -protected net.minecraft.client.renderer.block.ModelBlockRenderer$AmbientOcclusionRenderStorage blend(IIIIFFFF)I public net.minecraft.client.renderer.block.ModelBlockRenderer$Cache public net.minecraft.client.renderer.block.ModelBlockRenderer$CommonRenderStorage public net.minecraft.client.renderer.block.ModelBlockRenderer$SizeInfo @@ -100,12 +99,12 @@ protected net.minecraft.data.recipes.RecipeProvider fenceGateBuilder(Lnet/minecr protected net.minecraft.data.recipes.RecipeProvider signBuilder(Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/RecipeBuilder; # signBuilder protected net.minecraft.data.recipes.RecipeProvider smeltingResultFromBase(Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/level/ItemLike;)V # smeltingResultFromBase protected net.minecraft.data.recipes.RecipeProvider cutBuilder(Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/ShapedRecipeBuilder; # cutBuilder -protected net.minecraft.data.recipes.RecipeProvider oreCooking(Lnet/minecraft/world/item/crafting/RecipeSerializer;Lnet/minecraft/world/item/crafting/AbstractCookingRecipe$Factory;Ljava/util/List;Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;FILjava/lang/String;Ljava/lang/String;)V # oreCooking +protected net.minecraft.data.recipes.RecipeProvider oreCooking(Lnet/minecraft/world/item/crafting/AbstractCookingRecipe$Factory;Ljava/util/List;Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/item/crafting/CookingBookCategory;Lnet/minecraft/world/level/ItemLike;FILjava/lang/String;Ljava/lang/String;)V # oreCooking protected net.minecraft.data.recipes.RecipeProvider wallBuilder(Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/RecipeBuilder; # wallBuilder protected net.minecraft.data.recipes.RecipeProvider polishedBuilder(Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/RecipeBuilder; # polishedBuilder 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 simpleCookingRecipe(Ljava/lang/String;Lnet/minecraft/world/item/crafting/AbstractCookingRecipe$Factory;ILnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/level/ItemLike;F)V # simpleCookingRecipe 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 @@ -183,8 +182,8 @@ protected net.minecraft.world.entity.monster.zombie.Zombie conversionTime public net.minecraft.world.inventory.AnvilMenu repairItemCountCost # repairItemCountCost 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$Output public net.minecraft.world.item.CreativeModeTab$TabVisibility -private-f net.minecraft.world.item.Item components public net.minecraft.world.item.BucketItem content public net.minecraft.world.item.Item getPlayerPOVHitResult(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/level/ClipContext$Fluid;)Lnet/minecraft/world/phys/BlockHitResult; # getPlayerPOVHitResult public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG # TYPE_AND_TAG @@ -264,7 +263,6 @@ public net.minecraft.world.level.storage.LevelResource (Ljava/lang/String; private-f net.minecraft.world.level.storage.loot.LootPool rolls # rolls private-f net.minecraft.world.level.storage.loot.LootPool bonusRolls # bonusRolls public net.minecraft.server.network.ServerConfigurationPacketListenerImpl finishCurrentTask(Lnet/minecraft/server/network/ConfigurationTask$Type;)V -public-f net.minecraft.world.entity.npc.villager.VillagerTrades WANDERING_TRADER_TRADES # WANDERING_TRADER_TRADES public net.minecraft.world.entity.EquipmentSlot countLimit # EnchantmentHelper methods needed for adding custom enchantments @@ -283,7 +281,7 @@ public net.minecraft.world.item.enchantment.Enchantment itemContext(Lnet/minecra public net.minecraft.world.item.enchantment.Enchantment locationContext(Lnet/minecraft/server/level/ServerLevel;ILnet/minecraft/world/entity/Entity;Z)Lnet/minecraft/world/level/storage/loot/LootContext; public net.minecraft.world.item.enchantment.Enchantment entityContext(Lnet/minecraft/server/level/ServerLevel;ILnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;)Lnet/minecraft/world/level/storage/loot/LootContext; public net.minecraft.world.item.enchantment.Enchantment blockHitContext(Lnet/minecraft/server/level/ServerLevel;ILnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/level/storage/loot/LootContext; -public net.minecraft.world.item.enchantment.Enchantment applyEffects(Ljava/util/List;Lnet/minecraft/world/level/storage/loot/LootContext;Ljava/util/function/Consumer;)V +public net.minecraft.world.item.enchantment.Enchantment applyEffects(Ljava/util/List;Lnet/minecraft/world/level/storage/loot/LootContext;Lnet/minecraft/world/item/enchantment/Enchantment$GenericAction;)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 @@ -348,3 +346,12 @@ default net.minecraft.client.renderer.texture.SpriteContents$AnimatedTexture get default net.minecraft.client.KeyMapping$Category SORT_ORDER public net.minecraft.client.renderer.item.BlockModelWrapper (Ljava/util/List;Ljava/util/List;Lnet/minecraft/client/renderer/item/ModelRenderProperties;Ljava/util/function/Function;)V + +# Used by MutableBakedQuad#recalculateWinding +public net.minecraft.client.renderer.block.model.FaceBakery recalculateWinding([Lorg/joml/Vector3fc;[JLnet/minecraft/core/Direction;)V + +# Custom GameRule edit entries +public net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen markInvalid(Lnet/minecraft/client/gui/screens/worldselection/AbstractGameRulesScreen$RuleEntry;)V +public net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen clearInvalid(Lnet/minecraft/client/gui/screens/worldselection/AbstractGameRulesScreen$RuleEntry;)V +public net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen gameRules +public net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen$EntryFactory \ No newline at end of file diff --git a/src/main/resources/META-INF/accesstransformergenerated.cfg b/src/main/resources/META-INF/accesstransformergenerated.cfg index b013e04ce97..5d798e947ca 100644 --- a/src/main/resources/META-INF/accesstransformergenerated.cfg +++ b/src/main/resources/META-INF/accesstransformergenerated.cfg @@ -30,7 +30,7 @@ public net.minecraft.world.level.block.AbstractBannerBlock (Lnet/minecraft 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.AttachedStemBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/tags/TagKey;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 @@ -74,9 +74,8 @@ public net.minecraft.world.level.block.EndPortalBlock (Lnet/minecraft/worl 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.FarmlandBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.FlowerBedBlock (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 @@ -93,9 +92,12 @@ public net.minecraft.world.level.block.KelpPlantBlock (Lnet/minecraft/worl 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.LilyPadBlock (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.NetherFungusBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/block/Block;Lnet/minecraft/tags/TagKey;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.NetherRootsBlock (Lnet/minecraft/tags/TagKey;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.PipeBlock (FLnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -109,7 +111,6 @@ public net.minecraft.world.level.block.RedstoneTorchBlock (Lnet/minecraft/ 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 @@ -125,7 +126,7 @@ public net.minecraft.world.level.block.SpawnerBlock (Lnet/minecraft/world/ 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.StemBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/tags/TagKey;Lnet/minecraft/tags/TagKey;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 @@ -137,7 +138,6 @@ public net.minecraft.world.level.block.TrapDoorBlock (Lnet/minecraft/world public net.minecraft.world.level.block.VegetationBlock (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.WeatheringCopperBarsBlock (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.WeatheringCopperChainBlock (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -276,33 +276,11 @@ public net.minecraft.world.item.CreativeModeTabs SEARCH public net.minecraft.world.item.CreativeModeTabs SPAWN_EGGS public net.minecraft.world.item.CreativeModeTabs TOOLS_AND_UTILITIES -# villager item listings -public net.minecraft.world.entity.npc.villager.VillagerTrades$DyedArmorForEmeralds -public net.minecraft.world.entity.npc.villager.VillagerTrades$EmeraldForItems -public net.minecraft.world.entity.npc.villager.VillagerTrades$EmeraldsForVillagerTypeItem -public net.minecraft.world.entity.npc.villager.VillagerTrades$EnchantBookForEmeralds -public net.minecraft.world.entity.npc.villager.VillagerTrades$EnchantedItemForEmeralds -public net.minecraft.world.entity.npc.villager.VillagerTrades$FailureItemListing -public net.minecraft.world.entity.npc.villager.VillagerTrades$ItemsAndEmeraldsToItems -public net.minecraft.world.entity.npc.villager.VillagerTrades$ItemsForEmeralds -public net.minecraft.world.entity.npc.villager.VillagerTrades$SuspiciousStewForEmerald -public net.minecraft.world.entity.npc.villager.VillagerTrades$TippedArrowForItemsAndEmeralds -public net.minecraft.world.entity.npc.villager.VillagerTrades$TreasureMapForEmeralds -public net.minecraft.world.entity.npc.villager.VillagerTrades$TypeSpecificTrade -public net.minecraft.world.entity.npc.villager.VillagerTrades$TypeSpecificTrade (Ljava/util/Map;)V - -# villager item listing constructors -public net.minecraft.world.entity.npc.villager.VillagerTrades$FailureItemListing ()V -public net.minecraft.world.entity.npc.villager.VillagerTrades$ItemsAndEmeraldsToItems (Lnet/minecraft/world/level/ItemLike;IILnet/minecraft/world/item/ItemStack;IIIF)V -public net.minecraft.world.entity.npc.villager.VillagerTrades$ItemsAndEmeraldsToItems (Lnet/minecraft/world/level/ItemLike;IILnet/minecraft/world/level/ItemLike;IIIFLnet/minecraft/resources/ResourceKey;)V -public net.minecraft.world.entity.npc.villager.VillagerTrades$TypeSpecificTrade (Ljava/util/Map;)V - # DebugScreenEntry groups public net.minecraft.client.gui.components.debug.DebugEntryBiome GROUP public net.minecraft.client.gui.components.debug.DebugEntryChunkGeneration GROUP public net.minecraft.client.gui.components.debug.DebugEntryHeightmap GROUP -public net.minecraft.client.gui.components.debug.DebugEntryLookingAtBlock GROUP -public net.minecraft.client.gui.components.debug.DebugEntryLookingAtEntity GROUP -public net.minecraft.client.gui.components.debug.DebugEntryLookingAtFluid GROUP +public net.minecraft.client.gui.components.debug.DebugEntryLookingAt BLOCK_GROUP +public net.minecraft.client.gui.components.debug.DebugEntryLookingAt FLUID_GROUP public net.minecraft.client.gui.components.debug.DebugEntryMemory GROUP public net.minecraft.client.gui.components.debug.DebugEntrySystemSpecs GROUP diff --git a/src/main/resources/META-INF/injected-interfaces.json b/src/main/resources/META-INF/injected-interfaces.json index 1d160454149..6bdff7e2d15 100644 --- a/src/main/resources/META-INF/injected-interfaces.json +++ b/src/main/resources/META-INF/injected-interfaces.json @@ -317,5 +317,11 @@ ], "net/minecraft/client/resources/model/EquipmentClientInfo$LayerType": [ "net/neoforged/fml/common/asm/enumextension/IExtensibleEnum" + ], + "net/minecraft/gametest/framework/GameTestHelper": [ + "net/neoforged/neoforge/common/extensions/GameTestHelperExtension" + ], + "net/minecraft/world/level/gamerules/GameRuleType": [ + "net/neoforged/fml/common/asm/enumextension/IExtensibleEnum" ] } diff --git a/src/main/resources/assets/neoforge/lang/cs_cz.json b/src/main/resources/assets/neoforge/lang/cs_cz.json index 7e114f098e6..22cee1931b4 100644 --- a/src/main/resources/assets/neoforge/lang/cs_cz.json +++ b/src/main/resources/assets/neoforge/lang/cs_cz.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generování zastaveno! %1$s chunků z %2$s bylo vygenerováno. (%3$s%%)", "commands.neoforge.chunkgen.status": "Stav generace! %1$s chunků z %2$s bylo vygenerováno. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "V současné době neprobíhá žádná před-generace. Spusťte `/neoforge generate help` pro zobrazení seznam příkazů pro zahájení generace.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Vygeneruje čtverec, kterého střed je na dané pozici, a každá z jeho stran má velikost: chunkRadius * 2.\n§2/neoforge generate stop §r§f- Zastaví aktuální generaci a zobrazí její progres.\n§2/neoforge generate status §r- Zobrazí progres spuštěné generace.\n§2/neoforge generate help §r- Zobrazí tuto zprávu.\nObecný tip: Jestli budete příkazy spouštět přes server konzoli, můžete je spouštět v různých dimenzích použitím \"/execute in neoforge generate ...\"", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Čas v %s běží rychlostí %sx (%s minut za den).", "commands.neoforge.timespeed.query.default": "Čas v %s běží normální rychlostí (20 minut za den).", "commands.neoforge.timespeed.set": "Nastaven běh času v %s na %sx (%s minut za den).", diff --git a/src/main/resources/assets/neoforge/lang/da_dk.json b/src/main/resources/assets/neoforge/lang/da_dk.json index 44093d8ef99..08c886b7297 100644 --- a/src/main/resources/assets/neoforge/lang/da_dk.json +++ b/src/main/resources/assets/neoforge/lang/da_dk.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Ingen prægenerering kører i øjeblikket. Kør `/neoforge generate help` for at se kommandoer til at starte generering.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/de_de.json b/src/main/resources/assets/neoforge/lang/de_de.json index 3a5a9e42aa5..f879e205680 100644 --- a/src/main/resources/assets/neoforge/lang/de_de.json +++ b/src/main/resources/assets/neoforge/lang/de_de.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generierung gestoppt! %1$s von %2$s Chunks generiert. (%3$s%%)", "commands.neoforge.chunkgen.status": "Status der Generierung! %1$s von %2$s Chunks generiert. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Keine Vorabgenerierung läuft derzeit. Führe '/neoforge generate help' aus, um Befehle für den Start der Generierung anzuzeigen.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generiert ein Quadrat um die angegebene Position, das auf jeder Seite chunkRadius * 2 groß ist.\n§2/neoforge generate stop §r§f- Stoppt die aktuelle Generierung und zeigt den Fortschritt an, den sie abgeschlossen hatte.\n§2/neoforge generate status §r- Zeigt den abgeschlossenen Fortschritt der gerade laufenden Generierung an.\n§2/neoforge generate help §r- Zeigt diese Nachricht an.\nAllgemeine Tipps: Wenn du von der Serverkonsole ausführst, kannst du die Generierung in verschiedenen Dimensionen mit '/execute in neoforge generate...' durchführen.", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Die Zeit in %s vergeht %sx so schnell wie üblich (%s Minuten pro Tag).", "commands.neoforge.timespeed.query.default": "Die Zeit in %s vergeht normal (20 Minuten pro Tag).", "commands.neoforge.timespeed.set": "Die Zeit in %s vergeht jetzt %sx so schnell wie üblich (%s Minuten pro Tag).", diff --git a/src/main/resources/assets/neoforge/lang/en_gb.json b/src/main/resources/assets/neoforge/lang/en_gb.json index a3e36a97128..c8558eeda48 100644 --- a/src/main/resources/assets/neoforge/lang/en_gb.json +++ b/src/main/resources/assets/neoforge/lang/en_gb.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No pre-generation currently running. Run `/neoforge generate help` to see commands for starting generation.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/en_us.json b/src/main/resources/assets/neoforge/lang/en_us.json index 1f9affdb022..66c56caf5e4 100644 --- a/src/main/resources/assets/neoforge/lang/en_us.json +++ b/src/main/resources/assets/neoforge/lang/en_us.json @@ -200,8 +200,6 @@ "neoforge.configgui.fullBoundingBoxLadders.tooltip": "Set this to true to check the entire entity's collision bounding box for ladders instead of just the block they are in. Causes noticeable differences in mechanics so default is vanilla behavior. Default: false.", "neoforge.configgui.handleAmbientOcclusionPerPart": "Per-part block AO handling", "neoforge.configgui.handleAmbientOcclusionPerPart.tooltip": "When enabled, AO will be handled per BlockModelPart instead of using the first part's AO setting.", - "neoforge.configgui.logLegacyTagWarnings": "Log Legacy Tags", - "neoforge.configgui.logLegacyTagWarnings.tooltip": "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.", "neoforge.configgui.logUntranslatedConfigurationWarnings": "Log Untranslated Configuration Keys", "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "A config option mainly for developers. Logs out configuration values that do not have translations when running a client in a development environment.", "neoforge.configgui.logUntranslatedItemTagWarnings": "Log Untranslated Item Tags", diff --git a/src/main/resources/assets/neoforge/lang/eo_uy.json b/src/main/resources/assets/neoforge/lang/eo_uy.json index 80d788f788d..0e5186c2dc4 100644 --- a/src/main/resources/assets/neoforge/lang/eo_uy.json +++ b/src/main/resources/assets/neoforge/lang/eo_uy.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No pregeneration currently running. Run `/neoforge generate help` to see commands for starting generation.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/es_es.json b/src/main/resources/assets/neoforge/lang/es_es.json index 166c584822b..d1370dbe2d1 100644 --- a/src/main/resources/assets/neoforge/lang/es_es.json +++ b/src/main/resources/assets/neoforge/lang/es_es.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No hay pregeneración en ejecución. Ejecuta `/neoforge generate help` para ver los comandos para iniciar la generación.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Genera un cuadrado centrado en la posición dada que es chunkRadius * 2 en cada lado.\n§2/neoforge generate stop §r§f- Detiene la generación actual y muestra el progreso que ha completado.\n§2/neoforge generate status §r- Muestra el progreso completado de la generación en curso.\n§2/neoforge generate help §r- Muestra este mensaje.\nConsejos generales: Si se ejecuta desde una consola de servidor, puede ejecutar generate en diferentes dimensiones utilizando /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/et_ee.json b/src/main/resources/assets/neoforge/lang/et_ee.json index 345a2849e6a..68c0cb2202b 100644 --- a/src/main/resources/assets/neoforge/lang/et_ee.json +++ b/src/main/resources/assets/neoforge/lang/et_ee.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Eel-generatsioon ei ole hetkel käimas. Generatsiooni käivitamise käskluste vaatamiseks käivita \"/neoforge generate help\".", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressiRiba] §r§f- Genereerib antud positsiooni keskpunktis oleva ruudu, mille mõlemad küljed on kamakaRaadius * 2.\n§2/neoforge generate stop §r§f- Peatab käimasoleva genereerimise ja kuvab lõpule viidud progressi.\n§2/neoforge generate status §r- Kuvab hetkel käimasoleva genereerimise progressi.\n§2/neoforge generate help §r- Kuvab seda sõnumit\nÜldine nõuanne: Serverikonsoolis sisestades saad genereerimist käivitada erinevates dimensioonides, kasutades /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/fr_fr.json b/src/main/resources/assets/neoforge/lang/fr_fr.json index b8282741d67..4fb240e7c6e 100644 --- a/src/main/resources/assets/neoforge/lang/fr_fr.json +++ b/src/main/resources/assets/neoforge/lang/fr_fr.json @@ -12,7 +12,7 @@ "fml.menu.mods.info.idstate": "ModID : %1$s État : {1,lower}", "fml.menu.mods.info.credits": "Crédits : %1$s", "fml.menu.mods.info.authors": "Auteurs : %1$s", - "fml.menu.mods.info.displayurl": "Page d'accueil : %1$s", + "fml.menu.mods.info.displayurl": "Page d’accueil : %1$s", "fml.menu.mods.info.license": "Licence : %1$s", "fml.menu.mods.info.securejardisabled": "Fonctionnalités de sécurité des mods désactivées, mettez à jour JDK", "fml.menu.mods.info.signature": "Signature : %1$s", @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Génération stoppée ! %1$s sur %2$s chunks générés. (%3$s%%)", "commands.neoforge.chunkgen.status": "Statut de la génération ! %1$s sur %2$s chunks générés. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Aucune prégénération en cours d'exécution. Exécutez `/neoforge generate help` afin de voir les commandes pour démarrer la génération.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Génère un carré centré sur la position donnée qui est chunkRadius * 2 de chaque côté.\n§2/neoforge generate stop §r§f- Arrête la génération actuelle et affiche la progression qu'elle avait effectuée.\n§2/neoforge generate status §r - Affiche la progression effectuée pour la génération en cours.\n§2/neoforge generate help §r- Affiche ce message.\nConseils généraux : Si vous exécutez à partir d'une console basée sur le serveur, vous pouvez exécuter generate dans différentes dimensions en utilisant /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/hu_hu.json b/src/main/resources/assets/neoforge/lang/hu_hu.json index 1ce58eaaec4..fda02168877 100644 --- a/src/main/resources/assets/neoforge/lang/hu_hu.json +++ b/src/main/resources/assets/neoforge/lang/hu_hu.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No pregeneration currently running. Run `/neoforge generate help` to see commands for starting generation.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/it_it.json b/src/main/resources/assets/neoforge/lang/it_it.json index 1ea8a73f35b..951490c618b 100644 --- a/src/main/resources/assets/neoforge/lang/it_it.json +++ b/src/main/resources/assets/neoforge/lang/it_it.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Nessuna pregenerazione attualmente in esecuzione. Esegui `/neoforge genera help` per vedere i comandi per iniziare la generazione.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Genera un quadrato centrato sulla posizione data di chunkRadius * 2 su ogni lato.\n§2/neoforge generate stop §r§f- Ferma la generazione corrente e mostra i progressi che aveva completato.\n§2/neoforge generate status §r- Visualizza i progressi completati per la generazione corrente.\n§2/neoforge generate help §r- Visualizza questo messaggio.\nSuggerimenti generali: Se eseguito da una console server, è possibile eseguire la generazione in diverse dimensioni utilizzando /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/ja_jp.json b/src/main/resources/assets/neoforge/lang/ja_jp.json index 5b6aa8585b9..502202113e8 100644 --- a/src/main/resources/assets/neoforge/lang/ja_jp.json +++ b/src/main/resources/assets/neoforge/lang/ja_jp.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "生成ステータス! %1$s / %2$s チャンクが生成されました。 (%3$s%%)", "commands.neoforge.chunkgen.not_running": "事前生成は実行されていません。生成を開始するためのコマンドを確認するには「/neoforge generate help」を実行してください", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- 指定の位置を中心として、各辺がchunkRadius * 2の正方形で生成します。\n§2/neoforge generate stop §r§f- 現在の生成を停止し、完了した進行状況を表示します。\n§2/neoforge generate status §r- 現在実行中の生成に対する完了した進行状況を表示します。\n§2/neoforge generate help §r- このメッセージを表示します。\nヒント:サーバーコンソールから実行する場合は、/execute in neoforge generate...を使用することで、異なるディメンションで生成を実行できます。", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/ko_kr.json b/src/main/resources/assets/neoforge/lang/ko_kr.json index f6381c74dc7..18d358f5e01 100644 --- a/src/main/resources/assets/neoforge/lang/ko_kr.json +++ b/src/main/resources/assets/neoforge/lang/ko_kr.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "청크 생성 중단됨! %1$s/%2$s개의 청크를 생성했습니다. (%3$s%%)", "commands.neoforge.chunkgen.status": "청크 생성 진행률! %1$s/%2$s개의 청크를 생성했습니다. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "현재 청크를 생성하고 있지 않습니다. `/neoforge generate help`를 참고하여 청크 사전 생성 명령어 사용 방법을 확인하세요.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start <범위> [진행률 표시] §r§f- 주어진 위치를 중심으로 범위 * 2 길이의 정사각형 구역 내 청크를 생성합니다.\n§2/neoforge generate stop §r§f- 진행 중인 청크 사전 생성을 중단하고 진행률을 표시합니다.\n§2/neoforge generate status §r- 이미 진행 중인 청크 생성 작업의 진행률을 표시합니다.\n§2/neoforge generate help §r- 이 도움말을 표시합니다.\n팁: 다른 차원의 청크를 사전 생성할 땐 '/execute in <차원> neoforge generate...' 식으로 다른 차원에서 명령을 실행하세요.", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/ms_my.json b/src/main/resources/assets/neoforge/lang/ms_my.json index c67da53ce89..f7ada30742d 100644 --- a/src/main/resources/assets/neoforge/lang/ms_my.json +++ b/src/main/resources/assets/neoforge/lang/ms_my.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Penjanaan telah dihentikan! %1$s daripada %2$s cebisan telah dijana. (%3$s%%)", "commands.neoforge.chunkgen.status": "Status penjanaan! %1$s daripada %2$s cebisan telah dijana. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No pregeneration currently running. Run `/neoforge generate help` to see commands for starting generation.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Menghasilkan segi empat sama berpusat pada kedudukan yang diberikan iaitu chunkRadius * 2 pada setiap sisi.\n§2/neoforge generate stop §r§f- Menghentikan generasi semasa dan memaparkan kemajuan yang telah diselesaikannya.\n§2/neoforge generate status §r- Memaparkan kemajuan yang telah selesai untuk penjanaan yang sedang berjalan.\n§2/neoforge generate help §r- Memaparkan mesej ini.\nGeneral tips: Jika dijalankan dari konsol pelayan, anda boleh menjalankan generate dalam dimensi berbeza dengan menggunakan /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Masa dalam %s sedang mengalir pada kadar %sx (%s minit sehari).", "commands.neoforge.timespeed.query.default": "Masa dalam %s mengalir seperti biasa (20 minit sehari).", "commands.neoforge.timespeed.set": "Aliran masa dalam %s ditetapkan kepada %sx (%s minit sehari).", diff --git a/src/main/resources/assets/neoforge/lang/nl_nl.json b/src/main/resources/assets/neoforge/lang/nl_nl.json index 7756d2a475f..903bc3d02fb 100644 --- a/src/main/resources/assets/neoforge/lang/nl_nl.json +++ b/src/main/resources/assets/neoforge/lang/nl_nl.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Genereren gestopt! %1$s van de %2$s chunks zijn gegenereerd. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generatie status! %1$s van de %2$s chunks zijn gegenereerd. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Geen pregeneratie is op dit moment bezig. Run `/neoforge generate help` om commandos te zijn om generatie te starten.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Genereerd een vierkant gecentreerd om de gegeven positie heen die chunkRadius * 2 om elke kant groot is \n§2/neoforge generate stop §r§f- Stopt de huidige generatie en laat de voortgang zien die het al heeft voltooid.\n§2/neoforge generate status §r- Laat de huidige voortgang zien voor de generatie die op dit moment plaatsvindt. \n§2/neoforge generate help §r- Laat dit bericht zien\nAlgemene tips: Als je het van een server console, kan je het ook in verschillende dimensie runnen door '/execute in neoforge generate...' te gebruiken", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "De tijd in %s verloopt met een tempo van %sx (%s minuten per dag).", "commands.neoforge.timespeed.query.default": "De tijd in %s verloopt normaal (20 minuten per dag).", "commands.neoforge.timespeed.set": "Zet de tijd verloop in %s naar %sx (%s minuten per dag).", diff --git a/src/main/resources/assets/neoforge/lang/pl_pl.json b/src/main/resources/assets/neoforge/lang/pl_pl.json index 291a53c4ac5..d24f45a4975 100644 --- a/src/main/resources/assets/neoforge/lang/pl_pl.json +++ b/src/main/resources/assets/neoforge/lang/pl_pl.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generacja zatrzymana! %1$s z %2$s chunków wygenerowanych. (%3$s%%)", "commands.neoforge.chunkgen.status": "Status generacji! %1$s z %2$s chunków wygenerowanych. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Aktualnie brak uruchomionych pregeneracji. Uruchom `/neoforge generate help` aby zobaczyć polecenia do rozpoczęcia generacji.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generuje kwadrat wyśrodkowany na danej pozycji, czyli promień Chunku * 2 po każdej stronie.\n§2/neoforge generate stop §r§f- Zatrzymuje bieżące generowanie i wyświetla postępy, które zakończył.\n§2/neoforge generate status §r- Wyświetla postęp ukończony dla aktualnie działającej generacji.\n§2/neoforge generate help §r- Wyświetla tą wiadomość.\nOgólne wskazówki: Jeśli działa z konsoli serwera, możesz wygenerować świat w różnych wymiarach używając /execute in neoforge...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Czas w %s przepływa w tempie %sx (%s minut dziennie).", "commands.neoforge.timespeed.query.default": "Czas w %s przepływa normalnie (20 minut dziennie).", "commands.neoforge.timespeed.set": "Ustaw przepływ czasu w %s do %sx (%s minut dziennie).", diff --git a/src/main/resources/assets/neoforge/lang/pt_br.json b/src/main/resources/assets/neoforge/lang/pt_br.json index 0b06b473e27..5500677c3c9 100644 --- a/src/main/resources/assets/neoforge/lang/pt_br.json +++ b/src/main/resources/assets/neoforge/lang/pt_br.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Geração interrompida! %1$s de %2$s chunks gerados. (%3$s%%)", "commands.neoforge.chunkgen.status": "Estado de geração! %1$s de %2$s chunks gerados. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Nenhuma pré-geração está sendo executada. Execute `/neoforge generate help` para ver os comandos para iniciar a geração.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Gera um quadrado centralizado na posição informada que possui chunkRadius * 2 de cada lado.\n§2/neoforge generate stop §r§f- Interrompe a geração atual e exibe o progresso concluído até o momento.\n§2/neoforge generate status §r- Exibe o progresso concluído da geração em execução.\n§2/neoforge generate help §r- Exibe esta mensagem.\nDicas gerais: Se estiver executando a partir do console de um servidor, você pode rodar o generate em diferentes dimensões usando /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [barraDeProgresso] §r§f- Gera um quadrado centrado na posição dada, com o dobro do raio do chunkRadius em cada lado.\n§2/neoforge generate stop §r§f- Para a geração atual e exibe o progresso que foi completado.\n§2/neoforge generate status §r- Exibe o progresso completado para a geração que está em andamento.\n§2/neoforge generate help §r- Exibe esta mensagem.\nDicas gerais: Se estiver rodando a partir de um console de servidor, você pode rodar o comando generate em diferentes dimensões utilizando /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Tempo em %s flui a uma taxa de %sx (%s minutos por dia).", "commands.neoforge.timespeed.query.default": "Tempo em %s fluxos normalmente (20 minutos por dia).", "commands.neoforge.timespeed.set": "Definir fluxo de tempo em %s para %sx (%s minutos por dia).", @@ -122,7 +122,7 @@ "commands.neoforge.data_components.list.tooltip.deleted": "Componente %s com valor %s foi excluído", "commands.neoforge.data_components.list.tooltip.modified": "O componente %s foi modificado de %s para %s", "commands.neoforge.data_components.list.tooltip.added": "Componente %s foi adicionado com valor %s", - "commands.neoforge.debug_class_loading_transformations.message": "Transformed/total loaded classes: %s and %s parsed for mixin", + "commands.neoforge.debug_class_loading_transformations.message": "Classes transformadas/carregadas totais: %s e %s analisadas para mixin", "commands.neoforge.vanilla.resource_key.no_recipes_on_client": "Não é possível pesquisar por receita em comandos do cliente", "commands.config.getwithtype": "Configuração para %s do tipo %s encontrada em %s", "commands.config.noconfig": "Configuração para %s do tipo %s não encontrada", diff --git a/src/main/resources/assets/neoforge/lang/pt_pt.json b/src/main/resources/assets/neoforge/lang/pt_pt.json index e971a7148b6..cc5617c2af2 100644 --- a/src/main/resources/assets/neoforge/lang/pt_pt.json +++ b/src/main/resources/assets/neoforge/lang/pt_pt.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No pregeneration currently running. Run `/neoforge generate help` to see commands for starting generation.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/ru_ru.json b/src/main/resources/assets/neoforge/lang/ru_ru.json index 057fe044f82..3ccdeaa8723 100644 --- a/src/main/resources/assets/neoforge/lang/ru_ru.json +++ b/src/main/resources/assets/neoforge/lang/ru_ru.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Генерация остановлена! Сгенерировано %1$s из %2$s чанков (%3$s%%).", "commands.neoforge.chunkgen.status": "Состояние генерации: сгенерировано %1$s из %2$s чанков (%3$s%%).", "commands.neoforge.chunkgen.not_running": "Предварительная генерация не запущена. Выполните команду `/neoforge generate help`, чтобы увидеть команды для запуска генерации.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start <радиус_в_чанках> [шкала_прогресса] §r§f— Генерирует квадратную область с центром в заданных координатах с длиной сторон радиус_в_чанках * 2.\n§2/neoforge generate stop §r§f— Останавливает текущую генерацию и отображает достигнутый прогресс.\n§2/neoforge generate status §r— Отображает текущий прогресс генерации.\n§2/neoforge generate help §r— Отображает это сообщение.\nСовет: для генерации в иных измерениях из консоли сервера используйте команду /execute in <измерение> neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Время в %s проходит со скоростью %sx (%s минут в день).", "commands.neoforge.timespeed.query.default": "Время в %s проходит нормально (20 минут в день).", "commands.neoforge.timespeed.set": "Установить поток времени в %s на %sx (%s минут в день).", diff --git a/src/main/resources/assets/neoforge/lang/sk_sk.json b/src/main/resources/assets/neoforge/lang/sk_sk.json index 11480d0eada..f49a2bc9b98 100644 --- a/src/main/resources/assets/neoforge/lang/sk_sk.json +++ b/src/main/resources/assets/neoforge/lang/sk_sk.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generovanie zastavilo! %1$s z %2$s chunkov vygenerovaných. (%3$s%%)", "commands.neoforge.chunkgen.status": "Status generovania! %1$s z %2$s chunkov vygenerovaných. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Žiadne pregenerovnie chunkov nie je spustené. Spustite `/neoforge generate help` pre zobrazenie príkazov na začatie generovania.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Vygeneruje štvorcovo centrovane od danej pozície ktoreá je chunkRadius * 2 na každej strane\n§2/neoforge generate stop §r§f- Zastavý aktuálne generovanie a zobrazí sa docielený progres.\n§2/neoforge generate status §r- Zobrazí docielený progres aktuálne bežiacej generácie.\n§2/neoforge generate help §r- Zobrazí túto správu.\nVšeobecné rady: Pokiaľ je generovanie spúštané z konzoly serveru, môžete spustiť generovanie v iných dimenziách použitím /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Čas v %s tokoch s rýchlosťou %sx (%s minút za deň).", "commands.neoforge.timespeed.query.default": "Čas v %s plynie normálne (20 minút na deň).", "commands.neoforge.timespeed.set": "Nastaviť plynutie času v %s na %sx (%s minúty za deň).", diff --git a/src/main/resources/assets/neoforge/lang/tr_tr.json b/src/main/resources/assets/neoforge/lang/tr_tr.json index eaae41a4938..f8660db54bc 100644 --- a/src/main/resources/assets/neoforge/lang/tr_tr.json +++ b/src/main/resources/assets/neoforge/lang/tr_tr.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No pregeneration currently running. Run `/neoforge generate help` to see commands for starting generation.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/tt_ru.json b/src/main/resources/assets/neoforge/lang/tt_ru.json index 1ce74a832fd..885d55220b9 100644 --- a/src/main/resources/assets/neoforge/lang/tt_ru.json +++ b/src/main/resources/assets/neoforge/lang/tt_ru.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No pregeneration currently running. Run `/neoforge generate help` to see commands for starting generation.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/uk_ua.json b/src/main/resources/assets/neoforge/lang/uk_ua.json index cd7b2a69de1..66d6922b154 100644 --- a/src/main/resources/assets/neoforge/lang/uk_ua.json +++ b/src/main/resources/assets/neoforge/lang/uk_ua.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Генерація призупинена! %1$s з %2$s чанків згенеровано. (%3$s%%)", "commands.neoforge.chunkgen.status": "Статус генерації! %1$s з %2$s чанків згенеровано. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Жодна прегенерація наразі не виконується. Запустіть «/neoforge generate help», щоб побачити команди для початку генерації.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Генерує квадратну область з центром в наданих координатах і довжиною сторін chunkRadius * 2.\n§2/neoforge generate stop §r§f- Зупиняє поточну генерацію і відображає досягнутий прогрес.\n§2/neoforge generate status §r- Відображає поточний прогрес активної генерації.\n§2/neoforge generate help §r- Відображає це повідомлення.\nЗагальні рекомендації: Якщо команди виконуються з серверної консолі, ви зможете запустити генерацію для різних вимірів, використовуючи /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Час в %s тече зі швидкістю %sx (%s хвилин на день).", "commands.neoforge.timespeed.query.default": "Час в %s тече нормально (20 хвилин на день).", "commands.neoforge.timespeed.set": "Установити час в %s до %sx (%s хвилин на день).", diff --git a/src/main/resources/assets/neoforge/lang/vi_vn.json b/src/main/resources/assets/neoforge/lang/vi_vn.json index e971a7148b6..cc5617c2af2 100644 --- a/src/main/resources/assets/neoforge/lang/vi_vn.json +++ b/src/main/resources/assets/neoforge/lang/vi_vn.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "No pregeneration currently running. Run `/neoforge generate help` to see commands for starting generation.", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", diff --git a/src/main/resources/assets/neoforge/lang/zh_cn.json b/src/main/resources/assets/neoforge/lang/zh_cn.json index b44a36d88fd..82439e62666 100644 --- a/src/main/resources/assets/neoforge/lang/zh_cn.json +++ b/src/main/resources/assets/neoforge/lang/zh_cn.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "生成已停止!预定生成%2$s个区块,已生成%1$s个。(%3$s%%)", "commands.neoforge.chunkgen.status": "生成状态!预定生成%2$s个区块,已生成%1$s个。(%3$s%%)", "commands.neoforge.chunkgen.not_running": "无进行中的预生成。运行 `/neoforge generate help` 以查看开始生成的命令。", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- 生成一个以给定坐标为中心的、边长为 chunkRadius * 2的正方形。\n§2/neoforge generate stop §r§f- 停止当前生成,显示完成进度。\n§2/neoforge generate status §r- 显示当前生成的完成进度。\n§2/neoforge generate help §r- 显示此消息\n通用提示:如果从服务器控制台执行,可以通过 '/execute in neoforge generate...' 在特定维度执行。", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- 生成一个以给定坐标为中心的、边长为 chunkRadius * 2的正方形。\n§2/neoforge generate stop §r§f- 停止当前生成,显示完成进度。\n§2/neoforge generate status §r- 显示当前生成的完成进度。\n§2/neoforge generate help §r- 显示此消息\n通用提示:如果从服务器控制台执行,可以通过 '/execute in run neoforge generate...' 在特定维度执行。", "commands.neoforge.timespeed.query": "%s的时间以%sx的速度流逝 (%s分钟每天)。", "commands.neoforge.timespeed.query.default": "%s的时间以正常速度流逝 (20分钟每天)。", "commands.neoforge.timespeed.set": "已将%s的时间流速设为%sx (%s分钟每天)。", diff --git a/src/main/resources/assets/neoforge/lang/zh_tw.json b/src/main/resources/assets/neoforge/lang/zh_tw.json index 99bd477eff0..c617411543d 100644 --- a/src/main/resources/assets/neoforge/lang/zh_tw.json +++ b/src/main/resources/assets/neoforge/lang/zh_tw.json @@ -109,7 +109,7 @@ "commands.neoforge.chunkgen.stopped": "生成已停止!已生成 %1$s/%2$s 個區塊。(%3$s%%)", "commands.neoforge.chunkgen.status": "生成狀態!已生成 %1$s/%2$s 個區塊。(%3$s%%)", "commands.neoforge.chunkgen.not_running": "沒有正在進行的預生成。執行 `/neoforge generate help` 以查看開始生成的指令。", - "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- 生成一個以指定座標為中心、邊長為 chunkRadius * 2 的正方形。\n§2/neoforge generate stop §r§f- 停止目前生成,並顯示已完成的進度。\n§2/neoforge generate status §r- 顯示目前生成的完成進度。\n§2/neoforge generate help §r- 顯示這則訊息\n一般提示: 如果從伺服器控制台執行,可以使用 /execute in neoforge generate... 在不同維度進行生成。", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in run neoforge generate...", "commands.neoforge.timespeed.query": "%s 的時間流逝速度為 %s×(每天 %s 分鐘)。", "commands.neoforge.timespeed.query.default": "%s 的時間流逝速度為預設值(每天 20 分鐘)。", "commands.neoforge.timespeed.set": "已將 %s 的時間流逝速度設定為 %s×(每天 %s 分鐘)。", diff --git a/src/main/templates/minecraft.neoforge.mods.toml b/src/main/templates/minecraft.neoforge.mods.toml new file mode 100644 index 00000000000..dea3bb8d92e --- /dev/null +++ b/src/main/templates/minecraft.neoforge.mods.toml @@ -0,0 +1,8 @@ +modLoader="minecraft" +license="Minecraft EULA" +[[mods]] +modId="minecraft" +version="${minecraft_version}" +displayName="Minecraft" +authors="Mojang Studios" +description="" diff --git a/testframework/src/main/java/net/neoforged/testframework/condition/TestEnabledLootCondition.java b/testframework/src/main/java/net/neoforged/testframework/condition/TestEnabledLootCondition.java index df8bc51b4fe..80206418c97 100644 --- a/testframework/src/main/java/net/neoforged/testframework/condition/TestEnabledLootCondition.java +++ b/testframework/src/main/java/net/neoforged/testframework/condition/TestEnabledLootCondition.java @@ -10,7 +10,6 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.TestFramework; import net.neoforged.testframework.impl.MutableTestFramework; @@ -26,7 +25,7 @@ public TestEnabledLootCondition(DynamicTest test) { } @Override - public LootItemConditionType getType() { + public MapCodec codec() { return TestFrameworkMod.TEST_ENABLED.get(); } 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 308460b3b76..2b01b9bfaf0 100644 --- a/testframework/src/main/java/net/neoforged/testframework/gametest/ExtendedGameTestHelper.java +++ b/testframework/src/main/java/net/neoforged/testframework/gametest/ExtendedGameTestHelper.java @@ -59,7 +59,6 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.neoforged.bus.api.Event; -import net.neoforged.neoforge.capabilities.BlockCapability; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.util.FakePlayer; import net.neoforged.neoforge.event.entity.living.LivingKnockBackEvent; @@ -186,19 +185,6 @@ public T getBlockEntity(int x, int y, int z, Class ty return getBlockEntity(new BlockPos(x, y, z), type); } - @Nullable - public T getCapability(BlockCapability cap, BlockPos pos, C context) { - return getLevel().getCapability(cap, absolutePos(pos), context); - } - - public T requireCapability(BlockCapability cap, BlockPos pos, C context) { - final var capability = getCapability(cap, pos, context); - if (capability == null) { - throw this.assertionException(pos, "Expected capability %s but there was none", cap); - } - return capability; - } - public ParametrizedGameTestSequence startSequence(Supplier value) { return new ParametrizedGameTestSequence<>(this, this.startSequence(), value); } @@ -227,7 +213,7 @@ public void assertItemEntityCountIsAtLeast(Item item, BlockPos pos, double range } if (count < lowerLimit) { - throw this.assertionException(pos, "Expected at least %s %s items to exist (found %s)", lowerLimit, item.getName().getString(), count); + throw this.assertionException(pos, "Expected at least %s %s items to exist (found %s)", lowerLimit, item.getName(item.getDefaultInstance()).getString(), count); } } @@ -364,14 +350,6 @@ public void assertNotNull(@Nullable Object var, String message) { this.assertTrue(var != null, message); } - public void fail(String message) { - this.fail(Component.translatable(message)); - } - - public void fail(String message, BlockPos pos) { - this.fail(Component.translatable(message), pos); - } - public void assertBlock(BlockPos pos, Predicate predicate, String message) { this.assertBlock(pos, predicate, block -> Component.translatable(message, block)); } diff --git a/testframework/src/main/java/net/neoforged/testframework/gametest/GameTest.java b/testframework/src/main/java/net/neoforged/testframework/gametest/GameTest.java index b3745840e75..261c8a4f10c 100644 --- a/testframework/src/main/java/net/neoforged/testframework/gametest/GameTest.java +++ b/testframework/src/main/java/net/neoforged/testframework/gametest/GameTest.java @@ -19,6 +19,8 @@ boolean skyAccess() default false; + int padding() default 0; + int rotationSteps() default 0; boolean required() default true; diff --git a/testframework/src/main/java/net/neoforged/testframework/gametest/GameTestData.java b/testframework/src/main/java/net/neoforged/testframework/gametest/GameTestData.java index 4cd5d60577c..cc829ad7f4e 100644 --- a/testframework/src/main/java/net/neoforged/testframework/gametest/GameTestData.java +++ b/testframework/src/main/java/net/neoforged/testframework/gametest/GameTestData.java @@ -13,4 +13,4 @@ public record GameTestData( @Nullable String batchName, String structureName, boolean required, int maxAttempts, int requiredSuccesses, Consumer function, int maxTicks, - int setupTicks, Rotation rotation, boolean skyAccess, boolean manualOnly) {} + int setupTicks, Rotation rotation, boolean skyAccess, int padding, boolean manualOnly) {} diff --git a/testframework/src/main/java/net/neoforged/testframework/impl/GameTestRegistration.java b/testframework/src/main/java/net/neoforged/testframework/impl/GameTestRegistration.java index ca2f39c920d..a8f64c5c183 100644 --- a/testframework/src/main/java/net/neoforged/testframework/impl/GameTestRegistration.java +++ b/testframework/src/main/java/net/neoforged/testframework/impl/GameTestRegistration.java @@ -45,7 +45,7 @@ static final class Instance extends GameTestInstance { private final TestFramework framework; private final String testId; - public Instance(TestData> data, TestFramework framework, String testId) { + public Instance(TestData>> data, TestFramework framework, String testId) { super(data); this.framework = framework; this.testId = testId; @@ -145,7 +145,7 @@ record TestEntry(Test test, Identifier batchName, GameTestData gameTestData) {} game.maxTicks(), game.setupTicks(), game.required(), game.rotation(), game.manualOnly(), game.maxAttempts(), - game.requiredSuccesses(), game.skyAccess()), framework, test.id())); + game.requiredSuccesses(), game.skyAccess(), game.padding()), framework, test.id())); } } } diff --git a/testframework/src/main/java/net/neoforged/testframework/impl/TestFrameworkMod.java b/testframework/src/main/java/net/neoforged/testframework/impl/TestFrameworkMod.java index 2b79083fd05..ac52f18e00c 100644 --- a/testframework/src/main/java/net/neoforged/testframework/impl/TestFrameworkMod.java +++ b/testframework/src/main/java/net/neoforged/testframework/impl/TestFrameworkMod.java @@ -8,7 +8,7 @@ import com.mojang.serialization.MapCodec; import net.minecraft.core.registries.Registries; import net.minecraft.gametest.framework.GameTestInstance; -import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; import net.neoforged.neoforge.common.crafting.IngredientType; @@ -20,8 +20,8 @@ @Mod("testframework") public class TestFrameworkMod { - public static final DeferredRegister LOOT_CONDITIONS = DeferredRegister.create(Registries.LOOT_CONDITION_TYPE, "testframework"); - public static final DeferredHolder TEST_ENABLED = LOOT_CONDITIONS.register("test_enabled", () -> new LootItemConditionType(TestEnabledLootCondition.CODEC)); + public static final DeferredRegister> LOOT_CONDITIONS = DeferredRegister.create(Registries.LOOT_CONDITION_TYPE, "testframework"); + public static final DeferredHolder, MapCodec> TEST_ENABLED = LOOT_CONDITIONS.register("test_enabled", () -> TestEnabledLootCondition.CODEC); public static final DeferredRegister> INGREDIENTS = DeferredRegister.create(NeoForgeRegistries.INGREDIENT_TYPES, "testframework"); public static final DeferredHolder, IngredientType> TEST_ENABLED_INGREDIENT = INGREDIENTS.register("test_enabled", () -> new IngredientType<>(TestEnabledIngredient.CODEC)); diff --git a/testframework/src/main/java/net/neoforged/testframework/impl/test/AbstractTest.java b/testframework/src/main/java/net/neoforged/testframework/impl/test/AbstractTest.java index a77db213cda..e52bc9ef20b 100644 --- a/testframework/src/main/java/net/neoforged/testframework/impl/test/AbstractTest.java +++ b/testframework/src/main/java/net/neoforged/testframework/impl/test/AbstractTest.java @@ -113,7 +113,7 @@ protected final void configureGameTest(@Nullable GameTest gameTest, @Nullable Em gameTest.required(), gameTest.attempts(), gameTest.requiredSuccesses(), this::onGameTest, gameTest.timeoutTicks(), gameTest.setupTicks(), StructureUtils.getRotationForRotationSteps(gameTest.rotationSteps()), - gameTest.skyAccess(), gameTest.manualOnly()); + gameTest.skyAccess(), gameTest.padding(), gameTest.manualOnly()); } protected String gameTestTemplate(GameTest gameTest) { diff --git a/tests/src/generated/resources/assets/data_gen_test/lang/en_us.json b/tests/src/generated/resources/assets/data_gen_test/lang/en_us.json index b7ac4746646..9193113ac0f 100644 --- a/tests/src/generated/resources/assets/data_gen_test/lang/en_us.json +++ b/tests/src/generated/resources/assets/data_gen_test/lang/en_us.json @@ -1,5 +1,25 @@ { "block.minecraft.stone": "Stone", + "data_gen_test.test.component.appended": { + "extra": [ + { + "color": "gold", + "text": "Second" + } + ], + "text": "First" + }, + "data_gen_test.test.component.literal": "Literal", + "data_gen_test.test.component.nested": { + "translate": "data_gen_test.test.component.literal", + "with": [ + "minecraft:test" + ] + }, + "data_gen_test.test.component.styled": { + "color": "blue", + "text": "Blue" + }, "data_gen_test.test.unicode": "ʇsǝ┴ ǝpoɔᴉu∩", "effect.minecraft.poison": "Poison", "entity.minecraft.cat": "Cat", diff --git a/tests/src/generated/resources/assets/neotests_custom_game_rule/lang/en_us.json b/tests/src/generated/resources/assets/neotests_custom_game_rule/lang/en_us.json new file mode 100644 index 00000000000..9c67ec1b78e --- /dev/null +++ b/tests/src/generated/resources/assets/neotests_custom_game_rule/lang/en_us.json @@ -0,0 +1,11 @@ +{ + "gamerule.category.neotests_custom_game_rule.game_rules": "Custom GameRules", + "gamerule.neotests_custom_game_rule.custom_boolean_game_rule": "Custom Boolean", + "gamerule.neotests_custom_game_rule.custom_boolean_game_rule.description": "A custom boolean game rule", + "gamerule.neotests_custom_game_rule.custom_double_game_rule": "Custom Double", + "gamerule.neotests_custom_game_rule.custom_double_game_rule.description": "A custom double game rule", + "gamerule.neotests_custom_game_rule.custom_integer_game_rule": "Custom Integer", + "gamerule.neotests_custom_game_rule.custom_integer_game_rule.description": "A custom integer game rule", + "gamerule.neotests_custom_game_rule.custom_string_game_rule": "Custom String", + "gamerule.neotests_custom_game_rule.custom_string_game_rule.description": "A custom string game rule" +} \ No newline at end of file diff --git a/tests/src/generated/resources/data/data_gen_test/advancement/obtain_dirt.json b/tests/src/generated/resources/data/data_gen_test/advancement/obtain_dirt.json index 7766eaa29c9..61eea0153aa 100644 --- a/tests/src/generated/resources/data/data_gen_test/advancement/obtain_dirt.json +++ b/tests/src/generated/resources/data/data_gen_test/advancement/obtain_dirt.json @@ -17,7 +17,6 @@ "translate": "dirt_description" }, "icon": { - "count": 1, "id": "minecraft:dirt" }, "title": { diff --git a/tests/src/generated/resources/data/data_gen_test/recipe/compound_ingredient_custom_types.json b/tests/src/generated/resources/data/data_gen_test/recipe/compound_ingredient_custom_types.json index 46509c12cc1..009012c82df 100644 --- a/tests/src/generated/resources/data/data_gen_test/recipe/compound_ingredient_custom_types.json +++ b/tests/src/generated/resources/data/data_gen_test/recipe/compound_ingredient_custom_types.json @@ -10,59 +10,7 @@ { "neoforge:ingredient_type": "neoforge:components", "components": { - "minecraft:attribute_modifiers": [ - { - "type": "minecraft:attack_damage", - "amount": 2.0, - "id": "minecraft:base_attack_damage", - "operation": "add_value", - "slot": "mainhand" - }, - { - "type": "minecraft:attack_speed", - "amount": -2.799999952316284, - "id": "minecraft:base_attack_speed", - "operation": "add_value", - "slot": "mainhand" - } - ], - "minecraft:break_sound": "minecraft:entity.item.break", - "minecraft:damage": 3, - "minecraft:enchantable": { - "value": 5 - }, - "minecraft:enchantments": {}, - "minecraft:item_model": "minecraft:stone_pickaxe", - "minecraft:item_name": { - "translate": "item.minecraft.stone_pickaxe" - }, - "minecraft:lore": [], - "minecraft:max_damage": 131, - "minecraft:max_stack_size": 1, - "minecraft:rarity": "common", - "minecraft:repair_cost": 0, - "minecraft:repairable": { - "items": "#minecraft:stone_tool_materials" - }, - "minecraft:swing_animation": {}, - "minecraft:tool": { - "rules": [ - { - "blocks": "#minecraft:incorrect_for_stone_tool", - "correct_for_drops": false - }, - { - "blocks": "#minecraft:mineable/pickaxe", - "correct_for_drops": true, - "speed": 4.0 - } - ] - }, - "minecraft:tooltip_display": {}, - "minecraft:use_effects": {}, - "minecraft:weapon": { - "item_damage_per_attack": 2 - } + "minecraft:damage": 3 }, "items": "minecraft:stone_pickaxe", "strict": true @@ -75,7 +23,6 @@ "#" ], "result": { - "count": 1, "id": "minecraft:gold_block" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/data_gen_test/recipe/compound_ingredient_only_vanilla.json b/tests/src/generated/resources/data/data_gen_test/recipe/compound_ingredient_only_vanilla.json index 85e3c7d7926..f1f799ca7a4 100644 --- a/tests/src/generated/resources/data/data_gen_test/recipe/compound_ingredient_only_vanilla.json +++ b/tests/src/generated/resources/data/data_gen_test/recipe/compound_ingredient_only_vanilla.json @@ -16,7 +16,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:dirt" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/data_gen_test/recipe/conditional3.json b/tests/src/generated/resources/data/data_gen_test/recipe/conditional3.json index 0d478ced0f1..6e81db03fdd 100644 --- a/tests/src/generated/resources/data/data_gen_test/recipe/conditional3.json +++ b/tests/src/generated/resources/data/data_gen_test/recipe/conditional3.json @@ -15,7 +15,6 @@ "XX" ], "result": { - "count": 1, "id": "minecraft:netherite_block" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/data_gen_test/recipe/difference_ingredient.json b/tests/src/generated/resources/data/data_gen_test/recipe/difference_ingredient.json index aeec9e6ebe3..6e86cf12000 100644 --- a/tests/src/generated/resources/data/data_gen_test/recipe/difference_ingredient.json +++ b/tests/src/generated/resources/data/data_gen_test/recipe/difference_ingredient.json @@ -14,7 +14,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:flint_and_steel" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/data_gen_test/recipe/intersection_ingredient.json b/tests/src/generated/resources/data/data_gen_test/recipe/intersection_ingredient.json index f987924471b..545ecb88c15 100644 --- a/tests/src/generated/resources/data/data_gen_test/recipe/intersection_ingredient.json +++ b/tests/src/generated/resources/data/data_gen_test/recipe/intersection_ingredient.json @@ -16,7 +16,6 @@ " # " ], "result": { - "count": 1, "id": "minecraft:netherrack" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/minecraft/advancement/good_parent.json b/tests/src/generated/resources/data/minecraft/advancement/good_parent.json index cc94d9d20b2..60ff2024517 100644 --- a/tests/src/generated/resources/data/minecraft/advancement/good_parent.json +++ b/tests/src/generated/resources/data/minecraft/advancement/good_parent.json @@ -17,7 +17,6 @@ "background": "minecraft:textures/gui/advancements/backgrounds/stone.png", "description": "You got cobblestone", "icon": { - "count": 1, "id": "minecraft:cobblestone" }, "show_toast": false, diff --git a/tests/src/generated/resources/data/minecraft/advancement/obtain_diamond_block.json b/tests/src/generated/resources/data/minecraft/advancement/obtain_diamond_block.json index df2a7d3f434..670079b4b8c 100644 --- a/tests/src/generated/resources/data/minecraft/advancement/obtain_diamond_block.json +++ b/tests/src/generated/resources/data/minecraft/advancement/obtain_diamond_block.json @@ -17,7 +17,6 @@ "description": "You obtained a DiamondBlock", "frame": "challenge", "icon": { - "count": 1, "id": "minecraft:diamond_block" }, "title": { diff --git a/tests/src/generated/resources/data/minecraft/advancement/story/root.json b/tests/src/generated/resources/data/minecraft/advancement/story/root.json index f668f1a7360..bf5b5ece00f 100644 --- a/tests/src/generated/resources/data/minecraft/advancement/story/root.json +++ b/tests/src/generated/resources/data/minecraft/advancement/story/root.json @@ -16,7 +16,6 @@ "background": "minecraft:textures/gui/advancements/backgrounds/stone.png", "description": "Changed Description", "icon": { - "count": 1, "id": "minecraft:grass_block" }, "show_toast": false, diff --git a/tests/src/generated/resources/data/neotests_block_tag_ingredient/recipe/block_tag.json b/tests/src/generated/resources/data/neotests_block_tag_ingredient/recipe/block_tag.json index 6a9180db039..d36648b3417 100644 --- a/tests/src/generated/resources/data/neotests_block_tag_ingredient/recipe/block_tag.json +++ b/tests/src/generated/resources/data/neotests_block_tag_ingredient/recipe/block_tag.json @@ -14,7 +14,6 @@ "minecraft:water_bucket" ], "result": { - "count": 1, "id": "minecraft:mud" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_custom_predicate_test/advancement/named_item.json b/tests/src/generated/resources/data/neotests_custom_predicate_test/advancement/named_item.json index 318e2f81b69..4902428acfc 100644 --- a/tests/src/generated/resources/data/neotests_custom_predicate_test/advancement/named_item.json +++ b/tests/src/generated/resources/data/neotests_custom_predicate_test/advancement/named_item.json @@ -20,7 +20,6 @@ "display": { "description": "Get a named item", "icon": { - "count": 1, "id": "minecraft:anvil" }, "title": "Named!" diff --git a/tests/src/generated/resources/data/neotests_partial_nbtingredient/recipe/partial_nbt.json b/tests/src/generated/resources/data/neotests_partial_nbtingredient/recipe/partial_nbt.json index 2230a9c91e4..422e5fe239f 100644 --- a/tests/src/generated/resources/data/neotests_partial_nbtingredient/recipe/partial_nbt.json +++ b/tests/src/generated/resources/data/neotests_partial_nbtingredient/recipe/partial_nbt.json @@ -21,7 +21,6 @@ "IDE" ], "result": { - "count": 1, "id": "minecraft:allium" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_recipe_priorities/recipe/higher_priority_test.json b/tests/src/generated/resources/data/neotests_recipe_priorities/recipe/higher_priority_test.json index 78217713157..07cdb94698f 100644 --- a/tests/src/generated/resources/data/neotests_recipe_priorities/recipe/higher_priority_test.json +++ b/tests/src/generated/resources/data/neotests_recipe_priorities/recipe/higher_priority_test.json @@ -11,7 +11,6 @@ "XXX" ], "result": { - "count": 1, "id": "minecraft:redstone_block" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_strict_nbtingredient/recipe/strict_nbt.json b/tests/src/generated/resources/data/neotests_strict_nbtingredient/recipe/strict_nbt.json index bc4753c7cec..01d35e9a534 100644 --- a/tests/src/generated/resources/data/neotests_strict_nbtingredient/recipe/strict_nbt.json +++ b/tests/src/generated/resources/data/neotests_strict_nbtingredient/recipe/strict_nbt.json @@ -7,10 +7,10 @@ "base": { "neoforge:ingredient_type": "neoforge:components", "components": { + "!minecraft:custom_data": {}, "minecraft:damage": 4 }, - "items": "minecraft:diamond_pickaxe", - "strict": true + "items": "minecraft:diamond_pickaxe" }, "framework": "neotests:tests", "testId": "strictNBTIngredient" @@ -18,7 +18,6 @@ "minecraft:acacia_planks" ], "result": { - "count": 1, "id": "minecraft:acacia_boat" } } \ 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 index cd22632a3b1..0de4fa4f9b7 100644 --- 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 @@ -10,7 +10,6 @@ "minecraft:stone" ], "result": { - "count": 1, "id": "minecraft:bedrock" } } \ 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 5accc57d951..1af78ab8093 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 @@ -13,7 +13,6 @@ "#minecraft:dirt" ], "result": { - "count": 1, "id": "minecraft:diamond" } } \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_test_sized_ingredient/recipe/sized_ingredient_1.json b/tests/src/generated/resources/data/neotests_test_sized_ingredient/recipe/sized_ingredient_1.json index fd78cbc5201..67aeeec6986 100644 --- a/tests/src/generated/resources/data/neotests_test_sized_ingredient/recipe/sized_ingredient_1.json +++ b/tests/src/generated/resources/data/neotests_test_sized_ingredient/recipe/sized_ingredient_1.json @@ -20,7 +20,6 @@ } ], "result": { - "count": 1, "id": "minecraft:cherry_fence" } } \ No newline at end of file diff --git a/tests/src/generated/resources/pack.mcmeta b/tests/src/generated/resources/pack.mcmeta index 7a557f97bba..cc59a59d67f 100644 --- a/tests/src/generated/resources/pack.mcmeta +++ b/tests/src/generated/resources/pack.mcmeta @@ -4,14 +4,14 @@ { "directory": "neoforge_overlays_test", "formats": [ - 0, + 15, 2147483647 ], "max_format": [ 2147483647, 0 ], - "min_format": 0 + "min_format": 15 } ] }, @@ -20,14 +20,14 @@ { "directory": "pack_overlays_test", "formats": [ - 0, + 15, 2147483647 ], "max_format": [ 2147483647, 0 ], - "min_format": 0 + "min_format": 15 }, { "neoforge:conditions": [ @@ -38,14 +38,14 @@ ], "directory": "conditional_overlays_enabled", "formats": [ - 0, + 15, 2147483647 ], "max_format": [ 2147483647, 0 ], - "min_format": 0 + "min_format": 15 }, { "neoforge:conditions": [ @@ -56,24 +56,24 @@ ], "directory": "conditional_overlays_disabled", "formats": [ - 0, + 15, 2147483647 ], "max_format": [ 2147483647, 0 ], - "min_format": 0 + "min_format": 15 } ] }, "pack": { "description": "NeoForge tests resource pack", "max_format": 2147483647, - "min_format": 0, - "pack_format": 0, + "min_format": 15, + "pack_format": 15, "supported_formats": [ - 0, + 15, 2147483647 ] } diff --git a/tests/src/junit/java/net/neoforged/neoforge/unittest/ComponentHashingTest.java b/tests/src/junit/java/net/neoforged/neoforge/unittest/ComponentHashingTest.java index 481c6a9eafc..e57ef21d3dc 100644 --- a/tests/src/junit/java/net/neoforged/neoforge/unittest/ComponentHashingTest.java +++ b/tests/src/junit/java/net/neoforged/neoforge/unittest/ComponentHashingTest.java @@ -10,13 +10,23 @@ import java.util.List; import java.util.Map; import net.minecraft.core.component.DataComponents; +import net.minecraft.server.MinecraftServer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.neoforged.testframework.junit.EphemeralTestServerProvider; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.opentest4j.TestAbortedException; +@ExtendWith(EphemeralTestServerProvider.class) public class ComponentHashingTest { @Test - void testHashCodeCollisions() { + void testHashCodeCollisions(MinecraftServer server) { + // If the hashcode of DAMAGE and REPAIR_COST is identical, this test will produce a lot more collisions + if (System.identityHashCode(DataComponents.DAMAGE) == System.identityHashCode(DataComponents.REPAIR_COST)) { + throw new TestAbortedException("Cannot run hash collision test when hashcode of the two data components used by this test is the same"); + } + int MAX_DAMAGE = 1000; int MAX_REPAIR_COST = 100; 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 98a864310a4..97410198e09 100644 --- a/tests/src/junit/java/net/neoforged/neoforge/unittest/IngredientTests.java +++ b/tests/src/junit/java/net/neoforged/neoforge/unittest/IngredientTests.java @@ -68,7 +68,7 @@ void testIntersectionIngredient(MinecraftServer server) { void testComponentIngredient(boolean strict, MinecraftServer server) { var stack = new ItemStack(Items.DIAMOND_AXE); stack.set(DataComponents.DAMAGE, 1); - var ingredient = DataComponentIngredient.of(strict, stack); + var ingredient = DataComponentIngredient.of(strict, stack.getComponents(), stack.getItem()); Assertions.assertThat(ingredient.test(stack)).withFailMessage("Base ingredient doesn't match").isTrue(); stack.set(DataComponents.DAMAGE, 2); diff --git a/tests/src/junit/java/net/neoforged/neoforge/unittest/MutableQuadTests.java b/tests/src/junit/java/net/neoforged/neoforge/unittest/MutableQuadTests.java new file mode 100644 index 00000000000..52825176078 --- /dev/null +++ b/tests/src/junit/java/net/neoforged/neoforge/unittest/MutableQuadTests.java @@ -0,0 +1,463 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.unittest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; + +import com.mojang.blaze3d.platform.NativeImage; +import java.util.Arrays; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import net.minecraft.client.model.geom.builders.UVPair; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.renderer.block.model.BlockModelPart; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.renderer.texture.SpriteContents; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.metadata.animation.FrameSize; +import net.minecraft.client.resources.model.BlockModelRotation; +import net.minecraft.client.resources.model.Material; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelDebugName; +import net.minecraft.client.resources.model.ResolvedModel; +import net.minecraft.client.resources.model.SpriteGetter; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.core.Direction; +import net.minecraft.resources.Identifier; +import net.neoforged.neoforge.client.model.quad.BakedNormals; +import net.neoforged.neoforge.client.model.quad.MutableQuad; +import net.neoforged.neoforge.client.textures.UnitTextureAtlasSprite; +import org.joml.Matrix4f; +import org.joml.Quaternionf; +import org.joml.Vector2f; +import org.joml.Vector2fc; +import org.joml.Vector3f; +import org.joml.Vector3fc; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.EnumSource; + +public class MutableQuadTests { + private static final float WORLD_SCALE = 1 / 16f; // Factor for converting from "pixels" [0,16] to block space [0,1] + private static final Vector3fc REFERENCE_BLOCK_MIN = new Vector3f(1, 2, 3); + private static final Vector3fc REFERENCE_BLOCK_MAX = new Vector3f(8, 13, 16); + + static final String SQUARE_PARAMS = """ + side | l | b | r | t | d + NORTH | 8 | 2 | 15 | 13 | 3 + SOUTH | 1 | 2 | 8 | 13 | 0 + WEST | 3 | 2 | 16 | 13 | 1 + EAST | 0 | 2 | 13 | 13 | 8 + UP | 1 | 0 | 8 | 13 | 3 + DOWN | 1 | 3 | 8 | 16 | 2 + """; + + @CsvSource(textBlock = SQUARE_PARAMS, delimiter = '|', useHeadersInDisplayName = true) + @ParameterizedTest + public void testSetSquareAgainstVanillaBlockModel(Direction side, float left, float bottom, float right, float top, float depth) { + var referenceQuads = buildReferenceQuads(); + + var mutableQuad = new MutableQuad(); + mutableQuad.setCubeFaceFromSpriteCoords( + side, + left * WORLD_SCALE, + bottom * WORLD_SCALE, + right * WORLD_SCALE, + top * WORLD_SCALE, + depth * WORLD_SCALE); + mutableQuad.setSprite(new MockSprite()); + mutableQuad.bakeUvsFromPosition(); + assertQuadsEquals(referenceQuads.get(side), mutableQuad); + } + + @EnumSource(Direction.class) + @ParameterizedTest + public void testSetSquareAgainstVanillaBlockModelForFullBlock(Direction side) { + var referenceQuads = buildReferenceQuads(new Vector3f(0, 0, 0), new Vector3f(16, 16, 16)); + + var mutableQuad = new MutableQuad(); + mutableQuad.setCubeFaceFromSpriteCoords(side, 0, 0, 1, 1, 0); + mutableQuad.setSprite(new MockSprite()); + mutableQuad.bakeUvsFromPosition(); + assertQuadsEquals(referenceQuads.get(side), mutableQuad); + } + + /** + * These vertices were created using Fabrics QuadEmitter with baked UV using BAKE_UVLOCK, + * and a sprite that matches the positions of MockSprite. + */ + private static final Object[][] FABRIC_REFERENCE_DATA = { + { Direction.NORTH, new Vector3f(0.5f, 0.8125f, 0.1875f), UVPair.pack(0.53125f, 0.51171875f) }, + { Direction.NORTH, new Vector3f(0.5f, 0.125f, 0.1875f), UVPair.pack(0.53125f, 0.5546875f) }, + { Direction.NORTH, new Vector3f(0.0625f, 0.125f, 0.1875f), UVPair.pack(0.55859375f, 0.5546875f) }, + { Direction.NORTH, new Vector3f(0.0625f, 0.8125f, 0.1875f), UVPair.pack(0.55859375f, 0.51171875f) }, + { Direction.SOUTH, new Vector3f(0.0625f, 0.8125f, 1.0f), UVPair.pack(0.50390625f, 0.51171875f) }, + { Direction.SOUTH, new Vector3f(0.0625f, 0.125f, 1.0f), UVPair.pack(0.50390625f, 0.5546875f) }, + { Direction.SOUTH, new Vector3f(0.5f, 0.125f, 1.0f), UVPair.pack(0.53125f, 0.5546875f) }, + { Direction.SOUTH, new Vector3f(0.5f, 0.8125f, 1.0f), UVPair.pack(0.53125f, 0.51171875f) }, + { Direction.WEST, new Vector3f(0.0625f, 0.8125f, 0.1875f), UVPair.pack(0.51171875f, 0.51171875f) }, + { Direction.WEST, new Vector3f(0.0625f, 0.125f, 0.1875f), UVPair.pack(0.51171875f, 0.5546875f) }, + { Direction.WEST, new Vector3f(0.0625f, 0.125f, 1.0f), UVPair.pack(0.5625f, 0.5546875f) }, + { Direction.WEST, new Vector3f(0.0625f, 0.8125f, 1.0f), UVPair.pack(0.5625f, 0.51171875f) }, + { Direction.EAST, new Vector3f(0.5f, 0.8125f, 1.0f), UVPair.pack(0.5f, 0.51171875f) }, + { Direction.EAST, new Vector3f(0.5f, 0.125f, 1.0f), UVPair.pack(0.5f, 0.5546875f) }, + { Direction.EAST, new Vector3f(0.5f, 0.125f, 0.1875f), UVPair.pack(0.55078125f, 0.5546875f) }, + { Direction.EAST, new Vector3f(0.5f, 0.8125f, 0.1875f), UVPair.pack(0.55078125f, 0.51171875f) }, + { Direction.UP, new Vector3f(0.0625f, 0.8125f, 0.1875f), UVPair.pack(0.50390625f, 0.51171875f) }, + { Direction.UP, new Vector3f(0.0625f, 0.8125f, 1.0f), UVPair.pack(0.50390625f, 0.5625f) }, + { Direction.UP, new Vector3f(0.5f, 0.8125f, 1.0f), UVPair.pack(0.53125f, 0.5625f) }, + { Direction.UP, new Vector3f(0.5f, 0.8125f, 0.1875f), UVPair.pack(0.53125f, 0.51171875f) }, + { Direction.DOWN, new Vector3f(0.0625f, 0.125f, 1.0f), UVPair.pack(0.50390625f, 0.5f) }, + { Direction.DOWN, new Vector3f(0.0625f, 0.125f, 0.1875f), UVPair.pack(0.50390625f, 0.55078125f) }, + { Direction.DOWN, new Vector3f(0.5f, 0.125f, 0.1875f), UVPair.pack(0.53125f, 0.55078125f) }, + { Direction.DOWN, new Vector3f(0.5f, 0.125f, 1.0f), UVPair.pack(0.53125f, 0.5f) }, + }; + + @CsvSource(textBlock = SQUARE_PARAMS, delimiter = '|', useHeadersInDisplayName = true) + @ParameterizedTest + public void testSetSquareAgainstFabricSquare(Direction side, float left, float bottom, float right, float top, float depth) { + var f = 1 / 16f; // Factor for converting from "pixels" [0,16] to block space [0,1] + var refVertices = Arrays.stream(FABRIC_REFERENCE_DATA).filter(d -> d[0] == side).toList(); + assertEquals(4, refVertices.size()); + var referenceQuad = new BakedQuad( + (Vector3fc) refVertices.get(0)[1], + (Vector3fc) refVertices.get(1)[1], + (Vector3fc) refVertices.get(2)[1], + (Vector3fc) refVertices.get(3)[1], + (long) refVertices.get(0)[2], + (long) refVertices.get(1)[2], + (long) refVertices.get(2)[2], + (long) refVertices.get(3)[2], + 0, + side, + UnitTextureAtlasSprite.INSTANCE, + true, + 0); + + var mutableQuad = new MutableQuad(); + mutableQuad.setSprite(new MockSprite()); + mutableQuad.setCubeFaceFromSpriteCoords(side, left * f, bottom * f, right * f, top * f, depth * f); + mutableQuad.bakeUvsFromPosition(); + assertQuadsEquals(referenceQuad, mutableQuad); + } + + @ParameterizedTest + @EnumSource(Direction.class) + public void testSetCubeFaceFromVectors(Direction side) { + var referenceQuads = buildReferenceQuads(); + + var from = new Vector3f(REFERENCE_BLOCK_MIN).mul(WORLD_SCALE); + var to = new Vector3f(REFERENCE_BLOCK_MAX).mul(WORLD_SCALE); + + var mutableQuad = new MutableQuad(); + mutableQuad.setSprite(new MockSprite()); + mutableQuad.setCubeFace(side, from, to); + mutableQuad.bakeUvsFromPosition(); + assertQuadsEquals(referenceQuads.get(side), mutableQuad); + } + + @ParameterizedTest + @EnumSource(Direction.class) + public void testSetCubeFace(Direction side) { + var referenceQuads = buildReferenceQuads(); + + var from = new Vector3f(REFERENCE_BLOCK_MIN).mul(WORLD_SCALE); + var to = new Vector3f(REFERENCE_BLOCK_MAX).mul(WORLD_SCALE); + + var mutableQuad = new MutableQuad(); + mutableQuad.setSprite(new MockSprite()); + mutableQuad.setCubeFace(side, from.x, from.y, from.z, to.x, to.y, to.z); + mutableQuad.bakeUvsFromPosition(); + assertQuadsEquals(referenceQuads.get(side), mutableQuad); + } + + @ParameterizedTest + @EnumSource(Direction.class) + public void testSetCubeFaceFullBlock(Direction side) { + var min = new Vector3f(0, 0, 0); + var max = new Vector3f(16, 16, 16); + var referenceQuads = buildReferenceQuads(min, max); + + var from = new Vector3f(min).mul(WORLD_SCALE); + var to = new Vector3f(max).mul(WORLD_SCALE); + + var mutableQuad = new MutableQuad(); + mutableQuad.setSprite(new MockSprite()); + mutableQuad.setCubeFace(side, from.x, from.y, from.z, to.x, to.y, to.z); + mutableQuad.bakeUvsFromPosition(); + assertQuadsEquals(referenceQuads.get(side), mutableQuad); + } + + @Test + void testSetFromBakedQuad() { + var refQuad = buildReferenceQuads().get(Direction.NORTH); + var mutableQuad = new MutableQuad().setFrom(refQuad); + for (int i = 0; i < 4; i++) { + assertEquals(mutableQuad.copyPosition(i), refQuad.position(i), "position[" + i + "]"); + assertEquals(mutableQuad.copyNormal(i), BakedNormals.unpack(refQuad.bakedNormals().normal(i), new Vector3f()), "normal[" + i + "]"); + assertEquals(mutableQuad.u(i), UVPair.unpackU(refQuad.packedUV(i)), "uv[" + i + "].u"); + assertEquals(mutableQuad.v(i), UVPair.unpackV(refQuad.packedUV(i)), "uv[" + i + "].v"); + assertEquals(mutableQuad.color(i), refQuad.bakedColors().color(i), "color[" + i + "]"); + } + + assertEquals(mutableQuad.tintIndex(), refQuad.tintIndex()); + assertEquals(mutableQuad.direction(), refQuad.direction()); + assertEquals(mutableQuad.sprite(), refQuad.sprite()); + assertEquals(mutableQuad.shade(), refQuad.shade()); + assertEquals(mutableQuad.lightEmission(), refQuad.lightEmission()); + assertEquals(mutableQuad.hasAmbientOcclusion(), refQuad.hasAmbientOcclusion()); + } + + /** + * Moves from a sprite to a sprite with different position in the atlas and checks + * that the UV gets translated correctly. + */ + @Test + void testSetSpriteAndMoveUv() { + var refQuad = buildReferenceQuads().get(Direction.NORTH); + var oldSprite = new MockSprite(192, 192); + var mutableQuad = new MutableQuad().setFrom(refQuad); + mutableQuad.setSprite(oldSprite); + + // Move to some position within the old sprite + float[] localUv = { + 0.25f, 0.25f, + 0.75f, 0.25f, + 0.75f, 0.75f, + 0.25f, 0.75f + }; + for (int i = 0; i < 4; i++) { + float localU = localUv[i * 2]; + float localV = localUv[i * 2 + 1]; + mutableQuad.setUvFromSprite(i, localU, localV); + assertEquals(oldSprite.getU(localU), mutableQuad.u(i), "u[" + i + "] == oldSprite.getU(" + localU + ")"); + assertEquals(oldSprite.getV(localV), mutableQuad.v(i), "v[" + i + "] == oldSprite.getV(" + localV + ")"); + } + + // Now change the sprite and also move the UV + var newSprite = new MockSprite(32, 32); + mutableQuad.setSpriteAndMoveUv(newSprite); + + for (int i = 0; i < 4; i++) { + float localU = localUv[i * 2]; + float localV = localUv[i * 2 + 1]; + assertEquals(newSprite.getU(localU), mutableQuad.u(i), "u[" + i + "] == newSprite.getU(" + localU + ")"); + assertEquals(newSprite.getV(localV), mutableQuad.v(i), "v[" + i + "] == newSprite.getV(" + localV + ")"); + } + } + + @Test + void testToBakedQuadRoundtrip() { + var refQuad = buildReferenceQuads().get(Direction.NORTH); + var mutableQuad = new MutableQuad().setFrom(refQuad); + assertThat(mutableQuad.toBakedQuad()).usingRecursiveComparison().isEqualTo(refQuad); + } + + @Test + void testToBakedQuadPositionReuseWithoutChanges() { + var refQuad = buildReferenceQuads().get(Direction.NORTH); + var mutatedQuad = new MutableQuad().setFrom(refQuad).toBakedQuad(); + + // Without changes, the positions should be the same objects + assertSame(refQuad.position0(), mutatedQuad.position0()); + assertSame(refQuad.position1(), mutatedQuad.position1()); + assertSame(refQuad.position2(), mutatedQuad.position2()); + assertSame(refQuad.position3(), mutatedQuad.position3()); + } + + @Test + void testToBakedQuadPositionReuseWithPartialChanges() { + // Mutate one of the positions, check that all others are reused, but the changed one isn't + var refQuad = buildReferenceQuads().get(Direction.NORTH); + for (int i = 0; i < 4; i++) { + var mutatedQuad = new MutableQuad().setFrom(refQuad).setPosition(i, 1, 2, 3).toBakedQuad(); + + // Without changes, the positions should be the same objects + for (int j = 0; j < 4; j++) { + if (i == j) { + assertNotSame(refQuad.position(j), mutatedQuad.position(j)); + } else { + assertSame(refQuad.position(j), mutatedQuad.position(j)); + } + } + } + } + + @Test + void testTransform() { + // Apply a really simple transform to a quad on the south face + var refQuad = new MutableQuad().setCubeFace(Direction.SOUTH, 0, 0, 0, 1, 1, 1).setSprite(new MockSprite()).toBakedQuad(); + var quat = new Quaternionf().fromAxisAngleDeg(Direction.EAST.getUnitVec3f(), 180); + var rotation = new Matrix4f().rotateAround(quat, 0.5f, 0.5f, 0.5f, new Matrix4f()); + + // It should be equivalent to a cube face on the opposite side, incl. normal vectors + var expectedQuad = new MutableQuad().setCubeFace(Direction.NORTH, 0, 0, 0, 1, 1, 1).setSprite(new MockSprite()).toBakedQuad(); + + var transformedQuad = new MutableQuad().setFrom(refQuad).transform(rotation).setDirection(Direction.NORTH).recalculateWinding(); + assertQuadsEquals(expectedQuad, transformedQuad); + } + + private static void assertQuadsEquals(BakedQuad expected, MutableQuad actual) { + var actualVertices = IntStream.range(0, 4) + .mapToObj(actual::copyPosition) + .map(MutableQuadTests::formatVector) + .toList(); + var expectedVertices = IntStream.range(0, 4) + .mapToObj(expected::position) + .map(MutableQuadTests::formatVector) + .toList(); + + assertThat(actualVertices).as("positions match").containsExactlyElementsOf(expectedVertices); + + var actualUvs = IntStream.range(0, 4) + .mapToObj(actual::copyUv) + .map(MutableQuadTests::formatVector) + .toList(); + var expectedUvs = IntStream.range(0, 4) + .mapToObj(vertexIdx -> new Vector2f(UVPair.unpackU(expected.packedUV(vertexIdx)), UVPair.unpackV(expected.packedUV(vertexIdx)))) + .map(MutableQuadTests::formatVector) + .toList(); + + assertThat(actualUvs).as("uvs match").containsExactlyElementsOf(expectedUvs); + } + + private static String formatVector(Vector3fc v) { + return String.format(Locale.ROOT, "%.03f, %.03f, %.03f", v.x(), v.y(), v.z()); + } + + private static String formatVector(Vector2fc v) { + return String.format(Locale.ROOT, "%.03f, %.03f", v.x(), v.y()); + } + + private static Map buildReferenceQuads() { + return buildReferenceQuads(REFERENCE_BLOCK_MIN, REFERENCE_BLOCK_MAX); + } + + /** + * This test relies on baking a cube in the same way a Vanilla JSON blockmodel cube would be baked, + * and then using the resulting quads as the reference quads in terms of winding and UV. + */ + private static Map buildReferenceQuads(Vector3fc from, Vector3fc to) { + var blockModelJson = """ + { + "textures": { + "t": "x:y" + }, + "elements": [ + { + "from": [$x0, $y0, $z0], + "to": [$x1, $y1, $z1], + "faces": { + "north": {"texture": "#t", "cullface": "north"}, + "east": {"texture": "#t", "cullface": "east"}, + "south": {"texture": "#t", "cullface": "south"}, + "west": {"texture": "#t", "cullface": "west"}, + "up": {"texture": "#t", "cullface": "up"}, + "down": {"texture": "#t", "cullface": "down"} + } + } + ] + } + """; + blockModelJson = blockModelJson.replace("$x0", String.valueOf(from.x())); + blockModelJson = blockModelJson.replace("$y0", String.valueOf(from.y())); + blockModelJson = blockModelJson.replace("$z0", String.valueOf(from.z())); + blockModelJson = blockModelJson.replace("$x1", String.valueOf(to.x())); + blockModelJson = blockModelJson.replace("$y1", String.valueOf(to.y())); + blockModelJson = blockModelJson.replace("$z1", String.valueOf(to.z())); + var blockModel = BlockModel.GSON.fromJson(blockModelJson, BlockModel.class); + + var baked = blockModel.geometry().bake(TextureSlots.EMPTY, new MockModelBaker(), BlockModelRotation.IDENTITY, () -> ""); + return Arrays.stream(Direction.values()).collect(Collectors.toMap(d -> d, d -> { + var quads = baked.getQuads(d); + if (quads.size() != 1) { + throw new IllegalStateException("Expected exactly 1 quad to be baked for side " + d + " but: " + quads); + } + return quads.getFirst(); + })); + } + + static class MockSprite extends TextureAtlasSprite { + private static final Identifier ID = Identifier.parse("x:y"); + + public MockSprite() { + this(128, 128); + } + + public MockSprite(int x, int y) { + super(ID, new SpriteContents(ID, new FrameSize(16, 16), new NativeImage(16, 16, false)), 256, 256, 128, 128, 0); + } + + @Override + public float getU(float u) { + return super.getU(u); + } + + @Override + public float getV(float v) { + return super.getV(v); + } + } + + static class MockModelBaker implements ModelBaker, SpriteGetter, ModelBaker.PartCache { + @Override + public ResolvedModel getModel(Identifier location) { + throw new UnsupportedOperationException(); + } + + @Override + public BlockModelPart missingBlockModelPart() { + throw new UnsupportedOperationException(); + } + + @Override + public SpriteGetter sprites() { + return this; + } + + @Override + public PartCache parts() { + return this; + } + + @Override + public T compute(SharedOperationKey key) { + throw new UnsupportedOperationException(); + } + + @Override + public TextureAtlasSprite get(Material material, ModelDebugName name) { + return new MockSprite(); + } + + @Override + public TextureAtlasSprite reportMissingReference(String reference, ModelDebugName name) { + throw new UnsupportedOperationException(); + } + + @Override + public TextureAtlasSprite resolveSlot(TextureSlots slots, String id, ModelDebugName name) { + return new MockSprite(); + } + + @Override + public ResolvedModel resolveInlineModel(UnbakedModel inlineModel, ModelDebugName debugName) { + throw new UnsupportedOperationException(); + } + + @Override + public Vector3fc vector(Vector3fc vector) { + return vector; + } + } +} diff --git a/tests/src/junit/java/net/neoforged/neoforge/unittest/transfer/HandlerTestUtil.java b/tests/src/junit/java/net/neoforged/neoforge/unittest/transfer/HandlerTestUtil.java index 679c4a10f52..17445ac64ba 100644 --- a/tests/src/junit/java/net/neoforged/neoforge/unittest/transfer/HandlerTestUtil.java +++ b/tests/src/junit/java/net/neoforged/neoforge/unittest/transfer/HandlerTestUtil.java @@ -70,7 +70,7 @@ static MockResourceHandler handler(@Nullable SlotInfo firstSlot, S } @SafeVarargs - static MockResourceHandler handlerForStacks(ResourceStack... slots) { + static MockResourceHandler handlerForStacks(@Nullable ResourceStack... slots) { MockResourceHandler handler = new MockResourceHandler(slots.length); for (int i = 0; i < slots.length; i++) { var stack = slots[i]; diff --git a/tests/src/junit/java/net/neoforged/neoforge/unittest/transfer/ResourceHandlerUtilTest.java b/tests/src/junit/java/net/neoforged/neoforge/unittest/transfer/ResourceHandlerUtilTest.java index 817ad25105c..b0ee42b9242 100644 --- a/tests/src/junit/java/net/neoforged/neoforge/unittest/transfer/ResourceHandlerUtilTest.java +++ b/tests/src/junit/java/net/neoforged/neoforge/unittest/transfer/ResourceHandlerUtilTest.java @@ -640,6 +640,56 @@ void transactionIsRespected() { } } + @Nested + class MoveStacking { + // Note that the internal implementation of moveStacking is almost equivalent, so + // we do not repeat all the tests of 'move' here. + @Test + void stackingIntoFilledSlotsFirst() { + var source = handlerForStacks(stack(TestResource.OTHER_1, 10), stack(TestResource.SOME, 10)); + var target = handler(slotInfo(TestResource.EMPTY, 0, 100), slotInfo(TestResource.SOME, 0, 3)); + + int moved = ResourceHandlerUtil.moveStacking(source, target, r -> r.equals(TestResource.SOME), 10, null); + + assertEquals(10, moved); + + // Verify source and target state + assertThat(describeStacks(source)).containsExactly( + stack(TestResource.OTHER_1, 10), + null); + assertThat(describeStacks(target)).containsExactly( + stack(TestResource.SOME, 7), + stack(TestResource.SOME, 3)); + } + } + + @Nested + class MoveFirstStacking { + // Note that the internal implementation of moveFirstStacking is almost equivalent, so + // we do not repeat all the tests of 'moveFirst' here. + @Test + void stackingIntoFilledSlotsFirst() { + var source = handlerForStacks(stack(TestResource.OTHER_1, 10), stack(TestResource.SOME, 10)); + var target = handler( + slotInfo(TestResource.EMPTY, 0, 100), + slotInfo(TestResource.OTHER_1, 0, 3), + slotInfo(TestResource.EMPTY, 0, 100)); + + var moved = ResourceHandlerUtil.moveFirstStacking(source, target, r -> true, 10, null); + + assertEquals(new ResourceStack<>(TestResource.OTHER_1, 10), moved); + + // Verify source and target state + assertThat(describeStacks(source)).containsExactly( + null, + stack(TestResource.SOME, 10)); + assertThat(describeStacks(target)).containsExactly( + stack(TestResource.OTHER_1, 7), + stack(TestResource.OTHER_1, 3), + null); + } + } + @Nested class Contains { @Test diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/CustomDebugSubscriberTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/CustomDebugSubscriberTest.java new file mode 100644 index 00000000000..29184b01b07 --- /dev/null +++ b/tests/src/main/java/net/neoforged/neoforge/debug/CustomDebugSubscriberTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.debug; + +import com.mojang.serialization.MapCodec; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.client.renderer.debug.DebugRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.gizmos.Gizmos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.resources.Identifier; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.CommonColors; +import net.minecraft.util.debug.DebugSubscription; +import net.minecraft.util.debug.DebugValueAccess; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; +import net.minecraft.world.phys.BlockHitResult; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.neoforge.client.event.AddDebugSubscriptionFlagsEvent; +import net.neoforged.neoforge.client.event.RegisterDebugRenderersEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.registries.DeferredHolder; +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 = "custom_debug_subscribers", side = Dist.CLIENT) +public interface CustomDebugSubscriberTest { + @TestHolder(description = "Renders debug info for a new block entity using debug renderers and subscribers", enabledByDefault = true) + static void testDebugSubscriptions(DynamicTest test, RegistrationHelper reg) { + var id = "debug_subscription"; + var registryName = Identifier.fromNamespaceAndPath(reg.modId(), id); + var blockEntityType = DeferredHolder.create(Registries.BLOCK_ENTITY_TYPE, registryName); + + // register our custom debug subscription + var debugSubscription = reg.registrar(Registries.DEBUG_SUBSCRIPTION).register(id, () -> new DebugSubscription<>(ByteBufCodecs.VAR_INT, 200)); + + final class DebugBlockEntity extends BlockEntity { + private int counter = 0; + + private DebugBlockEntity(BlockPos pos, BlockState blockState) { + super(blockEntityType.value(), pos, blockState); + } + + public void incrementCounter() { + counter++; + setChanged(); + } + + @Override + protected void saveAdditional(ValueOutput output) { + super.saveAdditional(output); + output.putInt("counter", counter); + } + + @Override + protected void loadAdditional(ValueInput input) { + super.loadAdditional(input); + counter = input.getIntOr("counter", 0); + } + + @Override + public void registerDebugValues(ServerLevel level, Registration registration) { + // mark this entity for displaying debug info for our subscription + registration.register(debugSubscription.value(), () -> counter); + } + } + + // generic block for our block entity + final class DebugBlock extends BaseEntityBlock { + private DebugBlock(Properties properties) { + super(properties); + } + + @Override + protected MapCodec codec() { + return null; + } + + @Override + protected InteractionResult useWithoutItem(BlockState blockState, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!(level.getBlockEntity(pos) instanceof DebugBlockEntity blockEntity)) { + return InteractionResult.FAIL; + } + + blockEntity.incrementCounter(); + return InteractionResult.SUCCESS; + } + + @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState blockState) { + return new DebugBlockEntity(pos, blockState); + } + } + + var block = reg.blocks().registerBlock(id, DebugBlock::new); + reg.items().registerSimpleBlockItem(block); + reg.registrar(Registries.BLOCK_ENTITY_TYPE).register(id, () -> new BlockEntityType<>(DebugBlockEntity::new, block.value())); + + // debug renderer used to render counters above our block entities + final class DebugCountRenderer implements DebugRenderer.SimpleDebugRenderer { + private DebugCountRenderer(Minecraft client) {} + + @Override + public void emitGizmos(double camX, double camY, double camZ, DebugValueAccess valueAccess, Frustum frustum, float partialTicks) { + // list is populated via 'DebugBlockEntity.registerDebugValues' + // while we are using block entities this, you can also register subscribers for entities and chunks too + valueAccess.forEachBlock(debugSubscription.value(), (pos, count) -> { + Gizmos.billboardTextOverBlock(count + "", pos, 0, CommonColors.WHITE, .5F); + }); + } + } + + // mark our subscriber as only being active in dev + NeoForge.EVENT_BUS.addListener(AddDebugSubscriptionFlagsEvent.class, event -> event.addActiveInDev(debugSubscription.value())); + + // register our debug renderer + reg.eventListeners().accept((RegisterDebugRenderersEvent event) -> event.register(DebugCountRenderer::new)); + + test.pass(); + } +} diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/attachment/AttachmentSyncTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/attachment/AttachmentSyncTests.java index acb56faf40d..c83aa283830 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/attachment/AttachmentSyncTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/attachment/AttachmentSyncTests.java @@ -176,17 +176,22 @@ public void assertEqual(Supplier> type, @Nullable T value) }) // Test that players receive updates for changes to block entities in tracked chunks .thenExecute(() -> { - var testValue = helper.randomInt(); + var testValue = 12345; helper.setBlock(feetPos, Blocks.FURNACE); var be = helper.getBlockEntity(feetPos, FurnaceBlockEntity.class); be.setData(intAttachment, testValue); - + }) + // Wait for the BE to get synced + .thenIdle(1) + // Resume flushing after idling else packets won't get sent immediately + .thenExecute(() -> player.connection.resumeFlushing()) + .thenExecute(() -> { var payload = player.requireOutboundPayload(SyncAttachmentsPayload.class); helper.expectTarget(payload, new SyncAttachmentsPayload.BlockEntityTarget(helper.absolutePos(feetPos))); var holder = helper.holder(); holder.readFrom(payload); - holder.assertEqual(intAttachment, testValue); + holder.assertEqual(intAttachment, 12345); player.clearOutboundPackets(); }) diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/block/BlockPropertyTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/block/BlockPropertyTests.java index 2e6c3d470cb..7647fff0011 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/block/BlockPropertyTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/block/BlockPropertyTests.java @@ -64,12 +64,12 @@ static void levelSensitiveLight(final DynamicTest test, final RegistrationHelper .thenExecute(() -> helper.setBlock(lightPos, lightBlock.get())) .thenExecute(() -> helper.useBlock(lightPos, helper.makeMockPlayer(GameType.CREATIVE), Items.ACACIA_BUTTON.getDefaultInstance())) .thenMap(() -> helper.getLevel().getChunkAt(helper.absolutePos(testPos))) - .thenMap(chunk -> ((ThreadedLevelLightEngine) helper.getLevel().getLightEngine()).waitForPendingTasks(chunk.getPos().x, chunk.getPos().z)) + .thenMap(chunk -> ((ThreadedLevelLightEngine) helper.getLevel().getLightEngine()).waitForPendingTasks(chunk.getPos().x(), chunk.getPos().z())) .thenWaitUntil(future -> helper.assertTrue(future.isDone(), "Light engine did not update to lit")) .thenExecute(() -> helper.assertTrue(helper.getLevel().getLightEngine().getRawBrightness(helper.absolutePos(testPos), 15) == 14, "Lit light level was not as expected")) .thenExecute(() -> helper.destroyBlock(lightPos)) .thenMap(() -> helper.getLevel().getChunkAt(helper.absolutePos(new BlockPos(1, 2, 1)))) - .thenMap(chunk -> ((ThreadedLevelLightEngine) helper.getLevel().getLightEngine()).waitForPendingTasks(chunk.getPos().x, chunk.getPos().z)) + .thenMap(chunk -> ((ThreadedLevelLightEngine) helper.getLevel().getLightEngine()).waitForPendingTasks(chunk.getPos().x(), chunk.getPos().z())) .thenWaitUntil(future -> helper.assertTrue(future.isDone(), "Light engine did not update to unlit")) .thenExecute(() -> helper.assertTrue(helper.getLevel().getLightEngine().getRawBrightness(helper.absolutePos(testPos), 15) == 0, "Unlit light level was not as expected")) .thenSucceed()); 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 134546a4846..2c3ed085ad4 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 @@ -212,7 +212,7 @@ public CustomBubbleColumnSustainingBlock(Properties properties, BubbleColumnDire @Override protected void tick(BlockState blockState, ServerLevel serverLevel, BlockPos blockPos, RandomSource randomSource) { - BubbleColumnBlock.updateColumn(serverLevel, blockPos.above(), blockState); + BubbleColumnBlock.updateColumn(Blocks.BUBBLE_COLUMN, serverLevel, blockPos.above(), blockState); } @Override diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/capabilities/ItemInventoryTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/capabilities/ItemInventoryTests.java index 794d128e44c..69cf130112d 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/capabilities/ItemInventoryTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/capabilities/ItemInventoryTests.java @@ -10,6 +10,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.item.component.BundleContents; import net.minecraft.world.item.component.ItemContainerContents; import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; @@ -38,9 +39,7 @@ public class ItemInventoryTests { private static final DeferredItem BACKPACK; static { - NonNullList defaultContents = NonNullList.withSize(SLOTS, ItemStack.EMPTY); - defaultContents.set(STICK_SLOT, Items.STICK.getDefaultInstance().copyWithCount(64)); - BACKPACK = ITEMS.registerItem("test_backpack", Item::new, props -> props.component(DataComponents.CONTAINER, ItemContainerContents.fromItems(defaultContents))); + BACKPACK = ITEMS.registerItem("test_backpack", Item::new); } @OnInit @@ -56,10 +55,14 @@ static void init(final TestFramework framework) { @GameTest @EmptyTemplate @TestHolder(description = "Tests that ComponentItemHandler can read and write from a data component") - public static void testItemInventory(DynamicTest test, RegistrationHelper reg) { + public static void testItemContainer(DynamicTest test, RegistrationHelper reg) { test.onGameTest(helper -> { - ItemStack stack = BACKPACK.toStack(); - ItemAccess itemAccess = ItemAccess.forStack(stack); + ItemStack container = BACKPACK.toStack(); + NonNullList defaultContents = NonNullList.withSize(SLOTS, ItemStack.EMPTY); + defaultContents.set(STICK_SLOT, Items.STICK.getDefaultInstance().copyWithCount(64)); + container.set(DataComponents.CONTAINER, ItemContainerContents.fromItems(defaultContents)); + + ItemAccess itemAccess = ItemAccess.forStack(container); // Note: this uses the legacy wrappers, testing the wrappers and that the new ItemAccessItemHandler matches the old ComponentItemHandler. IItemHandler items = IItemHandler.of(itemAccess.getCapability(Capabilities.Item.ITEM)); @@ -67,18 +70,18 @@ public static void testItemInventory(DynamicTest test, RegistrationHelper reg) { helper.assertValueEqual(storedStick.getItem(), Items.STICK, "Default contents should contain a stick at slot " + STICK_SLOT); ItemStack toInsert = Items.APPLE.getDefaultInstance().copyWithCount(32); - ItemContainerContents contents = stack.get(DataComponents.CONTAINER); + ItemContainerContents contents = container.get(DataComponents.CONTAINER); ItemStack remainder = items.insertItem(STICK_SLOT, toInsert, false); helper.assertTrue(ItemStack.matches(toInsert, remainder), "Inserting an item where it does not fit should return the original item."); // Check identity equality to assert that the component object was not updated at all, even to an equivalent form. - helper.assertTrue(contents == stack.get(DataComponents.CONTAINER), "Inserting an item where it does not fit should not change the component."); + helper.assertTrue(contents == container.get(DataComponents.CONTAINER), "Inserting an item where it does not fit should not change the component."); remainder = items.insertItem(0, toInsert, false); helper.assertTrue(remainder.isEmpty(), "Successfully inserting the entire item should return an empty stack."); helper.assertTrue(ItemStack.matches(toInsert, items.getStackInSlot(0)), "Successfully inserting an item should be visible via getStackInSlot"); - ItemContainerContents newContents = stack.get(DataComponents.CONTAINER); + ItemContainerContents newContents = container.get(DataComponents.CONTAINER); helper.assertTrue(ItemStack.matches(toInsert, newContents.getStackInSlot(0)), "Successfully inserting an item should trigger a write-back to the component"); ItemStack extractedApple = items.extractItem(0, 64, false); @@ -94,4 +97,80 @@ public static void testItemInventory(DynamicTest test, RegistrationHelper reg) { helper.succeed(); }); } + + @GameTest + @EmptyTemplate + @TestHolder(description = "Tests that BundleItemHandler can read and write from a data component") + public static void testItemBundle(DynamicTest test, RegistrationHelper reg) { + test.onGameTest(helper -> { + ItemStack bundle = Items.BUNDLE.getDefaultInstance(); + BundleContents.Mutable mutable = new BundleContents.Mutable(bundle.get(DataComponents.BUNDLE_CONTENTS)); + mutable.tryInsert(Items.STICK.getDefaultInstance().copyWithCount(16)); + mutable.tryInsert(Items.APPLE.getDefaultInstance().copyWithCount(16)); + bundle.set(DataComponents.BUNDLE_CONTENTS, mutable.toImmutable()); + + ItemAccess itemAccess = ItemAccess.forStack(bundle); + IItemHandler items = IItemHandler.of(itemAccess.getCapability(Capabilities.Item.ITEM)); + + helper.assertValueEqual(items.getSlots(), 3, "Bundle with 2 stacks should report 3 slots (2 items + 1 empty)."); + + boolean foundStick = false; + boolean foundApple = false; + for (int i = 0; i < 2; i++) { + ItemStack s = items.getStackInSlot(i); + if (s.getItem() == Items.STICK && s.getCount() == 16) foundStick = true; + if (s.getItem() == Items.APPLE && s.getCount() == 16) foundApple = true; + } + helper.assertTrue(foundStick, "Bundle should contain 16 sticks."); + helper.assertTrue(foundApple, "Bundle should contain 16 apples."); + + ItemStack moreApples = new ItemStack(Items.APPLE, 32); + ItemStack remainder = items.insertItem(2, moreApples, false); + helper.assertTrue(remainder.isEmpty(), "Should be able to insert 32 more apples."); + + helper.assertValueEqual(items.getSlots(), 2, "After merging to full, slot count should be 2."); + + int appleCount = 0; + for (int i = 0; i < 2; i++) { + if (items.getStackInSlot(i).getItem() == Items.APPLE) appleCount += items.getStackInSlot(i).getCount(); + } + helper.assertValueEqual(appleCount, 48, "Total apples should be 16 + 32 = 48."); + + ItemStack excessApple = new ItemStack(Items.APPLE, 1); + remainder = items.insertItem(2, excessApple, false); + helper.assertValueEqual(remainder.getCount(), 1, "Should not accept apple when bundle is full."); + + bundle.set(DataComponents.BUNDLE_CONTENTS, BundleContents.EMPTY); + helper.assertValueEqual(items.getSlots(), 1, "Empty bundle should have 1 slot."); + + ItemStack snowballs = new ItemStack(Items.SNOWBALL, 16); + remainder = items.insertItem(0, snowballs, false); + helper.assertTrue(remainder.isEmpty(), "Should accept 16 snowballs."); + + remainder = items.insertItem(1, new ItemStack(Items.STICK), false); + helper.assertValueEqual(remainder.getCount(), 1, "Full bundle should not accept sticks."); + + bundle.set(DataComponents.BUNDLE_CONTENTS, BundleContents.EMPTY); + + ItemStack shulker = new ItemStack(Items.SHULKER_BOX); + remainder = items.insertItem(0, shulker, false); + helper.assertValueEqual(remainder.getCount(), 1, "Bundle should reject Shulker Box."); + + items.insertItem(0, new ItemStack(Items.DIRT, 32), false); + + ItemStack extracted = items.extractItem(0, 16, false); + helper.assertValueEqual(extracted.getCount(), 16, "Should extract 16 dirt."); + helper.assertValueEqual(extracted.getItem(), Items.DIRT, "Should be dirt."); + + helper.assertValueEqual(items.getStackInSlot(0).getCount(), 16, "Bundle should have 16 dirt left."); + + extracted = items.extractItem(0, 64, false); + helper.assertValueEqual(extracted.getCount(), 16, "Should extract remaining 16 dirt."); + + helper.assertValueEqual(items.getSlots(), 1, "Empty bundle should have 1 slot."); + helper.assertTrue(items.getStackInSlot(0).isEmpty(), "Slot 0 should be empty."); + + helper.succeed(); + }); + } } 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 8c5e59f2eb6..41bcf6806d4 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 @@ -10,7 +10,6 @@ import com.mojang.math.Axis; import java.util.Map; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.entity.AbstractHoglinRenderer; import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.entity.MobRenderer; @@ -25,6 +24,7 @@ import net.minecraft.core.SectionPos; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.context.ContextKey; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; @@ -44,6 +44,7 @@ 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.RenderNameTagEvent; import net.neoforged.neoforge.client.event.RenderPlayerEvent; import net.neoforged.neoforge.client.renderstate.RegisterRenderStateModifiersEvent; import net.neoforged.neoforge.common.NeoForge; @@ -140,7 +141,7 @@ static void renderPlayerEvent(final DynamicTest test) { ItemStackRenderState renderState = new ItemStackRenderState(); Minecraft.getInstance().getItemModelResolver().updateForTopItem(renderState, itemStack, ItemDisplayContext.GROUND, null, null, 0); - renderState.submit(event.getPoseStack(), event.getSubmitNodeCollector(), LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); + renderState.submit(event.getPoseStack(), event.getSubmitNodeCollector(), LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); event.getPoseStack().popPose(); }); @@ -243,4 +244,13 @@ static void renderLevelStageWithSectionData(final DynamicTest test) { }); }); } + + @TestHolder(description = { "Test RenderNameTagEvent.CanRender is called" }) + static void nameTagCanRender(final DynamicTest test) { + test.whenEnabled(listeners -> { + listeners.forge().addListener((final RenderNameTagEvent.CanRender canRenderEvent) -> { + test.pass(); + }); + }); + } } diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/AnvilUpdateEventTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/AnvilUpdateEventTests.java index a78959e3e65..9e418f25c30 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/AnvilUpdateEventTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/AnvilUpdateEventTests.java @@ -12,11 +12,12 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AnvilMenu; -import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.GameType; import net.minecraft.world.level.block.Blocks; +import net.neoforged.neoforge.common.util.Lazy; import net.neoforged.neoforge.event.AnvilUpdateEvent; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; @@ -37,8 +38,6 @@ public class AnvilUpdateEventTests { private static final int INVENTORY_SLOT_FIRST = 0; private static final int INVENTORY_SLOT_SECOND = 1; - private static final ItemStack MOCK_OUTPUT = new ItemStack(Items.COBBLESTONE); - private static ItemStack sampleStack() { ItemStack s = new ItemStack(Items.GOLDEN_HOE, 1); s.setDamageValue(4); @@ -46,13 +45,13 @@ private static ItemStack sampleStack() { } private static void moveItemsToInputs(AnvilMenu menu, Player player) { - menu.clicked(MENU_SLOT_INV_FIRST, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, player); - menu.clicked(MENU_SLOT_INV_SECOND, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, player); + menu.clicked(MENU_SLOT_INV_FIRST, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, player); + menu.clicked(MENU_SLOT_INV_SECOND, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, player); } private static void clearInputs(AnvilMenu menu, Player player) { - menu.clicked(MENU_SLOT_LEFT, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, player); - menu.clicked(MENU_SLOT_RIGHT, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, player); + menu.clicked(MENU_SLOT_LEFT, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, player); + menu.clicked(MENU_SLOT_RIGHT, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, player); } /** Holds the pieces every test needs after setup. */ @@ -104,8 +103,10 @@ static void customOutputAndCostTest(DynamicTest test) { final int CUSTOM_COST = 7; final int CUSTOM_MATERIAL_COST = 3; + var mockOutput = Lazy.of(() -> new ItemStack(Items.COBBLESTONE)); + test.whenEnabled(listeners -> listeners.forge().addListener((AnvilUpdateEvent e) -> { - e.setOutput(MOCK_OUTPUT.copy()); + e.setOutput(mockOutput.get().copy()); e.setXpCost(CUSTOM_COST); e.setMaterialCost(CUSTOM_MATERIAL_COST); })); @@ -117,7 +118,7 @@ static void customOutputAndCostTest(DynamicTest test) { moveItemsToInputs(ctx.menu, ctx.player); ItemStack out = ctx.menu.getSlot(MENU_SLOT_RESULT).getItem(); ctx.helper.assertTrue( - ItemStack.isSameItemSameComponents(out, MOCK_OUTPUT), + ItemStack.isSameItemSameComponents(out, mockOutput.get()), "Expected custom cobblestone output; output is " + out); ctx.helper.assertValueEqual( CUSTOM_COST, ctx.menu.getCost(), @@ -144,10 +145,10 @@ static void cancelClearsOutputTest(DynamicTest test) { ctx.player.getInventory().setItem(INVENTORY_SLOT_FIRST, sampleStack().copy()); ctx.player.getInventory().setItem(INVENTORY_SLOT_SECOND, sampleStack().copy()); - ctx.menu.clicked(MENU_SLOT_INV_FIRST, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, ctx.player); + ctx.menu.clicked(MENU_SLOT_INV_FIRST, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, ctx.player); ctx.menu.setItemName(CUSTOM_NAME); cancel.set(true); - ctx.menu.clicked(MENU_SLOT_INV_SECOND, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, ctx.player); + ctx.menu.clicked(MENU_SLOT_INV_SECOND, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, ctx.player); ItemStack out = ctx.menu.getSlot(MENU_SLOT_RESULT).getItem(); int cost = ctx.menu.getCost(); int repairItemCountCost = ctx.menu.repairItemCountCost; @@ -192,7 +193,7 @@ static void leftRemovalResetsOutputTest(DynamicTest test) { ctx.player.getInventory().setItem(INVENTORY_SLOT_SECOND, sampleStack().copy()); moveItemsToInputs(ctx.menu, ctx.player); - ctx.menu.clicked(MENU_SLOT_LEFT, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, ctx.player); + ctx.menu.clicked(MENU_SLOT_LEFT, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, ctx.player); ItemStack out = ctx.menu.getSlot(MENU_SLOT_RESULT).getItem(); ctx.helper.assertTrue(out.isEmpty(), "Expected result to reset when left slot cleared; the result is " + out); @@ -213,18 +214,18 @@ static void slotSpecificEventFiringTest(DynamicTest test) { // AnvilMenu#createResult() changes behavior depending on this component, but we must call the event even for stacks without this component ctx.player.getInventory().getItem(INVENTORY_SLOT_FIRST).remove(DataComponents.ENCHANTMENTS); - ctx.menu.clicked(MENU_SLOT_INV_FIRST, InputConstants.MOUSE_BUTTON_LEFT, ClickType.PICKUP, ctx.player); - ctx.menu.clicked(MENU_SLOT_RIGHT, InputConstants.MOUSE_BUTTON_LEFT, ClickType.PICKUP, ctx.player); + ctx.menu.clicked(MENU_SLOT_INV_FIRST, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.PICKUP, ctx.player); + ctx.menu.clicked(MENU_SLOT_RIGHT, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.PICKUP, ctx.player); ctx.helper.assertFalse(eventFired.getPlain(), "Event should not fire when placing item in right slot"); - ctx.menu.clicked(MENU_SLOT_RIGHT, InputConstants.MOUSE_BUTTON_LEFT, ClickType.PICKUP, ctx.player); + ctx.menu.clicked(MENU_SLOT_RIGHT, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.PICKUP, ctx.player); ctx.helper.assertFalse(eventFired.getPlain(), "Event should not fire when removing item from right slot"); - ctx.menu.clicked(MENU_SLOT_LEFT, InputConstants.MOUSE_BUTTON_LEFT, ClickType.PICKUP, ctx.player); + ctx.menu.clicked(MENU_SLOT_LEFT, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.PICKUP, ctx.player); ctx.helper.assertTrue(eventFired.getPlain(), "Event should fire when placing item in left slot"); eventFired.set(false); - ctx.menu.clicked(MENU_SLOT_LEFT, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, ctx.player); + ctx.menu.clicked(MENU_SLOT_LEFT, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, ctx.player); ctx.helper.assertFalse(eventFired.getPlain(), "Event should not fire when removing item from left slot"); ctx.helper.succeed(); diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/CraftingEventTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/CraftingEventTests.java index 03d9ed476ee..bd0c0cb1a39 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/CraftingEventTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/CraftingEventTests.java @@ -8,7 +8,7 @@ import com.mojang.blaze3d.platform.InputConstants; import java.util.concurrent.atomic.AtomicInteger; import net.minecraft.core.BlockPos; -import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.GameType; @@ -46,14 +46,14 @@ static void itemSmeltedEventTest(final DynamicTest test) { var player = helper.makeTickingMockServerPlayerInLevel(GameType.CREATIVE); player.openMenu(be); // Test that right-clicking half of the stack out of the FurnaceResultSlot functions as expected - player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_RIGHT, ClickType.PICKUP, player); + player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_RIGHT, ContainerInput.PICKUP, player); helper.assertTrue(timesFired.getPlain() == 1, "Event was not fired the expected number of times for right-click pickup. Fired: " + timesFired.getPlain()); player.containerMenu.setCarried(ItemStack.EMPTY); // Test that shift-left-clicking the rest of the stack out works (should only fire once, not twice) - player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, player); + player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, player); helper.assertTrue(timesFired.getPlain() == 2, "Event was not fired the expected number of times for shift-left-click quick-move. Fired: " + timesFired.getPlain()); // The slot is now empty, this should not fire the event - player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, player); + player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_LEFT, ContainerInput.QUICK_MOVE, player); helper.assertTrue(timesFired.getPlain() == 2, "Event fired for an empty slot, which should not happen."); helper.succeed(); }); 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 1c20ff2b3f4..ea75eca0211 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 @@ -22,6 +22,7 @@ import net.minecraft.core.FrontAndTop; import net.minecraft.core.HolderLookup; import net.minecraft.core.NonNullList; +import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.Registries; import net.minecraft.data.recipes.RecipeBuilder; @@ -33,8 +34,8 @@ import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.BlockTags; -import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; import net.minecraft.world.item.Items; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.crafting.CraftingBookCategory; @@ -155,7 +156,7 @@ public String getName() { // Axe is now damaged, we expect the recipe to work, even if we also add other random values to the compound .thenExecute(crafter -> crafter.getItem(0).hurtAndBreak(2, helper.getLevel(), null, item -> {})) - .thenExecute(crafter -> CustomData.update(DataComponents.CUSTOM_DATA, crafter.getItem(0), tag -> tag.putFloat("abcd", helper.getLevel().random.nextFloat()))) + .thenExecute(crafter -> CustomData.update(DataComponents.CUSTOM_DATA, crafter.getItem(0), tag -> tag.putFloat("abcd", helper.getLevel().getRandom().nextFloat()))) .thenExecute(() -> helper.pulseRedstone(1, 1, 2, 2)) .thenExecuteAfter(7, () -> helper.assertContainerContains(1, 2, 1, Items.ALLIUM)) @@ -175,7 +176,10 @@ protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, protected void buildRecipes() { this.shapeless(RecipeCategory.MISC, Items.ACACIA_BOAT) .requires(new TestEnabledIngredient( - DataComponentIngredient.of(true, DataComponents.DAMAGE, 4, Items.DIAMOND_PICKAXE), + DataComponentIngredient.of(DataComponentPatch.builder() + .set(DataComponents.DAMAGE, 4) + .remove(DataComponents.CUSTOM_DATA) + .build(), Items.DIAMOND_PICKAXE), test.framework(), test.id()).toVanilla()) .requires(Items.ACACIA_PLANKS) .unlockedBy("has_pick", has(Items.DIAMOND_PICKAXE)) @@ -239,12 +243,12 @@ private static List shapelessRecipeIngredients(ShapelessRecipe recip } static class CompressedShapelessRecipe extends ShapelessRecipe { - public CompressedShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, List ingredients) { + public CompressedShapelessRecipe(String group, CraftingBookCategory category, ItemStackTemplate result, List ingredients) { super(group, category, result, decompressList(ingredients)); } public CompressedShapelessRecipe(ShapelessRecipe uncompressed) { - this(uncompressed.group(), uncompressed.category(), uncompressed.assemble(null, null), compressIngredients(shapelessRecipeIngredients(uncompressed))); + this(uncompressed.group(), uncompressed.category(), uncompressed.result(), compressIngredients(shapelessRecipeIngredients(uncompressed))); } private static NonNullList decompressList(List ingredients) { @@ -277,8 +281,8 @@ static class CompressedShapelessRecipeSerializer implements RecipeSerializer CODEC = RecordCodecBuilder.mapCodec( p_337958_ -> p_337958_.group( Codec.STRING.optionalFieldOf("group", "").forGetter(ShapelessRecipe::group), - CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter(o -> o.category()), - ItemStack.CODEC.fieldOf("result").forGetter(o -> o.assemble(null, null)), + CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter(ShapelessRecipe::category), + ItemStackTemplate.CODEC.fieldOf("result").forGetter(ShapelessRecipe::result), SizedIngredient.NESTED_CODEC .listOf() .fieldOf("ingredients") @@ -310,23 +314,28 @@ public StreamCodec streamCod static class CompressedShapelessRecipeBuilder implements RecipeBuilder { private final RecipeCategory category; - private final ItemStack result; + private final ItemStackTemplate result; private final List ingredients = new ArrayList<>(); private final Map> criteria = new LinkedHashMap<>(); @org.jspecify.annotations.Nullable private String group; - private CompressedShapelessRecipeBuilder(RecipeCategory category, ItemStack result) { + private CompressedShapelessRecipeBuilder(RecipeCategory category, ItemStackTemplate result) { this.category = category; this.result = result; } + @Override + public ResourceKey> defaultId() { + return RecipeBuilder.getDefaultRecipeId(this.result); + } + public static CompressedShapelessRecipeBuilder compressedShapeless(RecipeCategory category, ItemLike item) { return compressedShapeless(category, item, 1); } public static CompressedShapelessRecipeBuilder compressedShapeless(RecipeCategory category, ItemLike item, int count) { - return new CompressedShapelessRecipeBuilder(category, item.asItem().getDefaultInstance().copyWithCount(count)); + return new CompressedShapelessRecipeBuilder(category, new ItemStackTemplate(item.asItem(), count)); } public CompressedShapelessRecipeBuilder requires(Ingredient ingredient, int count) { @@ -347,11 +356,6 @@ public CompressedShapelessRecipeBuilder group(@Nullable String group) { return this; } - @Override - public Item getResult() { - return this.result.getItem(); - } - @Override public void save(RecipeOutput output, ResourceKey> id) { this.ensureValid(id); 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 d2c6c4300e6..6593d1d0f51 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 @@ -245,7 +245,7 @@ protected void gather(HolderLookup.Provider provider) { // This is to make sure that sync work test.eventListeners().forge().addListener((final UseItemOnBlockEvent event) -> { if (event.getLevel().isClientSide() && event.getHand() == InteractionHand.MAIN_HAND) { - event.getPlayer().displayClientMessage(Component.literal("Attachment value: " + event.getItemStack().getItemHolder() + event.getPlayer().displayClientMessage(Component.literal("Attachment value: " + event.getItemStack().typeHolder() .getData(someData)), true); } }); diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/enchantment/EnchantmentLevelTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/enchantment/EnchantmentLevelTests.java index ac6edaa3c48..e6f1ff4853c 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/enchantment/EnchantmentLevelTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/enchantment/EnchantmentLevelTests.java @@ -73,7 +73,7 @@ static void getEnchLevelEvent(final DynamicTest test, final RegistrationHelper r @GameTest @EmptyTemplate - @TestHolder(description = "Tests if the PlayerEnchantedItemEvent fired.") + @TestHolder(description = "Tests if the PlayerEnchantItemEvent fired.") static void playerEnchantItemTest(final DynamicTest test, final RegistrationHelper reg) { test.eventListeners().forge().addListener((PlayerEnchantItemEvent event) -> { event.getEnchantedItem().setDamageValue(1); //change a value we can reference in our test sequence diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/entity/TradeTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/entity/TradeTests.java deleted file mode 100644 index dff04616f27..00000000000 --- a/tests/src/main/java/net/neoforged/neoforge/debug/entity/TradeTests.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.debug.entity; - -import java.lang.invoke.MethodHandle; -import java.util.ArrayList; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.NbtOps; -import net.minecraft.nbt.Tag; -import net.minecraft.resources.RegistryOps; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.npc.villager.VillagerData; -import net.minecraft.world.entity.npc.villager.VillagerProfession; -import net.minecraft.world.entity.npc.villager.VillagerTrades; -import net.minecraft.world.entity.npc.villager.VillagerType; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.trading.MerchantOffers; -import net.neoforged.neoforge.common.BasicItemListing; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.village.VillagerTradesEvent; -import net.neoforged.testframework.DynamicTest; -import net.neoforged.testframework.annotation.ForEachTest; -import net.neoforged.testframework.annotation.TestHolder; -import net.neoforged.testframework.gametest.EmptyTemplate; -import net.neoforged.testframework.gametest.GameTest; -import net.neoforged.testframework.impl.ReflectionUtils; - -@ForEachTest(groups = TradeTests.GROUP) -public class TradeTests { - public static final String GROUP = "level.entity.trades"; - - @GameTest - @EmptyTemplate - @TestHolder(description = "Verify we can add a trade to a villager") - static void villagerTradeAdd(final DynamicTest test) { - NeoForge.EVENT_BUS.addListener(TradeTests::villagerTradeAddEvent); - - test.onGameTest(helper -> helper.startSequence(() -> helper.spawn(EntityType.VILLAGER, new BlockPos(1, 1, 1))) - .thenExecute(villager -> { - // Set villager to level 6 trades - villager.setVillagerData(new VillagerData(helper.getHolder(VillagerType.PLAINS), helper.getHolder(VillagerProfession.WEAPONSMITH), 0)); - try { - MethodHandle methodHandle = ReflectionUtils.handle(villager.getClass().getDeclaredMethod("increaseMerchantCareer", ServerLevel.class)); - methodHandle.invoke(villager, helper.getLevel()); - methodHandle.invoke(villager, helper.getLevel()); - methodHandle.invoke(villager, helper.getLevel()); - methodHandle.invoke(villager, helper.getLevel()); - methodHandle.invoke(villager, helper.getLevel()); - methodHandle.invoke(villager, helper.getLevel()); - } catch (Throwable e) { - helper.fail("Cannot find Villager#increaseMerchantCareer method."); - } - - helper.assertTrue(villager.getOffers().size() == 9, "Weaponsmith did not get a new tier of trade"); - helper.assertTrue(villager.getOffers().get(8).getResult().is(Items.NETHERITE_SWORD), "Netherite Sword was not in trade."); - - MerchantOffers originalMerchantOffers = villager.getOffers(); - MerchantOffers newMerchantOffers; - try { - RegistryOps registryOps = villager.registryAccess().createSerializationContext(NbtOps.INSTANCE); - Tag tag = MerchantOffers.CODEC.encodeStart(registryOps, originalMerchantOffers).getOrThrow(); - newMerchantOffers = MerchantOffers.CODEC.decode(registryOps, tag).getOrThrow().getFirst(); - } catch (Exception e) { - helper.fail("Villager's modified merchant offer failed to serialize without throwing exception"); - return; - } - - if (newMerchantOffers.size() != originalMerchantOffers.size() || !newMerchantOffers.get(8).getResult().is(originalMerchantOffers.get(8).getResult().getItem())) { - helper.fail("Failed to serialize and deserialized modified merchant offers properly."); - } - }) - .thenSucceed()); - } - - public static void villagerTradeAddEvent(final VillagerTradesEvent event) { - if (event.getType() == VillagerProfession.WEAPONSMITH) { - ArrayList itemListings = new ArrayList<>(); - itemListings.add(new BasicItemListing(new ItemStack(Items.EMERALD, 5), new ItemStack(Items.NETHERITE_SWORD), 10, 20, 2)); - event.getTrades().put(6, itemListings); - } - } -} diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/entity/player/PlayerEventTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/entity/player/PlayerEventTests.java index 388b83cfa0b..54b257a25d1 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/entity/player/PlayerEventTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/entity/player/PlayerEventTests.java @@ -126,7 +126,7 @@ static void entityInteractEvent(final DynamicTest test) { test.onGameTest(helper -> { Mob illusioner = helper.spawnWithNoFreeWill(EntityType.ILLUSIONER, 1, 1, 1); helper.startSequence(() -> helper.makeTickingMockServerPlayerInCorner(GameType.SURVIVAL)) - .thenExecute(player -> player.connection.handleInteract(ServerboundInteractPacket.createInteractionPacket(illusioner, player.isShiftKeyDown(), InteractionHand.MAIN_HAND, helper.absoluteVec(new BlockPos(1, 1, 1).getCenter())))) + .thenExecute(player -> player.connection.handleInteract(new ServerboundInteractPacket(illusioner.getId(), InteractionHand.MAIN_HAND, helper.absoluteVec(new BlockPos(1, 1, 1).getCenter()), player.isShiftKeyDown()))) .thenExecute(player -> helper.assertTrue(illusioner.getName().getString().contains("entityInteractEventTest"), "Illager name did not get changed on player interact")) .thenSucceed(); }); diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemComponentTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemComponentTests.java index c882cc5b292..18da566cddb 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemComponentTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemComponentTests.java @@ -73,7 +73,7 @@ static void testModifyDefaultComponentsEvent(DynamicTest test, RegistrationHelpe .withLang("Test components item"); test.framework().modEventBus().addListener((final ModifyDefaultComponentsEvent event) -> { event.modify(testItem, builder -> builder - .remove(DataComponents.BASE_COLOR) + .set(DataComponents.BASE_COLOR, null) .set(DataComponents.MAX_STACK_SIZE, 5)); }); diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java index 83d2a94754d..df17c4d08a9 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java @@ -5,12 +5,21 @@ package net.neoforged.neoforge.debug.level; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.arguments.DoubleArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.serialization.Codec; import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.level.GameType; import net.minecraft.world.level.gamerules.GameRule; import net.minecraft.world.level.gamerules.GameRuleCategory; +import net.minecraft.world.level.gamerules.GameRuleType; import net.minecraft.world.level.gamerules.GameRules; +import net.neoforged.neoforge.common.data.LanguageProvider; +import net.neoforged.neoforge.event.RegisterGameRuleCategoryEvent; import net.neoforged.neoforge.event.tick.EntityTickEvent; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.testframework.DynamicTest; @@ -51,8 +60,14 @@ public class LevelTests { @EmptyTemplate @TestHolder(description = "Tests if custom game rules work") static void customGameRule(final DynamicTest test, final RegistrationHelper reg) { - final DeferredHolder, GameRule> booleanGameRule = reg.register(Registries.GAME_RULE, "custom_boolean_game_rule", (r, n) -> GameRules.registerBoolean(n.toString(), GameRuleCategory.MISC, true)); - final DeferredHolder, GameRule> integerGameRule = reg.register(Registries.GAME_RULE, "custom_integer_game_rule", (r, n) -> GameRules.registerInteger(n.toString(), GameRuleCategory.MISC, 1337, 1337)); + final GameRuleCategory category = new GameRuleCategory(Identifier.fromNamespaceAndPath(reg.modId(), "game_rules")); + final DeferredHolder, GameRule> booleanGameRule = reg.register(Registries.GAME_RULE, "custom_boolean_game_rule", (r, n) -> GameRules.registerBoolean(n.toString(), category, true)); + final DeferredHolder, GameRule> integerGameRule = reg.register(Registries.GAME_RULE, "custom_integer_game_rule", (r, n) -> GameRules.registerInteger(n.toString(), category, 1337, 1337)); + // '(visitor, gameRule) -> {}' is intentional here + // `GameRules#visitGameRuleTypes` calls the default `GameRuleTypeVisitor#visit(GameRule)` before invoking the game rule specific visitor + // DO NOT call `GameRuleTypeVisitor#visit` from your custom visitor, this will double up 'visits' to your game rule + final DeferredHolder, GameRule> doubleGameRule = reg.register(Registries.GAME_RULE, "custom_double_game_rule", (r, n) -> GameRules.register(n.toString(), category, GameRuleType.valueOf("NEOTESTS_DOUBLE"), DoubleArgumentType.doubleArg(), Codec.DOUBLE, 0D, FeatureFlagSet.of(), (visitor, gameRule) -> {}, value -> Command.SINGLE_SUCCESS)); + final DeferredHolder, GameRule> stringGameRule = reg.register(Registries.GAME_RULE, "custom_string_game_rule", (r, n) -> GameRules.register(n.toString(), category, GameRuleType.valueOf("NEOTESTS_STRING"), StringArgumentType.string(), Codec.STRING, "", FeatureFlagSet.of(), (visitor, gameRule) -> {}, value -> Command.SINGLE_SUCCESS)); test.eventListeners().forge().addListener((EntityTickEvent.Pre event) -> { if (event.getEntity() instanceof ServerPlayer player && player.getGameProfile().name().equals("test-mock-player")) { @@ -62,22 +77,48 @@ static void customGameRule(final DynamicTest test, final RegistrationHelper reg) } }); + test.eventListeners().mod().addListener((RegisterGameRuleCategoryEvent event) -> event.register(category)); + + reg.clientProvider(LanguageProvider.class, provider -> { + // GameRuleCategory#getDescriptionId - this is not the translation key as one would expect, its the registry name + // GameRuleCategory#label() - this uses #id to build the translation key by adding the below hardcoded prefix + provider.add(category.id().toLanguageKey("gamerule.category"), "Custom GameRules"); + + provider.add(booleanGameRule.value().getDescriptionId(), "Custom Boolean"); + provider.add(booleanGameRule.value().getDescriptionId() + ".description", "A custom boolean game rule"); + + provider.add(integerGameRule.value().getDescriptionId(), "Custom Integer"); + provider.add(integerGameRule.value().getDescriptionId() + ".description", "A custom integer game rule"); + + provider.add(doubleGameRule.value().getDescriptionId(), "Custom Double"); + provider.add(doubleGameRule.value().getDescriptionId() + ".description", "A custom double game rule"); + + provider.add(stringGameRule.value().getDescriptionId(), "Custom String"); + provider.add(stringGameRule.value().getDescriptionId() + ".description", "A custom string game rule"); + }); + test.onGameTest(helper -> { final ServerPlayer player = helper.makeTickingMockServerPlayerInCorner(GameType.SURVIVAL); var gameRules = player.level().getGameRules(); final var oldBool = gameRules.get(booleanGameRule.get()); final var oldInt = gameRules.get(integerGameRule.get()); + final var oldDouble = gameRules.get(doubleGameRule.get()); + final var oldString = gameRules.get(stringGameRule.get()); helper.startSequence() .thenExecute(() -> gameRules.set(booleanGameRule.get(), true, player.level().getServer())) .thenExecute(() -> gameRules.set(integerGameRule.get(), 12, player.level().getServer())) + .thenExecute(() -> gameRules.set(doubleGameRule.get(), 64D, player.level().getServer())) + .thenExecute(() -> gameRules.set(stringGameRule.get(), "test", player.level().getServer())) .thenIdle(1) .thenExecute(() -> helper.assertEntityProperty(player, ServerPlayer::getHealth, "player health", 8f)) .thenExecute(() -> gameRules.set(booleanGameRule.get(), oldBool, player.level().getServer())) .thenExecute(() -> gameRules.set(integerGameRule.get(), oldInt, player.level().getServer())) + .thenExecute(() -> gameRules.set(doubleGameRule.get(), oldDouble, player.level().getServer())) + .thenExecute(() -> gameRules.set(stringGameRule.get(), oldString, player.level().getServer())) .thenSucceed(); }); } 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 5fee1572032..dff1041eb82 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 @@ -111,7 +111,7 @@ public ObjectArrayList doApply(ObjectArrayList generatedLo private static ItemStack smelt(ItemStack stack, LootContext context) { SingleRecipeInput input = new SingleRecipeInput(stack); return context.getLevel().recipeAccess().getRecipeFor(RecipeType.SMELTING, input, context.getLevel()) - .map(smeltingRecipe -> smeltingRecipe.value().assemble(input, context.getLevel().registryAccess())) + .map(smeltingRecipe -> smeltingRecipe.value().assemble(input)) .filter(itemStack -> !itemStack.isEmpty()) .map(itemStack -> itemStack.copyWithCount(stack.getCount() * itemStack.getCount())) .orElse(stack); diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/transfer/VanillaHandlersTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/transfer/VanillaHandlersTests.java index db46ae4527e..b32d9d1f1e3 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/transfer/VanillaHandlersTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/transfer/VanillaHandlersTests.java @@ -64,7 +64,9 @@ @ForEachTest(groups = "transfer.vanillahandlers") public class VanillaHandlersTests { - private static final ItemResource RESOURCE = ItemResource.of(Items.APPLE); + private static ItemResource resource() { + return ItemResource.of(Items.APPLE); + } @GameTest @EmptyTemplate @@ -79,7 +81,7 @@ public static void testHopperCooldown(ExtendedGameTestHelper helper) { // Insertion into empty hopper -> cooldown try (var transaction = Transaction.openRoot()) { - hopper.insert(RESOURCE, 10, transaction); + hopper.insert(resource(), 10, transaction); transaction.commit(); } helper.assertValueEqual(HopperBlockEntity.MOVE_ITEM_SPEED, getHopperCooldown(hopperEntity), "hopper cooldown"); @@ -87,24 +89,24 @@ public static void testHopperCooldown(ExtendedGameTestHelper helper) { // Second insertion into hopper -> no cooldown because the hopper is not empty try (var transaction = Transaction.openRoot()) { - hopper.insert(RESOURCE, 10, transaction); + hopper.insert(resource(), 10, transaction); transaction.commit(); } helper.assertValueEqual(0, getHopperCooldown(hopperEntity), "hopper cooldown"); hopperEntity.clearContent(); - hopperEntity.setItem(4, RESOURCE.toStack()); + hopperEntity.setItem(4, resource().toStack()); // Insertion into non-empty (with an item at a different index) hopper -> no cooldown try (var transaction = Transaction.openRoot()) { - hopper.insert(RESOURCE, 10, transaction); + hopper.insert(resource(), 10, transaction); transaction.commit(); } helper.assertValueEqual(0, getHopperCooldown(hopperEntity), "hopper cooldown"); // Extraction -> no cooldown try (var transaction = Transaction.openRoot()) { - hopper.extract(RESOURCE, 15, transaction); + hopper.extract(resource(), 15, transaction); transaction.commit(); } helper.assertContainerEmpty(pos); @@ -112,15 +114,15 @@ public static void testHopperCooldown(ExtendedGameTestHelper helper) { // Simulated insertion into empty hopper -> no cooldown try (var transaction = Transaction.openRoot()) { - hopper.insert(RESOURCE, 10, transaction); + hopper.insert(resource(), 10, transaction); } helper.assertValueEqual(0, getHopperCooldown(hopperEntity), "hopper cooldown"); // Insertion into empty hopper + extract in the same transaction -> cooldown try (var transaction = Transaction.openRoot()) { - hopper.insert(RESOURCE, 10, transaction); - helper.assertContainerContains(pos, RESOURCE.getItem()); - hopper.extract(RESOURCE, 10, transaction); + hopper.insert(resource(), 10, transaction); + helper.assertContainerContains(pos, resource().getItem()); + hopper.extract(resource(), 10, transaction); transaction.commit(); } helper.assertValueEqual(HopperBlockEntity.MOVE_ITEM_SPEED, getHopperCooldown(hopperEntity), "hopper cooldown"); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/AttachmentSyncTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/AttachmentSyncTest.java index 37db0c6cec2..6217f8c2f27 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/AttachmentSyncTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/AttachmentSyncTest.java @@ -6,7 +6,10 @@ package net.neoforged.neoforge.oldtest; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import java.util.function.Supplier; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.world.InteractionHand; @@ -17,11 +20,16 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; import net.neoforged.neoforge.attachment.AttachmentType; import net.neoforged.neoforge.attachment.IAttachmentHolder; +import net.neoforged.neoforge.registries.DeferredBlock; import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.NeoForgeRegistries; @@ -42,10 +50,16 @@ public class AttachmentSyncTest { ITEMS.registerItem("tester_entity", EntityTester::new); ITEMS.registerItem("tester_level", LevelTester::new); } + private static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MOD_ID); + private static final DeferredBlock TEST_BLOCK = BLOCKS.registerBlock("test_block", TestBlock::new); + private static final DeferredRegister> BLOCK_ENTITY_TYPES = DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, MOD_ID); + private static final Supplier> TEST_BLOCK_ENTITY_TYPE = BLOCK_ENTITY_TYPES.register("test_block", () -> new BlockEntityType<>(TestBlockEntity::new, TEST_BLOCK.get())); public AttachmentSyncTest(IEventBus modBus) { ATTACHMENT_TYPES.register(modBus); ITEMS.register(modBus); + BLOCKS.register(modBus); + BLOCK_ENTITY_TYPES.register(modBus); } /** @@ -64,7 +78,7 @@ private static void testInteraction(String what, Player player, IAttachmentHolde Integer value = holder.getExistingDataOrNull(ATTACHMENT_TYPE); int newValue = value == null ? 1 : value + 1; - if (newValue == 5) { + if (newValue >= 5) { holder.removeData(ATTACHMENT_TYPE); } else { holder.setData(ATTACHMENT_TYPE, newValue); @@ -143,4 +157,40 @@ public InteractionResult use(Level level, Player player, InteractionHand hand) { return InteractionResult.SUCCESS_SERVER; } } + + /// Block with a block entity that sets data attachments at unusual timings, + /// to test how robust data attachment sync is in those cases. + private static class TestBlock extends BaseEntityBlock { + public TestBlock(Properties properties) { + super(properties); + } + + @Override + protected MapCodec codec() { + return simpleCodec(TestBlock::new); + } + + @Override + public BlockEntity newBlockEntity(BlockPos worldPosition, BlockState blockState) { + return new TestBlockEntity(worldPosition, blockState); + } + } + + private static class TestBlockEntity extends BlockEntity { + public TestBlockEntity(BlockPos worldPosition, BlockState blockState) { + super(TEST_BLOCK_ENTITY_TYPE.get(), worldPosition, blockState); + } + + @Override + public void preRemoveSideEffects(BlockPos pos, BlockState state) { + super.preRemoveSideEffects(pos, state); + setData(ATTACHMENT_TYPE, 10); + } + + @Override + public void setRemoved() { + super.setRemoved(); + setData(ATTACHMENT_TYPE, 20); + } + } } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/CreativeModeTabTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/CreativeModeTabTest.java index b5ac3b368ed..eebc5bc4de5 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/CreativeModeTabTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/CreativeModeTabTest.java @@ -26,6 +26,7 @@ import net.neoforged.fml.common.Mod; import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; import net.neoforged.neoforge.registries.RegisterEvent; +import org.jspecify.annotations.Nullable; @Mod(CreativeModeTabTest.MOD_ID) public class CreativeModeTabTest { @@ -143,20 +144,22 @@ private static void onCreativeModeTabBuildContents(BuildCreativeModeTabContentsE } private static class CreativeModeColorTab extends CreativeModeTab { - private final ItemStack[] iconItems; + private ItemStack @Nullable [] iconItems; public CreativeModeColorTab(CreativeModeTab.Builder builder) { super(builder); - - DyeColor[] colors = DyeColor.values(); - iconItems = new ItemStack[colors.length]; - for (int i = 0; i < colors.length; i++) { - iconItems[i] = new ItemStack(DyeItem.byColor(colors[i])); - } } @Override public ItemStack getIconItem() { + if (iconItems == null) { + DyeColor[] colors = DyeColor.values(); + iconItems = new ItemStack[colors.length]; + for (int i = 0; i < colors.length; i++) { + iconItems[i] = new ItemStack(DyeItem.byColor(colors[i])); + } + } + int idx = (int) (System.currentTimeMillis() / 1200) % iconItems.length; return iconItems[idx]; } 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 2d39f690290..f30aac2ab5a 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java @@ -29,6 +29,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; +import net.minecraft.ChatFormatting; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.AdvancementType; @@ -39,6 +40,8 @@ import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderLookup; import net.minecraft.core.RegistrySetBuilder; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.component.DataComponents; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; @@ -69,7 +72,7 @@ import net.minecraft.util.Util; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Recipe; @@ -130,14 +133,14 @@ public static void gatherData(GatherDataEvent.Client event) { gen.addProvider(true, new PackMetadataGenerator(packOutput) .add(GeneratingOverlayMetadataSection.neoforgeType(PackType.SERVER_DATA), new GeneratingOverlayMetadataSection(List.of( - new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(PackFormat.of(0), PackFormat.of(Integer.MAX_VALUE)), "neoforge_overlays_test"))))) + new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(PackFormat.of(15), PackFormat.of(Integer.MAX_VALUE)), "neoforge_overlays_test"))))) .add(GeneratingOverlayMetadataSection.type(PackType.SERVER_DATA), new GeneratingOverlayMetadataSection(List.of( - new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(PackFormat.of(0), PackFormat.of(Integer.MAX_VALUE)), "pack_overlays_test")), - new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(PackFormat.of(0), PackFormat.of(Integer.MAX_VALUE)), "conditional_overlays_enabled"), NeoForgeConditions.modLoaded(NeoForgeMod.MOD_ID)), - new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(PackFormat.of(0), PackFormat.of(Integer.MAX_VALUE)), "conditional_overlays_disabled"), NeoForgeConditions.modLoaded("does_not_exist"))))) + new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(PackFormat.of(15), PackFormat.of(Integer.MAX_VALUE)), "pack_overlays_test")), + new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(PackFormat.of(15), PackFormat.of(Integer.MAX_VALUE)), "conditional_overlays_enabled"), NeoForgeConditions.modLoaded(NeoForgeMod.MOD_ID)), + new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(PackFormat.of(15), PackFormat.of(Integer.MAX_VALUE)), "conditional_overlays_disabled"), NeoForgeConditions.modLoaded("does_not_exist"))))) .add(PackMetadataSection.CLIENT_TYPE, new PackMetadataSection( Component.literal("NeoForge tests resource pack"), - new InclusiveRange<>(PackFormat.of(0), PackFormat.of(Integer.MAX_VALUE, Integer.MAX_VALUE))))); + new InclusiveRange<>(PackFormat.of(15), PackFormat.of(Integer.MAX_VALUE, Integer.MAX_VALUE))))); gen.addProvider(true, new Lang(packOutput)); gen.addProvider(true, new SoundDefinitions(packOutput, event.getResourceManager(PackType.CLIENT_RESOURCES))); gen.addProvider(true, new ParticleDescriptions(packOutput, event.getResourceManager(PackType.CLIENT_RESOURCES))); @@ -254,9 +257,7 @@ protected void buildRecipes() { .pattern("#") .pattern("#") .define('#', CompoundIngredient.of(tag(ItemTags.PLANKS), tag(ItemTags.LOGS), net.neoforged.neoforge.common.crafting.DataComponentIngredient.of(true, Util.make(() -> { - ItemStack stack = new ItemStack(Items.STONE_PICKAXE); - stack.setDamageValue(3); - return stack; + return new ItemStackTemplate(Items.STONE_PICKAXE, DataComponentPatch.builder().set(DataComponents.DAMAGE, 3).build()); })))) .unlockedBy("has_planks", has(Items.CRIMSON_PLANKS)) .save(output, recipeKey("compound_ingredient_custom_types")); @@ -516,6 +517,10 @@ protected void addTranslations() { add(MobEffects.POISON.value(), "Poison"); add(EntityType.CAT, "Cat"); add(MODID + ".test.unicode", "\u0287s\u01DD\u2534 \u01DDpo\u0254\u1D09u\u2229"); + add(MODID + ".test.component.literal", Component.literal("Literal")); + add(MODID + ".test.component.styled", Component.literal("Blue").withStyle(ChatFormatting.BLUE)); + add(MODID + ".test.component.appended", Component.literal("First").append(Component.literal("Second").withStyle(ChatFormatting.GOLD))); + add(MODID + ".test.component.nested", Component.translatable(MODID + ".test.component.literal", Component.translationArg(Identifier.withDefaultNamespace("test")))); } } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/FluidUtilTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/FluidUtilTest.java index 1ac28f079e0..d4f714bb3ff 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/FluidUtilTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/FluidUtilTest.java @@ -11,9 +11,9 @@ import net.minecraft.world.item.Items; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; -import net.neoforged.fml.event.lifecycle.FMLLoadCompleteEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.DefaultDataComponentsBoundEvent; import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidUtil; import net.neoforged.neoforge.fluids.capability.templates.FluidTank; @@ -31,11 +31,11 @@ public class FluidUtilTest { public static final String MODID = "fluid_util_test"; - public FluidUtilTest(IEventBus modEventBus) { - modEventBus.addListener(FluidUtilTest::runTests); + public FluidUtilTest() { + NeoForge.EVENT_BUS.addListener(FluidUtilTest::runTests); } - private static void runTests(FMLLoadCompleteEvent commonSetupEvent) { + private static void runTests(DefaultDataComponentsBoundEvent event) { test_tryEmptyContainer(); test_tryFillContainer(); test_tryEmptyContainerAndStow_stackable(); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/StencilEnableTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/StencilEnableTest.java index bfc8fe34166..3459dfb4db3 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/StencilEnableTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/StencilEnableTest.java @@ -12,7 +12,6 @@ import net.minecraft.client.gui.navigation.ScreenRectangle; import net.minecraft.client.gui.render.pip.PictureInPictureRenderer; import net.minecraft.client.gui.render.state.pip.PictureInPictureRenderState; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.SubmitNodeStorage; import net.minecraft.client.renderer.feature.FeatureRenderDispatcher; @@ -21,6 +20,7 @@ import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Blocks; @@ -141,11 +141,11 @@ protected void renderToTexture(StenciledItemPictureInPictureRenderState state, P SubmitNodeStorage store = dispatcher.getSubmitNodeStorage(); RenderSystem.pushPipelineModifier(STENCIL_FILL_KEY); { - state.maskRenderState.submit(poseStack, store, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); + state.maskRenderState.submit(poseStack, store, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); poseStack.pushPose(); poseStack.translate(10F / scale, -10F / scale, 0); - state.maskRenderState.submit(poseStack, store, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); + state.maskRenderState.submit(poseStack, store, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); poseStack.popPose(); dispatcher.renderAllFeatures(); @@ -157,11 +157,11 @@ protected void renderToTexture(StenciledItemPictureInPictureRenderState state, P poseStack.scale(1.1F, 1.1F, 1.1F); poseStack.translate(-.5F / scale, .5F / scale, 0); - state.maskedRenderState.submit(poseStack, store, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); + state.maskedRenderState.submit(poseStack, store, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); poseStack.pushPose(); poseStack.translate(10F / scale, -10F / scale, 0); - state.maskedRenderState.submit(poseStack, store, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); + state.maskedRenderState.submit(poseStack, store, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0); poseStack.popPose(); dispatcher.renderAllFeatures(); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestMenu.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestMenu.java index e8d7200ff5c..2a074de2fd1 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestMenu.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestMenu.java @@ -184,7 +184,7 @@ protected static void slotChangedCraftingGrid( RecipeHolder recipeholder = optional.get(); RecipeBookTestRecipe craftingrecipe = recipeholder.value(); if (resultSlots.setRecipeUsed(serverplayer, recipeholder)) { - ItemStack itemstack1 = craftingrecipe.assemble(craftinginput, level.registryAccess()); + ItemStack itemstack1 = craftingrecipe.assemble(craftinginput); if (itemstack1.isItemEnabled(level.enabledFeatures())) { itemstack = itemstack1; } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestRecipe.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestRecipe.java index 8c048658a2e..4540ec5247a 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestRecipe.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestRecipe.java @@ -18,8 +18,8 @@ import java.util.Optional; import java.util.function.Function; import java.util.stream.Stream; -import net.minecraft.core.HolderLookup; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.CraftingInput; import net.minecraft.world.item.crafting.Ingredient; @@ -90,8 +90,8 @@ private boolean matches(CraftingInput input, boolean mirror) //unsure about the } @Override - public ItemStack assemble(CraftingInput p_44001_, HolderLookup.Provider registryAccess) { - return this.ingredients.result.copy(); + public ItemStack assemble(CraftingInput input) { + return this.ingredients.result.create(); } @Override @@ -137,7 +137,7 @@ public RecipeBookCategory recipeBookCategory() { } } - public record Ingredients(String group, List pattern, Map recipe, ItemStack result) { + public record Ingredients(String group, List pattern, Map recipe, ItemStackTemplate result) { private static final Function> VERIFY_LENGTH_2 = s -> s.length() == 2 ? DataResult.success(s) : DataResult.error(() -> "Key row length must be of 2!"); private static final Function, DataResult>> VERIFY_SIZE = l -> { if (l.size() <= 4 && l.size() >= 1) { @@ -153,6 +153,6 @@ public record Ingredients(String group, List pattern, Map