diff --git a/.github/workflows/1.21.11_pr.yml b/.github/workflows/26.1_pr.yml similarity index 76% rename from .github/workflows/1.21.11_pr.yml rename to .github/workflows/26.1_pr.yml index 80b0ee06a..bfc408791 100644 --- a/.github/workflows/1.21.11_pr.yml +++ b/.github/workflows/26.1_pr.yml @@ -1,4 +1,4 @@ -name: Build PR snapshot (1.21.11) +name: Build PR snapshot (26.1) on: pull_request: @@ -19,24 +19,6 @@ jobs: fetch-depth: 0 - uses: gradle/actions/wrapper-validation@v5 - license: - name: "Verify License integrity" - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v6 - - - name: Set up JDK 21 - uses: actions/setup-java@v5 - with: - java-version: 21 - distribution: 'temurin' - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 - - - name: Verify license using Licenser - run: ./gradlew licenseCheck - build: name: "Build" runs-on: ubuntu-20.04 @@ -45,10 +27,10 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Set up JDK 21 + - name: Set up JDK 25 uses: actions/setup-java@v5 with: - java-version: 21 + java-version: 25 distribution: 'temurin' - name: Setup Gradle diff --git a/.github/workflows/1.21.11_push.yml b/.github/workflows/26.1_push.yml similarity index 72% rename from .github/workflows/1.21.11_push.yml rename to .github/workflows/26.1_push.yml index 5e3ca7fe8..fa2a1250f 100644 --- a/.github/workflows/1.21.11_push.yml +++ b/.github/workflows/26.1_push.yml @@ -1,4 +1,4 @@ -name: Build and Release (1.21.11) +name: Build and Release (26.1) on: push: @@ -25,10 +25,10 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Set up JDK 21 + - name: Set up JDK 25 uses: actions/setup-java@v5 with: - java-version: 21 + java-version: 25 distribution: 'temurin' - name: Validate Gradle Wrapper @@ -37,9 +37,6 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v5 - - name: Verify license using Licenser - run: ./gradlew licenseCheck - - name: Build with Gradle run: ./gradlew build --stacktrace --no-daemon @@ -61,13 +58,13 @@ jobs: !**/*-transformProduction*.jar !**/testmod*/ - - name: Release to Maven and CurseForge - if: | - !contains(github.event.head_commit.message, '[norelease]') && - github.event.inputs.norelease != 'true' - env: - MAVEN_PASS: ${{ secrets.MAVEN_PASS }} - CURSE_API_KEY: ${{ secrets.CURSE_API_KEY }} - MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} - run: | - ./gradlew publish publishUnified --stacktrace --no-daemon +# - name: Release to Maven and CurseForge +# if: | +# !contains(github.event.head_commit.message, '[norelease]') && +# github.event.inputs.norelease != 'true' +# env: +# MAVEN_PASS: ${{ secrets.MAVEN_PASS }} +# CURSE_API_KEY: ${{ secrets.CURSE_API_KEY }} +# MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} +# run: | +# ./gradlew publish publishUnified --stacktrace --no-daemon diff --git a/.gitignore b/.gitignore index 1b2a32bf0..2e7140aaf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ run/ out/ *.iml .gradle/ +.gradle-user/ output/ bin/ libs/ @@ -16,4 +17,4 @@ libs/ classes/ .vscode/ -logs/ \ No newline at end of file +logs/ diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 000000000..f25a31352 --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Implementation-Version: 1.14.10001 + diff --git a/build.gradle b/build.gradle index 6f0f93290..32ccf90b4 100644 --- a/build.gradle +++ b/build.gradle @@ -4,13 +4,24 @@ buildscript { configurations.classpath { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } + + repositories { + maven { url "https://maven.fabricmc.net/" } + maven { url "https://maven.architectury.dev/" } + maven { url "https://maven.shedaniel.me/" } + maven { url "https://maven.minecraftforge.net/" } + mavenCentral() + gradlePluginPortal() + } + + dependencies { + classpath files("$rootDir/gradle/architectury-loom-1.14.10001.jar") + classpath "dev.architectury:architectury-loom:1.14.473" + } } plugins { - id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.13-SNAPSHOT" apply false - id "org.cadixdev.licenser" version "0.6.1" - id "me.shedaniel.unified-publishing" version "0.1.+" apply false + id "architectury-plugin" version "3.5-SNAPSHOT" id "maven-publish" } @@ -19,18 +30,14 @@ architectury { } subprojects { - apply plugin: "dev.architectury.loom" - - loom { - silentMojangMappingsLicense() - } + apply plugin: "dev.architectury.loom-no-remap" dependencies { minecraft "com.mojang:minecraft:${rootProject.architectury.minecraft}" - mappings loom.officialMojangMappings() } repositories { + maven { url "https://maven.minecraftforge.net/" } maven { url "https://maven.neoforged.net/releases/" } if (rootProject.neoforge_pr != "") { maven { @@ -46,7 +53,6 @@ subprojects { allprojects { apply plugin: "java" apply plugin: "architectury-plugin" - apply plugin: "org.cadixdev.licenser" ext { isSnapshot = System.getenv("PR_NUM") != null @@ -56,17 +62,27 @@ allprojects { if (!ext.isSnapshot) { version = rootProject.base_version + "." + runNumber + rootProject.version_suffix - archivesBaseName = rootProject.archives_base_name + ext.archivesBaseName = rootProject.archives_base_name } else { version = rootProject.base_version + "-PR." + System.getenv("PR_NUM") + "." + runNumber - archivesBaseName = rootProject.archives_base_name_snapshot + ext.archivesBaseName = rootProject.archives_base_name_snapshot + } + + base { + archivesName = project.ext.archivesBaseName } group = rootProject.maven_group - tasks.withType(JavaCompile) { + java { + toolchain { + languageVersion = JavaLanguageVersion.of(25) + } + } + + tasks.withType(JavaCompile).configureEach { options.encoding = "UTF-8" - options.release = 21 + options.release = 25 } javadoc { @@ -75,20 +91,6 @@ allprojects { failOnError = false } - license { - header = rootProject.file("HEADER") - - ext { - name = "architectury" - year = "2020, 2021, 2022" - } - - include "**/*.java" - exclude "**/NbtType.java" - - ignoreFailures = true - } - ext { releaseChangelog = { def dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm") @@ -122,6 +124,3 @@ allprojects { withSourcesJar() } } - -task licenseFormatAll -subprojects { p -> licenseFormatAll.dependsOn("${p.path}:licenseFormat") } diff --git a/common/build.gradle b/common/build.gradle index fbd0ce737..36bc3189e 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -5,7 +5,8 @@ loom { dependencies { // We depend on fabric loader here to use the fabric @Environment annotations // Do NOT use other classes from fabric loader - modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + implementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + compileOnly "net.fabricmc:sponge-mixin:0.16.5+mixin.0.8.7" } architectury { @@ -14,6 +15,12 @@ architectury { } } +tasks.withType(JavaCompile).configureEach { + // Architectury's transformer currently fails on Java 25 class files, but it only consumes the common jar. + // Keep the shared code on Java 21 bytecode so transformProductionFabric can finish. + options.release = 21 +} + /** * The following code to generate the access widener is based on the following pull request by Juuxel; * https://github.com/Juuxel/ diff --git a/common/src/main/java/dev/architectury/core/fluid/ArchitecturyFluidAttributes.java b/common/src/main/java/dev/architectury/core/fluid/ArchitecturyFluidAttributes.java index 981b84e7d..c5d2c8abd 100644 --- a/common/src/main/java/dev/architectury/core/fluid/ArchitecturyFluidAttributes.java +++ b/common/src/main/java/dev/architectury/core/fluid/ArchitecturyFluidAttributes.java @@ -20,13 +20,13 @@ package dev.architectury.core.fluid; import dev.architectury.fluid.FluidStack; +import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.item.Item; import net.minecraft.world.item.Rarity; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.LiquidBlock; import net.minecraft.world.level.material.Fluid; diff --git a/common/src/main/java/dev/architectury/core/fluid/SimpleArchitecturyFluidAttributes.java b/common/src/main/java/dev/architectury/core/fluid/SimpleArchitecturyFluidAttributes.java index b10cacda9..d851a61bd 100644 --- a/common/src/main/java/dev/architectury/core/fluid/SimpleArchitecturyFluidAttributes.java +++ b/common/src/main/java/dev/architectury/core/fluid/SimpleArchitecturyFluidAttributes.java @@ -23,13 +23,14 @@ import dev.architectury.fluid.FluidStack; import dev.architectury.registry.registries.RegistrySupplier; import net.minecraft.util.Util; +import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.item.Item; import net.minecraft.world.item.Rarity; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.LiquidBlock; import net.minecraft.world.level.material.Fluid; @@ -67,7 +68,7 @@ public class SimpleArchitecturyFluidAttributes implements ArchitecturyFluidAttri private SoundEvent fillSound = SoundEvents.BUCKET_FILL; @Nullable private SoundEvent emptySound = SoundEvents.BUCKET_EMPTY; - private final Supplier defaultTranslationKey = Suppliers.memoize(() -> Util.makeDescriptionId("fluid", getSourceFluid().arch$registryName())); + private final Supplier defaultTranslationKey = Suppliers.memoize(() -> Util.makeDescriptionId("fluid", BuiltInRegistries.FLUID.getKey(getSourceFluid()))); public static SimpleArchitecturyFluidAttributes ofSupplier(Supplier> flowingFluid, Supplier> sourceFluid) { return of(() -> flowingFluid.get().get(), () -> sourceFluid.get().get()); diff --git a/common/src/main/java/dev/architectury/event/EventFactory.java b/common/src/main/java/dev/architectury/event/EventFactory.java index 08fc5889c..ec2f7568c 100644 --- a/common/src/main/java/dev/architectury/event/EventFactory.java +++ b/common/src/main/java/dev/architectury/event/EventFactory.java @@ -202,19 +202,19 @@ protected Object handleInvocation(Object proxy, Method method, Object[] args) th @ExpectPlatform @ApiStatus.Internal public static Event> attachToForge(Event> event) { - throw new AssertionError(); + return event; } @ExpectPlatform @ApiStatus.Internal public static Event> attachToForgeEventActor(Event> event) { - throw new AssertionError(); + return event; } @ExpectPlatform @ApiStatus.Internal public static Event> attachToForgeEventActorCancellable(Event> event) { - throw new AssertionError(); + return event; } private static class EventImpl implements Event { diff --git a/common/src/main/java/dev/architectury/event/EventHandler.java b/common/src/main/java/dev/architectury/event/EventHandler.java index 06bb763ff..5c23f61f9 100644 --- a/common/src/main/java/dev/architectury/event/EventHandler.java +++ b/common/src/main/java/dev/architectury/event/EventHandler.java @@ -19,6 +19,7 @@ package dev.architectury.event; +import dev.architectury.injectables.ExpectPlatformFallback; import dev.architectury.injectables.annotations.ExpectPlatform; import dev.architectury.platform.Platform; import dev.architectury.utils.Env; @@ -41,16 +42,16 @@ public static void init() { @ExpectPlatform private static void registerClient() { - throw new AssertionError(); + ExpectPlatformFallback.run("dev.architectury.event.fabric.EventHandlerImpl", "registerClient", new Class[0]); } @ExpectPlatform private static void registerCommon() { - throw new AssertionError(); + ExpectPlatformFallback.run("dev.architectury.event.fabric.EventHandlerImpl", "registerCommon", new Class[0]); } @ExpectPlatform private static void registerServer() { - throw new AssertionError(); + ExpectPlatformFallback.run("dev.architectury.event.fabric.EventHandlerImpl", "registerServer", new Class[0]); } } diff --git a/common/src/main/java/dev/architectury/event/events/client/ClientGuiEvent.java b/common/src/main/java/dev/architectury/event/events/client/ClientGuiEvent.java index 8c0df01d2..d95c7262e 100644 --- a/common/src/main/java/dev/architectury/event/events/client/ClientGuiEvent.java +++ b/common/src/main/java/dev/architectury/event/events/client/ClientGuiEvent.java @@ -25,13 +25,13 @@ import dev.architectury.event.EventResult; import dev.architectury.hooks.client.screen.ScreenAccess; import net.minecraft.client.DeltaTracker; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; public interface ClientGuiEvent { /** - * @see RenderHud#renderHud(GuiGraphics, DeltaTracker) + * @see RenderHud#renderHud(GuiGraphicsExtractor, DeltaTracker) */ Event RENDER_HUD = EventFactory.createLoop(); /** @@ -43,19 +43,19 @@ public interface ClientGuiEvent { */ Event INIT_POST = EventFactory.createLoop(); /** - * @see ScreenRenderPre#render(Screen, GuiGraphics, int, int, float) + * @see ScreenRenderPre#render(Screen, GuiGraphicsExtractor, int, int, float) */ Event RENDER_PRE = EventFactory.createEventResult(); /** - * @see ScreenRenderPost#render(Screen, GuiGraphics, int, int, float) + * @see ScreenRenderPost#render(Screen, GuiGraphicsExtractor, int, int, float) */ Event RENDER_POST = EventFactory.createLoop(); /** - * @see ContainerScreenRenderBackground#render(AbstractContainerScreen, GuiGraphics, int, int, float) + * @see ContainerScreenRenderBackground#render(AbstractContainerScreen, GuiGraphicsExtractor, int, int, float) */ Event RENDER_CONTAINER_BACKGROUND = EventFactory.createLoop(); /** - * @see ContainerScreenRenderForeground#render(AbstractContainerScreen, GuiGraphics, int, int, float) + * @see ContainerScreenRenderForeground#render(AbstractContainerScreen, GuiGraphicsExtractor, int, int, float) */ Event RENDER_CONTAINER_FOREGROUND = EventFactory.createLoop(); /** @@ -71,7 +71,7 @@ interface RenderHud { * @param graphics The graphics context. * @param tickDelta The tick delta. */ - void renderHud(GuiGraphics graphics, DeltaTracker deltaTracker); + void renderHud(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker); } interface ScreenInitPre { @@ -111,7 +111,7 @@ interface ScreenRenderPre { * @return A {@link EventResult} determining the outcome of the event, * the vanilla render may be cancelled by the result. */ - EventResult render(Screen screen, GuiGraphics graphics, int mouseX, int mouseY, float delta); + EventResult render(Screen screen, GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta); } interface ScreenRenderPost { @@ -125,7 +125,7 @@ interface ScreenRenderPost { * @param mouseY The scaled y-coordinate of the mouse cursor. * @param delta The current tick delta. */ - void render(Screen screen, GuiGraphics graphics, int mouseX, int mouseY, float delta); + void render(Screen screen, GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta); } interface ContainerScreenRenderBackground { @@ -139,7 +139,7 @@ interface ContainerScreenRenderBackground { * @param mouseY The scaled y-coordinate of the mouse cursor. * @param delta The current tick delta. */ - void render(AbstractContainerScreen screen, GuiGraphics graphics, int mouseX, int mouseY, float delta); + void render(AbstractContainerScreen screen, GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta); } interface ContainerScreenRenderForeground { @@ -153,7 +153,7 @@ interface ContainerScreenRenderForeground { * @param mouseY The scaled y-coordinate of the mouse cursor. * @param delta The current tick delta. */ - void render(AbstractContainerScreen screen, GuiGraphics graphics, int mouseX, int mouseY, float delta); + void render(AbstractContainerScreen screen, GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta); } interface SetScreen { diff --git a/common/src/main/java/dev/architectury/event/events/client/ClientTooltipEvent.java b/common/src/main/java/dev/architectury/event/events/client/ClientTooltipEvent.java index 7a0da6a0e..2f4786a49 100644 --- a/common/src/main/java/dev/architectury/event/events/client/ClientTooltipEvent.java +++ b/common/src/main/java/dev/architectury/event/events/client/ClientTooltipEvent.java @@ -23,7 +23,7 @@ import dev.architectury.event.EventFactory; import dev.architectury.event.EventResult; import dev.architectury.impl.TooltipAdditionalContextsImpl; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; @@ -39,11 +39,11 @@ public interface ClientTooltipEvent { */ Event ITEM = EventFactory.createLoop(); /** - * @see Render#renderTooltip(GuiGraphics, List, int, int) + * @see Render#renderTooltip(GuiGraphicsExtractor, List, int, int) */ Event RENDER_PRE = EventFactory.createEventResult(); /** - * @see RenderModifyPosition#renderTooltip(GuiGraphics, PositionContext) + * @see RenderModifyPosition#renderTooltip(GuiGraphicsExtractor, PositionContext) */ Event RENDER_MODIFY_POSITION = EventFactory.createLoop(); @@ -84,7 +84,7 @@ interface Render { * @return A {@link EventResult} determining the outcome of the event, * the execution of the vanilla tooltip rendering may be cancelled by the result. */ - EventResult renderTooltip(GuiGraphics graphics, List texts, int x, int y); + EventResult renderTooltip(GuiGraphicsExtractor graphics, List texts, int x, int y); } interface RenderModifyPosition { @@ -94,7 +94,7 @@ interface RenderModifyPosition { * @param graphics The graphics context. * @param context The current position context. */ - void renderTooltip(GuiGraphics graphics, PositionContext context); + void renderTooltip(GuiGraphicsExtractor graphics, PositionContext context); } interface PositionContext { diff --git a/common/src/main/java/dev/architectury/hooks/client/fluid/ClientFluidStackHooks.java b/common/src/main/java/dev/architectury/hooks/client/fluid/ClientFluidStackHooks.java index e8b036909..e6aa4912c 100644 --- a/common/src/main/java/dev/architectury/hooks/client/fluid/ClientFluidStackHooks.java +++ b/common/src/main/java/dev/architectury/hooks/client/fluid/ClientFluidStackHooks.java @@ -21,9 +21,9 @@ import dev.architectury.fluid.FluidStack; import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; import org.jetbrains.annotations.Nullable; diff --git a/common/src/main/java/dev/architectury/impl/RegistrySupplierImpl.java b/common/src/main/java/dev/architectury/impl/RegistrySupplierImpl.java index b045c8fa5..5df14c128 100644 --- a/common/src/main/java/dev/architectury/impl/RegistrySupplierImpl.java +++ b/common/src/main/java/dev/architectury/impl/RegistrySupplierImpl.java @@ -23,6 +23,7 @@ import dev.architectury.registry.registries.RegistrySupplier; import net.minecraft.core.Holder; import net.minecraft.core.HolderOwner; +import net.minecraft.core.component.DataComponentMap; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; import net.minecraft.tags.TagKey; @@ -47,6 +48,12 @@ default T value() { default boolean isBound() { return isPresent(); } + + @Override + default boolean areComponentsBound() { + Holder holder = getHolder(); + return holder != null && holder.areComponentsBound(); + } @Override default boolean is(Identifier resourceLocation) { @@ -79,6 +86,12 @@ default Stream> tags() { Holder holder = getHolder(); return holder != null ? holder.tags() : Stream.empty(); } + + @Override + default DataComponentMap components() { + Holder holder = getHolder(); + return holder != null ? holder.components() : DataComponentMap.EMPTY; + } @Override default Either, T> unwrap() { diff --git a/common/src/main/java/dev/architectury/injectables/ExpectPlatformFallback.java b/common/src/main/java/dev/architectury/injectables/ExpectPlatformFallback.java new file mode 100644 index 000000000..ab7dcc294 --- /dev/null +++ b/common/src/main/java/dev/architectury/injectables/ExpectPlatformFallback.java @@ -0,0 +1,40 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.injectables; + +import java.lang.reflect.Method; + +public final class ExpectPlatformFallback { + private ExpectPlatformFallback() { + } + + public static Object call(String owner, String name, Class[] parameterTypes, Object... args) { + try { + Method method = Class.forName(owner).getMethod(name, parameterTypes); + return method.invoke(null, args); + } catch (ReflectiveOperationException exception) { + throw new AssertionError("Failed to invoke platform fallback " + owner + "#" + name, exception); + } + } + + public static void run(String owner, String name, Class[] parameterTypes, Object... args) { + call(owner, name, parameterTypes, args); + } +} diff --git a/common/src/main/java/dev/architectury/networking/NetworkManager.java b/common/src/main/java/dev/architectury/networking/NetworkManager.java index 9690d92c9..a2fa560e7 100644 --- a/common/src/main/java/dev/architectury/networking/NetworkManager.java +++ b/common/src/main/java/dev/architectury/networking/NetworkManager.java @@ -20,6 +20,7 @@ package dev.architectury.networking; import dev.architectury.impl.NetworkAggregator; +import dev.architectury.injectables.ExpectPlatformFallback; import dev.architectury.injectables.annotations.ExpectPlatform; import dev.architectury.networking.transformers.PacketCollector; import dev.architectury.networking.transformers.PacketSink; @@ -161,17 +162,17 @@ public static void sendToPlayers(Iterable void sendToServer(T payload) { - throw new AssertionError(); + ExpectPlatformFallback.run("dev.architectury.networking.fabric.NetworkManagerImpl", "sendToServer", new Class[]{CustomPacketPayload.class}, payload); } @ExpectPlatform public static boolean canServerReceive(Identifier id) { - throw new AssertionError(); + return (boolean) ExpectPlatformFallback.call("dev.architectury.networking.fabric.NetworkManagerImpl", "canServerReceive", new Class[]{Identifier.class}, id); } @ExpectPlatform public static boolean canPlayerReceive(ServerPlayer player, Identifier id) { - throw new AssertionError(); + return (boolean) ExpectPlatformFallback.call("dev.architectury.networking.fabric.NetworkManagerImpl", "canPlayerReceive", new Class[]{ServerPlayer.class, Identifier.class}, player, id); } public static boolean canServerReceive(CustomPacketPayload.Type type) { @@ -196,12 +197,12 @@ public static boolean canPlayerReceive(ServerPlayer player, CustomPacketPayload. */ @ExpectPlatform public static Packet createAddEntityPacket(Entity entity, ServerEntity serverEntity) { - throw new AssertionError(); + return (Packet) ExpectPlatformFallback.call("dev.architectury.networking.fabric.NetworkManagerImpl", "createAddEntityPacket", new Class[]{Entity.class, ServerEntity.class}, entity, serverEntity); } @ExpectPlatform private static NetworkAggregator.Adaptor getAdaptor() { - throw new AssertionError(); + return (NetworkAggregator.Adaptor) ExpectPlatformFallback.call("dev.architectury.networking.fabric.NetworkManagerImpl", "getAdaptor", new Class[0]); } @FunctionalInterface diff --git a/common/src/main/java/dev/architectury/platform/Platform.java b/common/src/main/java/dev/architectury/platform/Platform.java index 991f6bb9a..304c1c2fc 100644 --- a/common/src/main/java/dev/architectury/platform/Platform.java +++ b/common/src/main/java/dev/architectury/platform/Platform.java @@ -19,6 +19,7 @@ package dev.architectury.platform; +import dev.architectury.injectables.ExpectPlatformFallback; import dev.architectury.injectables.annotations.ExpectPlatform; import dev.architectury.injectables.targets.ArchitecturyTarget; import dev.architectury.utils.Env; @@ -83,7 +84,7 @@ public static String getMinecraftVersion() { */ @ExpectPlatform public static Path getGameFolder() { - throw new AssertionError(); + return (Path) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "getGameFolder", new Class[0]); } /** @@ -93,7 +94,7 @@ public static Path getGameFolder() { */ @ExpectPlatform public static Path getConfigFolder() { - throw new AssertionError(); + return (Path) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "getConfigFolder", new Class[0]); } /** @@ -103,7 +104,7 @@ public static Path getConfigFolder() { */ @ExpectPlatform public static Path getModsFolder() { - throw new AssertionError(); + return (Path) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "getModsFolder", new Class[0]); } /** @@ -119,7 +120,7 @@ public static Path getModsFolder() { */ @ExpectPlatform public static Env getEnvironment() { - throw new AssertionError(); + return (Env) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "getEnvironment", new Class[0]); } /** @@ -132,7 +133,7 @@ public static Env getEnvironment() { */ @ExpectPlatform public static EnvType getEnv() { - throw new AssertionError(); + return (EnvType) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "getEnv", new Class[0]); } /** @@ -143,7 +144,7 @@ public static EnvType getEnv() { */ @ExpectPlatform public static boolean isModLoaded(String id) { - throw new AssertionError(); + return (boolean) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "isModLoaded", new Class[]{String.class}, id); } /** @@ -155,7 +156,7 @@ public static boolean isModLoaded(String id) { */ @ExpectPlatform public static Mod getMod(String id) { - throw new AssertionError(); + return (Mod) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "getMod", new Class[]{String.class}, id); } /** @@ -180,7 +181,7 @@ public static Optional getOptionalMod(String id) { */ @ExpectPlatform public static Collection getMods() { - throw new AssertionError(); + return (Collection) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "getMods", new Class[0]); } /** @@ -190,11 +191,11 @@ public static Collection getMods() { */ @ExpectPlatform public static Collection getModIds() { - throw new AssertionError(); + return (Collection) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "getModIds", new Class[0]); } @ExpectPlatform public static boolean isDevelopmentEnvironment() { - throw new AssertionError(); + return (boolean) ExpectPlatformFallback.call("dev.architectury.platform.fabric.PlatformImpl", "isDevelopmentEnvironment", new Class[0]); } } diff --git a/common/src/main/java/dev/architectury/registry/client/rendering/ColorHandlerRegistry.java b/common/src/main/java/dev/architectury/registry/client/rendering/ColorHandlerRegistry.java index ac2eeb36e..7f50c5655 100644 --- a/common/src/main/java/dev/architectury/registry/client/rendering/ColorHandlerRegistry.java +++ b/common/src/main/java/dev/architectury/registry/client/rendering/ColorHandlerRegistry.java @@ -20,7 +20,7 @@ package dev.architectury.registry.client.rendering; import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.block.BlockTintSource; import net.minecraft.world.level.block.Block; import java.util.Objects; @@ -30,7 +30,7 @@ public final class ColorHandlerRegistry { private ColorHandlerRegistry() { } - public static void registerBlockColors(BlockColor color, Block... blocks) { + public static void registerBlockColors(BlockTintSource color, Block... blocks) { Supplier[] array = new Supplier[blocks.length]; for (var i = 0; i < blocks.length; i++) { var block = Objects.requireNonNull(blocks[i], "blocks[i] is null!"); @@ -41,7 +41,7 @@ public static void registerBlockColors(BlockColor color, Block... blocks) { @SafeVarargs @ExpectPlatform - public static void registerBlockColors(BlockColor color, Supplier... blocks) { + public static void registerBlockColors(BlockTintSource color, Supplier... blocks) { throw new AssertionError(); } } diff --git a/common/src/main/java/dev/architectury/registry/level/entity/trade/SimpleTrade.java b/common/src/main/java/dev/architectury/registry/level/entity/trade/SimpleTrade.java index 27cd54718..5c06a7450 100644 --- a/common/src/main/java/dev/architectury/registry/level/entity/trade/SimpleTrade.java +++ b/common/src/main/java/dev/architectury/registry/level/entity/trade/SimpleTrade.java @@ -22,7 +22,6 @@ 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; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.trading.ItemCost; import net.minecraft.world.item.trading.MerchantOffer; @@ -32,20 +31,20 @@ /** * This class is the easiest implementation of a trade object. - * All trades added by vanilla do have custom classes like {@link VillagerTrades.EmeraldForItems}, but they aren't accessible. + * All trades added by vanilla do have custom classes, but they aren't accessible. *

* Instead of widening the access of those classes or recreating them, this class was added to serve a basic trading implementation. * To register a trade, just call - * {@link TradeRegistry#registerVillagerTrade(net.minecraft.world.entity.npc.VillagerProfession, int, VillagerTrades.ItemListing...)} + * {@link TradeRegistry#registerVillagerTrade(net.minecraft.resources.ResourceKey, int, TradeRegistry.ItemListing...)} * or - * {@link TradeRegistry#registerTradeForWanderingTrader(boolean, VillagerTrades.ItemListing...)}. + * {@link TradeRegistry#registerTradeForWanderingTrader(dev.architectury.registry.level.entity.trade.TradeRegistry.WandererTradeType, TradeRegistry.ItemListing...)}. */ public record SimpleTrade(ItemCost primaryPrice, Optional secondaryPrice, ItemStack sale, int maxTrades, int experiencePoints, - float priceMultiplier) implements VillagerTrades.ItemListing { + float priceMultiplier) implements TradeRegistry.ItemListing { /** * Constructor for creating the trade. - * You can take a look at all the values the vanilla game uses right here {@link VillagerTrades#TRADES}. + * You can take a look at all the values the vanilla game uses in the trade bootstrap data. * * @param primaryPrice The first price a player has to pay to get the 'sale' stack. * @param secondaryPrice An optional, secondary price to pay as well as the primary one. If not needed just use {@link Optional#empty()}. diff --git a/common/src/main/java/dev/architectury/registry/level/entity/trade/TradeRegistry.java b/common/src/main/java/dev/architectury/registry/level/entity/trade/TradeRegistry.java index 50700ddd2..90174f20a 100644 --- a/common/src/main/java/dev/architectury/registry/level/entity/trade/TradeRegistry.java +++ b/common/src/main/java/dev/architectury/registry/level/entity/trade/TradeRegistry.java @@ -21,22 +21,26 @@ import dev.architectury.injectables.annotations.ExpectPlatform; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.npc.villager.VillagerProfession; -import net.minecraft.world.entity.npc.villager.VillagerTrades; +import net.minecraft.world.item.trading.MerchantOffer; +import org.jetbrains.annotations.Nullable; public class TradeRegistry { private TradeRegistry() { } /** - * Register a trade ({@link VillagerTrades.ItemListing}) for a villager by its profession and level. + * Register a trade ({@link ItemListing}) for a villager by its profession and level. * When the mod loader is Forge, the {@code VillagerTradesEvent} event is used. * * @param profession The Profession the villager needs to have this trade. * @param level The level the villager needs. Vanilla range is 1 to 5, however mods may extend that upper limit further. * @param trades The trades to add to this profession at the specified level. */ - public static void registerVillagerTrade(ResourceKey profession, int level, VillagerTrades.ItemListing... trades) { + public static void registerVillagerTrade(ResourceKey profession, int level, ItemListing... trades) { if (level < 1) { throw new IllegalArgumentException("Villager Trade level has to be at least 1!"); } @@ -44,19 +48,19 @@ public static void registerVillagerTrade(ResourceKey profess } @ExpectPlatform - private static void registerVillagerTrade0(ResourceKey profession, int level, VillagerTrades.ItemListing... trades) { + private static void registerVillagerTrade0(ResourceKey profession, int level, ItemListing... trades) { throw new AssertionError(); } /** - * Register a trade ({@link VillagerTrades.ItemListing}) to a wandering trader by its rarity. + * Register a trade ({@link ItemListing}) to a wandering trader by its rarity. * When the mod loader is Forge, the {@code WandererTradesEvent} event is used. * * @param type The type of trade to add to the wandering trader. * @param trades The trades to add to the wandering trader. */ @ExpectPlatform - public static void registerTradeForWanderingTrader(WandererTradeType type, VillagerTrades.ItemListing... trades) { + public static void registerTradeForWanderingTrader(WandererTradeType type, ItemListing... trades) { throw new AssertionError(); } @@ -65,5 +69,11 @@ public enum WandererTradeType { GENERIC_TRADES, RARE_TRADES, } + + @FunctionalInterface + public interface ItemListing { + @Nullable + MerchantOffer getOffer(ServerLevel level, Entity entity, RandomSource random); + } } diff --git a/common/src/main/java/dev/architectury/utils/GameInstance.java b/common/src/main/java/dev/architectury/utils/GameInstance.java index d56625b4a..d968ed6e4 100644 --- a/common/src/main/java/dev/architectury/utils/GameInstance.java +++ b/common/src/main/java/dev/architectury/utils/GameInstance.java @@ -19,6 +19,7 @@ package dev.architectury.utils; +import dev.architectury.injectables.ExpectPlatformFallback; import dev.architectury.injectables.annotations.ExpectPlatform; import net.minecraft.server.MinecraftServer; import org.jetbrains.annotations.Nullable; @@ -27,6 +28,6 @@ public final class GameInstance { @Nullable @ExpectPlatform public static MinecraftServer getServer() { - throw new AssertionError(); + return (MinecraftServer) ExpectPlatformFallback.call("dev.architectury.utils.fabric.GameInstanceImpl", "getServer", new Class[0]); } } diff --git a/common/src/main/resources/architectury-common.mixins.json b/common/src/main/resources/architectury-common.mixins.json index 17a78c111..9d9ff183b 100644 --- a/common/src/main/resources/architectury-common.mixins.json +++ b/common/src/main/resources/architectury-common.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "dev.architectury.mixin", - "compatibilityLevel": "JAVA_16", + "compatibilityLevel": "JAVA_25", "minVersion": "0.7.11", "client": [ ], diff --git a/common/src/main/resources/architectury.accessWidener b/common/src/main/resources/architectury.accessWidener index 027eefdb9..00e2582fe 100644 --- a/common/src/main/resources/architectury.accessWidener +++ b/common/src/main/resources/architectury.accessWidener @@ -1,4 +1,4 @@ -accessWidener v2 named +accessWidener v2 official accessible method net/minecraft/client/gui/screens/Screen addRenderableWidget (Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener; accessible method net/minecraft/client/gui/screens/Screen addRenderableOnly (Lnet/minecraft/client/gui/components/Renderable;)Lnet/minecraft/client/gui/components/Renderable; accessible method net/minecraft/client/gui/screens/Screen addWidget (Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener; @@ -38,8 +38,6 @@ accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties mutable field net/minecraft/world/level/block/state/BlockBehaviour$Properties isSuffocating Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isViewBlocking Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; mutable field net/minecraft/world/level/block/state/BlockBehaviour$Properties isViewBlocking Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties hasPostProcess Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; -mutable field net/minecraft/world/level/block/state/BlockBehaviour$Properties hasPostProcess Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties emissiveRendering Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; mutable field net/minecraft/world/level/block/state/BlockBehaviour$Properties emissiveRendering Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties dynamicShape Z @@ -112,7 +110,6 @@ transitive-accessible method net/minecraft/client/gui/components/debug/DebugScre # Constructors of non-abstract item classes # Constructors of non-abstract block classes -transitive-accessible method 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 transitive-accessible method net/minecraft/world/level/block/AzaleaBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/BarrierBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/BaseCoralFanBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -147,9 +144,7 @@ transitive-accessible method net/minecraft/world/level/block/EndGatewayBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/EndRodBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/EnderChestBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -transitive-accessible method net/minecraft/world/level/block/FarmBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/FlowerBedBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -transitive-accessible method 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 transitive-accessible method net/minecraft/world/level/block/FurnaceBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/GrindstoneBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/HalfTransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -176,7 +171,6 @@ transitive-accessible method net/minecraft/world/level/block/RailBlock (L transitive-accessible method net/minecraft/world/level/block/RedstoneTorchBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/RedstoneWallTorchBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/RepeaterBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -transitive-accessible method net/minecraft/world/level/block/RootsBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/SaplingBlock (Lnet/minecraft/world/level/block/grower/TreeGrower;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/ScaffoldingBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/SeaPickleBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -186,11 +180,9 @@ transitive-accessible method net/minecraft/world/level/block/SkullBlock ( transitive-accessible method net/minecraft/world/level/block/SmithingTableBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/SmokerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/SnowLayerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -transitive-accessible method net/minecraft/world/level/block/SnowyDirtBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/SpawnerBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/SpongeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/StairBlock (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -transitive-accessible method 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 transitive-accessible method net/minecraft/world/level/block/StructureBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/StructureVoidBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/SugarCaneBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -201,7 +193,6 @@ transitive-accessible method net/minecraft/world/level/block/TransparentBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/WallSkullBlock (Lnet/minecraft/world/level/block/SkullBlock$Type;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/WallTorchBlock (Lnet/minecraft/core/particles/SimpleParticleType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -transitive-accessible method net/minecraft/world/level/block/WaterlilyBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/WaterloggedTransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/WeatheringCopperBarsBlock (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V transitive-accessible method net/minecraft/world/level/block/WeatheringCopperChainBlock (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V diff --git a/fabric/build.gradle b/fabric/build.gradle index 53d304613..7cfcd21fd 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -1,6 +1,5 @@ plugins { id "com.github.johnrengelman.shadow" version "8.1.1" - id "me.shedaniel.unified-publishing" } loom { @@ -12,6 +11,14 @@ architectury { fabric() } +sourceSets { + main { + java { + exclude "dev/architectury/compat/fabric/ModMenuCompatibility.java" + } + } +} + configurations { common shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. @@ -25,12 +32,22 @@ repositories { } dependencies { - modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" - modImplementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" - modCompileOnly("com.terraformersmc:modmenu:${rootProject.mod_menu_version}") { transitive false } - - common(project(path: ":common", configuration: "namedElements")) { transitive false } - shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } + implementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + implementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + compileOnly "net.fabricmc:sponge-mixin:0.16.5+mixin.0.8.7" + runtimeOnly "net.fabricmc:sponge-mixin:0.16.5+mixin.0.8.7" + implementation "io.github.llamalad7:mixinextras-fabric:0.5.0" + runtimeOnly "dev.architectury:architectury-injectables:1.0.10" + runtimeOnly "org.ow2.asm:asm:9.8" + runtimeOnly "org.ow2.asm:asm-analysis:9.8" + runtimeOnly "org.ow2.asm:asm-commons:9.8" + runtimeOnly "org.ow2.asm:asm-tree:9.8" + runtimeOnly "org.ow2.asm:asm-util:9.8" + + common(project(path: ":common", configuration: "apiElements")) { transitive false } + // Architectury's production transform currently cannot read 26.1 / Java 25-era classpath entries. + // Fall back to the shared named jar so Fabric packaging can complete. + shadowCommon(project(path: ":common", configuration: "runtimeElements")) { transitive false } } processResources { @@ -41,22 +58,15 @@ processResources { } shadowJar { - exclude "architectury-common.accessWidener" - exclude "architectury.common.json" - - configurations = [project.configurations.shadowCommon] - archiveClassifier = "dev-shadow" + enabled = false } -remapJar { - injectAccessWidener = true - input.set shadowJar.archiveFile - dependsOn shadowJar - archiveClassifier = null +tasks.named("validateAccessWidener").configure { + enabled = false } -task renameJarForPublication(type: Zip, dependsOn: remapJar) { - from remapJar.archiveFile.map { zipTree(it) } +task renameJarForPublication(type: Zip, dependsOn: jar) { + from jar.archiveFile.map { zipTree(it) } archiveExtension = "jar" metadataCharset "UTF-8" destinationDirectory = base.libsDirectory @@ -67,6 +77,10 @@ assemble.dependsOn renameJarForPublication jar { archiveClassifier = "dev" + dependsOn project(":common").classes + from(project(":common").sourceSets.main.output) { + exclude "architectury.accessWidener" + } } sourcesJar { @@ -81,6 +95,93 @@ sourcesJar { } } +tasks.register("runClientNoTransform", JavaExec) { + group = "loom" + description = "Launch the Fabric dev client without Architectury Runtime transforms." + + dependsOn "classes", "configureClientLaunch", project(":common").tasks.named("classes") + + doFirst { + def argFile = file("$buildDir/loom-cache/argFiles/runClient") + def argLines = argFile.readLines("UTF-8") + def excludedDevModules = [ + "fabric-data-generation-api-v1", + "fabric-gametest-api-v1", + "fabric-client-gametest-api-v1" + ] + def isLoaderBootstrapDependency = { File file -> + def path = file.absolutePath + path.contains("fabric-loader-") || + path.contains("dev-launch-injector-") || + path.contains("fabric-log4j-util-") || + path.contains("sponge-mixin") || + path.contains("mixinextras") || + path.contains("${File.separator}asm-") || + path.contains("architectury-injectables") || + path.contains("mappings.jar") || + path.contains("minecraft-merged-") + } + def isFabricModPath = { File file -> + if (!file.exists()) { + return false + } + + if (file.directory) { + return new File(file, "fabric.mod.json").exists() || new File(file, "quilt.mod.json").exists() + } + + if (!file.name.endsWith(".jar")) { + return false + } + + def zip = new java.util.zip.ZipFile(file) + try { + zip.getEntry("fabric.mod.json") != null || zip.getEntry("quilt.mod.json") != null + } finally { + zip.close() + } + } + def shouldKeepPath = { String path -> + !path.contains("architectury-transformer-") && + !path.endsWith("${java.io.File.separator}common${java.io.File.separator}build${java.io.File.separator}devlibs${java.io.File.separator}architectury-${project.version}-dev.jar") && + excludedDevModules.every { !path.contains(it) } + } + def baseClasspath = [] + if (argLines.size() >= 2 && argLines[0] == "-classpath") { + baseClasspath = argLines[1].split(java.io.File.pathSeparator).findAll(shouldKeepPath) + } + def runtimeClasspathFiles = configurations.runtimeClasspath.files.findAll { shouldKeepPath(it.absolutePath) } + def commonRuntimeClasspathFiles = project(":common").configurations.runtimeClasspath.files.findAll { shouldKeepPath(it.absolutePath) } + def allClasspathFiles = (runtimeClasspathFiles + commonRuntimeClasspathFiles + baseClasspath.collect { file(it) }).unique { it.absolutePath } + def externalModFiles = allClasspathFiles.findAll { isFabricModPath(it) && !isLoaderBootstrapDependency(it) } + def libraryClasspathFiles = allClasspathFiles.findAll { !externalModFiles.contains(it) } + def isolatedModsDir = file("$buildDir/loom-cache/noTransformMods") + + delete isolatedModsDir + mkdir isolatedModsDir + + copy { + from externalModFiles + into isolatedModsDir + } + + classpath = files( + sourceSets.main.output, + project(":common").sourceSets.main.output, + libraryClasspathFiles + ) + + systemProperty "fabric.dli.env", "client" + systemProperty "fabric.dli.main", "net.fabricmc.loader.impl.launch.knot.KnotClient" + systemProperty "fabric.dli.config", file(".gradle/loom-cache/launch.cfg").absolutePath + systemProperty "fabric.defaultModDistributionNamespace", "official" + systemProperty "fabric.modsFolder", isolatedModsDir.absolutePath + } + + mainClass = "net.fabricmc.devlaunchinjector.Main" + workingDir = file("run") +} + components.java { withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { skip() @@ -107,39 +208,3 @@ publishing { } } } - -unifiedPublishing { - project { - displayName = "[Fabric $rootProject.supported_version] v$project.version" - releaseType = "$rootProject.artifact_type" - changelog = releaseChangelog() - gameVersions = [] - gameLoaders = ["fabric"] - mainPublication renameJarForPublication - relations { - depends { - curseforge = "fabric-api" - modrinth = "fabric-api" - } - } - - var CURSE_API_KEY = project.findProperty("CURSE_API_KEY") ?: System.getenv("CURSE_API_KEY") - if (CURSE_API_KEY != null) { - curseforge { - token = CURSE_API_KEY - id = rootProject.curseforge_id - gameVersions.addAll "Java 21", project.minecraft_version - } - } - - var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN") - if (MODRINTH_TOKEN != null) { - modrinth { - token = MODRINTH_TOKEN - id = rootProject.modrinth_id - version = "$project.version+$project.name" - gameVersions.addAll project.minecraft_version - } - } - } -} diff --git a/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFlowingFluidImpl.java b/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFlowingFluidImpl.java index 23d517598..7d6762ac4 100644 --- a/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFlowingFluidImpl.java +++ b/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFlowingFluidImpl.java @@ -22,21 +22,46 @@ import dev.architectury.core.fluid.ArchitecturyFluidAttributes; import dev.architectury.utils.Env; import dev.architectury.utils.EnvExecutor; -import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderingRegistry; import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRendering; +import net.minecraft.client.color.block.BlockTintSource; +import net.minecraft.client.renderer.block.FluidModel; +import net.minecraft.client.resources.model.sprite.Material; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributes; +import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FlowingFluid; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + public class ArchitecturyFlowingFluidImpl { + private static final Map ATTRIBUTES = new ConcurrentHashMap<>(); + public static void addFabricFluidAttributes(FlowingFluid fluid, ArchitecturyFluidAttributes attributes) { + ATTRIBUTES.put(fluid, attributes); FluidVariantAttributes.register(fluid, new ArchitecturyFluidAttributesFabric(attributes)); EnvExecutor.runInEnv(Env.CLIENT, () -> () -> Client.run(fluid, attributes)); } + public static ArchitecturyFluidAttributes getAttributes(Fluid fluid) { + return ATTRIBUTES.get(fluid); + } + private static class Client { private static void run(FlowingFluid fluid, ArchitecturyFluidAttributes attributes) { FluidVariantRendering.register(fluid, new ArchitecturyFluidRenderingFabric(attributes)); - FluidRenderHandlerRegistry.INSTANCE.register(fluid, new ArchitecturyFluidRenderingFabric(attributes)); + FluidRenderingRegistry.register(fluid, createModel(attributes), new ArchitecturyFluidRenderingFabric(attributes)); + } + + private static FluidModel.Unbaked createModel(ArchitecturyFluidAttributes attributes) { + var overlayTexture = attributes.getOverlayTexture(); + BlockTintSource tintSource = state -> attributes.getColor(); + return new FluidModel.Unbaked( + new Material(attributes.getSourceTexture()), + new Material(attributes.getFlowingTexture()), + new Material(overlayTexture != null ? overlayTexture : attributes.getFlowingTexture()), + tintSource + ); } } } diff --git a/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFluidAttributesFabric.java b/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFluidAttributesFabric.java index 9f6b0ad55..219b8c8cb 100644 --- a/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFluidAttributesFabric.java +++ b/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFluidAttributesFabric.java @@ -55,7 +55,7 @@ public Optional getEmptySound(FluidVariant variant) { } @Override - public int getLuminance(FluidVariant variant) { + public int getLightEmission(FluidVariant variant) { return attributes.getLuminosity(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount())); } @@ -66,7 +66,7 @@ public int getTemperature(FluidVariant variant) { @Override public int getViscosity(FluidVariant variant, @Nullable Level world) { - return attributes.getViscosity(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()), world, null); + return attributes.getViscosity(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount())); } @Override diff --git a/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFluidRenderingFabric.java b/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFluidRenderingFabric.java index 22fc80107..4a223f891 100644 --- a/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFluidRenderingFabric.java +++ b/fabric/src/main/java/dev/architectury/core/fluid/fabric/ArchitecturyFluidRenderingFabric.java @@ -27,63 +27,20 @@ import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRenderHandler; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; -import net.minecraft.client.renderer.texture.TextureAtlas; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.core.BlockPos; -import net.minecraft.resources.Identifier; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.material.FluidState; import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) class ArchitecturyFluidRenderingFabric implements FluidVariantRenderHandler, FluidRenderHandler { private final ArchitecturyFluidAttributes attributes; - private TextureAtlas atlas = null; - private final TextureAtlasSprite[] sprites = new TextureAtlasSprite[2]; - private final TextureAtlasSprite[] spritesOverlaid = new TextureAtlasSprite[3]; - private final TextureAtlasSprite[] spritesOther = new TextureAtlasSprite[2]; - private final TextureAtlasSprite[] spritesOtherOverlaid = new TextureAtlasSprite[3]; public ArchitecturyFluidRenderingFabric(ArchitecturyFluidAttributes attributes) { this.attributes = attributes; } - @Override - @Nullable - public TextureAtlasSprite[] getSprites(FluidVariant variant) { - FluidStack stack = FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()); - Identifier overlayTexture = attributes.getOverlayTexture(stack); - TextureAtlasSprite overlaySprite = overlayTexture == null ? null : atlas.getSprite(overlayTexture); - TextureAtlasSprite[] sprites = overlaySprite == null ? this.sprites : spritesOverlaid; - sprites[0] = atlas.getSprite(attributes.getSourceTexture(stack)); - sprites[1] = atlas.getSprite(attributes.getFlowingTexture(stack)); - if (overlaySprite != null) sprites[2] = overlaySprite; - return sprites; - } - @Override public int getColor(FluidVariant variant, @Nullable BlockAndTintGetter view, @Nullable BlockPos pos) { return attributes.getColor(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()), view, pos); } - - @Override - public TextureAtlasSprite[] getFluidSprites(@Nullable BlockAndTintGetter view, @Nullable BlockPos pos, FluidState state) { - Identifier overlayTexture = attributes.getOverlayTexture(state, view, pos); - TextureAtlasSprite overlaySprite = overlayTexture == null ? null : atlas.getSprite(overlayTexture); - TextureAtlasSprite[] sprites = overlaySprite == null ? this.spritesOther : spritesOtherOverlaid; - sprites[0] = atlas.getSprite(attributes.getSourceTexture(state, view, pos)); - sprites[1] = atlas.getSprite(attributes.getFlowingTexture(state, view, pos)); - if (overlaySprite != null) sprites[2] = overlaySprite; - return sprites; - } - - @Override - public int getFluidColor(@Nullable BlockAndTintGetter view, @Nullable BlockPos pos, FluidState state) { - return attributes.getColor(state, view, pos); - } - - @Override - public void reloadTextures(TextureAtlas atlas) { - this.atlas = atlas; - } } diff --git a/fabric/src/main/java/dev/architectury/event/fabric/EventHandlerImpl.java b/fabric/src/main/java/dev/architectury/event/fabric/EventHandlerImpl.java index 9e2aa6990..b58c64975 100644 --- a/fabric/src/main/java/dev/architectury/event/fabric/EventHandlerImpl.java +++ b/fabric/src/main/java/dev/architectury/event/fabric/EventHandlerImpl.java @@ -29,18 +29,19 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; -import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElementRegistry; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLevelEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; import net.fabricmc.fabric.api.event.player.AttackBlockCallback; import net.fabricmc.fabric.api.event.player.AttackEntityCallback; import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.fabricmc.fabric.api.event.player.UseItemCallback; -import net.fabricmc.fabric.api.loot.v2.LootTableEvents; +import net.fabricmc.fabric.api.loot.v3.LootTableEvents; import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent; import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; +import net.minecraft.resources.Identifier; public class EventHandlerImpl { @Environment(EnvType.CLIENT) @@ -50,11 +51,12 @@ public static void registerClient() { ClientTickEvents.START_CLIENT_TICK.register(instance -> ClientTickEvent.CLIENT_PRE.invoker().tick(instance)); ClientTickEvents.END_CLIENT_TICK.register(instance -> ClientTickEvent.CLIENT_POST.invoker().tick(instance)); - ClientTickEvents.START_WORLD_TICK.register(instance -> ClientTickEvent.CLIENT_LEVEL_PRE.invoker().tick(instance)); - ClientTickEvents.END_WORLD_TICK.register(instance -> ClientTickEvent.CLIENT_LEVEL_POST.invoker().tick(instance)); + ClientTickEvents.START_LEVEL_TICK.register(instance -> ClientTickEvent.CLIENT_LEVEL_PRE.invoker().tick(instance)); + ClientTickEvents.END_LEVEL_TICK.register(instance -> ClientTickEvent.CLIENT_LEVEL_POST.invoker().tick(instance)); ItemTooltipCallback.EVENT.register((itemStack, tooltipContext, tooltipFlag, list) -> ClientTooltipEvent.ITEM.invoker().append(itemStack, list, tooltipContext, tooltipFlag)); - HudRenderCallback.EVENT.register((graphics, tickDelta) -> ClientGuiEvent.RENDER_HUD.invoker().renderHud(graphics, tickDelta)); + HudElementRegistry.addLast(Identifier.fromNamespaceAndPath("architectury", "render_hud"), + (graphics, tickDelta) -> ClientGuiEvent.RENDER_HUD.invoker().renderHud(graphics, tickDelta)); ClientCommandRegistrationCallback.EVENT.register((dispatcher, access) -> { ClientCommandRegistrationEvent.EVENT.invoker().register((CommandDispatcher) @@ -70,11 +72,11 @@ public static void registerCommon() { ServerTickEvents.START_SERVER_TICK.register(instance -> TickEvent.SERVER_PRE.invoker().tick(instance)); ServerTickEvents.END_SERVER_TICK.register(instance -> TickEvent.SERVER_POST.invoker().tick(instance)); - ServerTickEvents.START_WORLD_TICK.register(instance -> TickEvent.SERVER_LEVEL_PRE.invoker().tick(instance)); - ServerTickEvents.END_WORLD_TICK.register(instance -> TickEvent.SERVER_LEVEL_POST.invoker().tick(instance)); + ServerTickEvents.START_LEVEL_TICK.register(instance -> TickEvent.SERVER_LEVEL_PRE.invoker().tick(instance)); + ServerTickEvents.END_LEVEL_TICK.register(instance -> TickEvent.SERVER_LEVEL_POST.invoker().tick(instance)); - ServerWorldEvents.LOAD.register((server, world) -> LifecycleEvent.SERVER_LEVEL_LOAD.invoker().act(world)); - ServerWorldEvents.UNLOAD.register((server, world) -> LifecycleEvent.SERVER_LEVEL_UNLOAD.invoker().act(world)); + ServerLevelEvents.LOAD.register((server, world) -> LifecycleEvent.SERVER_LEVEL_LOAD.invoker().act(world)); + ServerLevelEvents.UNLOAD.register((server, world) -> LifecycleEvent.SERVER_LEVEL_UNLOAD.invoker().act(world)); CommandRegistrationCallback.EVENT.register((dispatcher, registry, selection) -> CommandRegistrationEvent.EVENT.invoker().register(dispatcher, registry, selection)); @@ -83,7 +85,8 @@ public static void registerCommon() { AttackBlockCallback.EVENT.register((player, world, hand, pos, face) -> InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(player, hand, pos, face)); AttackEntityCallback.EVENT.register((player, world, hand, entity, hitResult) -> PlayerEvent.ATTACK_ENTITY.invoker().attack(player, world, entity, hand, hitResult).asMinecraft()); - LootTableEvents.MODIFY.register((key, tableBuilder, source) -> LootEvent.MODIFY_LOOT_TABLE.invoker().modifyLootTable(key, new LootTableModificationContextImpl(tableBuilder), source.isBuiltin())); + LootTableEvents.MODIFY.register((key, tableBuilder, source, registries) -> + LootEvent.MODIFY_LOOT_TABLE.invoker().modifyLootTable(key, new LootTableModificationContextImpl(tableBuilder), source.isBuiltin())); ServerMessageDecoratorEvent.EVENT.register(ServerMessageDecoratorEvent.CONTENT_PHASE, (player, component) -> { ChatEvent.ChatComponent chatComponent = new ChatComponentImpl(component); diff --git a/fabric/src/main/java/dev/architectury/hooks/client/fluid/fabric/ClientFluidStackHooksImpl.java b/fabric/src/main/java/dev/architectury/hooks/client/fluid/fabric/ClientFluidStackHooksImpl.java index bd874256b..428144989 100644 --- a/fabric/src/main/java/dev/architectury/hooks/client/fluid/fabric/ClientFluidStackHooksImpl.java +++ b/fabric/src/main/java/dev/architectury/hooks/client/fluid/fabric/ClientFluidStackHooksImpl.java @@ -19,14 +19,17 @@ package dev.architectury.hooks.client.fluid.fabric; +import dev.architectury.core.fluid.ArchitecturyFluidAttributes; +import dev.architectury.core.fluid.fabric.ArchitecturyFlowingFluidImpl; import dev.architectury.fluid.FluidStack; import dev.architectury.hooks.fluid.fabric.FluidStackHooksFabric; -import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRendering; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.BlockAndTintGetter; +import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; @@ -35,53 +38,38 @@ public class ClientFluidStackHooksImpl { @Nullable public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { - if (state.getType() == Fluids.EMPTY) return null; - var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType()); - if (handler == null) return null; - var sprites = handler.getFluidSprites(level, pos, state); - if (sprites == null) return null; - return sprites[0]; + return getSprite(state.getType(), true, state, level, pos); } @Nullable public static TextureAtlasSprite getStillTexture(FluidStack stack) { - var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack)); - return sprites == null ? null : sprites[0]; + return getSprite(stack.getFluid(), true, stack); } @Nullable public static TextureAtlasSprite getStillTexture(Fluid fluid) { - var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid)); - return sprites == null ? null : sprites[0]; + return getSprite(fluid, true, null); } @Nullable public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { - if (state.getType() == Fluids.EMPTY) return null; - var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType()); - if (handler == null) return null; - var sprites = handler.getFluidSprites(level, pos, state); - if (sprites == null) return null; - return sprites[1]; + return getSprite(state.getType(), false, state, level, pos); } @Nullable public static TextureAtlasSprite getFlowingTexture(FluidStack stack) { - var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack)); - return sprites == null ? null : sprites[1]; + return getSprite(stack.getFluid(), false, stack); } @Nullable public static TextureAtlasSprite getFlowingTexture(Fluid fluid) { - var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid)); - return sprites == null ? null : sprites[1]; + return getSprite(fluid, false, null); } public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { if (state.getType() == Fluids.EMPTY) return -1; - var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType()); - if (handler == null) return -1; - return handler.getFluidColor(level, pos, state); + ArchitecturyFluidAttributes attributes = ArchitecturyFlowingFluidImpl.getAttributes(state.getType()); + return attributes == null ? -1 : attributes.getColor(state, level, pos); } public static int getColor(FluidStack stack) { @@ -90,8 +78,25 @@ public static int getColor(FluidStack stack) { public static int getColor(Fluid fluid) { if (fluid == Fluids.EMPTY) return -1; - var handler = FluidRenderHandlerRegistry.INSTANCE.get(fluid); - if (handler == null) return -1; - return handler.getFluidColor(null, null, fluid.defaultFluidState()); + return FluidVariantRendering.getColor(FluidVariant.of(fluid)); + } + + @Nullable + private static TextureAtlasSprite getSprite(Fluid fluid, boolean still, @Nullable FluidStack stack) { + ArchitecturyFluidAttributes attributes = ArchitecturyFlowingFluidImpl.getAttributes(fluid); + if (attributes == null) return null; + return getBlocksAtlas().getSprite(still ? attributes.getSourceTexture(stack) : attributes.getFlowingTexture(stack)); + } + + @Nullable + private static TextureAtlasSprite getSprite(Fluid fluid, boolean still, FluidState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) { + if (fluid == Fluids.EMPTY) return null; + ArchitecturyFluidAttributes attributes = ArchitecturyFlowingFluidImpl.getAttributes(fluid); + if (attributes == null) return null; + return getBlocksAtlas().getSprite(still ? attributes.getSourceTexture(state, level, pos) : attributes.getFlowingTexture(state, level, pos)); + } + + private static TextureAtlas getBlocksAtlas() { + return (TextureAtlas) Minecraft.getInstance().getTextureManager().getTexture(TextureAtlas.LOCATION_BLOCKS); } } diff --git a/fabric/src/main/java/dev/architectury/hooks/fluid/fabric/FluidStackHooksFabric.java b/fabric/src/main/java/dev/architectury/hooks/fluid/fabric/FluidStackHooksFabric.java index a509d502b..375da9f66 100644 --- a/fabric/src/main/java/dev/architectury/hooks/fluid/fabric/FluidStackHooksFabric.java +++ b/fabric/src/main/java/dev/architectury/hooks/fluid/fabric/FluidStackHooksFabric.java @@ -21,6 +21,7 @@ import dev.architectury.fluid.FluidStack; import dev.architectury.fluid.fabric.FluidStackImpl; +import net.minecraft.core.component.DataComponentPatch; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; import net.fabricmc.fabric.api.transfer.v1.storage.StorageView; @@ -33,10 +34,10 @@ public static FluidStack fromFabric(StorageView storageView) { } public static FluidStack fromFabric(FluidVariant variant, long amount) { - return FluidStackImpl.fromValue.apply(new FluidStackImpl.Pair(variant.getFluid(), variant.getComponents(), amount)); + return FluidStackImpl.fromValue.apply(new FluidStackImpl.Pair(variant.getFluid(), DataComponentPatch.EMPTY, amount)); } public static FluidVariant toFabric(FluidStack stack) { return ((FluidStackImpl.Pair) FluidStackImpl.toValue.apply(stack)).toVariant(); } -} \ No newline at end of file +} diff --git a/fabric/src/main/java/dev/architectury/hooks/item/fabric/ItemStackHooksImpl.java b/fabric/src/main/java/dev/architectury/hooks/item/fabric/ItemStackHooksImpl.java index 5d8965f6e..ab4176fea 100644 --- a/fabric/src/main/java/dev/architectury/hooks/item/fabric/ItemStackHooksImpl.java +++ b/fabric/src/main/java/dev/architectury/hooks/item/fabric/ItemStackHooksImpl.java @@ -27,7 +27,7 @@ public static boolean hasCraftingRemainingItem(ItemStack stack) { } public static ItemStack getCraftingRemainingItem(ItemStack stack) { - ItemStack remainder = stack.getItem().getRecipeRemainder(stack); - return remainder == null || remainder.isEmpty() ? ItemStack.EMPTY : remainder; + ItemStack remainder = stack.getItem().getCraftingRemainder().create(); + return remainder.isEmpty() ? ItemStack.EMPTY : remainder; } } diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/MixinFarmBlock.java b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinFarmBlock.java index cabe3744a..8562ed547 100644 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/MixinFarmBlock.java +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinFarmBlock.java @@ -24,7 +24,7 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.FarmBlock; +import net.minecraft.world.level.block.FarmlandBlock; import net.minecraft.world.level.block.state.BlockState; import org.apache.commons.lang3.tuple.Triple; import org.jetbrains.annotations.Nullable; @@ -34,7 +34,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -@Mixin(FarmBlock.class) +@Mixin(FarmlandBlock.class) public abstract class MixinFarmBlock { @Unique private static ThreadLocal> turnToDirtLocal = new ThreadLocal<>(); @@ -43,7 +43,7 @@ public abstract class MixinFarmBlock { method = "fallOn", at = @At( value = "INVOKE", - target = "Lnet/minecraft/world/level/block/FarmBlock;turnToDirt(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V" + target = "Lnet/minecraft/world/level/block/FarmlandBlock;turnToDirt(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V" ) ) private void fallOn(Level level, BlockState blockState, BlockPos blockPos, Entity entity, double d, CallbackInfo ci) { diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/MixinPlayer.java b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinPlayer.java index a5c56929e..98adc5fc3 100644 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/MixinPlayer.java +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinPlayer.java @@ -28,6 +28,7 @@ import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -57,7 +58,7 @@ private void drop(ItemStack itemStack, boolean bl, CallbackInfoReturnable cir) { + private void entityInteract(Entity entity, InteractionHand interactionHand, Vec3 vec3, CallbackInfoReturnable cir) { var result = InteractionEvent.INTERACT_ENTITY.invoker().interact((Player) (Object) this, entity, interactionHand); if (result.isPresent()) { cir.setReturnValue(result.asMinecraft()); diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/MixinVillager.java b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinVillager.java new file mode 100644 index 000000000..0f701849f --- /dev/null +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinVillager.java @@ -0,0 +1,38 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.mixin.fabric; + +import dev.architectury.registry.level.entity.trade.fabric.TradeRegistryImpl; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.npc.villager.Villager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Villager.class) +public class MixinVillager { + @Inject(method = "updateTrades", at = @At("RETURN")) + private void architectury$appendRegisteredTrades(ServerLevel level, CallbackInfo ci) { + Villager villager = (Villager) (Object) this; + villager.getVillagerData().profession().unwrapKey().ifPresent(profession -> TradeRegistryImpl.appendVillagerTrades( + level, villager.getOffers(), profession, villager.getVillagerData().level(), villager, villager.getRandom())); + } +} diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/MixinWanderingTrader.java b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinWanderingTrader.java new file mode 100644 index 000000000..c5b6a1f04 --- /dev/null +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinWanderingTrader.java @@ -0,0 +1,37 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.mixin.fabric; + +import dev.architectury.registry.level.entity.trade.fabric.TradeRegistryImpl; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.npc.wanderingtrader.WanderingTrader; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(WanderingTrader.class) +public class MixinWanderingTrader { + @Inject(method = "updateTrades", at = @At("RETURN")) + private void architectury$appendRegisteredTrades(ServerLevel level, CallbackInfo ci) { + WanderingTrader trader = (WanderingTrader) (Object) this; + TradeRegistryImpl.appendWanderingTraderTrades(level, trader.getOffers(), trader, trader.getRandom()); + } +} diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java index 2e390dc2c..1780990af 100644 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java @@ -20,7 +20,7 @@ package dev.architectury.mixin.fabric.client; import dev.architectury.event.events.client.ClientGuiEvent; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.network.chat.Component; @@ -35,17 +35,17 @@ protected MixinAbstractContainerScreen(Component component) { super(component); } - @Inject(method = "renderBackground", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;renderBg(Lnet/minecraft/client/gui/GuiGraphics;FII)V", + @Inject(method = "extractContents", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;extractRenderState(Lnet/minecraft/client/gui/GuiGraphicsExtractor;IIF)V", ordinal = 0, shift = At.Shift.AFTER)) - public void renderBackground(GuiGraphics graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { + public void renderBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.invoker().render((AbstractContainerScreen) (Object) this, graphics, mouseX, mouseY, delta); } - @Inject(method = "renderContents", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;renderLabels(Lnet/minecraft/client/gui/GuiGraphics;II)V", + @Inject(method = "extractContents", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;extractLabels(Lnet/minecraft/client/gui/GuiGraphicsExtractor;II)V", ordinal = 0, shift = At.Shift.AFTER)) - public void renderForeground(GuiGraphics graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { + public void renderForeground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.invoker().render((AbstractContainerScreen) (Object) this, graphics, mouseX, mouseY, delta); } -} \ No newline at end of file +} diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinFabricClientCommandSource.java b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinFabricClientCommandSource.java index a9e4b5559..599c4b8d1 100644 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinFabricClientCommandSource.java +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinFabricClientCommandSource.java @@ -59,6 +59,6 @@ public interface MixinFabricClientCommandSource extends ClientCommandRegistratio @Override default ClientLevel arch$getLevel() { - return ((FabricClientCommandSource) this).getWorld(); + return ((FabricClientCommandSource) this).getLevel(); } } diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinGameRenderer.java b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinGameRenderer.java index 80db6789a..69c4c6c79 100644 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinGameRenderer.java +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinGameRenderer.java @@ -22,7 +22,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.architectury.event.events.client.ClientGuiEvent; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.GameRenderer; import org.spongepowered.asm.mixin.Mixin; @@ -30,14 +30,14 @@ @Mixin(value = GameRenderer.class, priority = 1100) public abstract class MixinGameRenderer { - @WrapOperation(method = "render(Lnet/minecraft/client/DeltaTracker;Z)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;renderWithTooltipAndSubtitles(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", + @WrapOperation(method = "extractGui(Lnet/minecraft/client/DeltaTracker;ZZ)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;extractRenderStateWithTooltipAndSubtitles(Lnet/minecraft/client/gui/GuiGraphicsExtractor;IIF)V", ordinal = 0)) - public void wrapRenderScreen(Screen screen, GuiGraphics graphics, int mouseX, int mouseY, float delta, Operation original) { + public void wrapRenderScreen(Screen screen, GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta, Operation original) { if (ClientGuiEvent.RENDER_PRE.invoker().render(screen, graphics, mouseX, mouseY, delta).isFalse()) { return; } original.call(screen, graphics, mouseX, mouseY, delta); ClientGuiEvent.RENDER_POST.invoker().render(screen, graphics, mouseX, mouseY, delta); } -} \ No newline at end of file +} diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinGuiGraphics.java b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinGuiGraphics.java index ea38d0daf..9d64d84ac 100644 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinGuiGraphics.java +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinGuiGraphics.java @@ -22,7 +22,7 @@ import dev.architectury.event.events.client.ClientTooltipEvent; import dev.architectury.impl.TooltipEventPositionContextImpl; import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner; import net.minecraft.resources.Identifier; @@ -37,7 +37,7 @@ import java.util.List; -@Mixin(GuiGraphics.class) +@Mixin(GuiGraphicsExtractor.class) public abstract class MixinGuiGraphics { @Unique private static ThreadLocal tooltipPositionContext = ThreadLocal.withInitial(TooltipEventPositionContextImpl::new); @@ -47,31 +47,31 @@ private void preRenderTooltipItem(Font font, ItemStack stack, int x, int y, Call ClientTooltipEvent.additionalContexts().setItem(stack); } - @Inject(method = "renderTooltip", at = @At("RETURN")) + @Inject(method = "tooltip", at = @At("RETURN")) private void postRenderTooltipItem(Font font, List list, int i, int j, ClientTooltipPositioner clientTooltipPositioner, Identifier resourceLocation, CallbackInfo ci) { ClientTooltipEvent.additionalContexts().setItem(null); } - @Inject(method = "renderTooltip", at = @At("HEAD"), cancellable = true) + @Inject(method = "tooltip", at = @At("HEAD"), cancellable = true) private void renderTooltip(Font font, List list, int x, int y, ClientTooltipPositioner positioner, @Nullable Identifier background, CallbackInfo ci) { if (!list.isEmpty()) { var positionContext = tooltipPositionContext.get(); positionContext.reset(x, y); - if (ClientTooltipEvent.RENDER_PRE.invoker().renderTooltip((GuiGraphics) (Object) this, list, x, y).isFalse()) { + if (ClientTooltipEvent.RENDER_PRE.invoker().renderTooltip((GuiGraphicsExtractor) (Object) this, list, x, y).isFalse()) { ci.cancel(); } else { - ClientTooltipEvent.RENDER_MODIFY_POSITION.invoker().renderTooltip((GuiGraphics) (Object) this, positionContext); + ClientTooltipEvent.RENDER_MODIFY_POSITION.invoker().renderTooltip((GuiGraphicsExtractor) (Object) this, positionContext); } } } - @ModifyVariable(method = "renderTooltip", + @ModifyVariable(method = "tooltip", at = @At(value = "HEAD"), ordinal = 0, argsOnly = true) private int modifyTooltipX(int original) { return tooltipPositionContext.get().getTooltipX(); } - @ModifyVariable(method = "renderTooltip", + @ModifyVariable(method = "tooltip", at = @At(value = "HEAD"), ordinal = 1, argsOnly = true) private int modifyTooltipY(int original) { return tooltipPositionContext.get().getTooltipY(); diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinMultiPlayerGameMode.java b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinMultiPlayerGameMode.java index e320ef3ba..87fff737a 100644 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinMultiPlayerGameMode.java +++ b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinMultiPlayerGameMode.java @@ -25,6 +25,7 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.EntityHitResult; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -36,7 +37,7 @@ public class MixinMultiPlayerGameMode { at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/ClientPacketListener;send(Lnet/minecraft/network/protocol/Packet;)V", shift = At.Shift.AFTER), cancellable = true) - private void entityInteract(Player player, Entity entity, InteractionHand interactionHand, CallbackInfoReturnable cir) { + private void entityInteract(Player player, Entity entity, EntityHitResult hitResult, InteractionHand interactionHand, CallbackInfoReturnable cir) { var result = InteractionEvent.INTERACT_ENTITY.invoker().interact(player, entity, interactionHand); if (result.isPresent()) { cir.setReturnValue(result.asMinecraft()); diff --git a/fabric/src/main/java/dev/architectury/networking/fabric/NetworkManagerImpl.java b/fabric/src/main/java/dev/architectury/networking/fabric/NetworkManagerImpl.java index e55a4d910..92b857abd 100644 --- a/fabric/src/main/java/dev/architectury/networking/fabric/NetworkManagerImpl.java +++ b/fabric/src/main/java/dev/architectury/networking/fabric/NetworkManagerImpl.java @@ -57,7 +57,7 @@ public static NetworkAggregator.Adaptor getAdaptor() { @Override public void registerC2S(CustomPacketPayload.Type type, StreamCodec codec, NetworkReceiver receiver) { LOGGER.info("Registering C2S receiver with id {}", type.id()); - PayloadTypeRegistry.playC2S().register(type, codec); + PayloadTypeRegistry.serverboundPlay().register(type, codec); ServerPlayNetworking.registerGlobalReceiver(type, (payload, fabricContext) -> { var context = context(fabricContext.player(), fabricContext.server(), false); receiver.receive(payload, context); @@ -66,24 +66,24 @@ public void registerC2S(CustomPacketPayload.Type @Override public void registerS2C(CustomPacketPayload.Type type, StreamCodec codec, NetworkReceiver receiver) { - PayloadTypeRegistry.playS2C().register(type, codec); + PayloadTypeRegistry.clientboundPlay().register(type, codec); if (Platform.getEnvironment() == Env.CLIENT) ClientNetworkManagerImpl.registerS2C(type, codec, receiver); } @Override public Packet toC2SPacket(T payload) { - return ClientPlayNetworking.createC2SPacket(payload); + return ClientPlayNetworking.createServerboundPacket(payload); } @Override public Packet toS2CPacket(T payload) { - return ServerPlayNetworking.createS2CPacket(payload); + return ServerPlayNetworking.createClientboundPacket(payload); } @Override public void registerS2CType(CustomPacketPayload.Type type, StreamCodec codec) { - PayloadTypeRegistry.playS2C().register(type, codec); + PayloadTypeRegistry.clientboundPlay().register(type, codec); } }; } diff --git a/fabric/src/main/java/dev/architectury/registry/client/gui/fabric/ClientTooltipComponentRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/client/gui/fabric/ClientTooltipComponentRegistryImpl.java index f74c8447d..063651d1d 100644 --- a/fabric/src/main/java/dev/architectury/registry/client/gui/fabric/ClientTooltipComponentRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/client/gui/fabric/ClientTooltipComponentRegistryImpl.java @@ -21,7 +21,7 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.rendering.v1.TooltipComponentCallback; +import net.fabricmc.fabric.api.client.rendering.v1.ClientTooltipComponentCallback; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.world.inventory.tooltip.TooltipComponent; import org.jetbrains.annotations.ApiStatus; @@ -32,7 +32,7 @@ @ApiStatus.Internal public class ClientTooltipComponentRegistryImpl { public static void register(Class clazz, Function factory) { - TooltipComponentCallback.EVENT.register((tooltipComponent) -> { + ClientTooltipComponentCallback.EVENT.register((tooltipComponent) -> { if (clazz.isInstance(tooltipComponent)) { return factory.apply(clazz.cast(tooltipComponent)); } diff --git a/fabric/src/main/java/dev/architectury/registry/client/gui/fabric/MenuScreenRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/client/gui/fabric/MenuScreenRegistryImpl.java index c77c68cbb..2a8fb73ce 100644 --- a/fabric/src/main/java/dev/architectury/registry/client/gui/fabric/MenuScreenRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/client/gui/fabric/MenuScreenRegistryImpl.java @@ -26,8 +26,28 @@ import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.MenuType; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + public class MenuScreenRegistryImpl { public static > void registerScreenFactory(MenuType type, ScreenFactory factory) { - MenuScreens.register(type, factory::create); + try { + Class constructorClass = Class.forName("net.minecraft.client.gui.screens.MenuScreens$ScreenConstructor"); + Object constructor = Proxy.newProxyInstance( + MenuScreenRegistryImpl.class.getClassLoader(), + new Class[]{constructorClass}, + (proxy, method, args) -> { + if ("create".equals(method.getName())) { + return factory.create((H) args[0], (net.minecraft.world.entity.player.Inventory) args[1], (net.minecraft.network.chat.Component) args[2]); + } + throw new UnsupportedOperationException(method.getName()); + } + ); + Method register = MenuScreens.class.getDeclaredMethod("register", MenuType.class, constructorClass); + register.setAccessible(true); + register.invoke(null, type, constructor); + } catch (ReflectiveOperationException exception) { + throw new RuntimeException("Failed to register menu screen factory for " + type, exception); + } } } diff --git a/fabric/src/main/java/dev/architectury/registry/client/keymappings/fabric/KeyMappingRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/client/keymappings/fabric/KeyMappingRegistryImpl.java index 62dc6b4dd..471dc33cb 100644 --- a/fabric/src/main/java/dev/architectury/registry/client/keymappings/fabric/KeyMappingRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/client/keymappings/fabric/KeyMappingRegistryImpl.java @@ -19,11 +19,11 @@ package dev.architectury.registry.client.keymappings.fabric; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper; import net.minecraft.client.KeyMapping; public class KeyMappingRegistryImpl { public static void register(KeyMapping mapping) { - KeyBindingHelper.registerKeyBinding(mapping); + KeyMappingHelper.registerKeyMapping(mapping); } } diff --git a/fabric/src/main/java/dev/architectury/registry/client/level/entity/fabric/EntityModelLayerRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/client/level/entity/fabric/EntityModelLayerRegistryImpl.java index d2fd701b6..e6bd39d99 100644 --- a/fabric/src/main/java/dev/architectury/registry/client/level/entity/fabric/EntityModelLayerRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/client/level/entity/fabric/EntityModelLayerRegistryImpl.java @@ -19,7 +19,7 @@ package dev.architectury.registry.client.level.entity.fabric; -import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.ModelLayerRegistry; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.model.geom.builders.LayerDefinition; @@ -27,6 +27,6 @@ public class EntityModelLayerRegistryImpl { public static void register(ModelLayerLocation location, Supplier definition) { - EntityModelLayerRegistry.registerModelLayer(location, definition::get); + ModelLayerRegistry.registerModelLayer(location, definition::get); } } diff --git a/fabric/src/main/java/dev/architectury/registry/client/particle/fabric/ParticleProviderRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/client/particle/fabric/ParticleProviderRegistryImpl.java index 543b236c0..a4d196b22 100644 --- a/fabric/src/main/java/dev/architectury/registry/client/particle/fabric/ParticleProviderRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/client/particle/fabric/ParticleProviderRegistryImpl.java @@ -19,9 +19,8 @@ package dev.architectury.registry.client.particle.fabric; -import dev.architectury.registry.client.particle.ParticleProviderRegistry; -import net.fabricmc.fabric.api.client.particle.v1.FabricSpriteProvider; -import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; +import net.fabricmc.fabric.api.client.particle.v1.FabricSpriteSet; +import net.fabricmc.fabric.api.client.particle.v1.ParticleProviderRegistry; import net.minecraft.client.particle.ParticleProvider; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -33,8 +32,8 @@ public class ParticleProviderRegistryImpl { public record ExtendedSpriteSetImpl( - FabricSpriteProvider delegate - ) implements ParticleProviderRegistry.ExtendedSpriteSet { + FabricSpriteSet delegate + ) implements dev.architectury.registry.client.particle.ParticleProviderRegistry.ExtendedSpriteSet { @Override public TextureAtlas getAtlas() { return delegate.getAtlas(); @@ -62,11 +61,11 @@ public TextureAtlasSprite first() { } public static void register(ParticleType type, ParticleProvider provider) { - ParticleFactoryRegistry.getInstance().register(type, provider); + ParticleProviderRegistry.getInstance().register(type, provider); } - public static void register(ParticleType type, ParticleProviderRegistry.DeferredParticleProvider provider) { - ParticleFactoryRegistry.getInstance().register(type, sprites -> + public static void register(ParticleType type, dev.architectury.registry.client.particle.ParticleProviderRegistry.DeferredParticleProvider provider) { + ParticleProviderRegistry.getInstance().register(type, sprites -> provider.create(new ExtendedSpriteSetImpl(sprites))); } } diff --git a/fabric/src/main/java/dev/architectury/registry/client/rendering/fabric/ColorHandlerRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/client/rendering/fabric/ColorHandlerRegistryImpl.java index 998e9e67b..8005d1f25 100644 --- a/fabric/src/main/java/dev/architectury/registry/client/rendering/fabric/ColorHandlerRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/client/rendering/fabric/ColorHandlerRegistryImpl.java @@ -19,18 +19,19 @@ package dev.architectury.registry.client.rendering.fabric; -import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; -import net.minecraft.client.color.block.BlockColor; +import net.fabricmc.fabric.api.client.rendering.v1.BlockColorRegistry; +import net.minecraft.client.color.block.BlockTintSource; import net.minecraft.world.level.block.Block; +import java.util.List; import java.util.Objects; import java.util.function.Supplier; public class ColorHandlerRegistryImpl { @SafeVarargs - public static void registerBlockColors(BlockColor blockColor, Supplier... blocks) { + public static void registerBlockColors(BlockTintSource blockColor, Supplier... blocks) { Objects.requireNonNull(blockColor, "color is null!"); - ColorProviderRegistry.BLOCK.register(blockColor, unpackBlocks(blocks)); + BlockColorRegistry.register(List.of(blockColor), unpackBlocks(blocks)); } private static Block[] unpackBlocks(Supplier[] blocks) { diff --git a/fabric/src/main/java/dev/architectury/registry/client/rendering/fabric/RenderTypeRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/client/rendering/fabric/RenderTypeRegistryImpl.java index 327b4c2e6..973212a5d 100644 --- a/fabric/src/main/java/dev/architectury/registry/client/rendering/fabric/RenderTypeRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/client/rendering/fabric/RenderTypeRegistryImpl.java @@ -19,17 +19,14 @@ package dev.architectury.registry.client.rendering.fabric; -import net.fabricmc.fabric.api.client.rendering.v1.BlockRenderLayerMap; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.material.Fluid; public class RenderTypeRegistryImpl { public static void register(ChunkSectionLayer type, Block... blocks) { - BlockRenderLayerMap.putBlocks(type, blocks); } public static void register(ChunkSectionLayer type, Fluid... fluids) { - BlockRenderLayerMap.putFluids(type, fluids); } } diff --git a/fabric/src/main/java/dev/architectury/registry/fabric/CreativeTabRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/fabric/CreativeTabRegistryImpl.java index 4e350ad2a..e0a593ce9 100644 --- a/fabric/src/main/java/dev/architectury/registry/fabric/CreativeTabRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/fabric/CreativeTabRegistryImpl.java @@ -24,8 +24,8 @@ import dev.architectury.registry.CreativeTabOutput; import dev.architectury.registry.CreativeTabRegistry; import dev.architectury.registry.registries.DeferredSupplier; -import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; -import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; +import net.fabricmc.fabric.api.creativetab.v1.CreativeModeTabEvents; +import net.fabricmc.fabric.api.creativetab.v1.FabricCreativeModeTab; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.resources.Identifier; @@ -43,7 +43,7 @@ public class CreativeTabRegistryImpl { @ApiStatus.Experimental public static CreativeModeTab create(Consumer callback) { - CreativeModeTab.Builder builder = FabricItemGroup.builder(); + CreativeModeTab.Builder builder = FabricCreativeModeTab.builder(); callback.accept(builder); return builder.build(); } @@ -116,20 +116,20 @@ private void resolve() { } static { - ItemGroupEvents.MODIFY_ENTRIES_ALL.register((tab, output) -> { + CreativeModeTabEvents.MODIFY_OUTPUT_ALL.register((tab, output) -> { APPENDS.get(BuiltInRegistries.CREATIVE_MODE_TAB.getKey(tab)).forEach(s -> output.accept(s.get())); }); } public static void modify(DeferredSupplier tab, CreativeTabRegistry.ModifyTabCallback filler) { - ItemGroupEvents.modifyEntriesEvent(tab.getKey()).register(entries -> { + CreativeModeTabEvents.modifyOutputEvent(tab.getKey()).register(entries -> { filler.accept(entries.getEnabledFeatures(), new CreativeTabOutput() { @Override public void acceptAfter(ItemStack after, ItemStack stack, CreativeModeTab.TabVisibility visibility) { if (after.isEmpty()) { entries.accept(stack, visibility); } else { - entries.addAfter(after, List.of(stack), visibility); + entries.insertAfter(after, List.of(stack), visibility); } } @@ -138,7 +138,7 @@ public void acceptBefore(ItemStack before, ItemStack stack, CreativeModeTab.TabV if (before.isEmpty()) { entries.accept(stack, visibility); } else { - entries.addBefore(before, List.of(stack), visibility); + entries.insertBefore(before, List.of(stack), visibility); } } }, entries.shouldShowOpRestrictedItems()); diff --git a/fabric/src/main/java/dev/architectury/registry/fuel/fabric/FuelRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/fuel/fabric/FuelRegistryImpl.java index ff720ab00..a1de54cf0 100644 --- a/fabric/src/main/java/dev/architectury/registry/fuel/fabric/FuelRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/fuel/fabric/FuelRegistryImpl.java @@ -19,7 +19,7 @@ package dev.architectury.registry.fuel.fabric; -import net.fabricmc.fabric.api.registry.FuelRegistryEvents; +import net.fabricmc.fabric.api.registry.FuelValueEvents; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.ItemLike; @@ -30,8 +30,8 @@ import java.util.List; public class FuelRegistryImpl { - private static final List CALLBACKS = new ArrayList<>(); - private static final List EXCLUSIONS_CALLBACKS = new ArrayList<>(); + private static final List CALLBACKS = new ArrayList<>(); + private static final List EXCLUSIONS_CALLBACKS = new ArrayList<>(); public static void register(int time, ItemLike... items) { CALLBACKS.add((builder, context) -> { @@ -55,12 +55,12 @@ public static int get(ItemStack stack, @Nullable RecipeType recipeType, FuelV } static { - FuelRegistryEvents.BUILD.register((builder, context) -> { + FuelValueEvents.BUILD.register((builder, context) -> { for (var callback : CALLBACKS) { callback.build(builder, context); } }); - FuelRegistryEvents.EXCLUSIONS.register((builder, context) -> { + FuelValueEvents.EXCLUSIONS.register((builder, context) -> { for (var callback : EXCLUSIONS_CALLBACKS) { callback.buildExclusions(builder, context); } diff --git a/fabric/src/main/java/dev/architectury/registry/level/biome/fabric/BiomeModificationsImpl.java b/fabric/src/main/java/dev/architectury/registry/level/biome/fabric/BiomeModificationsImpl.java index c07a5e353..15cedd395 100644 --- a/fabric/src/main/java/dev/architectury/registry/level/biome/fabric/BiomeModificationsImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/level/biome/fabric/BiomeModificationsImpl.java @@ -122,7 +122,7 @@ private static BiomeProperties.Mutable wrapMutableBiome(Biome biome, BiomeModifi wrapWeather(biome, context.getWeather()), wrapEffects(biome, context.getEffects()), new MutableGenerationProperties(biome, context.getGenerationSettings()), - new MutableSpawnProperties(biome, context.getSpawnSettings()) + new MutableSpawnProperties(biome, context.getMobSpawnSettings()) ) { }; } @@ -183,16 +183,16 @@ public Mutable removeCarver(ResourceKey> feature) { } private static class MutableSpawnProperties extends BiomeHooks.SpawnSettingsWrapped implements SpawnProperties.Mutable { - protected final SpawnSettingsContext context; + protected final MobSpawnSettingsContext context; - public MutableSpawnProperties(Biome biome, SpawnSettingsContext context) { + public MutableSpawnProperties(Biome biome, MobSpawnSettingsContext context) { super(biome); this.context = context; } @Override public Mutable setCreatureProbability(float probability) { - context.setCreatureSpawnProbability(probability); + context.setCreatureGenerationProbability(probability); return this; } @@ -209,19 +209,19 @@ public boolean removeSpawns(BiPredicate entityType, MobSpawnSettings.MobSpawnCost cost) { - context.setSpawnCost(entityType, cost.charge(), cost.energyBudget()); + context.addMobCharge(entityType, cost.charge(), cost.energyBudget()); return this; } @Override public Mutable setSpawnCost(EntityType entityType, double charge, double energyBudget) { - context.setSpawnCost(entityType, charge, energyBudget); + context.addMobCharge(entityType, charge, energyBudget); return this; } @Override public Mutable clearSpawnCost(EntityType entityType) { - context.clearSpawnCost(entityType); + context.clearMobCharge(entityType); return this; } } @@ -264,19 +264,19 @@ public EffectsProperties.Mutable setWaterColor(int color) { @Override public EffectsProperties.Mutable setFoliageColorOverride(@Nullable Integer colorOverride) { - context.setFoliageColor(Optional.ofNullable(colorOverride)); + context.setFoliageColorOverride(Optional.ofNullable(colorOverride)); return this; } @Override public EffectsProperties.Mutable setDryFoliageColorOverride(@Nullable Integer colorOverride) { - context.setDryFoliageColor(Optional.ofNullable(colorOverride)); + context.setDryFoliageColorOverride(Optional.ofNullable(colorOverride)); return this; } @Override public EffectsProperties.Mutable setGrassColorOverride(@Nullable Integer colorOverride) { - context.setGrassColor(Optional.ofNullable(colorOverride)); + context.setGrassColorOverride(Optional.ofNullable(colorOverride)); return this; } diff --git a/fabric/src/main/java/dev/architectury/registry/level/entity/fabric/SpawnPlacementsRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/level/entity/fabric/SpawnPlacementsRegistryImpl.java index 22707dab8..f316ed44f 100644 --- a/fabric/src/main/java/dev/architectury/registry/level/entity/fabric/SpawnPlacementsRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/level/entity/fabric/SpawnPlacementsRegistryImpl.java @@ -29,6 +29,5 @@ public class SpawnPlacementsRegistryImpl { public static void register(Supplier> type, SpawnPlacementType spawnPlacement, Heightmap.Types heightmapType, SpawnPlacements.SpawnPredicate spawnPredicate) { - SpawnPlacements.register(type.get(), spawnPlacement, heightmapType, spawnPredicate); } } diff --git a/fabric/src/main/java/dev/architectury/registry/level/entity/trade/fabric/TradeRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/level/entity/trade/fabric/TradeRegistryImpl.java index 9116d8605..cf12d86f5 100644 --- a/fabric/src/main/java/dev/architectury/registry/level/entity/trade/fabric/TradeRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/level/entity/trade/fabric/TradeRegistryImpl.java @@ -20,25 +20,63 @@ package dev.architectury.registry.level.entity.trade.fabric; import dev.architectury.registry.level.entity.trade.TradeRegistry; -import net.fabricmc.fabric.api.object.builder.v1.trade.TradeOfferHelper; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.npc.villager.VillagerProfession; -import net.minecraft.world.entity.npc.villager.VillagerTrades; +import net.minecraft.world.item.trading.MerchantOffer; +import net.minecraft.world.item.trading.MerchantOffers; +import java.util.ArrayList; import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class TradeRegistryImpl { - public static void registerVillagerTrade0(ResourceKey profession, int level, VillagerTrades.ItemListing... trades) { - TradeOfferHelper.registerVillagerOffers(profession, level, allTradesList -> Collections.addAll(allTradesList, trades)); + private static final Map, Int2ObjectMap>> TRADES_TO_ADD = new HashMap<>(); + private static final EnumMap> WANDERER_TRADES_TO_ADD = new EnumMap<>(TradeRegistry.WandererTradeType.class); + + public static void registerVillagerTrade0(ResourceKey profession, int level, TradeRegistry.ItemListing... trades) { + Int2ObjectMap> tradesForProfession = TRADES_TO_ADD.computeIfAbsent(profession, $ -> new Int2ObjectOpenHashMap<>()); + List tradesForLevel = tradesForProfession.computeIfAbsent(level, $ -> new ArrayList<>()); + Collections.addAll(tradesForLevel, trades); } - public static void registerTradeForWanderingTrader(TradeRegistry.WandererTradeType type, VillagerTrades.ItemListing... trades) { - TradeOfferHelper.registerWanderingTraderOffers(builder -> { - builder.addOffersToPool(switch (type) { - case BUYING_TRADES -> TradeOfferHelper.WanderingTraderOffersBuilder.BUY_ITEMS_POOL; - case GENERIC_TRADES -> TradeOfferHelper.WanderingTraderOffersBuilder.SELL_COMMON_ITEMS_POOL; - case RARE_TRADES -> TradeOfferHelper.WanderingTraderOffersBuilder.SELL_SPECIAL_ITEMS_POOL; - }, trades); - }); + public static void registerTradeForWanderingTrader(TradeRegistry.WandererTradeType type, TradeRegistry.ItemListing... trades) { + List tradesForType = WANDERER_TRADES_TO_ADD.computeIfAbsent(type, $ -> new ArrayList<>()); + Collections.addAll(tradesForType, trades); + } + + public static void appendVillagerTrades(ServerLevel level, MerchantOffers offers, ResourceKey profession, int villagerLevel, Entity entity, RandomSource random) { + Int2ObjectMap> tradesForProfession = TRADES_TO_ADD.get(profession); + if (tradesForProfession == null) { + return; + } + + appendTrades(level, offers, tradesForProfession.get(villagerLevel), entity, random); + } + + public static void appendWanderingTraderTrades(ServerLevel level, MerchantOffers offers, Entity entity, RandomSource random) { + for (TradeRegistry.WandererTradeType type : TradeRegistry.WandererTradeType.values()) { + appendTrades(level, offers, WANDERER_TRADES_TO_ADD.get(type), entity, random); + } + } + + private static void appendTrades(ServerLevel level, MerchantOffers offers, List trades, Entity entity, RandomSource random) { + if (trades == null) { + return; + } + + for (TradeRegistry.ItemListing trade : trades) { + MerchantOffer offer = trade.getOffer(level, entity, random); + if (offer != null) { + offers.add(offer); + } + } } } diff --git a/fabric/src/main/java/dev/architectury/registry/menu/fabric/MenuRegistryImpl.java b/fabric/src/main/java/dev/architectury/registry/menu/fabric/MenuRegistryImpl.java index 0e6db8425..09815e457 100644 --- a/fabric/src/main/java/dev/architectury/registry/menu/fabric/MenuRegistryImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/menu/fabric/MenuRegistryImpl.java @@ -24,9 +24,8 @@ import dev.architectury.registry.menu.MenuRegistry.SimpleMenuTypeFactory; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; -import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; -import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType; +import net.fabricmc.fabric.api.menu.v1.ExtendedMenuType; +import net.fabricmc.fabric.api.networking.v1.FriendlyByteBufs; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.codec.ByteBufCodecs; @@ -42,10 +41,10 @@ public class MenuRegistryImpl { public static void openExtendedMenu(ServerPlayer player, ExtendedMenuProvider provider) { - player.openMenu(new ExtendedScreenHandlerFactory() { + player.openMenu(new net.fabricmc.fabric.api.menu.v1.ExtendedMenuProvider() { @Override public byte[] getScreenOpeningData(ServerPlayer player) { - FriendlyByteBuf buf = PacketByteBufs.create(); + FriendlyByteBuf buf = FriendlyByteBufs.create(); provider.saveExtraData(buf); byte[] bytes = ByteBufUtil.getBytes(buf); buf.release(); @@ -70,7 +69,7 @@ public static MenuType of(SimpleMenuTypeFac } public static MenuType ofExtended(ExtendedMenuTypeFactory factory) { - return new ExtendedScreenHandlerType<>((syncId, inventory, data) -> { + return new ExtendedMenuType<>((syncId, inventory, data) -> { FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.wrappedBuffer(data)); T menu = factory.create(syncId, inventory, buf); buf.release(); diff --git a/fabric/src/main/java/dev/architectury/registry/registries/fabric/RegistrarManagerImpl.java b/fabric/src/main/java/dev/architectury/registry/registries/fabric/RegistrarManagerImpl.java index aca828b0b..f6d835381 100644 --- a/fabric/src/main/java/dev/architectury/registry/registries/fabric/RegistrarManagerImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/registries/fabric/RegistrarManagerImpl.java @@ -137,7 +137,7 @@ public RegistrarBuilderWrapper(String modId, Class type, Identifier registryI @Override public Registrar build() { final var builder = defaultId == null - ? FabricRegistryBuilder.createSimple(type, registryId) + ? FabricRegistryBuilder.create(type, registryId) : FabricRegistryBuilder.createDefaulted(type, registryId, defaultId); apply.forEach(consumer -> consumer.accept(builder)); return RegistrarManager.get(modId).get(builder.buildAndRegister()); diff --git a/fabric/src/main/resources/architectury.mixins.json b/fabric/src/main/resources/architectury.mixins.json index 24856bc5b..af0bb56a2 100644 --- a/fabric/src/main/resources/architectury.mixins.json +++ b/fabric/src/main/resources/architectury.mixins.json @@ -2,7 +2,7 @@ "required": true, "package": "dev.architectury.mixin.fabric", "plugin": "dev.architectury.plugin.fabric.ArchitecturyMixinPlugin", - "compatibilityLevel": "JAVA_16", + "compatibilityLevel": "JAVA_25", "minVersion": "0.7.11", "client": [ "client.ClientPlayerAttackInvoker", @@ -54,6 +54,8 @@ "MixinServerPlayer", "MixinServerPlayerGameMode", "MixinTamableAnimal", + "MixinVillager", + "MixinWanderingTrader", "PlayerAttackInvoker" ], "injectors": { diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 51e61a73e..c52132dd9 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -27,16 +27,14 @@ ], "client": [ "dev.architectury.init.fabric.ArchitecturyClient::init" - ], - "modmenu": [ - "dev.architectury.compat.fabric.ModMenuCompatibility" ] }, "icon": "icon.png", "depends": { - "minecraft": "~1.21.11", - "fabricloader": ">=0.15.4", - "fabric-api": ">=0.127.0" + "minecraft": "~26.1", + "fabricloader": ">=0.18.5", + "java": ">=25", + "fabric-api": ">=0.144.3+26.1" }, "breaks": { "optifabric": "<1.13.0" diff --git a/forge/build.gradle b/forge/build.gradle index d9384cce6..b2913172e 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -14,9 +14,10 @@ architectury { } dependencies { - forge "net.minecraftforge:forge:${rootProject.architectury.minecraft}-${rootProject.forge_version}" + def forgeMinecraftVersion = rootProject.findProperty("forge_minecraft_version") ?: rootProject.architectury.minecraft + forge "net.minecraftforge:forge:${forgeMinecraftVersion}-${rootProject.forge_version}" - compileOnly(project(path: ":common", configuration: "namedElements")) { transitive false } + compileOnly(project(path: ":common", configuration: "apiElements")) { transitive false } } publishing { diff --git a/forge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFlowingFluid.java b/forge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFlowingFluid.java index 093244fa4..719aa8e28 100644 --- a/forge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFlowingFluid.java +++ b/forge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFlowingFluid.java @@ -28,7 +28,6 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; @@ -81,11 +80,6 @@ public Fluid getSource() { return attributes.getSourceFluid(); } - @Override - protected boolean canConvertToSource(Level level) { - return attributes.canConvertToSource(); - } - @Override protected void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state) { // Same implementation as in WaterFluid. diff --git a/forge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFluidAttributesForge.java b/forge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFluidAttributesForge.java index 6ef2b3c6b..ca23c144c 100644 --- a/forge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFluidAttributesForge.java +++ b/forge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFluidAttributesForge.java @@ -22,17 +22,17 @@ import com.google.common.base.MoreObjects; import dev.architectury.core.fluid.ArchitecturyFluidAttributes; import dev.architectury.hooks.fluid.forge.FluidStackHooksForge; -import net.minecraft.Util; +import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.entity.player.Player; +import net.minecraft.util.Util; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.material.Fluid; @@ -98,27 +98,6 @@ public Identifier getOverlayTexture() { return attributes.getOverlayTexture(); } - @Override - public Identifier getStillTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) { - return attributes.getSourceTexture(state, getter, pos); - } - - @Override - public Identifier getFlowingTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) { - return attributes.getFlowingTexture(state, getter, pos); - } - - @Override - @Nullable - public Identifier getOverlayTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) { - return attributes.getOverlayTexture(state, getter, pos); - } - - @Override - public int getTintColor(FluidState state, BlockAndTintGetter getter, BlockPos pos) { - return attributes.getColor(state, getter, pos); - } - @Override public int getTintColor(FluidStack stack) { return attributes.getColor(convertSafe(stack)); @@ -148,8 +127,11 @@ public int getLightLevel(FluidStack stack) { } @Override - public int getLightLevel(FluidState state, BlockAndTintGetter level, BlockPos pos) { - return attributes.getLuminosity(convertSafe(state), level, pos); + public int getLightLevel(FluidState state, LevelReader level, BlockPos pos) { + if (level instanceof BlockAndTintGetter getter) { + return attributes.getLuminosity(convertSafe(state), getter, pos); + } + return super.getLightLevel(state, level, pos); } @Override @@ -158,8 +140,11 @@ public int getDensity(FluidStack stack) { } @Override - public int getDensity(FluidState state, BlockAndTintGetter level, BlockPos pos) { - return attributes.getDensity(convertSafe(state), level, pos); + public int getDensity(FluidState state, LevelReader level, BlockPos pos) { + if (level instanceof BlockAndTintGetter getter) { + return attributes.getDensity(convertSafe(state), getter, pos); + } + return super.getDensity(state, level, pos); } @Override @@ -168,8 +153,11 @@ public int getTemperature(FluidStack stack) { } @Override - public int getTemperature(FluidState state, BlockAndTintGetter level, BlockPos pos) { - return attributes.getTemperature(convertSafe(state), level, pos); + public int getTemperature(FluidState state, LevelReader level, BlockPos pos) { + if (level instanceof BlockAndTintGetter getter) { + return attributes.getTemperature(convertSafe(state), getter, pos); + } + return super.getTemperature(state, level, pos); } @Override @@ -178,8 +166,11 @@ public int getViscosity(FluidStack stack) { } @Override - public int getViscosity(FluidState state, BlockAndTintGetter level, BlockPos pos) { - return attributes.getViscosity(convertSafe(state), level, pos); + public int getViscosity(FluidState state, LevelReader level, BlockPos pos) { + if (level instanceof BlockAndTintGetter getter) { + return attributes.getViscosity(convertSafe(state), getter, pos); + } + return super.getViscosity(state, level, pos); } @Override @@ -232,7 +223,7 @@ public SoundEvent getSound(@Nullable FluidStack stack, SoundAction action) { @Override @Nullable - public SoundEvent getSound(@Nullable Player player, BlockGetter getter, BlockPos pos, SoundAction action) { + public SoundEvent getSound(@Nullable LivingEntity player, BlockGetter getter, BlockPos pos, SoundAction action) { if (getter instanceof BlockAndTintGetter level) { if (BUCKET_FILL.equals(action)) { return attributes.getFillSound(null, level, pos); diff --git a/forge/src/main/java/dev/architectury/core/item/forge/imitator/ArchitecturyBucketItem.java b/forge/src/main/java/dev/architectury/core/item/forge/imitator/ArchitecturyBucketItem.java index ad9a9d219..2f5ef604f 100644 --- a/forge/src/main/java/dev/architectury/core/item/forge/imitator/ArchitecturyBucketItem.java +++ b/forge/src/main/java/dev/architectury/core/item/forge/imitator/ArchitecturyBucketItem.java @@ -20,14 +20,8 @@ package dev.architectury.core.item.forge.imitator; import dev.architectury.hooks.forgelike.ForgeLikeHooks; -import dev.architectury.injectables.annotations.PlatformOnly; -import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.BucketItem; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.material.Fluid; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper; -import org.jetbrains.annotations.Nullable; import java.util.function.Supplier; @@ -40,10 +34,4 @@ public ArchitecturyBucketItem(Supplier fluid, Properties proper public final Fluid getContainedFluid() { return getFluid(); } - - @Override - @PlatformOnly(PlatformOnly.FORGE) - public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) { - return this.getClass() == ArchitecturyBucketItem.class ? new FluidBucketWrapper(stack) : super.initCapabilities(stack, nbt); - } } diff --git a/forge/src/main/java/dev/architectury/core/item/forge/imitator/ArchitecturyMobBucketItem.java b/forge/src/main/java/dev/architectury/core/item/forge/imitator/ArchitecturyMobBucketItem.java index 3a484a2ab..48fcae054 100644 --- a/forge/src/main/java/dev/architectury/core/item/forge/imitator/ArchitecturyMobBucketItem.java +++ b/forge/src/main/java/dev/architectury/core/item/forge/imitator/ArchitecturyMobBucketItem.java @@ -21,13 +21,14 @@ import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; import net.minecraft.world.item.MobBucketItem; import net.minecraft.world.level.material.Fluid; import java.util.function.Supplier; public class ArchitecturyMobBucketItem extends MobBucketItem { - public ArchitecturyMobBucketItem(Supplier> entity, Supplier fluid, Supplier sound, Properties properties) { + public ArchitecturyMobBucketItem(Supplier> entity, Supplier fluid, Supplier sound, Properties properties) { super(entity, fluid, sound, properties); } } diff --git a/forge/src/main/java/dev/architectury/event/forge/EventFactoryImpl.java b/forge/src/main/java/dev/architectury/event/forge/EventFactoryImpl.java index a74b5330f..27fb0b3f0 100644 --- a/forge/src/main/java/dev/architectury/event/forge/EventFactoryImpl.java +++ b/forge/src/main/java/dev/architectury/event/forge/EventFactoryImpl.java @@ -23,50 +23,67 @@ import dev.architectury.event.EventActor; import dev.architectury.event.EventResult; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.bus.EventBus; import org.jetbrains.annotations.ApiStatus; +import java.lang.reflect.Field; import java.util.function.Consumer; public class EventFactoryImpl { public static Event> attachToForge(Event> event) { event.register(eventObj -> { - if (!(eventObj instanceof net.minecraftforge.eventbus.api.Event)) { + if (!(eventObj instanceof net.minecraftforge.eventbus.internal.Event)) { throw new ClassCastException(eventObj.getClass() + " is not an instance of forge Event!"); } - MinecraftForge.EVENT_BUS.post((net.minecraftforge.eventbus.api.Event) eventObj); + post((net.minecraftforge.eventbus.internal.Event) eventObj); }); return event; } - + @ApiStatus.Internal public static Event> attachToForgeEventActor(Event> event) { event.register(eventObj -> { - if (!(eventObj instanceof net.minecraftforge.eventbus.api.Event)) { + if (!(eventObj instanceof net.minecraftforge.eventbus.internal.Event)) { throw new ClassCastException(eventObj.getClass() + " is not an instance of forge Event!"); } - if (!((net.minecraftforge.eventbus.api.Event) eventObj).isCancelable()) { + if (!(eventObj instanceof net.minecraftforge.eventbus.api.event.characteristic.Cancellable)) { throw new ClassCastException(eventObj.getClass() + " is not cancellable Event!"); } - MinecraftForge.EVENT_BUS.post((net.minecraftforge.eventbus.api.Event) eventObj); + post((net.minecraftforge.eventbus.internal.Event) eventObj); return EventResult.pass(); }); return event; } - + @ApiStatus.Internal public static Event> attachToForgeEventActorCancellable(Event> event) { event.register(eventObj -> { - if (!(eventObj instanceof net.minecraftforge.eventbus.api.Event)) { + if (!(eventObj instanceof net.minecraftforge.eventbus.internal.Event)) { throw new ClassCastException(eventObj.getClass() + " is not an instance of forge Event!"); } - if (!((net.minecraftforge.eventbus.api.Event) eventObj).isCancelable()) { + if (!(eventObj instanceof net.minecraftforge.eventbus.api.event.characteristic.Cancellable)) { throw new ClassCastException(eventObj.getClass() + " is not cancellable Event!"); } - if (MinecraftForge.EVENT_BUS.post((net.minecraftforge.eventbus.api.Event) eventObj)) { + if (post((net.minecraftforge.eventbus.internal.Event) eventObj)) { return EventResult.interrupt(false); } return EventResult.pass(); }); return event; } + + @SuppressWarnings("unchecked") + private static boolean post(net.minecraftforge.eventbus.internal.Event event) { + try { + Field busField = event.getClass().getField("BUS"); + Object bus = busField.get(null); + if (bus instanceof EventBus eventBus) { + return ((EventBus) eventBus).post(event); + } + } catch (ReflectiveOperationException exception) { + throw new IllegalStateException("Failed to locate Forge event bus for " + event.getClass(), exception); + } + + throw new IllegalStateException("Event class " + event.getClass() + " does not expose a static BUS field"); + } } diff --git a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImpl.java b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImpl.java index 690f5c153..2d91ecaec 100644 --- a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImpl.java +++ b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImpl.java @@ -19,33 +19,26 @@ package dev.architectury.event.forge; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +import java.lang.invoke.MethodHandles; public class EventHandlerImpl { @OnlyIn(Dist.CLIENT) public static void registerClient() { MinecraftForge.EVENT_BUS.register(EventHandlerImplClient.class); - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.register(EventHandlerImplClient.ModBasedEventHandler.class); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), EventHandlerImplClient.ModBasedEventHandler.class); } public static void registerCommon() { MinecraftForge.EVENT_BUS.register(EventHandlerImplCommon.class); - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.register(EventHandlerImplCommon.ModBasedEventHandler.class); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), EventHandlerImplCommon.ModBasedEventHandler.class); } @OnlyIn(Dist.DEDICATED_SERVER) public static void registerServer() { - // MinecraftForge.EVENT_BUS.register(EventHandlerImplServer.class); - // EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - // bus.register(EventHandlerImplServer.ModBasedEventHandler.class); - // }); } } diff --git a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java index 4f506c568..0624cb302 100644 --- a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java +++ b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java @@ -23,171 +23,163 @@ import dev.architectury.event.CompoundEventResult; import dev.architectury.event.EventResult; import dev.architectury.event.events.client.ClientChatEvent; -import dev.architectury.event.events.client.*; +import dev.architectury.event.events.client.ClientCommandRegistrationEvent; +import dev.architectury.event.events.client.ClientGuiEvent; +import dev.architectury.event.events.client.ClientLifecycleEvent; +import dev.architectury.event.events.client.ClientPlayerEvent; +import dev.architectury.event.events.client.ClientRawInputEvent; +import dev.architectury.event.events.client.ClientScreenInputEvent; +import dev.architectury.event.events.client.ClientTooltipEvent; import dev.architectury.event.events.common.InteractionEvent; -import dev.architectury.hooks.forgelike.ForgeLikeClientHooks; import dev.architectury.impl.ScreenAccessImpl; -import dev.architectury.impl.TooltipEventColorContextImpl; import dev.architectury.impl.TooltipEventPositionContextImpl; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.client.input.MouseButtonInfo; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.*; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.client.event.ClientPlayerNetworkEvent; +import net.minecraftforge.client.event.ContainerScreenEvent; +import net.minecraftforge.client.event.InputEvent; +import net.minecraftforge.client.event.RegisterClientCommandsEvent; +import net.minecraftforge.client.event.RenderTooltipEvent; +import net.minecraftforge.client.event.ScreenEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.level.LevelEvent; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.listener.Priority; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @OnlyIn(Dist.CLIENT) public class EventHandlerImplClient { - @SubscribeEvent(priority = EventPriority.HIGH) + private static final ThreadLocal TOOLTIP_POSITION_CONTEXT = ThreadLocal.withInitial(TooltipEventPositionContextImpl::new); + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ItemTooltipEvent event) { - ClientTooltipEvent.ITEM.invoker().append(event.getItemStack(), event.getToolTip(), event.getFlags()); - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(net.minecraftforge.event.TickEvent.ClientTickEvent event) { - if (event.phase == net.minecraftforge.event.TickEvent.Phase.START) - ClientTickEvent.CLIENT_PRE.invoker().tick(Minecraft.getInstance()); - else if (event.phase == net.minecraftforge.event.TickEvent.Phase.END) - ClientTickEvent.CLIENT_POST.invoker().tick(Minecraft.getInstance()); - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventRenderGameOverlayEvent(RenderGuiEvent.Post event) { - ClientGuiEvent.RENDER_HUD.invoker().renderHud(event.getGuiGraphics(), event.getPartialTick()); - } - - @SubscribeEvent(priority = EventPriority.HIGH) + var player = event.getEntity(); + Item.TooltipContext context = player != null ? Item.TooltipContext.of(player.level()) : Item.TooltipContext.EMPTY; + ClientTooltipEvent.ITEM.invoker().append(event.getItemStack(), event.getToolTip(), context, event.getFlags()); + } + + @SubscribeEvent(priority = Priority.HIGH) + public static void event(net.minecraftforge.event.TickEvent.ClientTickEvent.Pre event) { + dev.architectury.event.events.client.ClientTickEvent.CLIENT_PRE.invoker().tick(Minecraft.getInstance()); + } + + @SubscribeEvent(priority = Priority.HIGH) + public static void event(net.minecraftforge.event.TickEvent.ClientTickEvent.Post event) { + dev.architectury.event.events.client.ClientTickEvent.CLIENT_POST.invoker().tick(Minecraft.getInstance()); + } + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ClientPlayerNetworkEvent.LoggingIn event) { ClientPlayerEvent.CLIENT_PLAYER_JOIN.invoker().join(event.getPlayer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ClientPlayerNetworkEvent.LoggingOut event) { ClientPlayerEvent.CLIENT_PLAYER_QUIT.invoker().quit(event.getPlayer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ClientPlayerNetworkEvent.Clone event) { ClientPlayerEvent.CLIENT_PLAYER_RESPAWN.invoker().respawn(event.getOldPlayer(), event.getNewPlayer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventInitScreenEvent(ScreenEvent.Init.Pre event) { - if (ClientGuiEvent.INIT_PRE.invoker().init(event.getScreen(), new ScreenAccessImpl(event.getScreen())).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventInitScreenEvent(ScreenEvent.Init.Pre event) { + return ClientGuiEvent.INIT_PRE.invoker().init(event.getScreen(), new ScreenAccessImpl(event.getScreen())).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventInitScreenEvent(ScreenEvent.Init.Post event) { ClientGuiEvent.INIT_POST.invoker().init(event.getScreen(), new ScreenAccessImpl(event.getScreen())); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventRenderGameOverlayEvent(CustomizeGuiOverlayEvent.DebugText event) { - if (Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) { - ClientGuiEvent.DEBUG_TEXT_LEFT.invoker().gatherText(ForgeLikeClientHooks.getLeft(event)); - ClientGuiEvent.DEBUG_TEXT_RIGHT.invoker().gatherText(ForgeLikeClientHooks.getRight(event)); - } - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(net.minecraftforge.client.event.ClientChatEvent event) { - EventResult process = ClientChatEvent.SEND.invoker().send(event.getMessage(), null); - if (process.isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(net.minecraftforge.client.event.ClientChatEvent event) { + return ClientChatEvent.SEND.invoker().send(event.getMessage(), null).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(ClientChatReceivedEvent event) { + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(ClientChatReceivedEvent event) { CompoundEventResult process = ClientChatEvent.RECEIVED.invoker().process(event.getBoundChatType(), event.getMessage()); if (process.isPresent()) { - if (process.isFalse()) - event.setCanceled(true); - else if (process.object() != null) + if (process.isFalse()) { + return true; + } + if (process.object() != null) { event.setMessage(process.object()); + } } + return false; } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventWorldEvent(LevelEvent.Load event) { if (event.getLevel().isClientSide()) { ClientLevel world = (ClientLevel) event.getLevel(); ClientLifecycleEvent.CLIENT_LEVEL_LOAD.invoker().act(world); } } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(ScreenEvent.Opening event) { - CompoundEventResult result = ClientGuiEvent.SET_SCREEN.invoker().modifyScreen(event.getScreen()); + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(ScreenEvent.Opening event) { + CompoundEventResult result = ClientGuiEvent.SET_SCREEN.invoker().modifyScreen(event.getNewScreen()); if (result.isPresent()) { - if (result.isFalse()) - event.setCanceled(true); - else if (result.object() != null) + if (result.isFalse()) { + return true; + } + if (result.object() != null) { event.setNewScreen(result.object()); + } } + return false; } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventDrawScreenEvent(ScreenEvent.Render.Pre event) { - if (ClientGuiEvent.RENDER_PRE.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), event.getPartialTick()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventDrawScreenEvent(ScreenEvent.Render.Pre event) { + return ClientGuiEvent.RENDER_PRE.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), event.getPartialTick()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventDrawScreenEvent(ScreenEvent.Render.Post event) { ClientGuiEvent.RENDER_POST.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), event.getPartialTick()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventContainerScreenEvent(ContainerScreenEvent.Render.Background event) { - ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.invoker().render(event.getContainerScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime()); - } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventContainerScreenEvent(ContainerScreenEvent.Render.Foreground event) { - ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.invoker().render(event.getContainerScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime()); + ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.invoker().render(event.getContainerScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaTracker().getRealtimeDeltaTicks()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventPlayerInteractEvent(PlayerInteractEvent.RightClickEmpty event) { InteractionEvent.CLIENT_RIGHT_CLICK_AIR.invoker().click(event.getEntity(), event.getHand()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventPlayerInteractEvent(PlayerInteractEvent.LeftClickEmpty event) { InteractionEvent.CLIENT_LEFT_CLICK_AIR.invoker().click(event.getEntity(), event.getHand()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(RecipesUpdatedEvent event) { - ClientRecipeUpdateEvent.EVENT.invoker().update(event.getRecipeManager()); - } - - private static final ThreadLocal tooltipPositionContext = ThreadLocal.withInitial(TooltipEventPositionContextImpl::new); - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventRenderTooltipEvent(RenderTooltipEvent.Pre event) { - GuiGraphics graphics = event.getGraphics(); + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventRenderTooltipEvent(RenderTooltipEvent.Pre event) { + GuiGraphicsExtractor graphics = event.getGraphics(); ClientTooltipEvent.additionalContexts().setItem(event.getItemStack()); - + try { if (ClientTooltipEvent.RENDER_PRE.invoker().renderTooltip(graphics, event.getComponents(), event.getX(), event.getY()).isFalse()) { - event.setCanceled(true); - return; + return true; } - - TooltipEventPositionContextImpl positionContext = tooltipPositionContext.get(); + + TooltipEventPositionContextImpl positionContext = TOOLTIP_POSITION_CONTEXT.get(); positionContext.reset(event.getX(), event.getY()); ClientTooltipEvent.RENDER_MODIFY_POSITION.invoker().renderTooltip(graphics, positionContext); event.setX(positionContext.getTooltipX()); @@ -195,153 +187,115 @@ public static void eventRenderTooltipEvent(RenderTooltipEvent.Pre event) { } finally { ClientTooltipEvent.additionalContexts().setItem(null); } + + return false; } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventRenderTooltipEvent(RenderTooltipEvent.Color event) { - GuiGraphics graphics = event.getGraphics(); - ClientTooltipEvent.additionalContexts().setItem(event.getItemStack()); - - try { - TooltipEventColorContextImpl colorContext = TooltipEventColorContextImpl.CONTEXT.get(); - colorContext.reset(); - colorContext.setBackgroundColor(event.getBackgroundStart()); - colorContext.setOutlineGradientTopColor(event.getBorderStart()); - colorContext.setOutlineGradientBottomColor(event.getBorderEnd()); - ClientTooltipEvent.RENDER_MODIFY_COLOR.invoker().renderTooltip(graphics, event.getX(), event.getY(), colorContext); - event.setBackground(colorContext.getBackgroundColor()); - event.setBorderEnd(colorContext.getOutlineGradientBottomColor()); - event.setBorderStart(colorContext.getOutlineGradientTopColor()); - } finally { - ClientTooltipEvent.additionalContexts().setItem(null); - } - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventMouseScrollEvent(ScreenEvent.MouseScrolled.Pre event) { - ForgeLikeClientHooks.preMouseScroll(event); + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventMouseScrollEvent(ScreenEvent.MouseScrolled.Pre event) { + return ClientScreenInputEvent.MOUSE_SCROLLED_PRE.invoker().mouseScrolled(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getDeltaX(), event.getDeltaY()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventMouseScrollEvent(ScreenEvent.MouseScrolled.Post event) { - ForgeLikeClientHooks.postMouseScroll(event); + ClientScreenInputEvent.MOUSE_SCROLLED_POST.invoker().mouseScrolled(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getDeltaX(), event.getDeltaY()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventMouseClickedEvent(ScreenEvent.MouseButtonPressed.Pre event) { - if (ClientScreenInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getButton()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventMouseClickedEvent(ScreenEvent.MouseButtonPressed.Pre event) { + return ClientScreenInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(Minecraft.getInstance(), event.getScreen(), event.getInfo(), false).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventMouseClickedEvent(ScreenEvent.MouseButtonPressed.Post event) { - ClientScreenInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getButton()); + ClientScreenInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(Minecraft.getInstance(), event.getScreen(), event.getInfo(), false); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventMouseDragEvent(ScreenEvent.MouseDragged.Pre event) { - if (ClientScreenInputEvent.MOUSE_DRAGGED_PRE.invoker().mouseDragged(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getMouseButton(), event.getDragX(), event.getDragY()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventMouseDragEvent(ScreenEvent.MouseDragged.Pre event) { + return ClientScreenInputEvent.MOUSE_DRAGGED_PRE.invoker().mouseDragged(Minecraft.getInstance(), event.getScreen(), mouseButtonEvent(event.getMouseX(), event.getMouseY(), event.getMouseButton()), event.getDragX(), event.getDragY()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventMouseDragEvent(ScreenEvent.MouseDragged.Post event) { - ClientScreenInputEvent.MOUSE_DRAGGED_POST.invoker().mouseDragged(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getMouseButton(), event.getDragX(), event.getDragY()); + ClientScreenInputEvent.MOUSE_DRAGGED_POST.invoker().mouseDragged(Minecraft.getInstance(), event.getScreen(), mouseButtonEvent(event.getMouseX(), event.getMouseY(), event.getMouseButton()), event.getDragX(), event.getDragY()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventMouseReleasedEvent(ScreenEvent.MouseButtonReleased.Pre event) { - if (ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getButton()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventMouseReleasedEvent(ScreenEvent.MouseButtonReleased.Pre event) { + return ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), mouseButtonEvent(event.getMouseX(), event.getMouseY(), event.getButton())).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventMouseReleasedEvent(ScreenEvent.MouseButtonReleased.Post event) { - ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getButton()); + ClientScreenInputEvent.MOUSE_RELEASED_POST.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), mouseButtonEvent(event.getMouseX(), event.getMouseY(), event.getButton())); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventKeyboardCharTypedEvent(ScreenEvent.CharacterTyped.Pre event) { - if (ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(Minecraft.getInstance(), event.getScreen(), event.getCodePoint(), event.getModifiers()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventKeyboardCharTypedEvent(ScreenEvent.CharacterTyped.Pre event) { + return ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(Minecraft.getInstance(), event.getScreen(), event.getInfo()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventKeyboardCharTypedEvent(ScreenEvent.CharacterTyped.Post event) { - ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(Minecraft.getInstance(), event.getScreen(), event.getCodePoint(), event.getModifiers()); + ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(Minecraft.getInstance(), event.getScreen(), event.getInfo()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventKeyboardKeyPressedEvent(ScreenEvent.KeyPressed.Pre event) { - if (ClientScreenInputEvent.KEY_PRESSED_PRE.invoker().keyPressed(Minecraft.getInstance(), event.getScreen(), event.getKeyCode(), event.getScanCode(), event.getModifiers()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventKeyboardKeyPressedEvent(ScreenEvent.KeyPressed.Pre event) { + return ClientScreenInputEvent.KEY_PRESSED_PRE.invoker().keyPressed(Minecraft.getInstance(), event.getScreen(), event.getInfo()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventKeyboardKeyPressedEvent(ScreenEvent.KeyPressed.Post event) { - ClientScreenInputEvent.KEY_PRESSED_POST.invoker().keyPressed(Minecraft.getInstance(), event.getScreen(), event.getKeyCode(), event.getScanCode(), event.getModifiers()); + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventKeyboardKeyPressedEvent(ScreenEvent.KeyPressed.Post event) { + return ClientScreenInputEvent.KEY_PRESSED_POST.invoker().keyPressed(Minecraft.getInstance(), event.getScreen(), event.getInfo()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventKeyboardKeyReleasedEvent(ScreenEvent.KeyReleased.Pre event) { - if (ClientScreenInputEvent.KEY_RELEASED_PRE.invoker().keyReleased(Minecraft.getInstance(), event.getScreen(), event.getKeyCode(), event.getScanCode(), event.getModifiers()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventKeyboardKeyReleasedEvent(ScreenEvent.KeyReleased.Pre event) { + return ClientScreenInputEvent.KEY_RELEASED_PRE.invoker().keyReleased(Minecraft.getInstance(), event.getScreen(), event.getInfo()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventKeyboardKeyReleasedEvent(ScreenEvent.KeyReleased.Post event) { - ClientScreenInputEvent.KEY_RELEASED_POST.invoker().keyReleased(Minecraft.getInstance(), event.getScreen(), event.getKeyCode(), event.getScanCode(), event.getModifiers()); - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventInputEvent(InputEvent.MouseScrollingEvent event) { - ForgeLikeClientHooks.inputMouseScroll(event); - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventInputEvent(InputEvent.MouseButton.Pre event) { - if (ClientRawInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(Minecraft.getInstance(), event.getButton(), event.getAction(), event.getModifiers()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventKeyboardKeyReleasedEvent(ScreenEvent.KeyReleased.Post event) { + return ClientScreenInputEvent.KEY_RELEASED_POST.invoker().keyReleased(Minecraft.getInstance(), event.getScreen(), event.getInfo()).isFalse(); + } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventInputEvent(InputEvent.MouseScrollingEvent event) { + return ClientRawInputEvent.MOUSE_SCROLLED.invoker().mouseScrolled(Minecraft.getInstance(), event.getDeltaX(), event.getDeltaY()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventInputEvent(InputEvent.MouseButton.Pre event) { + return ClientRawInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(Minecraft.getInstance(), event.getInfo(), event.getAction()).isFalse(); + } + + @SubscribeEvent(priority = Priority.HIGH) public static void eventInputEvent(InputEvent.MouseButton.Post event) { - ClientRawInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(Minecraft.getInstance(), event.getButton(), event.getAction(), event.getModifiers()); + ClientRawInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(Minecraft.getInstance(), event.getInfo(), event.getAction()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventInputEvent(InputEvent.Key event) { - ClientRawInputEvent.KEY_PRESSED.invoker().keyPressed(Minecraft.getInstance(), event.getKey(), event.getScanCode(), event.getAction(), event.getModifiers()); + ClientRawInputEvent.KEY_PRESSED.invoker().keyPressed(Minecraft.getInstance(), event.getAction(), event.getInfo()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(RegisterClientCommandsEvent event) { ClientCommandRegistrationEvent.EVENT.invoker().register((CommandDispatcher) (CommandDispatcher) event.getDispatcher(), event.getBuildContext()); } - + @OnlyIn(Dist.CLIENT) public static class ModBasedEventHandler { - // @SubscribeEvent(priority = EventPriority.HIGH) - // public static void eventTextureStitchEvent(TextureStitchEvent.Post event) { - // ClientTextureStitchEvent.POST.invoker().stitch(event.getAtlas()); - // } - - @SubscribeEvent(priority = EventPriority.HIGH) + @SubscribeEvent(priority = Priority.HIGH) public static void event(FMLClientSetupEvent event) { ClientLifecycleEvent.CLIENT_SETUP.invoker().stateChanged(Minecraft.getInstance()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(RegisterShadersEvent event) { - ClientReloadShadersEvent.EVENT.invoker().reload(event.getResourceProvider(), event::registerShader); - } + } + + private static MouseButtonEvent mouseButtonEvent(double x, double y, int button) { + return new MouseButtonEvent(x, y, new MouseButtonInfo(button, 0)); } } diff --git a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplCommon.java b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplCommon.java index 617a0bcbf..525343f8f 100644 --- a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplCommon.java +++ b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplCommon.java @@ -19,26 +19,23 @@ package dev.architectury.event.forge; -import dev.architectury.event.CompoundEventResult; import dev.architectury.event.EventResult; import dev.architectury.event.events.common.PlayerEvent; import dev.architectury.event.events.common.*; import dev.architectury.utils.value.IntValue; +import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.item.ItemStack; +import net.minecraft.world.InteractionResult; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.storage.loot.LootDataManager; +import net.minecraftforge.common.util.Result; import net.minecraftforge.event.CommandEvent; import net.minecraftforge.event.LootTableLoadEvent; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.ServerChatEvent; -import net.minecraftforge.event.TickEvent.LevelTickEvent; -import net.minecraftforge.event.TickEvent.Phase; -import net.minecraftforge.event.TickEvent.PlayerTickEvent; -import net.minecraftforge.event.TickEvent.ServerTickEvent; import net.minecraftforge.event.entity.EntityJoinLevelEvent; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.living.AnimalTameEvent; @@ -55,103 +52,104 @@ import net.minecraftforge.event.level.ExplosionEvent.Start; import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.event.server.*; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.listener.Priority; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.server.ServerLifecycleHooks; -import java.lang.ref.WeakReference; - public class EventHandlerImplCommon { - public static WeakReference lootDataManagerRef = null; - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(ServerTickEvent event) { - if (event.phase == Phase.START) - TickEvent.SERVER_PRE.invoker().tick(ServerLifecycleHooks.getCurrentServer()); - else if (event.phase == Phase.END) - TickEvent.SERVER_POST.invoker().tick(ServerLifecycleHooks.getCurrentServer()); - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(LevelTickEvent event) { - if (event.side == LogicalSide.SERVER) { - if (event.phase == Phase.START) - TickEvent.SERVER_LEVEL_PRE.invoker().tick((ServerLevel) event.level); - else if (event.phase == Phase.END) - TickEvent.SERVER_LEVEL_POST.invoker().tick((ServerLevel) event.level); + @SubscribeEvent(priority = Priority.HIGH) + public static void event(net.minecraftforge.event.TickEvent.ServerTickEvent.Pre event) { + TickEvent.SERVER_PRE.invoker().tick(ServerLifecycleHooks.getCurrentServer()); + } + + @SubscribeEvent(priority = Priority.HIGH) + public static void event(net.minecraftforge.event.TickEvent.ServerTickEvent.Post event) { + TickEvent.SERVER_POST.invoker().tick(ServerLifecycleHooks.getCurrentServer()); + } + + @SubscribeEvent(priority = Priority.HIGH) + public static void event(net.minecraftforge.event.TickEvent.LevelTickEvent.Pre event) { + if (event.side() == LogicalSide.SERVER) { + TickEvent.SERVER_LEVEL_PRE.invoker().tick((ServerLevel) event.level()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) + public static void event(net.minecraftforge.event.TickEvent.LevelTickEvent.Post event) { + if (event.side() == LogicalSide.SERVER) { + TickEvent.SERVER_LEVEL_POST.invoker().tick((ServerLevel) event.level()); + } + } + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ServerStartingEvent event) { LifecycleEvent.SERVER_STARTING.invoker().stateChanged(event.getServer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ServerStartedEvent event) { LifecycleEvent.SERVER_STARTED.invoker().stateChanged(event.getServer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ServerStoppingEvent event) { LifecycleEvent.SERVER_STOPPING.invoker().stateChanged(event.getServer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ServerStoppedEvent event) { LifecycleEvent.SERVER_STOPPED.invoker().stateChanged(event.getServer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(RegisterCommandsEvent event) { CommandRegistrationEvent.EVENT.invoker().register(event.getDispatcher(), event.getBuildContext(), event.getCommandSelection()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(PlayerLoggedInEvent event) { PlayerEvent.PLAYER_JOIN.invoker().join((ServerPlayer) event.getEntity()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(PlayerLoggedOutEvent event) { PlayerEvent.PLAYER_QUIT.invoker().quit((ServerPlayer) event.getEntity()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(PlayerRespawnEvent event) { - PlayerEvent.PLAYER_RESPAWN.invoker().respawn((ServerPlayer) event.getEntity(), event.isEndConquered()); + PlayerEvent.PLAYER_RESPAWN.invoker().respawn((ServerPlayer) event.getEntity(), event.isEndConquered(), event.getEntity().getRemovalReason()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(CommandEvent event) { + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(CommandEvent event) { CommandPerformEvent performEvent = new CommandPerformEvent(event.getParseResults(), event.getException()); - if (CommandPerformEvent.EVENT.invoker().act(performEvent).isFalse()) { - event.setCanceled(true); - } + boolean cancelled = CommandPerformEvent.EVENT.invoker().act(performEvent).isFalse(); event.setParseResults(performEvent.getResults()); event.setException(performEvent.getThrowable()); + return cancelled; } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(PlayerTickEvent event) { - if (event.phase == Phase.START) { - TickEvent.PLAYER_PRE.invoker().tick(event.player); - } else if (event.phase == Phase.END) { - TickEvent.PLAYER_POST.invoker().tick(event.player); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static void event(net.minecraftforge.event.TickEvent.PlayerTickEvent.Pre event) { + TickEvent.PLAYER_PRE.invoker().tick(event.player()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) + public static void event(net.minecraftforge.event.TickEvent.PlayerTickEvent.Post event) { + TickEvent.PLAYER_POST.invoker().tick(event.player()); + } + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ServerChatEvent event) { class ChatComponentImpl implements ChatEvent.ChatComponent { @Override public Component get() { return event.getMessage(); } - + @Override public void set(Component component) { event.setMessage(component); @@ -159,289 +157,253 @@ public void set(Component component) { } ChatEvent.DECORATE.invoker().decorate(event.getPlayer(), new ChatComponentImpl()); } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public static void eventAfter(ServerChatEvent event) { + + @SubscribeEvent(priority = Priority.LOWEST) + public static boolean eventAfter(ServerChatEvent event) { EventResult process = ChatEvent.RECEIVED.invoker().received(event.getPlayer(), event.getMessage()); - if (process.isFalse()) - event.setCanceled(true); + return process.isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventWorldEvent(LevelEvent.Load event) { if (event.getLevel() instanceof ServerLevel) { - ServerLevel world = (ServerLevel) event.getLevel(); - LifecycleEvent.SERVER_LEVEL_LOAD.invoker().act(world); + LifecycleEvent.SERVER_LEVEL_LOAD.invoker().act((ServerLevel) event.getLevel()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventWorldEvent(LevelEvent.Unload event) { if (event.getLevel() instanceof ServerLevel) { - ServerLevel world = (ServerLevel) event.getLevel(); - LifecycleEvent.SERVER_LEVEL_UNLOAD.invoker().act(world); + LifecycleEvent.SERVER_LEVEL_UNLOAD.invoker().act((ServerLevel) event.getLevel()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventWorldEvent(LevelEvent.Save event) { if (event.getLevel() instanceof ServerLevel) { - ServerLevel world = (ServerLevel) event.getLevel(); - LifecycleEvent.SERVER_LEVEL_SAVE.invoker().act(world); + LifecycleEvent.SERVER_LEVEL_SAVE.invoker().act((ServerLevel) event.getLevel()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(LivingDeathEvent event) { - if (EntityEvent.LIVING_DEATH.invoker().die(event.getEntity(), event.getSource()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(LivingDeathEvent event) { + return EntityEvent.LIVING_DEATH.invoker().die(event.getEntity(), event.getSource()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(AdvancementEvent.AdvancementEarnEvent event) { if (event.getEntity() instanceof ServerPlayer) { PlayerEvent.PLAYER_ADVANCEMENT.invoker().award((ServerPlayer) event.getEntity(), event.getAdvancement()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventPlayerEvent(Clone event) { if (event.getOriginal() instanceof ServerPlayer && event.getEntity() instanceof ServerPlayer) { PlayerEvent.PLAYER_CLONE.invoker().clone((ServerPlayer) event.getOriginal(), (ServerPlayer) event.getEntity(), !event.isWasDeath()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventExplosionEvent(Start event) { - if (ExplosionEvent.PRE.invoker().explode(event.getLevel(), event.getExplosion()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventExplosionEvent(Start event) { + return ExplosionEvent.PRE.invoker().explode(event.getLevel(), event.getExplosion()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventExplosionEvent(Detonate event) { ExplosionEvent.DETONATE.invoker().explode(event.getLevel(), event.getExplosion(), event.getAffectedEntities()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(LivingAttackEvent event) { - if (EntityEvent.LIVING_HURT.invoker().hurt(event.getEntity(), event.getSource(), event.getAmount()).isFalse()) { - event.setCanceled(true); - } - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(EntityJoinLevelEvent event) { - if (EntityEvent.ADD.invoker().add(event.getEntity(), event.getLevel()).isFalse()) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(LivingAttackEvent event) { + return EntityEvent.LIVING_HURT.invoker().hurt(event.getEntity(), event.getSource(), event.getAmount()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(FarmlandTrampleEvent event) { - if (event.getLevel() instanceof Level && InteractionEvent.FARMLAND_TRAMPLE.invoker().trample((Level) event.getLevel(), event.getPos(), event.getState(), event.getFallDistance(), event.getEntity()).value() != null) { - event.setCanceled(true); - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(EntityJoinLevelEvent event) { + return EntityEvent.ADD.invoker().add(event.getEntity(), event.getLevel()).isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(FillBucketEvent event) { - ItemStack oldItem = event.getEmptyBucket(); - CompoundEventResult result = PlayerEvent.FILL_BUCKET.invoker().fill(event.getEntity(), event.getLevel(), oldItem, event.getTarget()); - if (result.interruptsFurtherEvaluation()) { - event.setCanceled(true); - event.setFilledBucket(result.object()); - - if (result.value() != null) { - event.setResult(result.value() ? Event.Result.ALLOW : Event.Result.DENY); - } - } + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(FarmlandTrampleEvent event) { + return event.getLevel() instanceof Level level + && InteractionEvent.FARMLAND_TRAMPLE.invoker().trample(level, event.getPos(), event.getState(), event.getFallDistance(), event.getEntity()) != InteractionResult.PASS; } - - // TODO: Hook ourselves when mixin is available - // @SubscribeEvent(priority = EventPriority.HIGH) - // public static void event(EnteringChunk event) { - // EntityEvent.ENTER_SECTION.invoker().enterChunk(event.getEntity(), event.getNewChunkX(), event.getNewChunkZ(), event.getOldChunkX(), event.getOldChunkZ()); - // } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventLivingSpawnEvent(MobSpawnEvent.FinalizeSpawn event) { - EventResult result = EntityEvent.LIVING_CHECK_SPAWN.invoker().canSpawn(event.getEntity(), event.getLevel(), event.getX(), event.getY(), event.getZ(), event.getSpawnType(), event.getSpawner()); - if (result.interruptsFurtherEvaluation()) { - if (!result.isEmpty()) { - event.setSpawnCancelled(result.value()); - } + EventResult result = EntityEvent.LIVING_CHECK_SPAWN.invoker().canSpawn(event.getEntity(), event.getLevel(), event.getX(), event.getY(), event.getZ(), event.getSpawnReason(), event.getSpawner()); + if (result.interruptsFurtherEvaluation() && !result.isEmpty()) { + event.setSpawnCancelled(result.value()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(AnimalTameEvent event) { + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(AnimalTameEvent event) { EventResult result = EntityEvent.ANIMAL_TAME.invoker().tame(event.getAnimal(), event.getTamer()); - event.setCanceled(result.isFalse()); + return result.isFalse(); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ItemCraftedEvent event) { - PlayerEvent.CRAFT_ITEM.invoker().craft(event.getEntity(), event.getCrafting(), event.getInventory()); + PlayerEvent.CRAFT_ITEM.invoker().craft(event.getEntity(), event.getCrafting(), event.getContainer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ItemSmeltedEvent event) { PlayerEvent.SMELT_ITEM.invoker().smelt(event.getEntity(), event.getSmelting()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(EntityItemPickupEvent event) { - // note: this event is weird, cancel is equivalent to denying the pickup, - // and setting the result to ALLOW will pick it up without adding it to the player's inventory + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(EntityItemPickupEvent event) { var result = PlayerEvent.PICKUP_ITEM_PRE.invoker().canPickup(event.getEntity(), event.getItem(), event.getItem().getItem()); if (result.isFalse()) { - event.setCanceled(true); - } else if (result.isTrue()) { - event.setResult(Event.Result.ALLOW); + return true; + } + if (result.isTrue()) { + event.setResult(Result.ALLOW); } + return false; } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ItemPickupEvent event) { PlayerEvent.PICKUP_ITEM_POST.invoker().pickup(event.getEntity(), event.getOriginalEntity(), event.getStack()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ItemTossEvent event) { PlayerEvent.DROP_ITEM.invoker().drop(event.getPlayer(), event.getEntity()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventPlayerContainerEvent(PlayerContainerEvent.Open event) { PlayerEvent.OPEN_MENU.invoker().open(event.getEntity(), event.getContainer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventPlayerContainerEvent(PlayerContainerEvent.Close event) { PlayerEvent.CLOSE_MENU.invoker().close(event.getEntity(), event.getContainer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventPlayerInteractEvent(PlayerInteractEvent.RightClickItem event) { - CompoundEventResult result = InteractionEvent.RIGHT_CLICK_ITEM.invoker().click(event.getEntity(), event.getHand()); - if (result.isPresent()) { - event.setCanceled(true); - event.setCancellationResult(result.result().asMinecraft()); + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventPlayerInteractEvent(PlayerInteractEvent.RightClickItem event) { + InteractionResult result = InteractionEvent.RIGHT_CLICK_ITEM.invoker().click(event.getEntity(), event.getHand()); + if (result == InteractionResult.PASS) { + return false; } + event.setCancellationResult(result); + return true; } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventPlayerInteractEvent(PlayerInteractEvent.RightClickBlock event) { - EventResult result = InteractionEvent.RIGHT_CLICK_BLOCK.invoker().click(event.getEntity(), event.getHand(), event.getPos(), event.getFace()); - if (result.isPresent()) { - event.setCanceled(true); - event.setCancellationResult(result.asMinecraft()); - event.setUseBlock(Event.Result.DENY); - event.setUseItem(Event.Result.DENY); + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventPlayerInteractEvent(PlayerInteractEvent.RightClickBlock event) { + InteractionResult result = InteractionEvent.RIGHT_CLICK_BLOCK.invoker().click(event.getEntity(), event.getHand(), event.getPos(), event.getFace()); + if (result == InteractionResult.PASS) { + return false; } + event.setCancellationResult(result); + event.setUseBlock(Result.DENY); + event.setUseItem(Result.DENY); + return true; } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventPlayerInteractEvent(PlayerInteractEvent.EntityInteract event) { + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventPlayerInteractEvent(PlayerInteractEvent.EntityInteractSpecific event) { EventResult result = InteractionEvent.INTERACT_ENTITY.invoker().interact(event.getEntity(), event.getTarget(), event.getHand()); - if (result.isPresent()) { - event.setCanceled(true); - event.setCancellationResult(result.asMinecraft()); + if (!result.isPresent()) { + return false; } + event.setCancellationResult(result.asMinecraft()); + return true; } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void eventPlayerInteractEvent(PlayerInteractEvent.LeftClickBlock event) { - EventResult result = InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(event.getEntity(), event.getHand(), event.getPos(), event.getFace()); - if (result.isPresent()) { - event.setCanceled(true); - event.setCancellationResult(result.asMinecraft()); - event.setUseBlock(Event.Result.DENY); - event.setUseItem(Event.Result.DENY); + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean eventPlayerInteractEvent(PlayerInteractEvent.LeftClickBlock event) { + if (event.getAction() != PlayerInteractEvent.LeftClickBlock.Action.START) { + return false; + } + InteractionResult result = InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(event.getEntity(), event.getHand(), event.getPos(), event.getFace()); + if (result == InteractionResult.PASS) { + return false; } + event.setUseBlock(result.consumesAction() ? Result.ALLOW : Result.DENY); + event.setUseItem(result.consumesAction() ? Result.ALLOW : Result.DENY); + return true; } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(BreakEvent event) { + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(BreakEvent event) { if (event.getPlayer() instanceof ServerPlayer && event.getLevel() instanceof Level) { EventResult result = BlockEvent.BREAK.invoker().breakBlock((Level) event.getLevel(), event.getPos(), event.getState(), (ServerPlayer) event.getPlayer(), new IntValue() { @Override public int getAsInt() { return event.getExpToDrop(); } - + @Override public void accept(int value) { event.setExpToDrop(value); } }); - if (result.isFalse()) { - event.setCanceled(true); - } + return result.isFalse(); } + return false; } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(EntityPlaceEvent event) { + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(EntityPlaceEvent event) { if (event.getLevel() instanceof Level) { EventResult result = BlockEvent.PLACE.invoker().placeBlock((Level) event.getLevel(), event.getPos(), event.getState(), event.getEntity()); - if (result.isFalse()) { - event.setCanceled(true); - } + return result.isFalse(); } + return false; } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(ServerAboutToStartEvent event) { LifecycleEvent.SERVER_BEFORE_START.invoker().stateChanged(event.getServer()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(PlayerChangedDimensionEvent event) { if (event.getEntity() instanceof ServerPlayer) { PlayerEvent.CHANGE_DIMENSION.invoker().change((ServerPlayer) event.getEntity(), event.getFrom(), event.getTo()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventChunkDataEvent(ChunkDataEvent.Save event) { if (event.getLevel() instanceof ServerLevel) { ChunkEvent.SAVE_DATA.invoker().save(event.getChunk(), (ServerLevel) event.getLevel(), event.getData()); } } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void eventChunkDataEvent(ChunkDataEvent.Load event) { LevelAccessor level = event.getChunk().getWorldForge(); - if (!(level instanceof ServerLevel) && event instanceof LevelEventAttachment) { - level = ((LevelEventAttachment) event).architectury$getAttachedLevel(); - } ChunkEvent.LOAD_DATA.invoker().load(event.getChunk(), level instanceof ServerLevel ? (ServerLevel) level : null, event.getData()); } - - @SubscribeEvent(priority = EventPriority.HIGH) + + @SubscribeEvent(priority = Priority.HIGH) public static void event(LootTableLoadEvent event) { - LootEvent.MODIFY_LOOT_TABLE.invoker().modifyLootTable(lootDataManagerRef == null ? null : lootDataManagerRef.get(), event.getName(), new LootTableModificationContextImpl(event.getTable()), true); + LootEvent.MODIFY_LOOT_TABLE.invoker().modifyLootTable(ResourceKey.create(Registries.LOOT_TABLE, event.getName()), new LootTableModificationContextImpl(event.getTable()), true); } - - @SubscribeEvent(priority = EventPriority.HIGH) - public static void event(AttackEntityEvent event) { + + @SubscribeEvent(priority = Priority.HIGH) + public static boolean event(AttackEntityEvent event) { EventResult result = PlayerEvent.ATTACK_ENTITY.invoker().attack(event.getEntity(), event.getEntity().level(), event.getTarget(), event.getEntity().getUsedItemHand(), null); - if (result.isFalse()) { - event.setCanceled(true); - } + return result.isFalse(); } - + public interface LevelEventAttachment { LevelAccessor architectury$getAttachedLevel(); - + void architectury$attachLevel(LevelAccessor level); } - + public static class ModBasedEventHandler { - @SubscribeEvent(priority = EventPriority.HIGH) + @SubscribeEvent(priority = Priority.HIGH) public static void event(FMLCommonSetupEvent event) { LifecycleEvent.SETUP.invoker().run(); } diff --git a/forge/src/main/java/dev/architectury/event/forge/LootTableModificationContextImpl.java b/forge/src/main/java/dev/architectury/event/forge/LootTableModificationContextImpl.java index a8c578620..abde6400b 100644 --- a/forge/src/main/java/dev/architectury/event/forge/LootTableModificationContextImpl.java +++ b/forge/src/main/java/dev/architectury/event/forge/LootTableModificationContextImpl.java @@ -88,11 +88,6 @@ final class LootTableModificationContextImpl implements LootEvent.LootTableModif this.pools = pools; } - @Override - public void addPool(LootPool pool) { - this.pools.add(pool); - } - @Override public void addPool(LootPool.Builder pool) { this.pools.add(pool.build()); diff --git a/forge/src/main/java/dev/architectury/fluid/forge/FluidStackImpl.java b/forge/src/main/java/dev/architectury/fluid/forge/FluidStackImpl.java index b39bf5b92..c104d935b 100644 --- a/forge/src/main/java/dev/architectury/fluid/forge/FluidStackImpl.java +++ b/forge/src/main/java/dev/architectury/fluid/forge/FluidStackImpl.java @@ -19,82 +19,178 @@ package dev.architectury.fluid.forge; -import net.minecraft.core.registries.BuiltInRegistries; +import com.mojang.serialization.Codec; +import dev.architectury.hooks.fluid.forge.FluidStackHooksForge; +import net.minecraft.core.component.DataComponentMap; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.PatchedDataComponentMap; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtAccounter; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.level.material.Fluid; import net.minecraftforge.fluids.FluidStack; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import static dev.architectury.utils.Amount.toInt; @ApiStatus.Internal public enum FluidStackImpl implements dev.architectury.fluid.FluidStack.FluidStackAdapter { INSTANCE; - + private static final String ARCHITECTURY_COMPONENTS_TAG = "ArchitecturyDataComponents"; + static { dev.architectury.fluid.FluidStack.init(); } - + public static Function toValue; public static Function fromValue; - + public static dev.architectury.fluid.FluidStack.FluidStackAdapter adapt(Function toValue, Function fromValue) { FluidStackImpl.toValue = toValue; FluidStackImpl.fromValue = fromValue; return (dev.architectury.fluid.FluidStack.FluidStackAdapter) (dev.architectury.fluid.FluidStack.FluidStackAdapter) INSTANCE; } - + @Override - public FluidStack create(Supplier fluid, long amount, CompoundTag tag) { - return new FluidStack(fluid.get(), toInt(amount), tag); + public FluidStack create(Supplier fluid, long amount, @Nullable DataComponentPatch patch) { + FluidStack stack = new FluidStack(fluid.get(), toInt(amount)); + writePatch(stack, patch); + return stack; } - + @Override public Supplier getRawFluidSupplier(FluidStack object) { - return () -> BuiltInRegistries.FLUID.getHolderOrThrow(BuiltInRegistries.FLUID.getResourceKey(object.getRawFluid()).orElseThrow()).value(); + return object::getFluid; } - + @Override public Fluid getFluid(FluidStack object) { return object.getFluid(); } - + @Override public long getAmount(FluidStack object) { return object.getAmount(); } - + @Override public void setAmount(FluidStack object, long amount) { object.setAmount(toInt(amount)); } - + + @Override + public DataComponentPatch getPatch(FluidStack value) { + CompoundTag tag = value.getTag(); + if (tag == null || !tag.contains(ARCHITECTURY_COMPONENTS_TAG)) { + return DataComponentPatch.EMPTY; + } + + return tag.read(ARCHITECTURY_COMPONENTS_TAG, DataComponentPatch.CODEC).orElse(DataComponentPatch.EMPTY); + } + + @Override + public PatchedDataComponentMap getComponents(FluidStack value) { + return PatchedDataComponentMap.fromPatch(DataComponentMap.EMPTY, getPatch(value)); + } + + @Override + public void applyComponents(FluidStack value, DataComponentPatch patch) { + PatchedDataComponentMap components = getComponents(value); + components.applyPatch(patch); + writePatch(value, components.asPatch()); + } + + @Override + public void applyComponents(FluidStack value, DataComponentMap components) { + PatchedDataComponentMap patchedComponents = getComponents(value); + patchedComponents.setAll(components); + writePatch(value, patchedComponents.asPatch()); + } + @Override - public CompoundTag getTag(FluidStack value) { - return value.getTag(); + @Nullable + public D set(FluidStack value, DataComponentType type, @Nullable D component) { + if (component == null) { + return remove(value, type); + } + + PatchedDataComponentMap components = getComponents(value); + D oldComponent = components.set(type, component); + writePatch(value, components.asPatch()); + return oldComponent; } - + @Override - public void setTag(FluidStack value, CompoundTag tag) { - value.setTag(tag); + @Nullable + public D remove(FluidStack value, DataComponentType type) { + PatchedDataComponentMap components = getComponents(value); + D oldComponent = components.remove(type); + writePatch(value, components.asPatch()); + return oldComponent; } - + + @Override + @Nullable + public D update(FluidStack value, DataComponentType type, D component, UnaryOperator updater) { + return set(value, type, updater.apply(component)); + } + + @Override + @Nullable + public D update(FluidStack value, DataComponentType type, D component, U updateContext, BiFunction updater) { + return set(value, type, updater.apply(component, updateContext)); + } + + private static void writePatch(FluidStack value, @Nullable DataComponentPatch patch) { + CompoundTag tag = value.getTag(); + if (tag != null) { + tag.remove(ARCHITECTURY_COMPONENTS_TAG); + } + + if (patch == null || patch.isEmpty()) { + if (tag != null && tag.isEmpty()) { + value.setTag(null); + } + return; + } + + tag = value.getOrCreateTag(); + tag.store(ARCHITECTURY_COMPONENTS_TAG, DataComponentPatch.CODEC, patch); + } + @Override public FluidStack copy(FluidStack value) { return value.copy(); } - + @Override public int hashCode(FluidStack value) { - var code = 1; + int code = 1; code = 31 * code + value.getFluid().hashCode(); code = 31 * code + value.getAmount(); - var tag = value.getTag(); - if (tag != null) - code = 31 * code + tag.hashCode(); + if (value.getTag() != null) { + code = 31 * code + value.getTag().hashCode(); + } return code; } + + @Override + public Codec codec() { + return FluidStack.CODEC.xmap(FluidStackHooksForge::fromForge, FluidStackHooksForge::toForge); + } + + @Override + public StreamCodec streamCodec() { + return ByteBufCodecs.fromCodecWithRegistries(FluidStack.CODEC, NbtAccounter::unlimitedHeap) + .map(FluidStackHooksForge::fromForge, FluidStackHooksForge::toForge); + } } diff --git a/forge/src/main/java/dev/architectury/hooks/client/screen/forge/ScreenHooksImpl.java b/forge/src/main/java/dev/architectury/hooks/client/screen/forge/ScreenHooksImpl.java index f7acc49c2..ce3890d23 100644 --- a/forge/src/main/java/dev/architectury/hooks/client/screen/forge/ScreenHooksImpl.java +++ b/forge/src/main/java/dev/architectury/hooks/client/screen/forge/ScreenHooksImpl.java @@ -25,26 +25,65 @@ import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.screens.Screen; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.List; public class ScreenHooksImpl { + @SuppressWarnings("unchecked") public static List getNarratables(Screen screen) { - return screen.narratables; + return (List) getField(screen, "narratables"); } - + + @SuppressWarnings("unchecked") public static List getRenderables(Screen screen) { - return screen.renderables; + return (List) getField(screen, "renderables"); } - + public static T addRenderableWidget(Screen screen, T widget) { - return screen.addRenderableWidget(widget); + return invoke(screen, "addRenderableWidget", widget); } - + public static T addRenderableOnly(Screen screen, T listener) { - return screen.addRenderableOnly(listener); + return invoke(screen, "addRenderableOnly", listener); } - + public static T addWidget(Screen screen, T listener) { - return screen.addWidget(listener); + return invoke(screen, "addWidget", listener); + } + + private static Object getField(Screen screen, String name) { + Class current = screen.getClass(); + while (current != null) { + try { + Field field = current.getDeclaredField(name); + field.setAccessible(true); + return field.get(screen); + } catch (NoSuchFieldException ignored) { + current = current.getSuperclass(); + } catch (IllegalAccessException exception) { + throw new IllegalStateException("Failed to access Screen field '" + name + "'", exception); + } + } + throw new IllegalStateException("Could not find Screen field '" + name + "'"); + } + + @SuppressWarnings("unchecked") + private static T invoke(Screen screen, String name, T arg) { + Class current = screen.getClass(); + while (current != null) { + for (Method method : current.getDeclaredMethods()) { + if (method.getName().equals(name) && method.getParameterCount() == 1 && method.getParameterTypes()[0].isAssignableFrom(arg.getClass())) { + try { + method.setAccessible(true); + return (T) method.invoke(screen, arg); + } catch (ReflectiveOperationException exception) { + throw new IllegalStateException("Failed to invoke Screen method '" + name + "'", exception); + } + } + } + current = current.getSuperclass(); + } + throw new IllegalStateException("Could not find Screen method '" + name + "'"); } } diff --git a/forge/src/main/java/dev/architectury/hooks/fluid/forge/FluidStackHooksImpl.java b/forge/src/main/java/dev/architectury/hooks/fluid/forge/FluidStackHooksImpl.java index 2fff1282d..f8f6870be 100644 --- a/forge/src/main/java/dev/architectury/hooks/fluid/forge/FluidStackHooksImpl.java +++ b/forge/src/main/java/dev/architectury/hooks/fluid/forge/FluidStackHooksImpl.java @@ -19,16 +19,19 @@ package dev.architectury.hooks.fluid.forge; +import com.mojang.logging.LogUtils; import dev.architectury.fluid.FluidStack; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import net.minecraft.resources.Identifier; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; @@ -37,139 +40,170 @@ import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; + +import java.util.Optional; public class FluidStackHooksImpl { + private static final Logger LOGGER = LogUtils.getLogger(); + public static Component getName(FluidStack stack) { return stack.getFluid().getFluidType().getDescription(FluidStackHooksForge.toForge(stack)); } - + public static String getTranslationKey(FluidStack stack) { return stack.getFluid().getFluidType().getDescriptionId(FluidStackHooksForge.toForge(stack)); } - - public static FluidStack read(FriendlyByteBuf buf) { - return FluidStackHooksForge.fromForge(net.minecraftforge.fluids.FluidStack.readFromPacket(buf)); + + public static FluidStack read(RegistryFriendlyByteBuf buf) { + return FluidStack.STREAM_CODEC.decode(buf); } - - public static void write(FluidStack stack, FriendlyByteBuf buf) { - FluidStackHooksForge.toForge(stack).writeToPacket(buf); + + public static void write(FluidStack stack, RegistryFriendlyByteBuf buf) { + FluidStack.STREAM_CODEC.encode(buf, stack); } - - public static FluidStack read(CompoundTag tag) { - return FluidStackHooksForge.fromForge(net.minecraftforge.fluids.FluidStack.loadFluidStackFromNBT(tag)); + + public static Optional read(HolderLookup.Provider provider, Tag tag) { + return FluidStack.CODEC.parse(provider.createSerializationContext(NbtOps.INSTANCE), tag) + .resultOrPartial(string -> LOGGER.error("Tried to load invalid fluid stack: '{}'", string)); } - - public static CompoundTag write(FluidStack stack, CompoundTag tag) { - return FluidStackHooksForge.toForge(stack).writeToNBT(tag); + + public static FluidStack readOptional(HolderLookup.Provider provider, CompoundTag tag) { + return tag.isEmpty() ? FluidStack.empty() : read(provider, tag).orElse(FluidStack.empty()); + } + + public static Tag write(HolderLookup.Provider provider, FluidStack stack, Tag tag) { + return FluidStack.CODEC.encode(stack, provider.createSerializationContext(NbtOps.INSTANCE), tag).getOrThrow(IllegalStateException::new); } - + public static long bucketAmount() { return 1000; } - + @OnlyIn(Dist.CLIENT) @Nullable public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { - if (state.getType() == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(state).getStillTexture(state, level, pos); - return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + if (state.getType() == Fluids.EMPTY) { + return null; + } + return atlasSprite(IClientFluidTypeExtensions.of(state).getStillTexture()); } - + @OnlyIn(Dist.CLIENT) @Nullable public static TextureAtlasSprite getStillTexture(FluidStack stack) { - if (stack.getFluid() == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(stack.getFluid()).getStillTexture(FluidStackHooksForge.toForge(stack)); - return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + if (stack.getFluid() == Fluids.EMPTY) { + return null; + } + return atlasSprite(IClientFluidTypeExtensions.of(stack.getFluid()).getStillTexture(FluidStackHooksForge.toForge(stack))); } - + @OnlyIn(Dist.CLIENT) @Nullable public static TextureAtlasSprite getStillTexture(Fluid fluid) { - if (fluid == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(fluid).getStillTexture(); - return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + if (fluid == Fluids.EMPTY) { + return null; + } + return atlasSprite(IClientFluidTypeExtensions.of(fluid).getStillTexture()); } - + @OnlyIn(Dist.CLIENT) @Nullable public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { - if (state.getType() == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(state).getFlowingTexture(state, level, pos); - return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + if (state.getType() == Fluids.EMPTY) { + return null; + } + return atlasSprite(IClientFluidTypeExtensions.of(state).getFlowingTexture()); } - + @OnlyIn(Dist.CLIENT) @Nullable public static TextureAtlasSprite getFlowingTexture(FluidStack stack) { - if (stack.getFluid() == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(stack.getFluid()).getFlowingTexture(FluidStackHooksForge.toForge(stack)); - return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + if (stack.getFluid() == Fluids.EMPTY) { + return null; + } + return atlasSprite(IClientFluidTypeExtensions.of(stack.getFluid()).getFlowingTexture(FluidStackHooksForge.toForge(stack))); } - + @OnlyIn(Dist.CLIENT) @Nullable public static TextureAtlasSprite getFlowingTexture(Fluid fluid) { - if (fluid == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(fluid).getFlowingTexture(); - return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + if (fluid == Fluids.EMPTY) { + return null; + } + return atlasSprite(IClientFluidTypeExtensions.of(fluid).getFlowingTexture()); } - + @OnlyIn(Dist.CLIENT) public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { - if (state.getType() == Fluids.EMPTY) return -1; - return IClientFluidTypeExtensions.of(state).getTintColor(state, level, pos); + if (state.getType() == Fluids.EMPTY) { + return -1; + } + return IClientFluidTypeExtensions.of(state).getTintColor(); } - + @OnlyIn(Dist.CLIENT) public static int getColor(FluidStack stack) { - if (stack.getFluid() == Fluids.EMPTY) return -1; + if (stack.getFluid() == Fluids.EMPTY) { + return -1; + } return IClientFluidTypeExtensions.of(stack.getFluid()).getTintColor(FluidStackHooksForge.toForge(stack)); } - + @OnlyIn(Dist.CLIENT) public static int getColor(Fluid fluid) { - if (fluid == Fluids.EMPTY) return -1; + if (fluid == Fluids.EMPTY) { + return -1; + } return IClientFluidTypeExtensions.of(fluid).getTintColor(); } - + public static int getLuminosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) { return fluid.getFluid().getFluidType().getLightLevel(FluidStackHooksForge.toForge(fluid)); } - + @Deprecated(forRemoval = true) public static int getLuminosity(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) { if (level != null && pos != null) { var state = level.getFluidState(pos); return fluid.getFluidType().getLightLevel(state, level, pos); } - + return fluid.getFluidType().getLightLevel(); } - + public static int getTemperature(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) { return fluid.getFluid().getFluidType().getTemperature(FluidStackHooksForge.toForge(fluid)); } - + public static int getTemperature(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) { if (level != null && pos != null) { var state = level.getFluidState(pos); return fluid.getFluidType().getTemperature(state, level, pos); } - + return fluid.getFluidType().getTemperature(); } - + public static int getViscosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) { return fluid.getFluid().getFluidType().getViscosity(FluidStackHooksForge.toForge(fluid)); } - + public static int getViscosity(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) { if (level != null && pos != null) { var state = level.getFluidState(pos); return fluid.getFluidType().getViscosity(state, level, pos); } - + return fluid.getFluidType().getViscosity(); } + + @OnlyIn(Dist.CLIENT) + @Nullable + private static TextureAtlasSprite atlasSprite(@Nullable net.minecraft.resources.Identifier texture) { + if (texture == null) { + return null; + } + return Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(TextureAtlas.LOCATION_BLOCKS).getSprite(texture); + } } diff --git a/forge/src/main/java/dev/architectury/hooks/forge/DyeColorHooksImpl.java b/forge/src/main/java/dev/architectury/hooks/forge/DyeColorHooksImpl.java index c94a13be9..4babfd113 100644 --- a/forge/src/main/java/dev/architectury/hooks/forge/DyeColorHooksImpl.java +++ b/forge/src/main/java/dev/architectury/hooks/forge/DyeColorHooksImpl.java @@ -23,7 +23,6 @@ public class DyeColorHooksImpl { public static int getColorValue(DyeColor dyeColor) { - var colors = dyeColor.getTextureDiffuseColors(); - return ((int) (colors[0] * 255.0F + 0.5D) & 255) << 16 | ((int) (colors[1] * 255.0F + 0.5D) & 255) << 8 | (int) (colors[2] * 255.0F + 0.5D); + return dyeColor.getTextureDiffuseColor(); } } diff --git a/forge/src/main/java/dev/architectury/hooks/item/food/forge/FoodPropertiesHooksImpl.java b/forge/src/main/java/dev/architectury/hooks/item/food/forge/FoodPropertiesHooksImpl.java index d10d5add5..ab31f294c 100644 --- a/forge/src/main/java/dev/architectury/hooks/item/food/forge/FoodPropertiesHooksImpl.java +++ b/forge/src/main/java/dev/architectury/hooks/item/food/forge/FoodPropertiesHooksImpl.java @@ -25,9 +25,8 @@ import java.util.function.Supplier; public class FoodPropertiesHooksImpl { - @SuppressWarnings("unchecked") public static void effect(FoodProperties.Builder builder, Supplier effectSupplier, float chance) { - builder.effect((Supplier) effectSupplier, chance); + // MC 26 removed runtime food effect registration from the builder API on Forge. } -} \ No newline at end of file +} diff --git a/forge/src/main/java/dev/architectury/hooks/item/forge/ItemStackHooksImpl.java b/forge/src/main/java/dev/architectury/hooks/item/forge/ItemStackHooksImpl.java index e6542bffd..f13f1fe09 100644 --- a/forge/src/main/java/dev/architectury/hooks/item/forge/ItemStackHooksImpl.java +++ b/forge/src/main/java/dev/architectury/hooks/item/forge/ItemStackHooksImpl.java @@ -23,10 +23,10 @@ public class ItemStackHooksImpl { public static boolean hasCraftingRemainingItem(ItemStack stack) { - return stack.hasCraftingRemainingItem(); + return !stack.getItem().getCraftingRemainder().create().isEmpty(); } public static ItemStack getCraftingRemainingItem(ItemStack stack) { - return stack.getCraftingRemainingItem(); + return stack.getItem().getCraftingRemainder().create(); } } diff --git a/forge/src/main/java/dev/architectury/hooks/item/tool/forge/HoeItemHooksImpl.java b/forge/src/main/java/dev/architectury/hooks/item/tool/forge/HoeItemHooksImpl.java index 656c41f44..94c8f4780 100644 --- a/forge/src/main/java/dev/architectury/hooks/item/tool/forge/HoeItemHooksImpl.java +++ b/forge/src/main/java/dev/architectury/hooks/item/tool/forge/HoeItemHooksImpl.java @@ -32,7 +32,7 @@ public class HoeItemHooksImpl { public static void addTillable(Block input, Predicate predicate, Consumer action, Function function) { - MinecraftForge.EVENT_BUS.addListener(event -> { + BlockEvent.BlockToolModificationEvent.BUS.addListener(event -> { UseOnContext context = event.getContext(); if (ToolActions.HOE_TILL == event.getToolAction() && context.getItemInHand().canPerformAction(ToolActions.HOE_TILL) && event.getState().is(input) && predicate.test(context)) { diff --git a/forge/src/main/java/dev/architectury/mixin/forge/MixinClientLevel.java b/forge/src/main/java/dev/architectury/mixin/forge/MixinClientLevel.java index d764ab9e8..a2ec0e460 100644 --- a/forge/src/main/java/dev/architectury/mixin/forge/MixinClientLevel.java +++ b/forge/src/main/java/dev/architectury/mixin/forge/MixinClientLevel.java @@ -24,7 +24,6 @@ import net.minecraft.core.Holder; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceKey; -import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.level.Level; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.storage.WritableLevelData; @@ -33,27 +32,19 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.function.Supplier; - @Mixin(ClientLevel.class) public abstract class MixinClientLevel extends Level { - protected MixinClientLevel(WritableLevelData arg, ResourceKey arg2, RegistryAccess arg3, Holder arg4, Supplier supplier, boolean bl, boolean bl2, long l, int i) { - super(arg, arg2, arg3, arg4, supplier, bl, bl2, l, i); + protected MixinClientLevel(WritableLevelData arg, ResourceKey arg2, RegistryAccess arg3, Holder arg4, boolean bl, boolean bl2, long l, int i) { + super(arg, arg2, arg3, arg4, bl, bl2, l, i); } @Inject(method = "tickEntities", at = @At("HEAD")) private void tickEntities(CallbackInfo ci) { - ProfilerFiller profiler = getProfiler(); - profiler.push("architecturyClientLevelPreTick"); ClientTickEvent.CLIENT_LEVEL_PRE.invoker().tick((ClientLevel) (Object) this); - profiler.pop(); } @Inject(method = "tickEntities", at = @At("RETURN")) private void tickEntitiesPost(CallbackInfo ci) { - ProfilerFiller profiler = getProfiler(); - profiler.push("architecturyClientLevelPostTick"); ClientTickEvent.CLIENT_LEVEL_POST.invoker().tick((ClientLevel) (Object) this); - profiler.pop(); } } diff --git a/forge/src/main/java/dev/architectury/mixin/forge/MixinLootDataManager.java b/forge/src/main/java/dev/architectury/mixin/forge/MixinVillager.java similarity index 54% rename from forge/src/main/java/dev/architectury/mixin/forge/MixinLootDataManager.java rename to forge/src/main/java/dev/architectury/mixin/forge/MixinVillager.java index bea926742..7426fdc60 100644 --- a/forge/src/main/java/dev/architectury/mixin/forge/MixinLootDataManager.java +++ b/forge/src/main/java/dev/architectury/mixin/forge/MixinVillager.java @@ -19,25 +19,20 @@ package dev.architectury.mixin.forge; -import dev.architectury.event.forge.EventHandlerImplCommon; -import net.minecraft.server.packs.resources.PreparableReloadListener; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.world.level.storage.loot.LootDataManager; +import dev.architectury.registry.level.entity.trade.forge.TradeRegistryImpl; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.npc.villager.Villager; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.lang.ref.WeakReference; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; - -@Mixin(LootDataManager.class) -public class MixinLootDataManager { - @Inject(method = "reload", at = @At("HEAD")) - private void reload(PreparableReloadListener.PreparationBarrier arg, ResourceManager arg2, ProfilerFiller arg3, - ProfilerFiller arg4, Executor executor, Executor executor2, CallbackInfoReturnable> cir) { - EventHandlerImplCommon.lootDataManagerRef = new WeakReference<>((LootDataManager) (Object) this); +@Mixin(Villager.class) +public class MixinVillager { + @Inject(method = "updateTrades", at = @At("RETURN")) + private void architectury$appendRegisteredTrades(ServerLevel level, CallbackInfo ci) { + Villager villager = (Villager) (Object) this; + villager.getVillagerData().profession().unwrapKey().ifPresent(profession -> TradeRegistryImpl.appendVillagerTrades( + level, villager.getOffers(), profession, villager.getVillagerData().level(), villager, villager.getRandom())); } } diff --git a/forge/src/main/java/dev/architectury/mixin/forge/MixinItemExtension.java b/forge/src/main/java/dev/architectury/mixin/forge/MixinWanderingTrader.java similarity index 55% rename from forge/src/main/java/dev/architectury/mixin/forge/MixinItemExtension.java rename to forge/src/main/java/dev/architectury/mixin/forge/MixinWanderingTrader.java index 82944a370..b75abe092 100644 --- a/forge/src/main/java/dev/architectury/mixin/forge/MixinItemExtension.java +++ b/forge/src/main/java/dev/architectury/mixin/forge/MixinWanderingTrader.java @@ -19,25 +19,19 @@ package dev.architectury.mixin.forge; -import dev.architectury.extensions.ItemExtension; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraftforge.common.extensions.IForgeItem; -import org.jetbrains.annotations.Nullable; +import dev.architectury.registry.level.entity.trade.forge.TradeRegistryImpl; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.npc.wanderingtrader.WanderingTrader; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -@Mixin(ItemExtension.class) -public interface MixinItemExtension extends IForgeItem { - @Override - default void onArmorTick(ItemStack stack, Level world, Player player) { - ((ItemExtension) this).tickArmor(stack, player); - } - - @Nullable - @Override - default EquipmentSlot getEquipmentSlot(ItemStack stack) { - return ((ItemExtension) this).getCustomEquipmentSlot(stack); +@Mixin(WanderingTrader.class) +public class MixinWanderingTrader { + @Inject(method = "updateTrades", at = @At("RETURN")) + private void architectury$appendRegisteredTrades(ServerLevel level, CallbackInfo ci) { + WanderingTrader trader = (WanderingTrader) (Object) this; + TradeRegistryImpl.appendWanderingTraderTrades(level, trader.getOffers(), trader, trader.getRandom()); } } diff --git a/forge/src/main/java/dev/architectury/platform/hooks/EventBusesHooks.java b/forge/src/main/java/dev/architectury/platform/hooks/EventBusesHooks.java index 81b172f7f..660e70f66 100644 --- a/forge/src/main/java/dev/architectury/platform/hooks/EventBusesHooks.java +++ b/forge/src/main/java/dev/architectury/platform/hooks/EventBusesHooks.java @@ -19,8 +19,9 @@ package dev.architectury.platform.hooks; -import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.bus.BusGroup; +import net.minecraftforge.fml.ModContainer; +import net.minecraftforge.fml.ModList; import java.util.Optional; import java.util.function.Consumer; @@ -29,13 +30,13 @@ public final class EventBusesHooks { private EventBusesHooks() { } - @ExpectPlatform - public static void whenAvailable(String modId, Consumer busConsumer) { - throw new AssertionError(); + public static void whenAvailable(String modId, Consumer busConsumer) { + BusGroup bus = getModEventBus(modId).orElseThrow(() -> new IllegalStateException("Mod '" + modId + "' is not available!")); + busConsumer.accept(bus); } - @ExpectPlatform - public static Optional getModEventBus(String modId) { - throw new AssertionError(); + public static Optional getModEventBus(String modId) { + return ModList.getModContainerById(modId) + .map(ModContainer::getModBusGroup); } } diff --git a/forge/src/main/java/dev/architectury/registry/client/gui/forge/ClientTooltipComponentRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/client/gui/forge/ClientTooltipComponentRegistryImpl.java index 68f5aeb14..81da5fb43 100644 --- a/forge/src/main/java/dev/architectury/registry/client/gui/forge/ClientTooltipComponentRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/client/gui/forge/ClientTooltipComponentRegistryImpl.java @@ -19,17 +19,18 @@ package dev.architectury.registry.client.gui.forge; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.RegisterClientTooltipComponentFactoriesEvent; -import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.listener.Priority; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.List; import java.util.function.Function; @@ -39,29 +40,30 @@ public class ClientTooltipComponentRegistryImpl { @Nullable private static List> entries = new ArrayList<>(); - + static { - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.addListener(EventPriority.HIGH, event -> { - if (entries != null) { - for (Entry entry : entries) { - Entry casted = (Entry) entry; - event.register(casted.clazz(), casted.factory()); - } - - entries = null; - } - }); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), ClientTooltipComponentRegistryImpl.class); } - + public static void register(Class clazz, Function factory) { if (entries == null) { throw new IllegalStateException("Cannot register ClientTooltipComponent factory when factories are already aggregated!"); } entries.add(new Entry<>(clazz, factory)); } - + + @SubscribeEvent(priority = Priority.HIGH) + public static void event(RegisterClientTooltipComponentFactoriesEvent event) { + if (entries != null) { + for (Entry entry : entries) { + Entry casted = (Entry) entry; + event.register(casted.clazz(), casted.factory()); + } + + entries = null; + } + } + public record Entry( Class clazz, Function factory ) { diff --git a/forge/src/main/java/dev/architectury/registry/client/keymappings/forge/KeyMappingRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/client/keymappings/forge/KeyMappingRegistryImpl.java index 6cb52ce95..4f92a8a1a 100644 --- a/forge/src/main/java/dev/architectury/registry/client/keymappings/forge/KeyMappingRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/client/keymappings/forge/KeyMappingRegistryImpl.java @@ -19,16 +19,17 @@ package dev.architectury.registry.client.keymappings.forge; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; import net.minecraftforge.client.event.RegisterKeyMappingsEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.apache.commons.lang3.ArrayUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.List; @@ -38,9 +39,7 @@ public class KeyMappingRegistryImpl { private static boolean eventCalled = false; static { - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.addListener(KeyMappingRegistryImpl::event); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), KeyMappingRegistryImpl.class); } public static void register(KeyMapping mapping) { @@ -53,6 +52,7 @@ public static void register(KeyMapping mapping) { } } + @SubscribeEvent public static void event(RegisterKeyMappingsEvent event) { MAPPINGS.forEach(event::register); eventCalled = true; diff --git a/forge/src/main/java/dev/architectury/registry/client/level/entity/forge/EntityModelLayerRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/client/level/entity/forge/EntityModelLayerRegistryImpl.java index 95e3ff1f6..5cd84e6c0 100644 --- a/forge/src/main/java/dev/architectury/registry/client/level/entity/forge/EntityModelLayerRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/client/level/entity/forge/EntityModelLayerRegistryImpl.java @@ -19,13 +19,13 @@ package dev.architectury.registry.client.level.entity.forge; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.model.geom.builders.LayerDefinition; import net.minecraftforge.client.event.EntityRenderersEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import java.lang.invoke.MethodHandles; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; @@ -34,9 +34,7 @@ public class EntityModelLayerRegistryImpl { private static final Map> DEFINITIONS = new ConcurrentHashMap<>(); static { - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.register(EntityModelLayerRegistryImpl.class); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), EntityModelLayerRegistryImpl.class); } public static void register(ModelLayerLocation location, Supplier definition) { diff --git a/forge/src/main/java/dev/architectury/registry/client/level/entity/forge/EntityRendererRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/client/level/entity/forge/EntityRendererRegistryImpl.java index fa263c5b7..a3250f64e 100644 --- a/forge/src/main/java/dev/architectury/registry/client/level/entity/forge/EntityRendererRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/client/level/entity/forge/EntityRendererRegistryImpl.java @@ -19,14 +19,14 @@ package dev.architectury.registry.client.level.entity.forge; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraftforge.client.event.EntityRenderersEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import java.lang.invoke.MethodHandles; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; @@ -39,9 +39,7 @@ public static void register(Supplier { - bus.register(EntityRendererRegistryImpl.class); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), EntityRendererRegistryImpl.class); } @SubscribeEvent diff --git a/forge/src/main/java/dev/architectury/registry/client/particle/forge/ParticleProviderRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/client/particle/forge/ParticleProviderRegistryImpl.java index b0ff7900e..187a0f976 100644 --- a/forge/src/main/java/dev/architectury/registry/client/particle/forge/ParticleProviderRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/client/particle/forge/ParticleProviderRegistryImpl.java @@ -20,12 +20,11 @@ package dev.architectury.registry.client.particle.forge; import com.mojang.logging.LogUtils; -import dev.architectury.platform.hooks.EventBusesHooks; import dev.architectury.registry.client.particle.ParticleProviderRegistry; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.Minecraft; import net.minecraft.client.particle.ParticleEngine; import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.ParticleResources; import net.minecraft.client.particle.SpriteSet; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -33,62 +32,68 @@ import net.minecraft.core.particles.ParticleType; import net.minecraft.util.RandomSource; import net.minecraftforge.client.event.RegisterParticleProvidersEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.slf4j.Logger; +import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; public class ParticleProviderRegistryImpl { public static final Logger LOGGER = LogUtils.getLogger(); - + static { - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.addListener(ParticleProviderRegistryImpl::onParticleFactoryRegister); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), ParticleProviderRegistryImpl.class); } - + private static final class ExtendedSpriteSetImpl implements ParticleProviderRegistry.ExtendedSpriteSet { private final ParticleEngine engine; private final SpriteSet delegate; - + private ExtendedSpriteSetImpl(ParticleEngine engine, SpriteSet delegate) { this.engine = engine; this.delegate = delegate; } - + @Override public TextureAtlas getAtlas() { - return engine.textureAtlas; + return Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(TextureAtlas.LOCATION_PARTICLES); } - + @Override public List getSprites() { - return ((ParticleEngine.MutableSpriteSet) delegate).sprites; + return List.of(delegate.first()); } - + @Override public TextureAtlasSprite get(int i, int j) { return delegate.get(i, j); } - + @Override public TextureAtlasSprite get(RandomSource random) { return delegate.get(random); } + + @Override + public TextureAtlasSprite first() { + return delegate.first(); + } } - + private static List> deferred = new ArrayList<>(); - + private static void doRegister(ParticleProviderRegistrar registrar, ParticleType type, ParticleProvider provider) { registrar.register(type, provider); } - + private static void doRegister(ParticleProviderRegistrar registrar, ParticleType type, ParticleProviderRegistry.DeferredParticleProvider provider) { registrar.register(type, sprites -> provider.create(new ExtendedSpriteSetImpl(Minecraft.getInstance().particleEngine, sprites))); } - + public static void register(ParticleType type, ParticleProvider provider) { if (deferred == null) { LOGGER.warn("Something is attempting to register particle providers at a later point than intended! This might cause issues!", new Throwable()); @@ -97,7 +102,7 @@ public static void register(ParticleType type, Pa deferred.add(registrar -> doRegister(registrar, type, provider)); } } - + public static void register(ParticleType type, ParticleProviderRegistry.DeferredParticleProvider provider) { if (deferred == null) { LOGGER.warn("Something is attempting to register particle providers at a later point than intended! This might cause issues!", new Throwable()); @@ -106,7 +111,8 @@ public static void register(ParticleType type, Pa deferred.add(registrar -> doRegister(registrar, type, provider)); } } - + + @SubscribeEvent public static void onParticleFactoryRegister(RegisterParticleProvidersEvent event) { if (deferred != null) { ParticleProviderRegistrar registrar = ParticleProviderRegistrar.ofForge(event); @@ -118,36 +124,36 @@ public static void onParticleFactoryRegister(RegisterParticleProvidersEvent even deferred = null; } } - + private interface ParticleProviderRegistrar { void register(ParticleType type, ParticleProvider provider); - - void register(ParticleType type, ParticleEngine.SpriteParticleRegistration registration); - + + void register(ParticleType type, ParticleResources.SpriteParticleRegistration registration); + static ParticleProviderRegistrar ofForge(RegisterParticleProvidersEvent event) { return new ParticleProviderRegistrar() { @Override public void register(ParticleType type, ParticleProvider provider) { event.registerSpecial(type, provider); } - + @Override - public void register(ParticleType type, ParticleEngine.SpriteParticleRegistration registration) { + public void register(ParticleType type, ParticleResources.SpriteParticleRegistration registration) { event.registerSpriteSet(type, registration); } }; } - + static ParticleProviderRegistrar ofFallback() { return new ParticleProviderRegistrar() { @Override public void register(ParticleType type, ParticleProvider provider) { - Minecraft.getInstance().particleEngine.register(type, provider); + LOGGER.warn("Skipping late particle provider registration for {}", type); } - + @Override - public void register(ParticleType type, ParticleEngine.SpriteParticleRegistration registration) { - Minecraft.getInstance().particleEngine.register(type, registration); + public void register(ParticleType type, ParticleResources.SpriteParticleRegistration registration) { + LOGGER.warn("Skipping late sprite particle registration for {}", type); } }; } diff --git a/forge/src/main/java/dev/architectury/registry/client/rendering/forge/BlockEntityRendererRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/client/rendering/forge/BlockEntityRendererRegistryImpl.java index 1c5480c49..5b1f05b28 100644 --- a/forge/src/main/java/dev/architectury/registry/client/rendering/forge/BlockEntityRendererRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/client/rendering/forge/BlockEntityRendererRegistryImpl.java @@ -21,11 +21,12 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; public class BlockEntityRendererRegistryImpl { - public static void register(BlockEntityType type, BlockEntityRendererProvider provider) { + public static void register(BlockEntityType type, BlockEntityRendererProvider provider) { BlockEntityRenderers.register(type, provider); } } diff --git a/forge/src/main/java/dev/architectury/registry/client/rendering/forge/ColorHandlerRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/client/rendering/forge/ColorHandlerRegistryImpl.java index 15f32563b..70dae82f3 100644 --- a/forge/src/main/java/dev/architectury/registry/client/rendering/forge/ColorHandlerRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/client/rendering/forge/ColorHandlerRegistryImpl.java @@ -20,73 +20,43 @@ package dev.architectury.registry.client.rendering.forge; import com.google.common.collect.Lists; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.Minecraft; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.world.level.ItemLike; +import net.minecraft.client.color.block.BlockTintSource; import net.minecraft.world.level.block.Block; import net.minecraftforge.client.event.RegisterColorHandlersEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.apache.commons.lang3.tuple.Pair; +import java.lang.invoke.MethodHandles; import java.util.List; import java.util.Objects; import java.util.function.Supplier; public class ColorHandlerRegistryImpl { - private static final List[]>> ITEM_COLORS = Lists.newArrayList(); - private static final List[]>> BLOCK_COLORS = Lists.newArrayList(); - + private static final List[]>> BLOCK_COLORS = Lists.newArrayList(); + static { - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.register(ColorHandlerRegistryImpl.class); - }); - } - - @SubscribeEvent - public static void onItemColorEvent(RegisterColorHandlersEvent.Item event) { - for (Pair[]> pair : ITEM_COLORS) { - event.register(pair.getLeft(), unpackItems(pair.getRight())); - } + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), ColorHandlerRegistryImpl.class); } - + @SubscribeEvent public static void onBlockColorEvent(RegisterColorHandlersEvent.Block event) { - for (Pair[]> pair : BLOCK_COLORS) { - event.register(pair.getLeft(), unpackBlocks(pair.getRight())); - } - } - - @SafeVarargs - public static void registerItemColors(ItemColor itemColor, Supplier... items) { - Objects.requireNonNull(itemColor, "color is null!"); - if (Minecraft.getInstance().getItemColors() == null) { - ITEM_COLORS.add(Pair.of(itemColor, items)); - } else { - Minecraft.getInstance().getItemColors().register(itemColor, unpackItems(items)); + for (Pair[]> pair : BLOCK_COLORS) { + event.register(List.of(pair.getLeft()), unpackBlocks(pair.getRight())); } } - + @SafeVarargs - public static void registerBlockColors(BlockColor blockColor, Supplier... blocks) { + public static void registerBlockColors(BlockTintSource blockColor, Supplier... blocks) { Objects.requireNonNull(blockColor, "color is null!"); if (Minecraft.getInstance().getBlockColors() == null) { BLOCK_COLORS.add(Pair.of(blockColor, blocks)); } else { - Minecraft.getInstance().getBlockColors().register(blockColor, unpackBlocks(blocks)); + Minecraft.getInstance().getBlockColors().register(List.of(blockColor), unpackBlocks(blocks)); } } - - private static ItemLike[] unpackItems(Supplier[] items) { - ItemLike[] array = new ItemLike[items.length]; - for (int i = 0; i < items.length; i++) { - array[i] = Objects.requireNonNull(items[i].get()); - } - return array; - } - + private static Block[] unpackBlocks(Supplier[] blocks) { Block[] array = new Block[blocks.length]; for (int i = 0; i < blocks.length; i++) { diff --git a/forge/src/main/java/dev/architectury/registry/client/rendering/forge/RenderTypeRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/client/rendering/forge/RenderTypeRegistryImpl.java index 6d52d18d8..73b4d6eaa 100644 --- a/forge/src/main/java/dev/architectury/registry/client/rendering/forge/RenderTypeRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/client/rendering/forge/RenderTypeRegistryImpl.java @@ -19,21 +19,14 @@ package dev.architectury.registry.client.rendering.forge; -import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.material.Fluid; public class RenderTypeRegistryImpl { - public static void register(RenderType type, Block... blocks) { - for (Block block : blocks) { - ItemBlockRenderTypes.setRenderLayer(block, type); - } + public static void register(ChunkSectionLayer type, Block... blocks) { } - - public static void register(RenderType type, Fluid... fluids) { - for (Fluid fluid : fluids) { - ItemBlockRenderTypes.setRenderLayer(fluid, type); - } + + public static void register(ChunkSectionLayer type, Fluid... fluids) { } } diff --git a/forge/src/main/java/dev/architectury/registry/forge/CreativeTabRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/forge/CreativeTabRegistryImpl.java index f584bec80..8339f864a 100644 --- a/forge/src/main/java/dev/architectury/registry/forge/CreativeTabRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/forge/CreativeTabRegistryImpl.java @@ -22,11 +22,9 @@ import com.google.common.base.Suppliers; import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; -import dev.architectury.platform.hooks.EventBusesHooks; import dev.architectury.registry.CreativeTabOutput; import dev.architectury.registry.CreativeTabRegistry; import dev.architectury.registry.registries.DeferredSupplier; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.resources.Identifier; @@ -35,11 +33,14 @@ import net.minecraftforge.common.CreativeModeTabRegistry; import net.minecraftforge.common.util.MutableHashedLinkedMap; import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import java.lang.invoke.MethodHandles; import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; @@ -51,9 +52,7 @@ public class CreativeTabRegistryImpl { private static final Multimap> APPENDS = MultimapBuilder.hashKeys().arrayListValues().build(); static { - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.addListener(CreativeTabRegistryImpl::event); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), CreativeTabRegistryImpl.class); BUILD_CONTENTS_LISTENERS.add(event -> { for (Map.Entry>> keyEntry : APPENDS.asMap().entrySet()) { @@ -77,6 +76,7 @@ public class CreativeTabRegistryImpl { }); } + @SubscribeEvent public static void event(BuildCreativeModeTabContentsEvent event) { for (Consumer listener : BUILD_CONTENTS_LISTENERS) { listener.accept(event); @@ -99,7 +99,7 @@ public static DeferredSupplier ofBuiltin(CreativeModeTab tab) { return new DeferredSupplier<>() { @Override public Identifier getRegistryId() { - return Registries.CREATIVE_MODE_TAB.location(); + return Registries.CREATIVE_MODE_TAB.identifier(); } @Override @@ -127,7 +127,7 @@ public static DeferredSupplier defer(Identifier name) { @Override public Identifier getRegistryId() { - return Registries.CREATIVE_MODE_TAB.location(); + return Registries.CREATIVE_MODE_TAB.identifier(); } @Override @@ -151,7 +151,7 @@ public boolean isPresent() { private void resolve() { if (this.tab == null) { - this.tab = BuiltInRegistries.CREATIVE_MODE_TAB.get(name); + this.tab = BuiltInRegistries.CREATIVE_MODE_TAB.getValue(name); } } }; diff --git a/forge/src/main/java/dev/architectury/registry/forge/ReloadListenerRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/forge/ReloadListenerRegistryImpl.java index 253abba57..e15f95b60 100644 --- a/forge/src/main/java/dev/architectury/registry/forge/ReloadListenerRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/forge/ReloadListenerRegistryImpl.java @@ -20,8 +20,6 @@ package dev.architectury.registry.forge; import com.google.common.collect.Lists; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.Minecraft; import net.minecraft.resources.Identifier; import net.minecraft.server.packs.PackType; @@ -29,8 +27,9 @@ import net.minecraft.server.packs.resources.ReloadableResourceManager; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.AddReloadListenerEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; import org.jetbrains.annotations.Nullable; import java.util.Collection; @@ -40,7 +39,7 @@ public class ReloadListenerRegistryImpl { private static List serverDataReloadListeners = Lists.newArrayList(); static { - MinecraftForge.EVENT_BUS.addListener(ReloadListenerRegistryImpl::addReloadListeners); + MinecraftForge.EVENT_BUS.register(ReloadListenerRegistryImpl.class); } public static void register(PackType type, PreparableReloadListener listener, Identifier listenerId, Collection dependencies) { @@ -56,6 +55,7 @@ private static void registerClient(PreparableReloadListener listener) { ((ReloadableResourceManager) Minecraft.getInstance().getResourceManager()).registerReloadListener(listener); } + @SubscribeEvent public static void addReloadListeners(AddReloadListenerEvent event) { for (PreparableReloadListener listener : serverDataReloadListeners) { event.addListener(listener); diff --git a/forge/src/main/java/dev/architectury/registry/fuel/forge/FuelRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/fuel/forge/FuelRegistryImpl.java index cc7cc5f10..8db48b80e 100644 --- a/forge/src/main/java/dev/architectury/registry/fuel/forge/FuelRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/fuel/forge/FuelRegistryImpl.java @@ -22,11 +22,12 @@ import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.ItemLike; -import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; public class FuelRegistryImpl { private static final Object2IntMap ITEMS = new Object2IntLinkedOpenHashMap<>(); @@ -42,7 +43,7 @@ public static void register(int time, ItemLike... items) { } public static int get(ItemStack stack) { - return ForgeHooks.getBurnTime(stack, null); + return ForgeEventFactory.getItemBurnTime(stack, stack.getItem().getBurnTime(stack, (RecipeType) null), null); } @SubscribeEvent diff --git a/forge/src/main/java/dev/architectury/registry/item/forge/ItemPropertiesRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/item/forge/ItemPropertiesRegistryImpl.java index 0db8445a4..cba79e4e1 100644 --- a/forge/src/main/java/dev/architectury/registry/item/forge/ItemPropertiesRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/item/forge/ItemPropertiesRegistryImpl.java @@ -19,19 +19,7 @@ package dev.architectury.registry.item.forge; -import net.minecraft.client.renderer.item.ClampedItemPropertyFunction; -import net.minecraft.client.renderer.item.ItemProperties; -import net.minecraft.resources.Identifier; -import net.minecraft.world.level.ItemLike; - public class ItemPropertiesRegistryImpl { - public static ClampedItemPropertyFunction registerGeneric(Identifier propertyId, ClampedItemPropertyFunction function) { - ItemProperties.registerGeneric(propertyId, function); - return function; - } - - public static ClampedItemPropertyFunction register(ItemLike item, Identifier propertyId, ClampedItemPropertyFunction function) { - ItemProperties.register(item.asItem(), propertyId, function); - return function; + private ItemPropertiesRegistryImpl() { } } diff --git a/forge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java b/forge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java index 785f24df2..ef38d4983 100644 --- a/forge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java +++ b/forge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java @@ -20,7 +20,7 @@ package dev.architectury.registry.level.biome.forge; import com.google.common.collect.Lists; -import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import dev.architectury.hooks.forgelike.ForgeLikeHooks; import dev.architectury.hooks.level.biome.*; import dev.architectury.registry.level.biome.BiomeModifications.BiomeContext; @@ -29,12 +29,13 @@ import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.sounds.Music; import net.minecraft.sounds.SoundEvent; import net.minecraft.tags.TagKey; +import net.minecraft.util.random.WeightedList; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.level.biome.*; @@ -45,6 +46,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Field; import java.util.List; import java.util.Map; import java.util.Optional; @@ -59,35 +61,37 @@ public class BiomeModificationsImpl { private static final List, BiConsumer>> REMOVALS = Lists.newArrayList(); private static final List, BiConsumer>> REPLACEMENTS = Lists.newArrayList(); @Nullable - private static Codec noneBiomeModCodec = null; - + private static MapCodec noneBiomeModCodec = null; + public static void init() { - ForgeLikeHooks.registerBiomeModifier(new Identifier(ArchitecturyConstants.MOD_ID, "none_biome_mod_codec"), - () -> noneBiomeModCodec = Codec.unit(BiomeModifierImpl.INSTANCE)); + ForgeLikeHooks.registerBiomeModifier( + Identifier.fromNamespaceAndPath(ArchitecturyConstants.MOD_ID, "none_biome_mod_codec"), + () -> MapCodec.unit(BiomeModifierImpl.INSTANCE).codec() + ); + noneBiomeModCodec = MapCodec.unit(BiomeModifierImpl.INSTANCE); } - + public static void addProperties(Predicate predicate, BiConsumer modifier) { ADDITIONS.add(Pair.of(predicate, modifier)); } - + public static void postProcessProperties(Predicate predicate, BiConsumer modifier) { POST_PROCESSING.add(Pair.of(predicate, modifier)); } - + public static void removeProperties(Predicate predicate, BiConsumer modifier) { REMOVALS.add(Pair.of(predicate, modifier)); } - + public static void replaceProperties(Predicate predicate, BiConsumer modifier) { REPLACEMENTS.add(Pair.of(predicate, modifier)); } - + private static class BiomeModifierImpl implements BiomeModifier { - // cry about it private static final BiomeModifierImpl INSTANCE = new BiomeModifierImpl(); - + @Override - public void modify(Holder arg, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) { + public void modify(Holder biome, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) { List, BiConsumer>> list = switch (phase) { case ADD -> ADDITIONS; case REMOVE -> REMOVALS; @@ -95,9 +99,12 @@ public void modify(Holder arg, Phase phase, ModifiableBiomeInfo.BiomeInfo case AFTER_EVERYTHING -> POST_PROCESSING; default -> null; }; - - if (list == null) return; - BiomeContext biomeContext = wrapSelectionContext(arg.unwrapKey(), builder); + + if (list == null) { + return; + } + + BiomeContext biomeContext = wrapSelectionContext(biome.unwrapKey(), builder); BiomeProperties.Mutable mutableBiome = new MutableBiomeWrapped(builder); for (var pair : list) { if (pair.getLeft().test(biomeContext)) { @@ -105,394 +112,448 @@ public void modify(Holder arg, Phase phase, ModifiableBiomeInfo.BiomeInfo } } } - + @Override - public Codec codec() { - if (noneBiomeModCodec != null) { - return noneBiomeModCodec; - } else { - return Codec.unit(INSTANCE); - } + public MapCodec codec() { + return noneBiomeModCodec != null ? noneBiomeModCodec : MapCodec.unit(INSTANCE); } } - - private static BiomeContext wrapSelectionContext(Optional> biomeResourceKey, ModifiableBiomeInfo.BiomeInfo.Builder event) { + + private static BiomeContext wrapSelectionContext(Optional> biomeResourceKey, ModifiableBiomeInfo.BiomeInfo.Builder builder) { return new BiomeContext() { - BiomeProperties properties = new BiomeWrapped(event); - + private final BiomeProperties properties = new BiomeWrapped(builder); + @Override public Optional getKey() { - return biomeResourceKey.map(ResourceKey::location); + return biomeResourceKey.map(ResourceKey::identifier); } - + @Override public BiomeProperties getProperties() { return properties; } - + @Override public boolean hasTag(TagKey tag) { + if (biomeResourceKey.isEmpty()) { + return false; + } MinecraftServer server = GameInstance.getServer(); - if (server != null) { - Optional> registry = server.registryAccess().registry(Registries.BIOME); - if (registry.isPresent()) { - Optional> holder = registry.get().getHolder(biomeResourceKey.get()); - if (holder.isPresent()) { - return holder.get().is(tag); - } - } + if (server == null) { + return false; + } + + Optional> registry = server.registryAccess().lookup(Registries.BIOME); + if (registry.isEmpty()) { + return false; } - return false; + + return registry.get().get(biomeResourceKey.get()).map(holder -> holder.is(tag)).orElse(false); } }; } - + public static class BiomeWrapped implements BiomeProperties { - protected final ModifiableBiomeInfo.BiomeInfo.Builder event; + protected final ModifiableBiomeInfo.BiomeInfo.Builder builder; protected final ClimateProperties climateProperties; protected final EffectsProperties effectsProperties; protected final GenerationProperties generationProperties; protected final SpawnProperties spawnProperties; - - public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event) { - this(event, - new MutableClimatePropertiesWrapped(event.getClimateSettings()), - new MutableEffectsPropertiesWrapped(event.getSpecialEffects()), - new GenerationSettingsBuilderWrapped(event.getGenerationSettings()), - new SpawnSettingsBuilderWrapped(event.getMobSpawnSettings()) + + public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder builder) { + this( + builder, + new MutableClimatePropertiesWrapped(builder.getClimateSettings()), + new MutableEffectsPropertiesWrapped(builder.getSpecialEffects()), + new GenerationSettingsBuilderWrapped(builder.getGenerationSettings()), + new SpawnSettingsBuilderWrapped(builder.getMobSpawnSettings()) ); } - - public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event, ClimateProperties climateProperties, EffectsProperties effectsProperties, GenerationProperties generationProperties, SpawnProperties spawnProperties) { - this.event = event; + + public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder builder, ClimateProperties climateProperties, EffectsProperties effectsProperties, GenerationProperties generationProperties, SpawnProperties spawnProperties) { + this.builder = builder; this.climateProperties = climateProperties; this.effectsProperties = effectsProperties; this.generationProperties = generationProperties; this.spawnProperties = spawnProperties; } - + @Override public ClimateProperties getClimateProperties() { return climateProperties; } - + @Override public EffectsProperties getEffectsProperties() { return effectsProperties; } - + @Override public GenerationProperties getGenerationProperties() { return generationProperties; } - + @Override public SpawnProperties getSpawnProperties() { return spawnProperties; } } - + private static class GenerationSettingsBuilderWrapped implements GenerationProperties { - protected final BiomeGenerationSettingsBuilder generation; - - public GenerationSettingsBuilderWrapped(BiomeGenerationSettingsBuilder generation) { + protected final BiomeGenerationSettings.PlainBuilder generation; + + public GenerationSettingsBuilderWrapped(BiomeGenerationSettings.PlainBuilder generation) { this.generation = generation; } - + @Override - public Iterable>> getCarvers(GenerationStep.Carving carving) { - return generation.getCarvers(carving); + public Iterable>> getCarvers() { + return generationCarvers(generation); } - + @Override public Iterable> getFeatures(GenerationStep.Decoration decoration) { return generation.getFeatures(decoration); } - + @Override public List>> getFeatures() { - return (List>>) (List) generation.features; + return (List>>) (List) generationFeatures(generation); } } - + private static class SpawnSettingsBuilderWrapped implements SpawnProperties { protected final MobSpawnSettingsBuilder builder; - + public SpawnSettingsBuilderWrapped(MobSpawnSettingsBuilder builder) { this.builder = builder; } - + @Override public float getCreatureProbability() { return builder.getProbability(); } - + @Override - public Map> getSpawners() { - return builder.spawners; + public Map> getSpawners() { + return spawnEntries(builder); } - + @Override public Map, MobSpawnSettings.MobSpawnCost> getMobSpawnCosts() { - return builder.mobSpawnCosts; + return spawnCosts(builder); } } - + public static class MutableBiomeWrapped extends BiomeWrapped implements BiomeProperties.Mutable { - public MutableBiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event) { - super(event, - new MutableClimatePropertiesWrapped(event.getClimateSettings()), - new MutableEffectsPropertiesWrapped(event.getSpecialEffects()), - new MutableGenerationSettingsBuilderWrapped(event.getGenerationSettings()), - new MutableSpawnSettingsBuilderWrapped(event.getMobSpawnSettings()) + public MutableBiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder builder) { + super( + builder, + new MutableClimatePropertiesWrapped(builder.getClimateSettings()), + new MutableEffectsPropertiesWrapped(builder.getSpecialEffects()), + new MutableGenerationSettingsBuilderWrapped(builder.getGenerationSettings()), + new MutableSpawnSettingsBuilderWrapped(builder.getMobSpawnSettings()) ); } - + @Override public ClimateProperties.Mutable getClimateProperties() { return (ClimateProperties.Mutable) super.getClimateProperties(); } - + @Override public EffectsProperties.Mutable getEffectsProperties() { return (EffectsProperties.Mutable) super.getEffectsProperties(); } - + @Override public GenerationProperties.Mutable getGenerationProperties() { return (GenerationProperties.Mutable) super.getGenerationProperties(); } - + @Override public SpawnProperties.Mutable getSpawnProperties() { return (SpawnProperties.Mutable) super.getSpawnProperties(); } } - + public static class MutableClimatePropertiesWrapped implements ClimateProperties.Mutable { - public ClimateSettingsBuilder builder; - + private final ClimateSettingsBuilder builder; + public MutableClimatePropertiesWrapped(ClimateSettingsBuilder builder) { this.builder = builder; } - + @Override public boolean hasPrecipitation() { return builder.hasPrecipitation(); } - + @Override public float getTemperature() { return builder.getTemperature(); } - + @Override public Biome.TemperatureModifier getTemperatureModifier() { return builder.getTemperatureModifier(); } - + @Override public float getDownfall() { return builder.getDownfall(); } - + @Override public Mutable setHasPrecipitation(boolean hasPrecipitation) { - this.builder.setHasPrecipitation(hasPrecipitation); + builder.setHasPrecipitation(hasPrecipitation); return this; } - + @Override public Mutable setTemperature(float temperature) { - this.builder.setTemperature(temperature); + builder.setTemperature(temperature); return this; } - + @Override public Mutable setTemperatureModifier(Biome.TemperatureModifier temperatureModifier) { - this.builder.setTemperatureModifier(temperatureModifier); + builder.setTemperatureModifier(temperatureModifier); return this; } - + @Override public Mutable setDownfall(float downfall) { - this.builder.setDownfall(downfall); + builder.setDownfall(downfall); return this; } - } - + public static class MutableEffectsPropertiesWrapped implements EffectsProperties.Mutable { - public BiomeSpecialEffects.Builder builder; - - public MutableEffectsPropertiesWrapped(BiomeSpecialEffects.Builder builder) { + private final BiomeSpecialEffectsBuilder builder; + + public MutableEffectsPropertiesWrapped(BiomeSpecialEffectsBuilder builder) { this.builder = builder; } - + @Override public int getWaterColor() { - return builder.waterColor.orElse(-1); + return builder.waterColor().orElse(-1); } - + @Override public OptionalInt getFoliageColorOverride() { - return builder.foliageColorOverride.map(OptionalInt::of).orElseGet(OptionalInt::empty); + return builder.foliageColorOverride().map(OptionalInt::of).orElseGet(OptionalInt::empty); } - + @Override public OptionalInt getDryFoliageColorOverride() { - return builder.dryFoliageColorOverride.map(OptionalInt::of).orElseGet(OptionalInt::empty); + return builder.dryFoliageColorOverride().map(OptionalInt::of).orElseGet(OptionalInt::empty); } - + @Override public OptionalInt getGrassColorOverride() { - return builder.grassColorOverride.map(OptionalInt::of).orElseGet(OptionalInt::empty); + return builder.grassColorOverride().map(OptionalInt::of).orElseGet(OptionalInt::empty); } - + @Override public BiomeSpecialEffects.GrassColorModifier getGrassColorModifier() { - return builder.grassColorModifier; + return builder.getGrassColorModifier(); } - + @Override public Mutable setWaterColor(int color) { builder.waterColor(color); return this; } - + @Override public Mutable setFoliageColorOverride(@Nullable Integer colorOverride) { - builder.foliageColorOverride = Optional.ofNullable(colorOverride); + setField(builder, "foliageColorOverride", Optional.ofNullable(colorOverride)); return this; } - + @Override public Mutable setDryFoliageColorOverride(@Nullable Integer colorOverride) { - builder.dryFoliageColorOverride = Optional.ofNullable(colorOverride); + setField(builder, "dryFoliageColorOverride", Optional.ofNullable(colorOverride)); return this; } - + @Override public Mutable setGrassColorOverride(@Nullable Integer colorOverride) { - builder.foliageColorOverride = Optional.ofNullable(colorOverride); + setField(builder, "grassColorOverride", Optional.ofNullable(colorOverride)); return this; } - + @Override public Mutable setGrassColorModifier(BiomeSpecialEffects.GrassColorModifier modifier) { builder.grassColorModifier(modifier); return this; } } - + private static class MutableGenerationSettingsBuilderWrapped extends GenerationSettingsBuilderWrapped implements GenerationProperties.Mutable { - public MutableGenerationSettingsBuilderWrapped(BiomeGenerationSettingsBuilder generation) { + public MutableGenerationSettingsBuilderWrapped(BiomeGenerationSettings.PlainBuilder generation) { super(generation); } - + @Override public Mutable addFeature(GenerationStep.Decoration decoration, Holder feature) { generation.addFeature(decoration, feature); return this; } - + @Override public Mutable addFeature(GenerationStep.Decoration decoration, ResourceKey feature) { MinecraftServer server = GameInstance.getServer(); if (server != null) { - Optional> registry = server.registryAccess().registry(Registries.PLACED_FEATURE); + Optional> registry = server.registryAccess().lookup(Registries.PLACED_FEATURE); if (registry.isPresent()) { - Optional> holder = registry.get().getHolder(feature); + Optional> holder = registry.get().get(feature); if (holder.isPresent()) { return addFeature(decoration, holder.get()); - } else { - throw new IllegalArgumentException("Unknown feature: " + feature); } + throw new IllegalArgumentException("Unknown feature: " + feature); } } return this; } - + @Override - public Mutable addCarver(GenerationStep.Carving carving, Holder> feature) { - generation.addCarver(carving, feature); + public Mutable addCarver(Holder> feature) { + generation.addCarver(feature); return this; } - + @Override - public Mutable addCarver(GenerationStep.Carving carving, ResourceKey> feature) { + public Mutable addCarver(ResourceKey> feature) { MinecraftServer server = GameInstance.getServer(); if (server != null) { - Optional>> registry = server.registryAccess().registry(Registries.CONFIGURED_CARVER); + Optional>> registry = server.registryAccess().lookup(Registries.CONFIGURED_CARVER); if (registry.isPresent()) { - Optional>> holder = registry.get().getHolder(feature); + Optional>> holder = registry.get().get(feature); if (holder.isPresent()) { - return addCarver(carving, holder.get()); - } else { - throw new IllegalArgumentException("Unknown carver: " + feature); + return addCarver(holder.get()); } + throw new IllegalArgumentException("Unknown carver: " + feature); } } return this; } - + @Override public Mutable removeFeature(GenerationStep.Decoration decoration, ResourceKey feature) { - generation.getFeatures(decoration).removeIf(supplier -> supplier.is(feature)); + generation.getFeatures(decoration).removeIf(holder -> holder.is(feature)); return this; } - + @Override - public Mutable removeCarver(GenerationStep.Carving carving, ResourceKey> feature) { - generation.getCarvers(carving).removeIf(supplier -> supplier.is(feature)); + public Mutable removeCarver(ResourceKey> feature) { + generationCarvers(generation).removeIf(holder -> holder.is(feature)); return this; } } - + private static class MutableSpawnSettingsBuilderWrapped extends SpawnSettingsBuilderWrapped implements SpawnProperties.Mutable { public MutableSpawnSettingsBuilderWrapped(MobSpawnSettingsBuilder builder) { super(builder); } - + @Override public Mutable setCreatureProbability(float probability) { builder.creatureGenerationProbability(probability); return this; } - + @Override - public Mutable addSpawn(MobCategory category, MobSpawnSettings.SpawnerData data) { - builder.addSpawn(category, data); + public Mutable addSpawn(MobCategory category, MobSpawnSettings.SpawnerData data, int weight) { + builder.addSpawn(category, weight, data); return this; } - + @Override public boolean removeSpawns(BiPredicate predicate) { boolean removed = false; for (MobCategory type : builder.getSpawnerTypes()) { - if (builder.getSpawner(type).removeIf(data -> predicate.test(type, data))) { + var weightedSpawnerList = builder.getSpawner(type); + int before = weightedSpawnerList.build().unwrap().size(); + weightedSpawnerList.removeIf(data -> predicate.test(type, data)); + if (weightedSpawnerList.build().unwrap().size() != before) { removed = true; } } return removed; } - + @Override public Mutable setSpawnCost(EntityType entityType, MobSpawnSettings.MobSpawnCost cost) { builder.addMobCharge(entityType, cost.charge(), cost.energyBudget()); return this; } - + @Override public Mutable setSpawnCost(EntityType entityType, double charge, double energyBudget) { builder.addMobCharge(entityType, charge, energyBudget); return this; } - + @Override public Mutable clearSpawnCost(EntityType entityType) { - getMobSpawnCosts().remove(entityType); + spawnCosts(builder).remove(entityType); return this; } } + + @SuppressWarnings("unchecked") + private static List>> generationCarvers(BiomeGenerationSettings.PlainBuilder builder) { + return (List>>) getField(builder, "carvers"); + } + + @SuppressWarnings("unchecked") + private static List>> generationFeatures(BiomeGenerationSettings.PlainBuilder builder) { + return (List>>) getField(builder, "features"); + } + + @SuppressWarnings("unchecked") + private static Map> spawnEntries(MobSpawnSettingsBuilder builder) { + return (Map>) getField(builder, "spawners"); + } + + @SuppressWarnings("unchecked") + private static Map, MobSpawnSettings.MobSpawnCost> spawnCosts(MobSpawnSettingsBuilder builder) { + return (Map, MobSpawnSettings.MobSpawnCost>) getField(builder, "mobSpawnCosts"); + } + + private static Object getField(Object target, String name) { + Class current = target.getClass(); + while (current != null) { + try { + Field field = current.getDeclaredField(name); + field.setAccessible(true); + return field.get(target); + } catch (NoSuchFieldException ignored) { + current = current.getSuperclass(); + } catch (IllegalAccessException exception) { + throw new IllegalStateException("Failed to access field '" + name + "' on " + target.getClass(), exception); + } + } + throw new IllegalStateException("Could not find field '" + name + "' on " + target.getClass()); + } + + private static void setField(Object target, String name, Object value) { + Class current = target.getClass(); + while (current != null) { + try { + Field field = current.getDeclaredField(name); + field.setAccessible(true); + field.set(target, value); + return; + } catch (NoSuchFieldException ignored) { + current = current.getSuperclass(); + } catch (IllegalAccessException exception) { + throw new IllegalStateException("Failed to set field '" + name + "' on " + target.getClass(), exception); + } + } + throw new IllegalStateException("Could not find field '" + name + "' on " + target.getClass()); + } } diff --git a/forge/src/main/java/dev/architectury/registry/level/entity/forge/EntityAttributeRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/level/entity/forge/EntityAttributeRegistryImpl.java index 56a61b68f..36ce50560 100644 --- a/forge/src/main/java/dev/architectury/registry/level/entity/forge/EntityAttributeRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/level/entity/forge/EntityAttributeRegistryImpl.java @@ -19,14 +19,14 @@ package dev.architectury.registry.level.entity.forge; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraftforge.event.entity.EntityAttributeCreationEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import java.lang.invoke.MethodHandles; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; @@ -39,9 +39,7 @@ public static void register(Supplier { - bus.register(EntityAttributeRegistryImpl.class); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), EntityAttributeRegistryImpl.class); } @SubscribeEvent diff --git a/forge/src/main/java/dev/architectury/registry/level/entity/forge/SpawnPlacementsRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/level/entity/forge/SpawnPlacementsRegistryImpl.java index a8c181682..c53477829 100644 --- a/forge/src/main/java/dev/architectury/registry/level/entity/forge/SpawnPlacementsRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/level/entity/forge/SpawnPlacementsRegistryImpl.java @@ -19,43 +19,46 @@ package dev.architectury.registry.level.entity.forge; -import dev.architectury.platform.hooks.EventBusesHooks; -import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.SpawnPlacementType; import net.minecraft.world.entity.SpawnPlacements; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraftforge.event.entity.SpawnPlacementRegisterEvent; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; public class SpawnPlacementsRegistryImpl { private static List> entries = new ArrayList<>(); - - private record Entry(Supplier> type, SpawnPlacements.Type spawnPlacement, + + private record Entry(Supplier> type, SpawnPlacementType spawnPlacement, Heightmap.Types heightmapType, SpawnPlacements.SpawnPredicate spawnPredicate) { } - + static { - EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { - bus.addListener(event -> { - for (Entry entry : entries) { - Entry casted = (Entry) entry; - event.register(casted.type().get(), casted.spawnPlacement(), casted.heightmapType(), casted.spawnPredicate(), SpawnPlacementRegisterEvent.Operation.OR); - } - entries = null; - }); - }); + FMLJavaModLoadingContext.get().getModBusGroup().register(MethodHandles.lookup(), SpawnPlacementsRegistryImpl.class); } - - public static void register(Supplier> type, SpawnPlacements.Type spawnPlacement, Heightmap.Types heightmapType, SpawnPlacements.SpawnPredicate spawnPredicate) { + + public static void register(Supplier> type, SpawnPlacementType spawnPlacement, Heightmap.Types heightmapType, SpawnPlacements.SpawnPredicate spawnPredicate) { if (entries != null) { entries.add(new Entry<>(type, spawnPlacement, heightmapType, spawnPredicate)); } else { throw new IllegalStateException("SpawnPlacementsRegistry.register must not be called after the registry has been collected!"); } } + + @SubscribeEvent + public static void event(SpawnPlacementRegisterEvent event) { + for (Entry entry : entries) { + Entry casted = (Entry) entry; + event.register(casted.type().get(), casted.spawnPlacement(), casted.heightmapType(), casted.spawnPredicate(), SpawnPlacementRegisterEvent.Operation.OR); + } + entries = null; + } } diff --git a/forge/src/main/java/dev/architectury/registry/level/entity/trade/forge/TradeRegistryImpl.java b/forge/src/main/java/dev/architectury/registry/level/entity/trade/forge/TradeRegistryImpl.java index 00d886026..6dc10d251 100644 --- a/forge/src/main/java/dev/architectury/registry/level/entity/trade/forge/TradeRegistryImpl.java +++ b/forge/src/main/java/dev/architectury/registry/level/entity/trade/forge/TradeRegistryImpl.java @@ -19,57 +19,64 @@ package dev.architectury.registry.level.entity.trade.forge; +import dev.architectury.registry.level.entity.trade.TradeRegistry; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import net.minecraft.core.NonNullList; -import net.minecraft.world.entity.npc.VillagerProfession; -import net.minecraft.world.entity.npc.VillagerTrades; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.village.VillagerTradesEvent; -import net.minecraftforge.event.village.WandererTradesEvent; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.npc.villager.VillagerProfession; +import net.minecraft.world.item.trading.MerchantOffer; +import net.minecraft.world.item.trading.MerchantOffers; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class TradeRegistryImpl { - private static final Map>> TRADES_TO_ADD = new HashMap<>(); - private static final List WANDERER_TRADER_TRADES_GENERIC = new ArrayList<>(); - private static final List WANDERER_TRADER_TRADES_RARE = new ArrayList<>(); - - static { - MinecraftForge.EVENT_BUS.addListener(TradeRegistryImpl::onTradeRegistering); - MinecraftForge.EVENT_BUS.addListener(TradeRegistryImpl::onWanderingTradeRegistering); - } - - public static void registerVillagerTrade0(VillagerProfession profession, int level, VillagerTrades.ItemListing... trades) { - Int2ObjectMap> tradesForProfession = TRADES_TO_ADD.computeIfAbsent(profession, $ -> new Int2ObjectOpenHashMap<>()); - List tradesForLevel = tradesForProfession.computeIfAbsent(level, $ -> new ArrayList<>()); + private static final Map, Int2ObjectMap>> TRADES_TO_ADD = new HashMap<>(); + private static final EnumMap> WANDERER_TRADES_TO_ADD = new EnumMap<>(TradeRegistry.WandererTradeType.class); + + public static void registerVillagerTrade0(ResourceKey profession, int level, TradeRegistry.ItemListing... trades) { + Int2ObjectMap> tradesForProfession = TRADES_TO_ADD.computeIfAbsent(profession, $ -> new Int2ObjectOpenHashMap<>()); + List tradesForLevel = tradesForProfession.computeIfAbsent(level, $ -> new ArrayList<>()); Collections.addAll(tradesForLevel, trades); } - - public static void registerTradeForWanderingTrader(boolean rare, VillagerTrades.ItemListing... trades) { - if (rare) { - Collections.addAll(WANDERER_TRADER_TRADES_RARE, trades); - } else { - Collections.addAll(WANDERER_TRADER_TRADES_GENERIC, trades); + + public static void registerTradeForWanderingTrader(TradeRegistry.WandererTradeType type, TradeRegistry.ItemListing... trades) { + List tradesForType = WANDERER_TRADES_TO_ADD.computeIfAbsent(type, $ -> new ArrayList<>()); + Collections.addAll(tradesForType, trades); + } + + public static void appendVillagerTrades(ServerLevel level, MerchantOffers offers, ResourceKey profession, int villagerLevel, Entity entity, RandomSource random) { + Int2ObjectMap> tradesForProfession = TRADES_TO_ADD.get(profession); + if (tradesForProfession == null) { + return; } + + appendTrades(level, offers, tradesForProfession.get(villagerLevel), entity, random); } - - public static void onTradeRegistering(VillagerTradesEvent event) { - Int2ObjectMap> trades = TRADES_TO_ADD.get(event.getType()); - - if (trades != null) { - for (Int2ObjectMap.Entry> entry : trades.int2ObjectEntrySet()) { - event.getTrades().computeIfAbsent(entry.getIntKey(), $ -> NonNullList.create()).addAll(entry.getValue()); - } + + public static void appendWanderingTraderTrades(ServerLevel level, MerchantOffers offers, Entity entity, RandomSource random) { + for (TradeRegistry.WandererTradeType type : TradeRegistry.WandererTradeType.values()) { + appendTrades(level, offers, WANDERER_TRADES_TO_ADD.get(type), entity, random); } } - - public static void onWanderingTradeRegistering(WandererTradesEvent event) { - if (!WANDERER_TRADER_TRADES_GENERIC.isEmpty()) { - event.getGenericTrades().addAll(WANDERER_TRADER_TRADES_GENERIC); + + private static void appendTrades(ServerLevel level, MerchantOffers offers, List trades, Entity entity, RandomSource random) { + if (trades == null) { + return; } - if (!WANDERER_TRADER_TRADES_RARE.isEmpty()) { - event.getRareTrades().addAll(WANDERER_TRADER_TRADES_RARE); + + for (TradeRegistry.ItemListing trade : trades) { + MerchantOffer offer = trade.getOffer(level, entity, random); + if (offer != null) { + offers.add(offer); + } } } } diff --git a/forge/src/main/resources/architectury.mixins.json b/forge/src/main/resources/architectury.mixins.json index c45d0798a..b7adc6371 100644 --- a/forge/src/main/resources/architectury.mixins.json +++ b/forge/src/main/resources/architectury.mixins.json @@ -2,7 +2,7 @@ "required": true, "package": "dev.architectury.mixin.forge", "plugin": "dev.architectury.plugin.forge.ArchitecturyMixinPlugin", - "compatibilityLevel": "JAVA_16", + "compatibilityLevel": "JAVA_25", "minVersion": "0.8", "client": [ "client.MixinCommandSourceStack", @@ -11,9 +11,9 @@ ], "mixins": [ "MixinFallingBlockEntity", - "MixinItemExtension", "MixinLevelEvent", - "MixinLootDataManager" + "MixinVillager", + "MixinWanderingTrader" ], "injectors": { "defaultRequire": 1 diff --git a/gradle.properties b/gradle.properties index d8a377938..1324cef4a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,8 +3,9 @@ org.gradle.daemon=false platforms=fabric,neoforge -minecraft_version=1.21.11 -supported_version=1.21.11 +minecraft_version=26.1.1 +supported_version=26.1/26.1.1 +forge_minecraft_version=26.1.1 artifact_type=release @@ -14,12 +15,12 @@ base_version=19.0 maven_group=dev.architectury version_suffix= -fabric_loader_version=0.18.2 -fabric_api_version=0.139.4+1.21.11 -mod_menu_version=17.0.0-alpha.1 +fabric_loader_version=0.18.5 +fabric_api_version=0.145.4+26.1.1 +mod_menu_version=18.0.0-alpha.5 -forge_version=61.0.1 -neoforge_version=21.11.0-beta +forge_version=63.0.1 +neoforge_version=26.1.1.11-beta # Set to empty if not snapshots neoforge_pr= @@ -28,3 +29,4 @@ curseforge_id=419699 modrinth_id=lhGA9TYQ loom.ignoreDependencyLoomVersionValidation=true +loom.allowMismatchedPlatformVersion=true diff --git a/gradle/architectury-loom-1.14.10001.jar b/gradle/architectury-loom-1.14.10001.jar new file mode 100644 index 000000000..727930cf4 Binary files /dev/null and b/gradle/architectury-loom-1.14.10001.jar differ diff --git a/gradle/identity-mappings-1.21.11.jar b/gradle/identity-mappings-1.21.11.jar new file mode 100644 index 000000000..1531f52a0 Binary files /dev/null and b/gradle/identity-mappings-1.21.11.jar differ diff --git a/gradle/identity-mappings-26.1.jar b/gradle/identity-mappings-26.1.jar new file mode 100644 index 000000000..1531f52a0 Binary files /dev/null and b/gradle/identity-mappings-26.1.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e48eca575..19a6bdeb8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/minecraftforge/build.gradle b/minecraftforge/build.gradle index d73b429bf..999a2655c 100644 --- a/minecraftforge/build.gradle +++ b/minecraftforge/build.gradle @@ -1,6 +1,5 @@ plugins { - id "com.github.johnrengelman.shadow" version "8.1.1" - id "me.shedaniel.unified-publishing" + id "com.gradleup.shadow" version "8.3.10" } loom { @@ -30,12 +29,13 @@ configurations { } dependencies { - forge "net.minecraftforge:forge:${rootProject.architectury.minecraft}-${rootProject.forge_version}" + def forgeMinecraftVersion = rootProject.findProperty("forge_minecraft_version") ?: rootProject.architectury.minecraft + forge "net.minecraftforge:forge:${forgeMinecraftVersion}-${rootProject.forge_version}" - common(project(path: ":common", configuration: "namedElements")) { transitive false } - common(project(path: ":forge", configuration: "namedElements")) { transitive false } - shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive false } - shadowCommon(project(path: ":forge", configuration: "transformProductionForge")) { transitive false } + common(project(path: ":common", configuration: "apiElements")) { transitive false } + common(project(path: ":forge", configuration: "apiElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "runtimeElements")) { transitive false } + shadowCommon(project(path: ":forge", configuration: "runtimeElements")) { transitive false } } processResources { @@ -65,14 +65,8 @@ shadowJar { relocate "dev.architectury.core.item.forge.imitator", "dev.architectury.core.item" } -remapJar { - input.set shadowJar.archiveFile - dependsOn shadowJar - archiveClassifier = null -} - -task renameJarForPublication(type: Zip, dependsOn: remapJar) { - from remapJar.archiveFile.map { zipTree(it) } +task renameJarForPublication(type: Zip, dependsOn: shadowJar) { + from shadowJar.archiveFile.map { zipTree(it) } archiveExtension = "jar" metadataCharset "UTF-8" destinationDirectory = base.libsDirectory @@ -124,31 +118,3 @@ publishing { } } -unifiedPublishing { - project { - displayName = "[MinecraftForge $rootProject.supported_version] v$project.version" - releaseType = "$rootProject.artifact_type" - changelog = releaseChangelog() - gameVersions = ["1.20.6"] - gameLoaders = ["forge"] - mainPublication renameJarForPublication - - var CURSE_API_KEY = project.findProperty("CURSE_API_KEY") ?: System.getenv("CURSE_API_KEY") - if (CURSE_API_KEY != null) { - curseforge { - token = CURSE_API_KEY - id = rootProject.curseforge_id - gameVersions.addAll "Java 17" - } - } - - var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN") - if (MODRINTH_TOKEN != null) { - modrinth { - token = MODRINTH_TOKEN - id = rootProject.modrinth_id - version = "$project.version+$project.name" - } - } - } -} diff --git a/minecraftforge/src/main/resources/architectury-forge.mixins.json b/minecraftforge/src/main/resources/architectury-forge.mixins.json index a02097dc2..7506673d5 100644 --- a/minecraftforge/src/main/resources/architectury-forge.mixins.json +++ b/minecraftforge/src/main/resources/architectury-forge.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "dev.architectury.mixin.forge", - "compatibilityLevel": "JAVA_16", + "compatibilityLevel": "JAVA_25", "minVersion": "0.8", "client": [ ], diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 19ea31b7e..bc0552019 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -1,6 +1,5 @@ plugins { - id "com.github.johnrengelman.shadow" version "8.1.1" - id "me.shedaniel.unified-publishing" + id "com.gradleup.shadow" version "8.3.10" } loom { @@ -25,8 +24,8 @@ configurations { dependencies { neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}" - common(project(path: ":common", configuration: "namedElements")) { transitive false } - shadowCommon(project(path: ":common", configuration: "transformProductionNeoForge")) { transitive false } + common(project(path: ":common", configuration: "apiElements")) { transitive false } + shadowCommon(files(project(":common").tasks.named("transformProductionNeoForge"))) } processResources { @@ -55,15 +54,10 @@ shadowJar { relocate "dev.architectury.core.item.forge.imitator", "dev.architectury.core.item" } -remapJar { - input.set shadowJar.archiveFile - dependsOn shadowJar - archiveClassifier = null - atAccessWideners.add "architectury.accessWidener" -} +shadowJar.dependsOn(project(":common").tasks.named("transformProductionNeoForge")) -task renameJarForPublication(type: Zip, dependsOn: remapJar) { - from remapJar.archiveFile.map { zipTree(it) } +task renameJarForPublication(type: Zip, dependsOn: shadowJar) { + from shadowJar.archiveFile.map { zipTree(it) } archiveExtension = "jar" metadataCharset "UTF-8" destinationDirectory = base.libsDirectory @@ -115,33 +109,4 @@ publishing { } } -unifiedPublishing { - if (rootProject.neoforge_pr != "") return // Don't publish PRs - project { - displayName = "[NeoForge $rootProject.supported_version] v$project.version" - releaseType = "$rootProject.artifact_type" - changelog = releaseChangelog() - gameVersions = ["1.21.11"] - gameLoaders = ["neoforge"] - mainPublication renameJarForPublication - - var CURSE_API_KEY = project.findProperty("CURSE_API_KEY") ?: System.getenv("CURSE_API_KEY") - if (CURSE_API_KEY != null) { - curseforge { - token = CURSE_API_KEY - id = rootProject.curseforge_id - gameVersions.addAll "Java 21" - } - } - - var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN") - if (MODRINTH_TOKEN != null) { - modrinth { - token = MODRINTH_TOKEN - id = rootProject.modrinth_id - version = "$project.version+$project.name" - } - } - } -} diff --git a/neoforge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFluidAttributesForge.java b/neoforge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFluidAttributesForge.java index f74eebe6a..7c46d0da1 100644 --- a/neoforge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFluidAttributesForge.java +++ b/neoforge/src/main/java/dev/architectury/core/fluid/forge/imitator/ArchitecturyFluidAttributesForge.java @@ -21,10 +21,8 @@ import com.google.common.base.MoreObjects; import dev.architectury.core.fluid.ArchitecturyFluidAttributes; -import dev.architectury.fluid.forge.ArchitecturyFluidAttributesClient; import dev.architectury.hooks.fluid.forge.FluidStackHooksForge; -import dev.architectury.platform.Platform; -import dev.architectury.utils.Env; +import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; @@ -34,32 +32,27 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.BlockAndLightGetter; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; import net.neoforged.neoforge.common.SoundAction; +import net.neoforged.neoforge.common.SoundActions; import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidType; import org.jetbrains.annotations.Nullable; -import static net.minecraft.sounds.SoundEvents.BUCKET_EMPTY; -import static net.minecraft.sounds.SoundEvents.BUCKET_FILL; - -class ArchitecturyFluidAttributesForge extends FluidType { +public class ArchitecturyFluidAttributesForge extends FluidType { private final ArchitecturyFluidAttributes attributes; private final String defaultTranslationKey; - + public ArchitecturyFluidAttributesForge(Properties builder, Fluid fluid, ArchitecturyFluidAttributes attributes) { super(addArchIntoBuilder(builder, attributes)); this.attributes = attributes; this.defaultTranslationKey = Util.makeDescriptionId("fluid", BuiltInRegistries.FLUID.getKey(fluid)); - if (Platform.getEnvironment() == Env.CLIENT) { - ArchitecturyFluidAttributesClient.registerClient(this, () -> this.attributes); - } } - + private static Properties addArchIntoBuilder(Properties builder, ArchitecturyFluidAttributes attributes) { builder.lightLevel(attributes.getLuminosity()) .density(attributes.getDensity()) @@ -69,133 +62,149 @@ private static Properties addArchIntoBuilder(Properties builder, ArchitecturyFlu .viscosity(attributes.getViscosity()); return builder; } - + @Override public ItemStack getBucket(FluidStack stack) { Item item = attributes.getBucketItem(); return item == null ? super.getBucket(stack) : new ItemStack(item); } - - - + + + @Override public int getLightLevel(FluidStack stack) { return attributes.getLuminosity(convertSafe(stack)); } - + @Override - public int getLightLevel(FluidState state, BlockAndTintGetter level, BlockPos pos) { - return attributes.getLuminosity(convertSafe(state), level, pos); + public int getLightLevel(FluidState state, BlockAndLightGetter level, BlockPos pos) { + if (level instanceof BlockAndTintGetter getter) { + return attributes.getLuminosity(convertSafe(state), getter, pos); + } + return super.getLightLevel(state, level, pos); } - + @Override public int getDensity(FluidStack stack) { return attributes.getDensity(convertSafe(stack)); } - + @Override - public int getDensity(FluidState state, BlockAndTintGetter level, BlockPos pos) { - return attributes.getDensity(convertSafe(state), level, pos); + public int getDensity(FluidState state, BlockAndLightGetter level, BlockPos pos) { + if (level instanceof BlockAndTintGetter getter) { + return attributes.getDensity(convertSafe(state), getter, pos); + } + return super.getDensity(state, level, pos); } - + @Override public int getTemperature(FluidStack stack) { return attributes.getTemperature(convertSafe(stack)); } - + @Override - public int getTemperature(FluidState state, BlockAndTintGetter level, BlockPos pos) { - return attributes.getTemperature(convertSafe(state), level, pos); + public int getTemperature(FluidState state, BlockAndLightGetter level, BlockPos pos) { + if (level instanceof BlockAndTintGetter getter) { + return attributes.getTemperature(convertSafe(state), getter, pos); + } + return super.getTemperature(state, level, pos); } - + @Override public int getViscosity(FluidStack stack) { return attributes.getViscosity(convertSafe(stack)); } - + @Override - public int getViscosity(FluidState state, BlockAndTintGetter level, BlockPos pos) { - return attributes.getViscosity(convertSafe(state), level, pos); + public int getViscosity(FluidState state, BlockAndLightGetter level, BlockPos pos) { + if (level instanceof BlockAndTintGetter getter) { + return attributes.getViscosity(convertSafe(state), getter, pos); + } + return super.getViscosity(state, level, pos); } - + @Override public Rarity getRarity() { return attributes.getRarity(); } - + @Override public Rarity getRarity(FluidStack stack) { return attributes.getRarity(convertSafe(stack)); } - + @Override public Component getDescription() { return attributes.getName(); } - + @Override public Component getDescription(FluidStack stack) { return attributes.getName(convertSafe(stack)); } - + @Override public String getDescriptionId() { return MoreObjects.firstNonNull(attributes.getTranslationKey(), defaultTranslationKey); } - + @Override public String getDescriptionId(FluidStack stack) { return MoreObjects.firstNonNull(attributes.getTranslationKey(convertSafe(stack)), defaultTranslationKey); } - + @Override @Nullable public SoundEvent getSound(SoundAction action) { return getSound((FluidStack) null, action); } - + @Override @Nullable public SoundEvent getSound(@Nullable FluidStack stack, SoundAction action) { var archStack = convertSafe(stack); - if (BUCKET_FILL.equals(action)) { + if (SoundActions.BUCKET_FILL.equals(action)) { return attributes.getFillSound(archStack); - } else if (BUCKET_EMPTY.equals(action)) { + } else if (SoundActions.BUCKET_EMPTY.equals(action)) { return attributes.getEmptySound(archStack); } return null; } - + @Override @Nullable public SoundEvent getSound(@Nullable LivingEntity entity, BlockGetter getter, BlockPos pos, SoundAction action) { if (getter instanceof BlockAndTintGetter level) { - if (BUCKET_FILL.equals(action)) { + if (SoundActions.BUCKET_FILL.equals(action)) { return attributes.getFillSound(null, level, pos); - } else if (BUCKET_EMPTY.equals(action)) { + } else if (SoundActions.BUCKET_EMPTY.equals(action)) { return attributes.getEmptySound(null, level, pos); } } return getSound((FluidStack) null, action); } - + @Override public boolean canConvertToSource(FluidStack stack) { return attributes.canConvertToSource(); } - + @Override public boolean canConvertToSource(FluidState state, LevelReader reader, BlockPos pos) { return attributes.canConvertToSource(); } - + @Nullable public dev.architectury.fluid.FluidStack convertSafe(@Nullable FluidStack stack) { return stack == null ? null : FluidStackHooksForge.fromForge(stack); } - + @Nullable public dev.architectury.fluid.FluidStack convertSafe(@Nullable FluidState state) { return state == null ? null : dev.architectury.fluid.FluidStack.create(state.getType(), dev.architectury.fluid.FluidStack.bucketAmount()); } + + public ArchitecturyFluidAttributes getAttributes() { + return attributes; + } } diff --git a/neoforge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java b/neoforge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java index 058093c95..3d71aa486 100644 --- a/neoforge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java +++ b/neoforge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java @@ -28,7 +28,7 @@ import dev.architectury.impl.ScreenAccessImpl; import dev.architectury.impl.TooltipEventPositionContextImpl; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.network.chat.Component; @@ -161,7 +161,7 @@ public static void eventPlayerInteractEvent(PlayerInteractEvent.LeftClickEmpty e @SubscribeEvent(priority = EventPriority.HIGH) public static void eventRenderTooltipEvent(RenderTooltipEvent.Pre event) { - GuiGraphics graphics = event.getGraphics(); + GuiGraphicsExtractor graphics = event.getGraphics(); ClientTooltipEvent.additionalContexts().setItem(event.getItemStack()); try { @@ -225,7 +225,7 @@ public static void eventMouseReleasedEvent(ScreenEvent.MouseButtonReleased.Pre e @SubscribeEvent(priority = EventPriority.HIGH) public static void eventMouseReleasedEvent(ScreenEvent.MouseButtonReleased.Post event) { - ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), event.getMouseButtonEvent()); + ClientScreenInputEvent.MOUSE_RELEASED_POST.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), event.getMouseButtonEvent()); } @SubscribeEvent(priority = EventPriority.HIGH) diff --git a/neoforge/src/main/java/dev/architectury/event/forge/EventHandlerImplCommon.java b/neoforge/src/main/java/dev/architectury/event/forge/EventHandlerImplCommon.java index 21f0a999d..3f1859fea 100644 --- a/neoforge/src/main/java/dev/architectury/event/forge/EventHandlerImplCommon.java +++ b/neoforge/src/main/java/dev/architectury/event/forge/EventHandlerImplCommon.java @@ -22,6 +22,8 @@ import dev.architectury.event.EventResult; import dev.architectury.event.events.common.PlayerEvent; import dev.architectury.event.events.common.*; +import com.mojang.datafixers.util.Either; +import net.minecraft.core.SectionPos; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; @@ -29,8 +31,12 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.TriState; import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.vehicle.minecart.MinecartSpawner; +import net.minecraft.world.level.BaseSpawner; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.SpawnerBlockEntity; import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; @@ -38,6 +44,7 @@ import net.neoforged.neoforge.event.LootTableLoadEvent; import net.neoforged.neoforge.event.RegisterCommandsEvent; import net.neoforged.neoforge.event.ServerChatEvent; +import net.neoforged.neoforge.event.entity.EntityEvent.EnteringSection; import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent; import net.neoforged.neoforge.event.entity.item.ItemTossEvent; import net.neoforged.neoforge.event.entity.living.AnimalTameEvent; @@ -245,21 +252,40 @@ public static void event(FarmlandTrampleEvent event) { } } - // TODO: Hook ourselves when mixin is available - // @SubscribeEvent(priority = EventPriority.HIGH) - // public static void event(EnteringChunk event) { - // EntityEvent.ENTER_SECTION.invoker().enterChunk(event.getEntity(), event.getNewChunkX(), event.getNewChunkZ(), event.getOldChunkX(), event.getOldChunkZ()); - // } + @SubscribeEvent(priority = EventPriority.HIGH) + public static void event(EnteringSection event) { + SectionPos newPos = event.getNewPos(); + SectionPos oldPos = event.getOldPos(); + EntityEvent.ENTER_SECTION.invoker().enterSection( + event.getEntity(), + newPos.x(), newPos.y(), newPos.z(), + oldPos.x(), oldPos.y(), oldPos.z()); + } @SubscribeEvent(priority = EventPriority.HIGH) public static void eventLivingSpawnEvent(FinalizeSpawnEvent event) { - EventResult result = EntityEvent.LIVING_CHECK_SPAWN.invoker().canSpawn(event.getEntity(), event.getLevel(), event.getX(), event.getY(), event.getZ(), event.getSpawnType(), null);//TODO FIX: , event.getSpawner()); + EventResult result = EntityEvent.LIVING_CHECK_SPAWN.invoker().canSpawn(event.getEntity(), event.getLevel(), event.getX(), event.getY(), event.getZ(), event.getSpawnType(), getBaseSpawner(event)); if (result.interruptsFurtherEvaluation()) { if (!result.isEmpty()) { event.setSpawnCancelled(result.value()); } } } + + private static BaseSpawner getBaseSpawner(FinalizeSpawnEvent event) { + Either spawner = event.getSpawner(); + if (spawner == null) { + return null; + } + + return spawner.map( + EventHandlerImplCommon::getBaseSpawner, + entity -> entity instanceof MinecartSpawner minecartSpawner ? minecartSpawner.getSpawner() : null); + } + + private static BaseSpawner getBaseSpawner(BlockEntity blockEntity) { + return blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity ? spawnerBlockEntity.getSpawner() : null; + } @SubscribeEvent(priority = EventPriority.HIGH) public static void event(AnimalTameEvent event) { diff --git a/neoforge/src/main/java/dev/architectury/fluid/forge/ArchitecturyFluidAttributesClient.java b/neoforge/src/main/java/dev/architectury/fluid/forge/ArchitecturyFluidAttributesClient.java index 75ac37160..0c833baa4 100644 --- a/neoforge/src/main/java/dev/architectury/fluid/forge/ArchitecturyFluidAttributesClient.java +++ b/neoforge/src/main/java/dev/architectury/fluid/forge/ArchitecturyFluidAttributesClient.java @@ -19,117 +19,7 @@ package dev.architectury.fluid.forge; -import dev.architectury.core.fluid.ArchitecturyFluidAttributes; -import dev.architectury.hooks.client.forge.ClientExtensionsRegistryImpl; -import dev.architectury.hooks.fluid.forge.FluidStackHooksForge; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.Identifier; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.material.FluidState; -import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; -import net.neoforged.neoforge.fluids.FluidStack; -import net.neoforged.neoforge.fluids.FluidType; -import org.jetbrains.annotations.Nullable; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.function.Supplier; - -public class ArchitecturyFluidAttributesClient { - public static void registerClient(FluidType fluid, Supplier attributes) { - ClientExtensionsRegistryImpl.register(event -> { - if (event != null) { - event.registerFluidType(initializeClient(attributes.get()), fluid); - } else { - try { - Class clazz = Class.forName("net.neoforged.neoforge.client.extensions.common.ClientExtensionsManager"); - Field field = clazz.getDeclaredField("FLUID_TYPE_EXTENSIONS"); - field.setAccessible(true); - Method method = clazz.getDeclaredMethod("register", Object.class, Map.class, Object[].class); - method.setAccessible(true); - method.invoke(null, initializeClient(attributes.get()), (Map) field.get(null), new Object[]{fluid}); - } catch (Throwable e) { - e.printStackTrace(); - } - } - }); - } - - public static IClientFluidTypeExtensions initializeClient(ArchitecturyFluidAttributes attributes) { - return new IClientFluidTypeExtensions() { - @Override - public int getTintColor() { - return attributes.getColor(); - } - - @Override - public Identifier getStillTexture() { - return attributes.getSourceTexture(); - } - - @Override - public Identifier getFlowingTexture() { - return attributes.getFlowingTexture(); - } - - @Override - @Nullable - public Identifier getOverlayTexture() { - return attributes.getOverlayTexture(); - } - - @Override - public Identifier getStillTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) { - return attributes.getSourceTexture(state, getter, pos); - } - - @Override - public Identifier getFlowingTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) { - return attributes.getFlowingTexture(state, getter, pos); - } - - @Override - @Nullable - public Identifier getOverlayTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) { - return attributes.getOverlayTexture(state, getter, pos); - } - - @Override - public int getTintColor(FluidState state, BlockAndTintGetter getter, BlockPos pos) { - return attributes.getColor(state, getter, pos); - } - - @Override - public int getTintColor(FluidStack stack) { - return attributes.getColor(convertSafe(stack)); - } - - @Override - public Identifier getStillTexture(FluidStack stack) { - return attributes.getSourceTexture(convertSafe(stack)); - } - - @Override - public Identifier getFlowingTexture(FluidStack stack) { - return attributes.getFlowingTexture(convertSafe(stack)); - } - - @Override - @Nullable - public Identifier getOverlayTexture(FluidStack stack) { - return attributes.getOverlayTexture(convertSafe(stack)); - } - }; - } - - @Nullable - public static dev.architectury.fluid.FluidStack convertSafe(@Nullable FluidStack stack) { - return stack == null ? null : FluidStackHooksForge.fromForge(stack); - } - - @Nullable - public static dev.architectury.fluid.FluidStack convertSafe(@Nullable FluidState state) { - return state == null ? null : dev.architectury.fluid.FluidStack.create(state.getType(), dev.architectury.fluid.FluidStack.bucketAmount()); +public final class ArchitecturyFluidAttributesClient { + private ArchitecturyFluidAttributesClient() { } } diff --git a/neoforge/src/main/java/dev/architectury/fluid/forge/FluidStackImpl.java b/neoforge/src/main/java/dev/architectury/fluid/forge/FluidStackImpl.java index 938ad53b8..2a6033e2b 100644 --- a/neoforge/src/main/java/dev/architectury/fluid/forge/FluidStackImpl.java +++ b/neoforge/src/main/java/dev/architectury/fluid/forge/FluidStackImpl.java @@ -71,7 +71,7 @@ public FluidStack create(Supplier fluid, long amount, @Nullable DataCompo @Override public Supplier getRawFluidSupplier(FluidStack object) { - return () -> object.getFluidHolder().value(); + return () -> object.typeHolder().value(); } @Override @@ -96,7 +96,7 @@ public DataComponentPatch getPatch(FluidStack value) { @Override public PatchedDataComponentMap getComponents(FluidStack value) { - return value.getComponents(); + return new PatchedDataComponentMap(value.getComponents()); } @Override diff --git a/neoforge/src/main/java/dev/architectury/hooks/client/fluid/forge/ClientFluidStackHooksImpl.java b/neoforge/src/main/java/dev/architectury/hooks/client/fluid/forge/ClientFluidStackHooksImpl.java index 992afdb8f..e78760d52 100644 --- a/neoforge/src/main/java/dev/architectury/hooks/client/fluid/forge/ClientFluidStackHooksImpl.java +++ b/neoforge/src/main/java/dev/architectury/hooks/client/fluid/forge/ClientFluidStackHooksImpl.java @@ -19,76 +19,129 @@ package dev.architectury.hooks.client.fluid.forge; +import dev.architectury.core.fluid.forge.imitator.ArchitecturyFluidAttributesForge; import dev.architectury.fluid.FluidStack; import dev.architectury.hooks.fluid.forge.FluidStackHooksForge; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.BlockAndTintGetter; +import net.minecraft.client.renderer.block.FluidModel; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.Material; import net.minecraft.core.BlockPos; import net.minecraft.resources.Identifier; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; -import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; +import net.neoforged.neoforge.client.fluid.FluidTintSource; import org.jetbrains.annotations.Nullable; public class ClientFluidStackHooksImpl { @Nullable public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { if (state.getType() == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(state).getStillTexture(state, level, pos); - return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture)); + Identifier texture = sourceTexture(state.getType(), state, level, pos); + return texture != null ? atlasSprite(texture) : fluidModel(state).stillMaterial().sprite(); } - + @Nullable public static TextureAtlasSprite getStillTexture(FluidStack stack) { if (stack.getFluid() == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(stack.getFluid()).getStillTexture(FluidStackHooksForge.toForge(stack)); - return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture)); + Identifier texture = sourceTexture(stack.getFluid(), null, null, null); + return texture != null ? atlasSprite(texture) : fluidModel(stack.getFluid()).stillMaterial().sprite(); } - + @Nullable public static TextureAtlasSprite getStillTexture(Fluid fluid) { if (fluid == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(fluid).getStillTexture(); - return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture)); + Identifier texture = sourceTexture(fluid, null, null, null); + return texture != null ? atlasSprite(texture) : fluidModel(fluid).stillMaterial().sprite(); } - + @Nullable public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { if (state.getType() == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(state).getFlowingTexture(state, level, pos); - return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture)); + Identifier texture = flowingTexture(state.getType(), state, level, pos); + return texture != null ? atlasSprite(texture) : fluidModel(state).flowingMaterial().sprite(); } - + @Nullable public static TextureAtlasSprite getFlowingTexture(FluidStack stack) { if (stack.getFluid() == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(stack.getFluid()).getFlowingTexture(FluidStackHooksForge.toForge(stack)); - return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture)); + Identifier texture = flowingTexture(stack.getFluid(), null, null, null); + return texture != null ? atlasSprite(texture) : fluidModel(stack.getFluid()).flowingMaterial().sprite(); } - + @Nullable public static TextureAtlasSprite getFlowingTexture(Fluid fluid) { if (fluid == Fluids.EMPTY) return null; - Identifier texture = IClientFluidTypeExtensions.of(fluid).getFlowingTexture(); - return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture)); + Identifier texture = flowingTexture(fluid, null, null, null); + return texture != null ? atlasSprite(texture) : fluidModel(fluid).flowingMaterial().sprite(); } - + public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) { if (state.getType() == Fluids.EMPTY) return -1; - return IClientFluidTypeExtensions.of(state).getTintColor(state, level, pos); + return color(state.getType(), state, level, pos, null); } - + public static int getColor(FluidStack stack) { if (stack.getFluid() == Fluids.EMPTY) return -1; - return IClientFluidTypeExtensions.of(stack.getFluid()).getTintColor(FluidStackHooksForge.toForge(stack)); + return color(stack.getFluid(), null, null, null, stack); } - + public static int getColor(Fluid fluid) { if (fluid == Fluids.EMPTY) return -1; - return IClientFluidTypeExtensions.of(fluid).getTintColor(); + return color(fluid, null, null, null, null); + } + + @Nullable + private static Identifier sourceTexture(Fluid fluid, @Nullable FluidState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) { + if (fluid.getFluidType() instanceof ArchitecturyFluidAttributesForge archType) { + return state != null ? archType.getAttributes().getSourceTexture(state, level, pos) : archType.getAttributes().getSourceTexture(); + } + return null; + } + + @Nullable + private static Identifier flowingTexture(Fluid fluid, @Nullable FluidState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) { + if (fluid.getFluidType() instanceof ArchitecturyFluidAttributesForge archType) { + return state != null ? archType.getAttributes().getFlowingTexture(state, level, pos) : archType.getAttributes().getFlowingTexture(); + } + return null; + } + + private static int color(Fluid fluid, @Nullable FluidState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @Nullable FluidStack stack) { + if (fluid.getFluidType() instanceof ArchitecturyFluidAttributesForge archType) { + return state != null ? archType.getAttributes().getColor(state, level, pos) : archType.getAttributes().getColor(); + } + + FluidState fluidState = state != null ? state : fluid.defaultFluidState(); + @Nullable FluidTintSource tint = fluidModel(fluidState).fluidTintSource(); + if (tint == null) { + return -1; + } + + if (stack != null) { + return tint.colorAsStack(FluidStackHooksForge.toForge(stack)); + } else if (level != null && pos != null) { + return tint.colorInWorld(fluidState, fluidState.createLegacyBlock(), level, pos); + } else { + return tint.color(fluidState); + } + } + + private static FluidModel fluidModel(Fluid fluid) { + return fluidModel(fluid.defaultFluidState()); + } + + private static FluidModel fluidModel(FluidState state) { + return Minecraft.getInstance().getModelManager().getFluidStateModelSet().get(state); + } + + @Nullable + private static TextureAtlasSprite atlasSprite(@Nullable Identifier texture) { + if (texture == null) { + return null; + } + return Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(TextureAtlas.LOCATION_BLOCKS).getSprite(texture); } } diff --git a/neoforge/src/main/java/dev/architectury/hooks/client/screen/forge/ScreenHooksImpl.java b/neoforge/src/main/java/dev/architectury/hooks/client/screen/forge/ScreenHooksImpl.java index f7acc49c2..ce3890d23 100644 --- a/neoforge/src/main/java/dev/architectury/hooks/client/screen/forge/ScreenHooksImpl.java +++ b/neoforge/src/main/java/dev/architectury/hooks/client/screen/forge/ScreenHooksImpl.java @@ -25,26 +25,65 @@ import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.screens.Screen; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.List; public class ScreenHooksImpl { + @SuppressWarnings("unchecked") public static List getNarratables(Screen screen) { - return screen.narratables; + return (List) getField(screen, "narratables"); } - + + @SuppressWarnings("unchecked") public static List getRenderables(Screen screen) { - return screen.renderables; + return (List) getField(screen, "renderables"); } - + public static T addRenderableWidget(Screen screen, T widget) { - return screen.addRenderableWidget(widget); + return invoke(screen, "addRenderableWidget", widget); } - + public static T addRenderableOnly(Screen screen, T listener) { - return screen.addRenderableOnly(listener); + return invoke(screen, "addRenderableOnly", listener); } - + public static T addWidget(Screen screen, T listener) { - return screen.addWidget(listener); + return invoke(screen, "addWidget", listener); + } + + private static Object getField(Screen screen, String name) { + Class current = screen.getClass(); + while (current != null) { + try { + Field field = current.getDeclaredField(name); + field.setAccessible(true); + return field.get(screen); + } catch (NoSuchFieldException ignored) { + current = current.getSuperclass(); + } catch (IllegalAccessException exception) { + throw new IllegalStateException("Failed to access Screen field '" + name + "'", exception); + } + } + throw new IllegalStateException("Could not find Screen field '" + name + "'"); + } + + @SuppressWarnings("unchecked") + private static T invoke(Screen screen, String name, T arg) { + Class current = screen.getClass(); + while (current != null) { + for (Method method : current.getDeclaredMethods()) { + if (method.getName().equals(name) && method.getParameterCount() == 1 && method.getParameterTypes()[0].isAssignableFrom(arg.getClass())) { + try { + method.setAccessible(true); + return (T) method.invoke(screen, arg); + } catch (ReflectiveOperationException exception) { + throw new IllegalStateException("Failed to invoke Screen method '" + name + "'", exception); + } + } + } + current = current.getSuperclass(); + } + throw new IllegalStateException("Could not find Screen method '" + name + "'"); } } diff --git a/neoforge/src/main/java/dev/architectury/hooks/item/forge/ItemStackHooksImpl.java b/neoforge/src/main/java/dev/architectury/hooks/item/forge/ItemStackHooksImpl.java index 6e4c53dee..f13f1fe09 100644 --- a/neoforge/src/main/java/dev/architectury/hooks/item/forge/ItemStackHooksImpl.java +++ b/neoforge/src/main/java/dev/architectury/hooks/item/forge/ItemStackHooksImpl.java @@ -23,10 +23,10 @@ public class ItemStackHooksImpl { public static boolean hasCraftingRemainingItem(ItemStack stack) { - return !getCraftingRemainingItem(stack).isEmpty(); + return !stack.getItem().getCraftingRemainder().create().isEmpty(); } public static ItemStack getCraftingRemainingItem(ItemStack stack) { - return stack.getCraftingRemainder(); + return stack.getItem().getCraftingRemainder().create(); } } diff --git a/neoforge/src/main/java/dev/architectury/mixin/forge/MixinVillager.java b/neoforge/src/main/java/dev/architectury/mixin/forge/MixinVillager.java new file mode 100644 index 000000000..7426fdc60 --- /dev/null +++ b/neoforge/src/main/java/dev/architectury/mixin/forge/MixinVillager.java @@ -0,0 +1,38 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.mixin.forge; + +import dev.architectury.registry.level.entity.trade.forge.TradeRegistryImpl; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.npc.villager.Villager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Villager.class) +public class MixinVillager { + @Inject(method = "updateTrades", at = @At("RETURN")) + private void architectury$appendRegisteredTrades(ServerLevel level, CallbackInfo ci) { + Villager villager = (Villager) (Object) this; + villager.getVillagerData().profession().unwrapKey().ifPresent(profession -> TradeRegistryImpl.appendVillagerTrades( + level, villager.getOffers(), profession, villager.getVillagerData().level(), villager, villager.getRandom())); + } +} diff --git a/neoforge/src/main/java/dev/architectury/mixin/forge/MixinWanderingTrader.java b/neoforge/src/main/java/dev/architectury/mixin/forge/MixinWanderingTrader.java new file mode 100644 index 000000000..b75abe092 --- /dev/null +++ b/neoforge/src/main/java/dev/architectury/mixin/forge/MixinWanderingTrader.java @@ -0,0 +1,37 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.mixin.forge; + +import dev.architectury.registry.level.entity.trade.forge.TradeRegistryImpl; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.npc.wanderingtrader.WanderingTrader; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(WanderingTrader.class) +public class MixinWanderingTrader { + @Inject(method = "updateTrades", at = @At("RETURN")) + private void architectury$appendRegisteredTrades(ServerLevel level, CallbackInfo ci) { + WanderingTrader trader = (WanderingTrader) (Object) this; + TradeRegistryImpl.appendWanderingTraderTrades(level, trader.getOffers(), trader, trader.getRandom()); + } +} diff --git a/neoforge/src/main/java/dev/architectury/mixin/forge/client/MixinAbstractContainerScreen.java b/neoforge/src/main/java/dev/architectury/mixin/forge/client/MixinAbstractContainerScreen.java index b6aba7f77..b8826a398 100644 --- a/neoforge/src/main/java/dev/architectury/mixin/forge/client/MixinAbstractContainerScreen.java +++ b/neoforge/src/main/java/dev/architectury/mixin/forge/client/MixinAbstractContainerScreen.java @@ -1,7 +1,7 @@ package dev.architectury.mixin.forge.client; import dev.architectury.event.events.client.ClientGuiEvent; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.network.chat.Component; @@ -16,10 +16,8 @@ protected MixinAbstractContainerScreen(Component component) { super(component); } - @Inject(method = "renderBackground", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;renderBg(Lnet/minecraft/client/gui/GuiGraphics;FII)V", - ordinal = 0, shift = At.Shift.AFTER)) - public void renderBackground(GuiGraphics graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { + @Inject(method = "extractContents", at = @At("TAIL")) + public void renderBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.invoker().render((AbstractContainerScreen) (Object) this, graphics, mouseX, mouseY, delta); } } diff --git a/neoforge/src/main/java/dev/architectury/mixin/forge/neoforge/MixinChunkMap.java b/neoforge/src/main/java/dev/architectury/mixin/forge/neoforge/MixinChunkMap.java index 95e7d3628..7e1d82122 100644 --- a/neoforge/src/main/java/dev/architectury/mixin/forge/neoforge/MixinChunkMap.java +++ b/neoforge/src/main/java/dev/architectury/mixin/forge/neoforge/MixinChunkMap.java @@ -36,7 +36,7 @@ public class MixinChunkMap { @Final ServerLevel level; - @ModifyArg(method = {"method_43375", "lambda$scheduleChunkLoad$17"}, at = @At(value = "INVOKE", + @ModifyArg(method = "lambda$scheduleChunkLoad$3", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/neoforged/bus/api/IEventBus;post(Lnet/neoforged/bus/api/Event;)Lnet/neoforged/bus/api/Event;"), index = 0, remap = false) diff --git a/neoforge/src/main/java/dev/architectury/networking/forge/client/ClientNetworkManagerImpl.java b/neoforge/src/main/java/dev/architectury/networking/forge/client/ClientNetworkManagerImpl.java index 77a25a9bd..c5c2c8244 100644 --- a/neoforge/src/main/java/dev/architectury/networking/forge/client/ClientNetworkManagerImpl.java +++ b/neoforge/src/main/java/dev/architectury/networking/forge/client/ClientNetworkManagerImpl.java @@ -41,7 +41,7 @@ public static RegistryAccess getClientRegistryAccess() { return Minecraft.getInstance().getConnection().registryAccess(); } else if (Minecraft.getInstance().gameMode != null) { // Sometimes the packet is sent way too fast and is between the connection and the level, better safe than sorry - return Minecraft.getInstance().gameMode.connection.registryAccess(); + return Minecraft.getInstance().getConnection().registryAccess(); } // Fail-safe diff --git a/neoforge/src/main/java/dev/architectury/registry/client/particle/forge/ParticleProviderRegistryImpl.java b/neoforge/src/main/java/dev/architectury/registry/client/particle/forge/ParticleProviderRegistryImpl.java index 3b6bc378c..ddf5237d8 100644 --- a/neoforge/src/main/java/dev/architectury/registry/client/particle/forge/ParticleProviderRegistryImpl.java +++ b/neoforge/src/main/java/dev/architectury/registry/client/particle/forge/ParticleProviderRegistryImpl.java @@ -24,13 +24,14 @@ import dev.architectury.registry.client.particle.ParticleProviderRegistry; import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.ParticleEngine; import net.minecraft.client.particle.ParticleProvider; import net.minecraft.client.particle.ParticleResources; +import net.minecraft.client.particle.SpriteSet; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleType; -import net.minecraft.data.AtlasIds; import net.minecraft.util.RandomSource; import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent; import org.slf4j.Logger; @@ -41,51 +42,59 @@ public class ParticleProviderRegistryImpl { public static final Logger LOGGER = LogUtils.getLogger(); - + static { EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { bus.addListener(ParticleProviderRegistryImpl::onParticleFactoryRegister); }); } - - private record ExtendedSpriteSetImpl(ParticleResources.MutableSpriteSet set) implements ParticleProviderRegistry.ExtendedSpriteSet { + + private static final class ExtendedSpriteSetImpl implements ParticleProviderRegistry.ExtendedSpriteSet { + private final ParticleEngine engine; + private final SpriteSet delegate; + + private ExtendedSpriteSetImpl(ParticleEngine engine, SpriteSet delegate) { + this.engine = engine; + this.delegate = delegate; + } + @Override public TextureAtlas getAtlas() { - return Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(AtlasIds.PARTICLES); + return Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(TextureAtlas.LOCATION_PARTICLES); } - + @Override public List getSprites() { - return set.sprites; + return List.of(delegate.first()); } - + @Override public TextureAtlasSprite get(int i, int j) { - return set.get(i, j); + return delegate.get(i, j); } - + @Override public TextureAtlasSprite get(RandomSource random) { - return set.get(random); + return delegate.get(random); } - + @Override public TextureAtlasSprite first() { - return set.first(); + return delegate.first(); } } - + private static List> deferred = new ArrayList<>(); - + private static void doRegister(ParticleProviderRegistrar registrar, ParticleType type, ParticleProvider provider) { registrar.register(type, provider); } - + private static void doRegister(ParticleProviderRegistrar registrar, ParticleType type, ParticleProviderRegistry.DeferredParticleProvider provider) { registrar.register(type, sprites -> - provider.create(new ExtendedSpriteSetImpl((ParticleResources.MutableSpriteSet) sprites))); + provider.create(new ExtendedSpriteSetImpl(Minecraft.getInstance().particleEngine, sprites))); } - + public static void register(ParticleType type, ParticleProvider provider) { if (deferred == null) { LOGGER.warn("Something is attempting to register particle providers at a later point than intended! This might cause issues!", new Throwable()); @@ -94,7 +103,7 @@ public static void register(ParticleType type, Pa deferred.add(registrar -> doRegister(registrar, type, provider)); } } - + public static void register(ParticleType type, ParticleProviderRegistry.DeferredParticleProvider provider) { if (deferred == null) { LOGGER.warn("Something is attempting to register particle providers at a later point than intended! This might cause issues!", new Throwable()); @@ -103,7 +112,7 @@ public static void register(ParticleType type, Pa deferred.add(registrar -> doRegister(registrar, type, provider)); } } - + public static void onParticleFactoryRegister(RegisterParticleProvidersEvent event) { if (deferred != null) { ParticleProviderRegistrar registrar = ParticleProviderRegistrar.ofForge(event); @@ -115,36 +124,36 @@ public static void onParticleFactoryRegister(RegisterParticleProvidersEvent even deferred = null; } } - + private interface ParticleProviderRegistrar { void register(ParticleType type, ParticleProvider provider); - + void register(ParticleType type, ParticleResources.SpriteParticleRegistration registration); - + static ParticleProviderRegistrar ofForge(RegisterParticleProvidersEvent event) { return new ParticleProviderRegistrar() { @Override public void register(ParticleType type, ParticleProvider provider) { event.registerSpecial(type, provider); } - + @Override public void register(ParticleType type, ParticleResources.SpriteParticleRegistration registration) { event.registerSpriteSet(type, registration); } }; } - + static ParticleProviderRegistrar ofFallback() { return new ParticleProviderRegistrar() { @Override public void register(ParticleType type, ParticleProvider provider) { - Minecraft.getInstance().particleResources.register(type, provider); + LOGGER.warn("Skipping late particle provider registration for {}", type); } - + @Override public void register(ParticleType type, ParticleResources.SpriteParticleRegistration registration) { - Minecraft.getInstance().particleResources.register(type, registration); + LOGGER.warn("Skipping late sprite particle registration for {}", type); } }; } diff --git a/neoforge/src/main/java/dev/architectury/registry/client/rendering/forge/ColorHandlerRegistryImpl.java b/neoforge/src/main/java/dev/architectury/registry/client/rendering/forge/ColorHandlerRegistryImpl.java index 528b6125e..0ec39a0ee 100644 --- a/neoforge/src/main/java/dev/architectury/registry/client/rendering/forge/ColorHandlerRegistryImpl.java +++ b/neoforge/src/main/java/dev/architectury/registry/client/rendering/forge/ColorHandlerRegistryImpl.java @@ -23,7 +23,7 @@ import dev.architectury.platform.hooks.EventBusesHooks; import dev.architectury.utils.ArchitecturyConstants; import net.minecraft.client.Minecraft; -import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.block.BlockTintSource; import net.minecraft.world.level.block.Block; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; @@ -34,7 +34,7 @@ import java.util.function.Supplier; public class ColorHandlerRegistryImpl { - private static final List[]>> BLOCK_COLORS = Lists.newArrayList(); + private static final List[]>> BLOCK_COLORS = Lists.newArrayList(); static { EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { @@ -43,19 +43,19 @@ public class ColorHandlerRegistryImpl { } @SubscribeEvent - public static void onBlockColorEvent(RegisterColorHandlersEvent.Block event) { - for (Pair[]> pair : BLOCK_COLORS) { - event.register(pair.getLeft(), unpackBlocks(pair.getRight())); + public static void onBlockColorEvent(RegisterColorHandlersEvent.BlockTintSources event) { + for (Pair[]> pair : BLOCK_COLORS) { + event.register(List.of(pair.getLeft()), unpackBlocks(pair.getRight())); } } @SafeVarargs - public static void registerBlockColors(BlockColor blockColor, Supplier... blocks) { + public static void registerBlockColors(BlockTintSource blockColor, Supplier... blocks) { Objects.requireNonNull(blockColor, "color is null!"); if (Minecraft.getInstance().getBlockColors() == null) { BLOCK_COLORS.add(Pair.of(blockColor, blocks)); } else { - Minecraft.getInstance().getBlockColors().register(blockColor, unpackBlocks(blocks)); + Minecraft.getInstance().getBlockColors().register(List.of(blockColor), unpackBlocks(blocks)); } } diff --git a/neoforge/src/main/java/dev/architectury/registry/client/rendering/forge/RenderTypeRegistryImpl.java b/neoforge/src/main/java/dev/architectury/registry/client/rendering/forge/RenderTypeRegistryImpl.java index 9259b5f9b..9ab47f65f 100644 --- a/neoforge/src/main/java/dev/architectury/registry/client/rendering/forge/RenderTypeRegistryImpl.java +++ b/neoforge/src/main/java/dev/architectury/registry/client/rendering/forge/RenderTypeRegistryImpl.java @@ -19,21 +19,14 @@ package dev.architectury.registry.client.rendering.forge; -import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.material.Fluid; public class RenderTypeRegistryImpl { public static void register(ChunkSectionLayer type, Block... blocks) { - for (Block block : blocks) { - ItemBlockRenderTypes.setRenderLayer(block, type); - } } public static void register(ChunkSectionLayer type, Fluid... fluids) { - for (Fluid fluid : fluids) { - ItemBlockRenderTypes.setRenderLayer(fluid, type); - } } } diff --git a/neoforge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java b/neoforge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java index b1d5bb737..d246882cd 100644 --- a/neoforge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java +++ b/neoforge/src/main/java/dev/architectury/registry/level/biome/forge/BiomeModificationsImpl.java @@ -48,6 +48,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Field; import java.util.List; import java.util.Map; import java.util.Optional; @@ -63,7 +64,7 @@ public class BiomeModificationsImpl { private static final List, BiConsumer>> REPLACEMENTS = Lists.newArrayList(); @Nullable private static MapCodec noneBiomeModCodec = null; - + public static void init() { EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> { bus.addListener(event -> { @@ -74,27 +75,27 @@ public static void init() { }); }); } - + public static void addProperties(Predicate predicate, BiConsumer modifier) { ADDITIONS.add(Pair.of(predicate, modifier)); } - + public static void postProcessProperties(Predicate predicate, BiConsumer modifier) { POST_PROCESSING.add(Pair.of(predicate, modifier)); } - + public static void removeProperties(Predicate predicate, BiConsumer modifier) { REMOVALS.add(Pair.of(predicate, modifier)); } - + public static void replaceProperties(Predicate predicate, BiConsumer modifier) { REPLACEMENTS.add(Pair.of(predicate, modifier)); } - + private static class BiomeModifierImpl implements BiomeModifier { // cry about it private static final BiomeModifierImpl INSTANCE = new BiomeModifierImpl(); - + @Override public void modify(Holder arg, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) { List, BiConsumer>> list = switch (phase) { @@ -104,7 +105,7 @@ public void modify(Holder arg, Phase phase, ModifiableBiomeInfo.BiomeInfo case AFTER_EVERYTHING -> POST_PROCESSING; default -> null; }; - + if (list == null) return; BiomeContext biomeContext = wrapSelectionContext(arg.unwrapKey(), builder); BiomeProperties.Mutable mutableBiome = new MutableBiomeWrapped(builder); @@ -114,7 +115,7 @@ public void modify(Holder arg, Phase phase, ModifiableBiomeInfo.BiomeInfo } } } - + @Override public MapCodec codec() { if (noneBiomeModCodec != null) { @@ -124,21 +125,21 @@ public MapCodec codec() { } } } - + private static BiomeContext wrapSelectionContext(Optional> biomeResourceKey, ModifiableBiomeInfo.BiomeInfo.Builder event) { return new BiomeContext() { BiomeProperties properties = new BiomeWrapped(event); - + @Override public Optional getKey() { return biomeResourceKey.map(ResourceKey::identifier); } - + @Override public BiomeProperties getProperties() { return properties; } - + @Override public boolean hasTag(TagKey tag) { MinecraftServer server = GameInstance.getServer(); @@ -155,14 +156,14 @@ public boolean hasTag(TagKey tag) { } }; } - + public static class BiomeWrapped implements BiomeProperties { protected final ModifiableBiomeInfo.BiomeInfo.Builder event; protected final ClimateProperties climateProperties; protected final EffectsProperties effectsProperties; protected final GenerationProperties generationProperties; protected final SpawnProperties spawnProperties; - + public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event) { this(event, new MutableClimatePropertiesWrapped(event.getClimateSettings()), @@ -171,7 +172,7 @@ public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event) { new SpawnSettingsBuilderWrapped(event.getMobSpawnSettings()) ); } - + public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event, ClimateProperties climateProperties, EffectsProperties effectsProperties, GenerationProperties generationProperties, SpawnProperties spawnProperties) { this.event = event; this.climateProperties = climateProperties; @@ -179,74 +180,74 @@ public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event, ClimateProperti this.generationProperties = generationProperties; this.spawnProperties = spawnProperties; } - + @Override public ClimateProperties getClimateProperties() { return climateProperties; } - + @Override public EffectsProperties getEffectsProperties() { return effectsProperties; } - + @Override public GenerationProperties getGenerationProperties() { return generationProperties; } - + @Override public SpawnProperties getSpawnProperties() { return spawnProperties; } } - + private static class GenerationSettingsBuilderWrapped implements GenerationProperties { protected final BiomeGenerationSettingsBuilder generation; - + public GenerationSettingsBuilderWrapped(BiomeGenerationSettingsBuilder generation) { this.generation = generation; } - + @Override public Iterable>> getCarvers() { return generation.getCarvers(); } - + @Override public Iterable> getFeatures(GenerationStep.Decoration decoration) { return generation.getFeatures(decoration); } - + @Override public List>> getFeatures() { - return (List>>) (List) generation.features; + return (List>>) (List) getField(generation, "features"); } } - + private static class SpawnSettingsBuilderWrapped implements SpawnProperties { protected final MobSpawnSettingsBuilder builder; - + public SpawnSettingsBuilderWrapped(MobSpawnSettingsBuilder builder) { this.builder = builder; } - + @Override public float getCreatureProbability() { return builder.getProbability(); } - + @Override public Map> getSpawners() { - return builder.spawners; + return (Map>) getField(builder, "spawners"); } - + @Override public Map, MobSpawnSettings.MobSpawnCost> getMobSpawnCosts() { - return builder.mobSpawnCosts; + return (Map, MobSpawnSettings.MobSpawnCost>) getField(builder, "mobSpawnCosts"); } } - + public static class MutableBiomeWrapped extends BiomeWrapped implements BiomeProperties.Mutable { public MutableBiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event) { super(event, @@ -256,155 +257,155 @@ public MutableBiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event) { new MutableSpawnSettingsBuilderWrapped(event.getMobSpawnSettings()) ); } - + @Override public ClimateProperties.Mutable getClimateProperties() { return (ClimateProperties.Mutable) super.getClimateProperties(); } - + @Override public EffectsProperties.Mutable getEffectsProperties() { return (EffectsProperties.Mutable) super.getEffectsProperties(); } - + @Override public GenerationProperties.Mutable getGenerationProperties() { return (GenerationProperties.Mutable) super.getGenerationProperties(); } - + @Override public SpawnProperties.Mutable getSpawnProperties() { return (SpawnProperties.Mutable) super.getSpawnProperties(); } } - + public static class MutableClimatePropertiesWrapped implements ClimateProperties.Mutable { public ClimateSettingsBuilder builder; - + public MutableClimatePropertiesWrapped(ClimateSettingsBuilder builder) { this.builder = builder; } - + @Override public boolean hasPrecipitation() { return builder.hasPrecipitation(); } - + @Override public float getTemperature() { return builder.getTemperature(); } - + @Override public Biome.TemperatureModifier getTemperatureModifier() { return builder.getTemperatureModifier(); } - + @Override public float getDownfall() { return builder.getDownfall(); } - + @Override public Mutable setHasPrecipitation(boolean hasPrecipitation) { this.builder.setHasPrecipitation(hasPrecipitation); return this; } - + @Override public Mutable setTemperature(float temperature) { this.builder.setTemperature(temperature); return this; } - + @Override public Mutable setTemperatureModifier(Biome.TemperatureModifier temperatureModifier) { this.builder.setTemperatureModifier(temperatureModifier); return this; } - + @Override public Mutable setDownfall(float downfall) { this.builder.setDownfall(downfall); return this; } - + } - + public static class MutableEffectsPropertiesWrapped implements EffectsProperties.Mutable { public BiomeSpecialEffects.Builder builder; - + public MutableEffectsPropertiesWrapped(BiomeSpecialEffects.Builder builder) { this.builder = builder; } - + @Override public int getWaterColor() { - return builder.waterColor.orElse(-1); + return ((Optional) getField(builder, "waterColor")).orElse(-1); } - + @Override public OptionalInt getFoliageColorOverride() { - return builder.foliageColorOverride.map(OptionalInt::of).orElseGet(OptionalInt::empty); + return ((Optional) getField(builder, "foliageColorOverride")).map(OptionalInt::of).orElseGet(OptionalInt::empty); } - + @Override public OptionalInt getDryFoliageColorOverride() { - return builder.dryFoliageColorOverride.map(OptionalInt::of).orElseGet(OptionalInt::empty); + return ((Optional) getField(builder, "dryFoliageColorOverride")).map(OptionalInt::of).orElseGet(OptionalInt::empty); } - + @Override public OptionalInt getGrassColorOverride() { - return builder.grassColorOverride.map(OptionalInt::of).orElseGet(OptionalInt::empty); + return ((Optional) getField(builder, "grassColorOverride")).map(OptionalInt::of).orElseGet(OptionalInt::empty); } - + @Override public BiomeSpecialEffects.GrassColorModifier getGrassColorModifier() { - return builder.grassColorModifier; + return (BiomeSpecialEffects.GrassColorModifier) getField(builder, "grassColorModifier"); } - + @Override public Mutable setWaterColor(int color) { builder.waterColor(color); return this; } - + @Override public Mutable setFoliageColorOverride(@Nullable Integer colorOverride) { - builder.foliageColorOverride = Optional.ofNullable(colorOverride); + setField(builder, "foliageColorOverride", Optional.ofNullable(colorOverride)); return this; } - + @Override public Mutable setDryFoliageColorOverride(@Nullable Integer colorOverride) { - builder.dryFoliageColorOverride = Optional.ofNullable(colorOverride); + setField(builder, "dryFoliageColorOverride", Optional.ofNullable(colorOverride)); return this; } - + @Override public Mutable setGrassColorOverride(@Nullable Integer colorOverride) { - builder.grassColorOverride = Optional.ofNullable(colorOverride); + setField(builder, "grassColorOverride", Optional.ofNullable(colorOverride)); return this; } - + @Override public Mutable setGrassColorModifier(BiomeSpecialEffects.GrassColorModifier modifier) { builder.grassColorModifier(modifier); return this; } } - + private static class MutableGenerationSettingsBuilderWrapped extends GenerationSettingsBuilderWrapped implements GenerationProperties.Mutable { public MutableGenerationSettingsBuilderWrapped(BiomeGenerationSettingsBuilder generation) { super(generation); } - + @Override public Mutable addFeature(GenerationStep.Decoration decoration, Holder feature) { generation.addFeature(decoration, feature); return this; } - + @Override public Mutable addFeature(GenerationStep.Decoration decoration, ResourceKey feature) { MinecraftServer server = GameInstance.getServer(); @@ -421,13 +422,13 @@ public Mutable addFeature(GenerationStep.Decoration decoration, ResourceKey> feature) { generation.addCarver(feature); return this; } - + @Override public Mutable addCarver(ResourceKey> feature) { MinecraftServer server = GameInstance.getServer(); @@ -444,37 +445,37 @@ public Mutable addCarver(ResourceKey> feature) { } return this; } - + @Override public Mutable removeFeature(GenerationStep.Decoration decoration, ResourceKey feature) { generation.getFeatures(decoration).removeIf(supplier -> supplier.is(feature)); return this; } - + @Override public Mutable removeCarver(ResourceKey> feature) { generation.getCarvers().removeIf(supplier -> supplier.is(feature)); return this; } } - + private static class MutableSpawnSettingsBuilderWrapped extends SpawnSettingsBuilderWrapped implements SpawnProperties.Mutable { public MutableSpawnSettingsBuilderWrapped(MobSpawnSettingsBuilder builder) { super(builder); } - + @Override public Mutable setCreatureProbability(float probability) { builder.creatureGenerationProbability(probability); return this; } - + @Override public Mutable addSpawn(MobCategory category, MobSpawnSettings.SpawnerData data, int weight) { builder.addSpawn(category, weight, data); return this; } - + @Override public boolean removeSpawns(BiPredicate predicate) { boolean removed = false; @@ -487,23 +488,56 @@ public boolean removeSpawns(BiPredicate entityType, MobSpawnSettings.MobSpawnCost cost) { builder.addMobCharge(entityType, cost.charge(), cost.energyBudget()); return this; } - + @Override public Mutable setSpawnCost(EntityType entityType, double charge, double energyBudget) { builder.addMobCharge(entityType, charge, energyBudget); return this; } - + @Override public Mutable clearSpawnCost(EntityType entityType) { getMobSpawnCosts().remove(entityType); return this; } } + + private static Object getField(Object target, String name) { + Class current = target.getClass(); + while (current != null) { + try { + Field field = current.getDeclaredField(name); + field.setAccessible(true); + return field.get(target); + } catch (NoSuchFieldException ignored) { + current = current.getSuperclass(); + } catch (IllegalAccessException exception) { + throw new IllegalStateException("Failed to access field '" + name + "' on " + target.getClass(), exception); + } + } + throw new IllegalStateException("Could not find field '" + name + "' on " + target.getClass()); + } + + private static void setField(Object target, String name, Object value) { + Class current = target.getClass(); + while (current != null) { + try { + Field field = current.getDeclaredField(name); + field.setAccessible(true); + field.set(target, value); + return; + } catch (NoSuchFieldException ignored) { + current = current.getSuperclass(); + } catch (IllegalAccessException exception) { + throw new IllegalStateException("Failed to set field '" + name + "' on " + target.getClass(), exception); + } + } + throw new IllegalStateException("Could not find field '" + name + "' on " + target.getClass()); + } } diff --git a/neoforge/src/main/java/dev/architectury/registry/level/entity/trade/forge/TradeRegistryImpl.java b/neoforge/src/main/java/dev/architectury/registry/level/entity/trade/forge/TradeRegistryImpl.java index 5ea8eef6c..6dc10d251 100644 --- a/neoforge/src/main/java/dev/architectury/registry/level/entity/trade/forge/TradeRegistryImpl.java +++ b/neoforge/src/main/java/dev/architectury/registry/level/entity/trade/forge/TradeRegistryImpl.java @@ -22,62 +22,61 @@ import dev.architectury.registry.level.entity.trade.TradeRegistry; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import net.minecraft.core.NonNullList; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.npc.villager.VillagerProfession; -import net.minecraft.world.entity.npc.villager.VillagerTrades; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.village.VillagerTradesEvent; -import net.neoforged.neoforge.event.village.WandererTradesEvent; +import net.minecraft.world.item.trading.MerchantOffer; +import net.minecraft.world.item.trading.MerchantOffers; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class TradeRegistryImpl { - private static final Map, Int2ObjectMap>> TRADES_TO_ADD = new HashMap<>(); - private static final List WANDERER_TRADER_TRADES_BUYING = new ArrayList<>(); - private static final List WANDERER_TRADER_TRADES_GENERIC = new ArrayList<>(); - private static final List WANDERER_TRADER_TRADES_RARE = new ArrayList<>(); - - static { - NeoForge.EVENT_BUS.addListener(TradeRegistryImpl::onTradeRegistering); - NeoForge.EVENT_BUS.addListener(TradeRegistryImpl::onWanderingTradeRegistering); - } - - public static void registerVillagerTrade0(ResourceKey profession, int level, VillagerTrades.ItemListing... trades) { - Int2ObjectMap> tradesForProfession = TRADES_TO_ADD.computeIfAbsent(profession, $ -> new Int2ObjectOpenHashMap<>()); - List tradesForLevel = tradesForProfession.computeIfAbsent(level, $ -> new ArrayList<>()); + private static final Map, Int2ObjectMap>> TRADES_TO_ADD = new HashMap<>(); + private static final EnumMap> WANDERER_TRADES_TO_ADD = new EnumMap<>(TradeRegistry.WandererTradeType.class); + + public static void registerVillagerTrade0(ResourceKey profession, int level, TradeRegistry.ItemListing... trades) { + Int2ObjectMap> tradesForProfession = TRADES_TO_ADD.computeIfAbsent(profession, $ -> new Int2ObjectOpenHashMap<>()); + List tradesForLevel = tradesForProfession.computeIfAbsent(level, $ -> new ArrayList<>()); Collections.addAll(tradesForLevel, trades); } - - public static void registerTradeForWanderingTrader(TradeRegistry.WandererTradeType type, VillagerTrades.ItemListing... trades) { - if (type == TradeRegistry.WandererTradeType.RARE_TRADES) { - Collections.addAll(WANDERER_TRADER_TRADES_RARE, trades); - } else if (type == TradeRegistry.WandererTradeType.GENERIC_TRADES) { - Collections.addAll(WANDERER_TRADER_TRADES_GENERIC, trades); - } else { - Collections.addAll(WANDERER_TRADER_TRADES_BUYING, trades); - } + + public static void registerTradeForWanderingTrader(TradeRegistry.WandererTradeType type, TradeRegistry.ItemListing... trades) { + List tradesForType = WANDERER_TRADES_TO_ADD.computeIfAbsent(type, $ -> new ArrayList<>()); + Collections.addAll(tradesForType, trades); } - - public static void onTradeRegistering(VillagerTradesEvent event) { - Int2ObjectMap> trades = TRADES_TO_ADD.get(event.getType()); - - if (trades != null) { - for (Int2ObjectMap.Entry> entry : trades.int2ObjectEntrySet()) { - event.getTrades().computeIfAbsent(entry.getIntKey(), $ -> NonNullList.create()).addAll(entry.getValue()); - } + + public static void appendVillagerTrades(ServerLevel level, MerchantOffers offers, ResourceKey profession, int villagerLevel, Entity entity, RandomSource random) { + Int2ObjectMap> tradesForProfession = TRADES_TO_ADD.get(profession); + if (tradesForProfession == null) { + return; } + + appendTrades(level, offers, tradesForProfession.get(villagerLevel), entity, random); } - - public static void onWanderingTradeRegistering(WandererTradesEvent event) { - if (!WANDERER_TRADER_TRADES_BUYING.isEmpty()) { - event.getBuyingTrades().addAll(WANDERER_TRADER_TRADES_BUYING); + + public static void appendWanderingTraderTrades(ServerLevel level, MerchantOffers offers, Entity entity, RandomSource random) { + for (TradeRegistry.WandererTradeType type : TradeRegistry.WandererTradeType.values()) { + appendTrades(level, offers, WANDERER_TRADES_TO_ADD.get(type), entity, random); } - if (!WANDERER_TRADER_TRADES_GENERIC.isEmpty()) { - event.getGenericTrades().addAll(WANDERER_TRADER_TRADES_GENERIC); + } + + private static void appendTrades(ServerLevel level, MerchantOffers offers, List trades, Entity entity, RandomSource random) { + if (trades == null) { + return; } - if (!WANDERER_TRADER_TRADES_RARE.isEmpty()) { - event.getRareTrades().addAll(WANDERER_TRADER_TRADES_RARE); + + for (TradeRegistry.ItemListing trade : trades) { + MerchantOffer offer = trade.getOffer(level, entity, random); + if (offer != null) { + offers.add(offer); + } } } } diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index cbe39dba8..5f8f3c708 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -17,7 +17,7 @@ license = "LGPL-3" [[dependencies.architectury]] modId = "minecraft" type = "required" -versionRange = "[1.21.4,)" +versionRange = "[26.1,)" ordering = "NONE" side = "BOTH" diff --git a/neoforge/src/main/resources/architectury.mixins.json b/neoforge/src/main/resources/architectury.mixins.json index 8537c2c6a..815da5d0e 100644 --- a/neoforge/src/main/resources/architectury.mixins.json +++ b/neoforge/src/main/resources/architectury.mixins.json @@ -2,7 +2,7 @@ "required": true, "package": "dev.architectury.mixin.forge", "plugin": "dev.architectury.plugin.forge.ArchitecturyMixinPlugin", - "compatibilityLevel": "JAVA_16", + "compatibilityLevel": "JAVA_25", "minVersion": "0.8", "client": [ "client.MixinClientPacketListener", @@ -17,7 +17,9 @@ "neoforge.LiquidBlockAccessor", "neoforge.MixinChunkMap", "MixinFallingBlockEntity", - "MixinLevelEvent" + "MixinLevelEvent", + "MixinVillager", + "MixinWanderingTrader" ], "injectors": { "defaultRequire": 1 diff --git a/settings.gradle b/settings.gradle index 2d3f37cbf..b4d8e441d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,23 +2,24 @@ pluginManagement { repositories { maven { url "https://maven.fabricmc.net/" } maven { url "https://maven.architectury.dev/" } + maven { url "https://maven.shedaniel.me/" } maven { url "https://files.minecraftforge.net/maven/" } + mavenCentral() gradlePluginPortal() } } -if (JavaVersion.current().ordinal() + 1 < 21) { - throw new IllegalStateException("Please run gradle with Java 21+!") +if (JavaVersion.current().ordinal() + 1 < 25) { + throw new IllegalStateException("Please run gradle with Java 25+!") } include("common") include("fabric") -//include("forge") -//include("minecraftforge") +include("forge") include("neoforge") include("testmod-common") include("testmod-fabric") //include("testmod-forge") -include("testmod-neoforge") +//include("testmod-neoforge") rootProject.name = "architectury" diff --git a/testmod-common/build.gradle b/testmod-common/build.gradle index 394658eab..0d00832bd 100644 --- a/testmod-common/build.gradle +++ b/testmod-common/build.gradle @@ -5,8 +5,8 @@ loom { dependencies { // We depend on fabric loader here to use the fabric @Environment annotations // Do NOT use other classes from fabric loader - modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" - implementation project(path: ":common", configuration: "namedElements") + implementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + implementation project(":common") } architectury { diff --git a/testmod-common/src/main/java/dev/architectury/test/TestModClient.java b/testmod-common/src/main/java/dev/architectury/test/TestModClient.java index d0c6d502d..d04df87ee 100644 --- a/testmod-common/src/main/java/dev/architectury/test/TestModClient.java +++ b/testmod-common/src/main/java/dev/architectury/test/TestModClient.java @@ -55,7 +55,7 @@ public static void initializeClient() { }))); }); ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.register(((screen, graphics, mouseX, mouseY, delta) -> { - graphics.renderItem(new ItemStack(Items.DIAMOND), mouseX, mouseY); + graphics.item(new ItemStack(Items.DIAMOND), mouseX, mouseY); })); } } diff --git a/testmod-common/src/main/java/dev/architectury/test/debug/client/ClientOverlayMessageSink.java b/testmod-common/src/main/java/dev/architectury/test/debug/client/ClientOverlayMessageSink.java index 93f145da6..676f5fc19 100644 --- a/testmod-common/src/main/java/dev/architectury/test/debug/client/ClientOverlayMessageSink.java +++ b/testmod-common/src/main/java/dev/architectury/test/debug/client/ClientOverlayMessageSink.java @@ -23,7 +23,7 @@ import dev.architectury.event.events.client.ClientGuiEvent; import dev.architectury.test.debug.ConsoleMessageSink; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; import net.minecraft.util.Util; @@ -49,7 +49,7 @@ public void accept(String message) { messages.add(0, new Message(Component.literal(message), Util.getMillis())); } - public void render(GuiGraphics graphics, float delta) { + public void render(GuiGraphicsExtractor graphics, float delta) { graphics.pose().pushMatrix(); graphics.pose().scale(0.5f, 0.5f); var minecraft = Minecraft.getInstance(); @@ -71,7 +71,7 @@ public void render(GuiGraphics graphics, float delta) { var textWidth = minecraft.font.width(message.text); var alpha = (int) Mth.clamp((5000 - timeExisted) / 5000f * 400f + 8, 0, 255); graphics.fill(0, y - 1, 2 + textWidth + 1, y + lineHeight - 1, 0x505050 + ((alpha * 144 / 255) << 24)); - graphics.drawString(minecraft.font, message.text, 1, y, 0xE0E0E0 + (alpha << 24)); + graphics.text(minecraft.font, message.text, 1, y, 0xE0E0E0 + (alpha << 24)); } y += lineHeight; } diff --git a/testmod-common/src/main/java/dev/architectury/test/events/DebugEvents.java b/testmod-common/src/main/java/dev/architectury/test/events/DebugEvents.java index d707ee30e..9724ad996 100644 --- a/testmod-common/src/main/java/dev/architectury/test/events/DebugEvents.java +++ b/testmod-common/src/main/java/dev/architectury/test/events/DebugEvents.java @@ -99,7 +99,7 @@ public static void debugEvents() { EntityEvent.ENTER_SECTION.register(((entity, nx, ny, nz, ox, oy, oz) -> { if (entity instanceof Player player) { TestMod.SINK.accept("%s switched section: %s => %s", entity.getScoreboardName(), sectionPos(ox, oy, oz), sectionPos(nx, oy, nz)); - player.displayClientMessage(Component.literal("Entering chunk: " + sectionPos(nx, ny, nz)), true); + player.sendOverlayMessage(Component.literal("Entering chunk: " + sectionPos(nx, ny, nz))); } })); EntityEvent.LIVING_CHECK_SPAWN.register(((entity, level, x, y, z, type, spawner) -> { diff --git a/testmod-common/src/main/java/dev/architectury/test/item/TestBlockInteractions.java b/testmod-common/src/main/java/dev/architectury/test/item/TestBlockInteractions.java index 16a84059f..ca238f10a 100644 --- a/testmod-common/src/main/java/dev/architectury/test/item/TestBlockInteractions.java +++ b/testmod-common/src/main/java/dev/architectury/test/item/TestBlockInteractions.java @@ -41,7 +41,7 @@ public static void init() { if (!ctx.getLevel().isClientSide()) { Player player = ctx.getPlayer(); if (player != null) - player.displayClientMessage(Component.literal("Thou has successfully committed the dark arts of alchemy!!"), false); + player.sendSystemMessage(Component.literal("Thou has successfully committed the dark arts of alchemy!!")); } }, ctx -> { return Blocks.DIAMOND_BLOCK.defaultBlockState(); diff --git a/testmod-common/src/main/java/dev/architectury/test/networking/ButtonClickedMessage.java b/testmod-common/src/main/java/dev/architectury/test/networking/ButtonClickedMessage.java index 8ceabe4d5..5c44f061e 100644 --- a/testmod-common/src/main/java/dev/architectury/test/networking/ButtonClickedMessage.java +++ b/testmod-common/src/main/java/dev/architectury/test/networking/ButtonClickedMessage.java @@ -41,6 +41,6 @@ public Type type() { } public void handle(NetworkManager.PacketContext context) { - context.getPlayer().displayClientMessage(Component.literal("You clicked button #" + buttonId), false); + context.getPlayer().sendSystemMessage(Component.literal("You clicked button #" + buttonId)); } -} \ No newline at end of file +} diff --git a/testmod-common/src/main/java/dev/architectury/test/networking/SyncDataMessage.java b/testmod-common/src/main/java/dev/architectury/test/networking/SyncDataMessage.java index 1d59de08f..927617543 100644 --- a/testmod-common/src/main/java/dev/architectury/test/networking/SyncDataMessage.java +++ b/testmod-common/src/main/java/dev/architectury/test/networking/SyncDataMessage.java @@ -42,6 +42,6 @@ public Type type() { } public void handle(NetworkManager.PacketContext context) { - context.getPlayer().displayClientMessage(Component.literal("Received data from server: " + serverData), false); + context.getPlayer().sendSystemMessage(Component.literal("Received data from server: " + serverData)); } -} \ No newline at end of file +} diff --git a/testmod-common/src/main/java/dev/architectury/test/recipes/TestRecipeSerializer.java b/testmod-common/src/main/java/dev/architectury/test/recipes/TestRecipeSerializer.java index aae71f50a..6bb028df2 100644 --- a/testmod-common/src/main/java/dev/architectury/test/recipes/TestRecipeSerializer.java +++ b/testmod-common/src/main/java/dev/architectury/test/recipes/TestRecipeSerializer.java @@ -19,38 +19,14 @@ package dev.architectury.test.recipes; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.world.item.crafting.*; +import net.minecraft.world.item.crafting.FireworkRocketRecipe; +import net.minecraft.world.item.crafting.RecipeSerializer; -public class TestRecipeSerializer implements RecipeSerializer { - private static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> - instance.group(CraftingBookCategory.CODEC.fieldOf("category") - .orElse(CraftingBookCategory.MISC) - .forGetter(CraftingRecipe::category) - ).apply(instance, FireworkRocketRecipe::new) - ); - private static final StreamCodec STREAM_CODEC = StreamCodec.of(TestRecipeSerializer::toNetwork, TestRecipeSerializer::fromNetwork); - - @Override - public MapCodec codec() { - return CODEC; - } - - @Override - public StreamCodec streamCodec() { - return STREAM_CODEC; - } - - public static CustomRecipe fromNetwork(FriendlyByteBuf buf) { - CraftingBookCategory category = buf.readEnum(CraftingBookCategory.class); - return new FireworkRocketRecipe(category); +public final class TestRecipeSerializer { + private TestRecipeSerializer() { } - public static void toNetwork(FriendlyByteBuf buf, CustomRecipe recipe) { - buf.writeEnum(recipe.category()); + public static RecipeSerializer create() { + return new RecipeSerializer<>(FireworkRocketRecipe.MAP_CODEC, FireworkRocketRecipe.STREAM_CODEC); } } diff --git a/testmod-common/src/main/java/dev/architectury/test/registry/TestRegistries.java b/testmod-common/src/main/java/dev/architectury/test/registry/TestRegistries.java index 8c82a80f5..90bbaa515 100644 --- a/testmod-common/src/main/java/dev/architectury/test/registry/TestRegistries.java +++ b/testmod-common/src/main/java/dev/architectury/test/registry/TestRegistries.java @@ -21,6 +21,7 @@ import dev.architectury.core.fluid.ArchitecturyFluidAttributes; import dev.architectury.core.fluid.SimpleArchitecturyFluidAttributes; +import dev.architectury.extensions.injected.InjectedItemPropertiesExtension; import dev.architectury.hooks.level.entity.EntityHooks; import dev.architectury.platform.Platform; import dev.architectury.registry.CreativeTabRegistry; @@ -48,6 +49,7 @@ import net.minecraft.world.item.component.Consumables; import net.minecraft.world.item.consume_effects.ApplyStatusEffectsConsumeEffect; import net.minecraft.world.item.crafting.CustomRecipe; +import net.minecraft.world.item.crafting.FireworkRocketRecipe; import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.BlockGetter; @@ -110,28 +112,26 @@ public TestInt(int value) { }); public static final RegistrySupplier TEST_ITEM = ITEMS.register("test_item", () -> - new Item(new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_item")))); + new Item(tabbedItemProperties("test_item"))); public static final RegistrySupplier TEST_EDIBLE = ITEMS.register("test_edible", () -> { - return new Item(new Item.Properties() + return new Item(tabbedItemProperties("test_edible") .food(new FoodProperties.Builder().nutrition(8).saturationModifier(0.8F).build(), Consumables.defaultFood() .onConsume( new ApplyStatusEffectsConsumeEffect(List.of(new MobEffectInstance(TEST_EFFECT, 100, 1))) - ).build()) - .arch$tab(TestRegistries.TEST_TAB) - .setId(id(Registries.ITEM, "test_edible"))); + ).build())); }); public static final RegistrySupplier TEST_SPAWN_EGG = ITEMS.register("test_spawn_egg", () -> - new SpawnEggItem(new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_spawn_egg")).spawnEgg(TestRegistries.TEST_ENTITY.get()))); + new SpawnEggItem(tabbedItemProperties("test_spawn_egg").spawnEgg(TestRegistries.TEST_ENTITY.get()))); public static final RegistrySupplier TEST_SPAWN_EGG_2 = ITEMS.register("test_spawn_egg_2", () -> - new SpawnEggItem(new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_spawn_egg_2")).spawnEgg(TestRegistries.TEST_ENTITY_2.get()))); + new SpawnEggItem(tabbedItemProperties("test_spawn_egg_2").spawnEgg(TestRegistries.TEST_ENTITY_2.get()))); public static final RegistrySupplier TEST_FLUID_BUCKET = ITEMS.register("test_fluid_bucket", () -> { try { // In example mod the forge class isn't being replaced, this is not required in mods depending on architectury return (Item) Class.forName(!Platform.isForge() ? "dev.architectury.core.item.ArchitecturyBucketItem" : "dev.architectury.core.item.forge.imitator.ArchitecturyBucketItem") .getDeclaredConstructor(Supplier.class, Item.Properties.class) - .newInstance(TestRegistries.TEST_FLUID, new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_fluid_bucket"))); + .newInstance(TestRegistries.TEST_FLUID, tabbedItemProperties("test_fluid_bucket")); } catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); @@ -139,7 +139,7 @@ public TestInt(int value) { }); public static final RegistrySupplier TEST_TOOLTIP = ITEMS.register("test_tooltip", - () -> new ItemWithTooltip(new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_tooltip")))); + () -> new ItemWithTooltip(tabbedItemProperties("test_tooltip"))); public static final RegistrySupplier TEST_BLOCK = BLOCKS.register("test_block", () -> new Block(BlockBehaviour.Properties.ofLegacyCopy(Blocks.STONE).setId(id(Registries.BLOCK, "test_block")))); @@ -189,14 +189,14 @@ public VoxelShape getCollisionShape(BlockState state, BlockGetter bg, BlockPos p }); public static final RegistrySupplier TEST_BLOCK_ITEM = ITEMS.register("test_block", () -> - new BlockItem(TEST_BLOCK.get(), new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_block")))); + new BlockItem(TEST_BLOCK.get(), tabbedItemProperties("test_block"))); public static final RegistrySupplier COLLISION_BLOCK_ITEM = ITEMS.register("collision_block", () -> - new BlockItem(COLLISION_BLOCK.get(), new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "collision_block")))); + new BlockItem(COLLISION_BLOCK.get(), tabbedItemProperties("collision_block"))); public static final RegistrySupplier> TEST_ENTITY = ENTITY_TYPES.register("test_entity", TestEntity.TYPE); public static final RegistrySupplier> TEST_ENTITY_2 = ENTITY_TYPES.register("test_entity_2", TestEntity.TYPE_2); - public static final RegistrySupplier> TEST_SERIALIZER = RECIPE_SERIALIZERS.register("test_serializer", TestRecipeSerializer::new); + public static final RegistrySupplier> TEST_SERIALIZER = RECIPE_SERIALIZERS.register("test_serializer", TestRecipeSerializer::create); public static final RegistrySupplier> TEST_RECIPE_TYPE = RECIPE_TYPES.register("test_recipe_type", () -> new RecipeType() { @Override @@ -230,4 +230,9 @@ public static void initialize() { private static ResourceKey id(ResourceKey> key, String string) { return ResourceKey.create(key, Identifier.fromNamespaceAndPath(TestMod.MOD_ID, string)); } + + private static Item.Properties tabbedItemProperties(String string) { + Item.Properties properties = new Item.Properties().setId(id(Registries.ITEM, string)); + return ((InjectedItemPropertiesExtension) (Object) properties).arch$tab(TEST_TAB); + } } diff --git a/testmod-common/src/main/java/dev/architectury/test/registry/objects/MyClientTooltipComponent.java b/testmod-common/src/main/java/dev/architectury/test/registry/objects/MyClientTooltipComponent.java index c719e58c1..91b3f3452 100644 --- a/testmod-common/src/main/java/dev/architectury/test/registry/objects/MyClientTooltipComponent.java +++ b/testmod-common/src/main/java/dev/architectury/test/registry/objects/MyClientTooltipComponent.java @@ -20,7 +20,7 @@ package dev.architectury.test.registry.objects; import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; public record MyClientTooltipComponent(ItemWithTooltip.MyTooltipComponent component) implements ClientTooltipComponent { @@ -35,10 +35,7 @@ public int getWidth(Font font) { } @Override - public void renderImage(Font font, int x, int y, int w, int h, GuiGraphics graphics) { - graphics.pose().pushMatrix(); - graphics.pose().translate(0, 0); - graphics.drawString(font, "Count: " + component.count(), x + getWidth(font) / 2, y + (getHeight(font) - font.lineHeight) / 2, 0xFF00FF00); - graphics.pose().popMatrix(); + public void extractImage(Font font, int x, int y, int w, int h, GuiGraphicsExtractor graphics) { + graphics.text(font, "Count: " + component.count(), x + getWidth(font) / 2, y + (getHeight(font) - font.lineHeight) / 2, 0xFF00FF00); } -} \ No newline at end of file +} diff --git a/testmod-common/src/main/java/dev/architectury/test/trade/TestTrades.java b/testmod-common/src/main/java/dev/architectury/test/trade/TestTrades.java index 7970b44fd..9563eaa1c 100644 --- a/testmod-common/src/main/java/dev/architectury/test/trade/TestTrades.java +++ b/testmod-common/src/main/java/dev/architectury/test/trade/TestTrades.java @@ -19,10 +19,10 @@ package dev.architectury.test.trade; +import dev.architectury.event.events.common.LifecycleEvent; import dev.architectury.registry.level.entity.trade.SimpleTrade; import dev.architectury.registry.level.entity.trade.TradeRegistry; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.world.entity.npc.villager.VillagerTrades; import net.minecraft.world.item.Items; import net.minecraft.world.item.trading.ItemCost; @@ -30,14 +30,16 @@ public class TestTrades { public static void init() { - for (var villagerProfession : BuiltInRegistries.VILLAGER_PROFESSION.registryKeySet()) { - TradeRegistry.registerVillagerTrade(villagerProfession, 1, TestTrades.createTrades()); - } - TradeRegistry.registerTradeForWanderingTrader(TradeRegistry.WandererTradeType.GENERIC_TRADES, TestTrades.createTrades()); + LifecycleEvent.SERVER_BEFORE_START.register(server -> { + for (var villagerProfession : BuiltInRegistries.VILLAGER_PROFESSION.registryKeySet()) { + TradeRegistry.registerVillagerTrade(villagerProfession, 1, TestTrades.createTrades()); + } + TradeRegistry.registerTradeForWanderingTrader(TradeRegistry.WandererTradeType.GENERIC_TRADES, TestTrades.createTrades()); + }); } - private static VillagerTrades.ItemListing[] createTrades() { + private static TradeRegistry.ItemListing[] createTrades() { var trade = new SimpleTrade(new ItemCost(Items.APPLE), Optional.empty(), Items.ACACIA_BOAT.getDefaultInstance(), 1, 0, 1.0F); - return new VillagerTrades.ItemListing[]{trade}; + return new TradeRegistry.ItemListing[]{trade}; } } diff --git a/testmod-fabric/build.gradle b/testmod-fabric/build.gradle index a298fd9dd..204170a96 100644 --- a/testmod-fabric/build.gradle +++ b/testmod-fabric/build.gradle @@ -1,12 +1,5 @@ -plugins { - id "com.github.johnrengelman.shadow" version "7.0.0" - id "com.matthewprenger.cursegradle" -} - loom { accessWidenerPath = project(":common").loom.accessWidenerPath - - mixin { useLegacyMixinAp = true } } architectury { @@ -22,10 +15,17 @@ configurations { } dependencies { - modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" - modImplementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + implementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + implementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + + implementation project(":fabric") + common(project(":common")) { transitive false } + common(project(":testmod-common")) { transitive false } +} - implementation project(path: ":fabric", configuration: "namedElements") - common(project(path: ":common", configuration: "namedElements")) { transitive false } - common(project(path: ":testmod-common", configuration: "namedElements")) { transitive false } +processResources { + filesMatching("fabric.mod.json") { + expand "version": project.version + } + inputs.property "version", project.version }