diff --git a/build.gradle b/build.gradle index 6cbedf7238..2014b41faa 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ loom { "mixins.oculus.compat.indigo.json", "mixins.oculus.compat.dh.json", "mixins.oculus.compat.indium.json", - "mixins.oculus.compat.json" + "mixins.oculus.compat.pixelmon.json" ] } mixin.defaultRefmapName = "oculus-mixins-refmap.json" @@ -94,13 +94,16 @@ repositories { maven { url "https://maven.blamejared.com/" } + maven { + url "https://maven.neoforged.net/releases" + } mavenCentral() } dependencies { minecraft "com.mojang:minecraft:${minecraft_version}" mappings loom.officialMojangMappings() - forge "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + forge "net.neoforged:forge:${minecraft_version}-${forge_version}" modCompileOnly "org.embeddedt:embeddium-${minecraft_version}:${embeddium_version}" compileOnly "maven.modrinth:distanthorizons:2.0.1-a-1.20.1" diff --git a/gradle.properties b/gradle.properties index f6379dc521..b692dd2aa4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ loom.platform = forge # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.20.1 - forge_version= 47.2.0 + forge_version=47.1.84 # Mod Properties mod_version = 1.6.13 diff --git a/settings.gradle b/settings.gradle index cd1b41ef27..e5e1d69339 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,7 +4,7 @@ pluginManagement { name = 'Fabric' url = 'https://maven.fabricmc.net/' } - maven { url "https://maven.architectury.dev/" } + maven { url "https://maven.architectury.dev/" } maven { url "https://maven.minecraftforge.net" } mavenCentral() gradlePluginPortal() diff --git a/src/main/java/net/coderbot/iris/Iris.java b/src/main/java/net/coderbot/iris/Iris.java index 6921830638..f8935d7448 100644 --- a/src/main/java/net/coderbot/iris/Iris.java +++ b/src/main/java/net/coderbot/iris/Iris.java @@ -33,6 +33,7 @@ import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; +import net.minecraftforge.client.ConfigScreenHandler; import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.client.event.RegisterKeyMappingsEvent; import net.minecraftforge.common.MinecraftForge; @@ -111,6 +112,7 @@ public Iris() { IRIS_VERSION = ModList.get().getModContainerById(MODID).get().getModInfo().getVersion().toString(); + ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () -> new ConfigScreenHandler.ConfigScreenFactory((mc, screen) -> new ShaderPackScreen(screen))); ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (a, b) -> true)); }catch (Exception ignored) { } diff --git a/src/main/java/net/coderbot/iris/LaunchWarn.java b/src/main/java/net/coderbot/iris/LaunchWarn.java index b6298e6654..30ee3c91e9 100644 --- a/src/main/java/net/coderbot/iris/LaunchWarn.java +++ b/src/main/java/net/coderbot/iris/LaunchWarn.java @@ -12,7 +12,7 @@ public class LaunchWarn { public static void main(String[] args) { // TODO: make this translatable String message = "This file is the Forge version of Oculus, meant to be installed as a mod. Would you like to get the Forge Installer instead?"; - String fallback = "This file is the Forge version of Oculus, meant to be installed as a mod. Please download the Forge Installer from https://files.minecraftforge.net."; + String fallback = "This file is the Forge version of Oculus, meant to be installed as a mod. Please download the Forge Installer from https://neoforged.net/"; if (GraphicsEnvironment.isHeadless()) { System.err.println(fallback); } else { @@ -27,7 +27,7 @@ public static void main(String[] args) { if (option == JOptionPane.YES_OPTION) { try { - Desktop.getDesktop().browse(URI.create("https://files.minecraftforge.net")); + Desktop.getDesktop().browse(URI.create("https://neoforged.net")); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/net/coderbot/iris/block_rendering/BlockMaterialMapping.java b/src/main/java/net/coderbot/iris/block_rendering/BlockMaterialMapping.java index 8f46aa0f41..4cc7554275 100644 --- a/src/main/java/net/coderbot/iris/block_rendering/BlockMaterialMapping.java +++ b/src/main/java/net/coderbot/iris/block_rendering/BlockMaterialMapping.java @@ -3,12 +3,13 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.coderbot.iris.Iris; import net.coderbot.iris.shaderpack.materialmap.BlockEntry; import net.coderbot.iris.shaderpack.materialmap.BlockRenderType; import net.coderbot.iris.shaderpack.materialmap.NamespacedId; import net.minecraft.client.renderer.RenderType; +import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; @@ -18,10 +19,12 @@ import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.Property; import net.minecraftforge.client.ChunkRenderTypeSet; +import net.minecraftforge.registries.ForgeRegistries; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; public class BlockMaterialMapping { public static Object2IntMap createBlockStateIdMap(Int2ObjectMap> blockPropertiesMap) { @@ -36,13 +39,13 @@ public static Object2IntMap createBlockStateIdMap(Int2ObjectMap createBlockTypeMap(Map blockPropertiesMap) { - Map blockTypeIds = new Reference2ReferenceOpenHashMap<>(); + public static Map, ChunkRenderTypeSet> createBlockTypeMap(Map blockPropertiesMap) { + Map, ChunkRenderTypeSet> blockTypeIds = new Object2ObjectOpenHashMap<>(); blockPropertiesMap.forEach((id, blockType) -> { ResourceLocation resourceLocation = new ResourceLocation(id.getNamespace(), id.getName()); - Block block = BuiltInRegistries.BLOCK.get(resourceLocation); + Holder.Reference block = ForgeRegistries.BLOCKS.getDelegateOrThrow(resourceLocation); blockTypeIds.put(block, ChunkRenderTypeSet.of(convertBlockToRenderType(blockType))); }); @@ -68,10 +71,15 @@ private static void addBlockStates(BlockEntry entry, Object2IntMap i NamespacedId id = entry.getId(); ResourceLocation resourceLocation = new ResourceLocation(id.getNamespace(), id.getName()); - Block block = BuiltInRegistries.BLOCK.get(resourceLocation); + Optional> delegateOpt = ForgeRegistries.BLOCKS.getDelegate(resourceLocation); // If the block doesn't exist, by default the registry will return AIR. That probably isn't what we want. - // TODO: Assuming that Registry.BLOCK.getDefaultId() == "minecraft:air" here + if (delegateOpt.isEmpty() || !delegateOpt.get().isBound()) { + return; + } + + Block block = delegateOpt.get().get(); + if (block == Blocks.AIR) { return; } diff --git a/src/main/java/net/coderbot/iris/block_rendering/BlockRenderingSettings.java b/src/main/java/net/coderbot/iris/block_rendering/BlockRenderingSettings.java index 6b57c32ddc..04bb07014b 100644 --- a/src/main/java/net/coderbot/iris/block_rendering/BlockRenderingSettings.java +++ b/src/main/java/net/coderbot/iris/block_rendering/BlockRenderingSettings.java @@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.coderbot.iris.shaderpack.materialmap.NamespacedId; import net.minecraft.client.renderer.RenderType; +import net.minecraft.core.Holder; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.client.ChunkRenderTypeSet; @@ -16,7 +17,7 @@ public class BlockRenderingSettings { private boolean reloadRequired; private Object2IntMap blockStateIds; - private Map blockTypeIds; + private Map, ChunkRenderTypeSet> blockTypeIds; private Object2IntFunction entityIds; private Object2IntFunction itemIds; private float ambientOcclusionLevel; @@ -54,7 +55,7 @@ public Object2IntMap getBlockStateIds() { } @Nullable - public Map getBlockTypeIds() { + public Map, ChunkRenderTypeSet> getBlockTypeIds() { return blockTypeIds; } @@ -78,7 +79,7 @@ public void setBlockStateIds(Object2IntMap blockStateIds) { this.blockStateIds = blockStateIds; } - public void setBlockTypeIds(Map blockTypeIds) { + public void setBlockTypeIds(Map, ChunkRenderTypeSet> blockTypeIds) { if (this.blockTypeIds != null && this.blockTypeIds.equals(blockTypeIds)) { return; } diff --git a/src/main/java/net/coderbot/iris/mixin/compat/pixelmon/MixinNormalizedFace.java b/src/main/java/net/coderbot/iris/compat/pixelmon/mixin/MixinNormalizedFace.java similarity index 95% rename from src/main/java/net/coderbot/iris/mixin/compat/pixelmon/MixinNormalizedFace.java rename to src/main/java/net/coderbot/iris/compat/pixelmon/mixin/MixinNormalizedFace.java index 8e24b31063..214530d4fd 100644 --- a/src/main/java/net/coderbot/iris/mixin/compat/pixelmon/MixinNormalizedFace.java +++ b/src/main/java/net/coderbot/iris/compat/pixelmon/mixin/MixinNormalizedFace.java @@ -1,4 +1,4 @@ -package net.coderbot.iris.mixin.compat.pixelmon; +package net.coderbot.iris.compat.pixelmon.mixin; import com.mojang.blaze3d.vertex.BufferBuilder; import org.objectweb.asm.Opcodes; diff --git a/src/main/java/net/coderbot/iris/mixin/compat/CompatMixinPlugin.java b/src/main/java/net/coderbot/iris/compat/pixelmon/mixin/OculusPixelmonCompatMixinPlugin.java similarity index 71% rename from src/main/java/net/coderbot/iris/mixin/compat/CompatMixinPlugin.java rename to src/main/java/net/coderbot/iris/compat/pixelmon/mixin/OculusPixelmonCompatMixinPlugin.java index 43dc50f6b7..9189816f7c 100644 --- a/src/main/java/net/coderbot/iris/mixin/compat/CompatMixinPlugin.java +++ b/src/main/java/net/coderbot/iris/compat/pixelmon/mixin/OculusPixelmonCompatMixinPlugin.java @@ -1,4 +1,4 @@ -package net.coderbot.iris.mixin.compat; +package net.coderbot.iris.compat.pixelmon.mixin; import net.minecraftforge.fml.loading.FMLLoader; import org.objectweb.asm.tree.ClassNode; @@ -8,7 +8,7 @@ import java.util.List; import java.util.Set; -public class CompatMixinPlugin implements IMixinConfigPlugin { +public class OculusPixelmonCompatMixinPlugin implements IMixinConfigPlugin { @Override public void onLoad(String mixinPackage) { @@ -21,10 +21,7 @@ public String getRefMapperConfig() { @Override public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - int startIndex = mixinClassName.indexOf("compat.") + "compat.".length(); - int endIndex = mixinClassName.indexOf(".", startIndex); - String modid = mixinClassName.substring(startIndex, endIndex); - return FMLLoader.getLoadingModList().getModFileById(modid) != null; + return FMLLoader.getLoadingModList().getModFileById("pixelmon") != null; } @Override diff --git a/src/main/java/net/coderbot/iris/mixin/MixinChunkRenderDispatcherRebuildTask.java b/src/main/java/net/coderbot/iris/mixin/MixinChunkRenderDispatcherRebuildTask.java new file mode 100644 index 0000000000..64d0cdaaa8 --- /dev/null +++ b/src/main/java/net/coderbot/iris/mixin/MixinChunkRenderDispatcherRebuildTask.java @@ -0,0 +1,33 @@ +package net.coderbot.iris.mixin; + +import net.coderbot.iris.block_rendering.BlockRenderingSettings; +import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.Holder; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.client.ChunkRenderTypeSet; +import net.minecraftforge.client.model.data.ModelData; +import net.minecraftforge.registries.ForgeRegistries; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.Map; + +@Mixin(ChunkRenderDispatcher.RenderChunk.RebuildTask.class) +public class MixinChunkRenderDispatcherRebuildTask { + @Redirect(method = "compile", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/BakedModel;getRenderTypes(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/util/RandomSource;Lnet/minecraftforge/client/model/data/ModelData;)Lnet/minecraftforge/client/ChunkRenderTypeSet;")) + private ChunkRenderTypeSet oculus$overrideRenderTypes(BakedModel instance, BlockState blockState, RandomSource randomSource, ModelData modelData) { + Map, ChunkRenderTypeSet> idMap = BlockRenderingSettings.INSTANCE.getBlockTypeIds(); + if (idMap != null) { + ChunkRenderTypeSet type = idMap.get(ForgeRegistries.BLOCKS.getDelegateOrThrow(blockState.getBlock())); + if (type != null) { + return type; + } + } + + return instance.getRenderTypes(blockState, randomSource, modelData); + } +} diff --git a/src/main/java/net/coderbot/iris/mixin/MixinClientPacketListener.java b/src/main/java/net/coderbot/iris/mixin/MixinClientPacketListener.java new file mode 100644 index 0000000000..8446e81652 --- /dev/null +++ b/src/main/java/net/coderbot/iris/mixin/MixinClientPacketListener.java @@ -0,0 +1,31 @@ +package net.coderbot.iris.mixin; + +import net.coderbot.iris.Iris; +import net.coderbot.iris.gl.shader.ShaderCompileException; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.network.chat.ClickEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundLoginPacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ClientPacketListener.class) +public class MixinClientPacketListener { + @Shadow + private Minecraft minecraft; + + @Inject(method = "handleLogin", at = @At("TAIL")) + private void iris$showUpdateMessage(ClientboundLoginPacket a, CallbackInfo ci) { + if (this.minecraft.player == null) { + return; + } + + Iris.getStoredError().ifPresent(e -> + this.minecraft.player.displayClientMessage(Component.translatable(e instanceof ShaderCompileException ? "iris.load.failure.shader" : "iris.load.failure.generic").append(Component.literal("Copy Info").withStyle(arg -> arg.withUnderlined(true).withColor(ChatFormatting.BLUE).withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, e.getMessage())))), false)); + } +} diff --git a/src/main/java/net/coderbot/iris/mixin/MixinItemBlockRenderTypes.java b/src/main/java/net/coderbot/iris/mixin/MixinItemBlockRenderTypes.java index cc2b639540..c719be9856 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinItemBlockRenderTypes.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinItemBlockRenderTypes.java @@ -3,9 +3,11 @@ import net.coderbot.iris.block_rendering.BlockRenderingSettings; import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.RenderType; +import net.minecraft.core.Holder; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.client.ChunkRenderTypeSet; +import net.minecraftforge.registries.ForgeRegistries; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -17,9 +19,9 @@ public class MixinItemBlockRenderTypes { @Inject(method = "getRenderLayers", at = @At("HEAD"), cancellable = true, remap = false) private static void iris$setCustomRenderType(BlockState arg, CallbackInfoReturnable cir) { - Map idMap = BlockRenderingSettings.INSTANCE.getBlockTypeIds(); + Map, ChunkRenderTypeSet> idMap = BlockRenderingSettings.INSTANCE.getBlockTypeIds(); if (idMap != null) { - ChunkRenderTypeSet type = idMap.get(arg.getBlock()); + ChunkRenderTypeSet type = idMap.get(ForgeRegistries.BLOCKS.getDelegateOrThrow(arg.getBlock())); if (type != null) { cir.setReturnValue(type); } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index bff076172b..6b9c63e9b0 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -29,6 +29,7 @@ side = "BOTH" [[dependencies.oculus]] modId = "embeddium" +mandatory = false versionRange = "[0.2.14,)" ordering = "NONE" side = "CLIENT" \ No newline at end of file diff --git a/src/main/resources/mixins.oculus.compat.json b/src/main/resources/mixins.oculus.compat.json deleted file mode 100644 index ea43c3a13a..0000000000 --- a/src/main/resources/mixins.oculus.compat.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "net.coderbot.iris.mixin.compat", - "plugin": "net.coderbot.iris.mixin.compat.CompatMixinPlugin", - "refmap": "oculus-refmap.json", - "compatibilityLevel": "JAVA_8", - "client": [ - "pixelmon.MixinNormalizedFace" - ], - "injectors": { - "defaultRequire": 1 - } -} \ No newline at end of file diff --git a/src/main/resources/mixins.oculus.compat.pixelmon.json b/src/main/resources/mixins.oculus.compat.pixelmon.json new file mode 100644 index 0000000000..ac57cce946 --- /dev/null +++ b/src/main/resources/mixins.oculus.compat.pixelmon.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "plugin": "net.coderbot.iris.compat.pixelmon.mixin.OculusPixelmonCompatMixinPlugin", + "package": "net.coderbot.iris.compat.pixelmon.mixin", + "compatibilityLevel": "JAVA_8", + "client": [ + "MixinNormalizedFace" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/main/resources/mixins.oculus.json b/src/main/resources/mixins.oculus.json index f9f3243469..d0b332451f 100644 --- a/src/main/resources/mixins.oculus.json +++ b/src/main/resources/mixins.oculus.json @@ -17,7 +17,9 @@ "MixinChainedJsonException", "MixinBooleanState", "MixinBiomes", + "MixinChunkRenderDispatcherRebuildTask", "MixinClientLanguage", + "MixinClientPacketListener", "MixinDebugScreenOverlay", "MixinTheEndPortalRenderer", "MixinEntityRenderDispatcher", diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkBuilderMeshingTask.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkBuilderMeshingTask.java new file mode 100644 index 0000000000..304eb70c38 --- /dev/null +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkBuilderMeshingTask.java @@ -0,0 +1,42 @@ +package net.coderbot.iris.compat.sodium.mixin.shader_overrides; + +import me.jellysquid.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask; +import net.coderbot.iris.block_rendering.BlockRenderingSettings; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.Holder; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.client.ChunkRenderTypeSet; +import net.minecraftforge.client.model.data.ModelData; +import net.minecraftforge.registries.ForgeRegistries; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.Map; + +@Mixin(ChunkBuilderMeshingTask.class) +public class MixinChunkBuilderMeshingTask { + /** + * @author embeddedt + * @reason On Forge, render types are not intended to be driven by a central registry like in vanilla; instead, they + * get queried from the block model during meshing. Only the default baked models defer to the vanilla registry; + * specifying a render type in the model JSON or using a custom model will return its own value. Thus, we need + * to redirect the access at a higher level. + */ + @Redirect(method = "execute(Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildContext;Lme/jellysquid/mods/sodium/client/util/task/CancellationToken;)Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildOutput;", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/BakedModel;getRenderTypes(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/util/RandomSource;Lnet/minecraftforge/client/model/data/ModelData;)Lnet/minecraftforge/client/ChunkRenderTypeSet;"), + remap = false) + private ChunkRenderTypeSet oculus$overrideRenderTypes(BakedModel instance, BlockState blockState, RandomSource randomSource, ModelData modelData) { + Map, ChunkRenderTypeSet> idMap = BlockRenderingSettings.INSTANCE.getBlockTypeIds(); + if (idMap != null) { + ChunkRenderTypeSet type = idMap.get(ForgeRegistries.BLOCKS.getDelegateOrThrow(blockState.getBlock())); + if (type != null) { + return type; + } + } + + return instance.getRenderTypes(blockState, randomSource, modelData); + } +} diff --git a/src/sodiumCompatibility/resources/mixins.oculus.compat.sodium.json b/src/sodiumCompatibility/resources/mixins.oculus.compat.sodium.json index 204b542155..39864d6ea0 100644 --- a/src/sodiumCompatibility/resources/mixins.oculus.compat.sodium.json +++ b/src/sodiumCompatibility/resources/mixins.oculus.compat.sodium.json @@ -29,6 +29,7 @@ "copyEntity.shadows.EntityRenderDispatcherMixin", "font.MixinGlyphRenderer", "pbr_animation.MixinSpriteContents", + "shader_overrides.MixinChunkBuilderMeshingTask", "shader_overrides.MixinGlProgram", "shader_overrides.MixinRegionChunkRenderer", "shader_overrides.MixinShaderChunkRenderer",