From 8998fa71b246482b5fdd6436ed892f36114855ab Mon Sep 17 00:00:00 2001 From: Take Weiland Date: Wed, 17 Aug 2022 22:51:05 +0200 Subject: [PATCH] Allow registering custom `ColorResolver`s (#8880) --- .../net/minecraft/client/Minecraft.java.patch | 3 +- .../client/multiplayer/ClientLevel.java.patch | 9 ++- .../client/ColorResolverManager.java | 51 ++++++++++++++ .../event/RegisterColorHandlersEvent.java | 25 +++++++ .../debug/client/CustomColorResolverTest.java | 66 +++++++++++++++++++ src/test/resources/META-INF/mods.toml | 2 + .../blockstates/test_block.json | 7 ++ .../models/block/block.json | 3 + 8 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/minecraftforge/client/ColorResolverManager.java create mode 100644 src/test/java/net/minecraftforge/debug/client/CustomColorResolverTest.java create mode 100644 src/test/resources/assets/custom_color_resolver_test/blockstates/test_block.json create mode 100644 src/test/resources/assets/custom_color_resolver_test/models/block/block.json diff --git a/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/patches/minecraft/net/minecraft/client/Minecraft.java.patch index 211be79363..2f8de55741 100644 --- a/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ b/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -67,7 +67,7 @@ this.f_91064_ = new DebugRenderer(this); this.f_238717_ = new RealmsDataFetcher(RealmsClient.m_239151_(this)); RenderSystem.m_69900_(this::m_91113_); -@@ -541,6 +_,19 @@ +@@ -541,6 +_,20 @@ TinyFileDialogs.tinyfd_messageBox("Minecraft", stringbuilder.toString(), "ok", "error", false); } @@ -83,6 +83,7 @@ + net.minecraftforge.client.gui.overlay.GuiOverlayManager.init(); + net.minecraftforge.client.DimensionSpecialEffectsManager.init(); + net.minecraftforge.client.NamedRenderTypeManager.init(); ++ net.minecraftforge.client.ColorResolverManager.init(); + this.f_90990_.m_85409_(this.f_91066_.m_231817_().m_231551_()); this.f_90990_.m_85424_(this.f_91066_.m_232123_().m_231551_()); diff --git a/patches/minecraft/net/minecraft/client/multiplayer/ClientLevel.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/ClientLevel.java.patch index 9ebbb6abdc..f74f73d29a 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/ClientLevel.java.patch +++ b/patches/minecraft/net/minecraft/client/multiplayer/ClientLevel.java.patch @@ -1,6 +1,13 @@ --- a/net/minecraft/client/multiplayer/ClientLevel.java +++ b/net/minecraft/client/multiplayer/ClientLevel.java -@@ -121,6 +_,8 @@ +@@ -115,12 +_,15 @@ + p_194170_.put(BiomeColors.f_108791_, new BlockTintCache((p_194168_) -> { + return this.m_104762_(p_194168_, BiomeColors.f_108791_); + })); ++ net.minecraftforge.client.ColorResolverManager.registerBlockTintCaches(ClientLevel.this, p_194170_); + }); + private final ClientChunkCache f_104559_; + private final Deque f_194122_ = Queues.newArrayDeque(); private int f_194123_; private final BlockStatePredictionHandler f_233599_ = new BlockStatePredictionHandler(); private static final Set f_194124_ = Set.of(Items.f_42127_, Items.f_151033_); diff --git a/src/main/java/net/minecraftforge/client/ColorResolverManager.java b/src/main/java/net/minecraftforge/client/ColorResolverManager.java new file mode 100644 index 0000000000..1c385635a5 --- /dev/null +++ b/src/main/java/net/minecraftforge/client/ColorResolverManager.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.client; + +import com.google.common.collect.ImmutableList; +import net.minecraft.client.color.block.BlockTintCache; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.level.ColorResolver; +import net.minecraftforge.client.event.RegisterColorHandlersEvent; +import net.minecraftforge.fml.ModLoader; +import org.jetbrains.annotations.ApiStatus; + +import java.util.Map; + +/** + * Manager for custom {@link ColorResolver} instances, collected via {@link RegisterColorHandlersEvent.ColorResolvers}. + */ +public final class ColorResolverManager +{ + + private static ImmutableList colorResolvers; + + @ApiStatus.Internal + public static void init() + { + ImmutableList.Builder builder = ImmutableList.builder(); + ModLoader.get().postEvent(new RegisterColorHandlersEvent.ColorResolvers(builder)); + colorResolvers = builder.build(); + } + + /** + * Register a {@link BlockTintCache} for every registered {@link ColorResolver} into the given target map. + * + * @param level the level to use + * @param target the map to populate + */ + public static void registerBlockTintCaches(ClientLevel level, Map target) + { + for (var resolver : colorResolvers) + { + target.put(resolver, new BlockTintCache(pos -> level.calculateBlockTint(pos, resolver))); + } + } + + private ColorResolverManager() + { + } +} diff --git a/src/main/java/net/minecraftforge/client/event/RegisterColorHandlersEvent.java b/src/main/java/net/minecraftforge/client/event/RegisterColorHandlersEvent.java index 29444c54c3..2376a39fc0 100644 --- a/src/main/java/net/minecraftforge/client/event/RegisterColorHandlersEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RegisterColorHandlersEvent.java @@ -5,10 +5,13 @@ package net.minecraftforge.client.event; +import com.google.common.collect.ImmutableList; import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.color.item.ItemColor; import net.minecraft.client.color.item.ItemColors; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.ColorResolver; import net.minecraft.world.level.ItemLike; import net.minecraftforge.eventbus.api.Cancelable; import net.minecraftforge.eventbus.api.Event; @@ -127,4 +130,26 @@ public abstract class RegisterColorHandlersEvent extends Event implements IModBu itemColors.register(itemColor, items); } } + + /** + * Allows registration of custom {@link ColorResolver} implementations to be used with + * {@link net.minecraft.world.level.BlockAndTintGetter#getBlockTint(BlockPos, ColorResolver)}. + */ + public static class ColorResolvers extends RegisterColorHandlersEvent + { + private final ImmutableList.Builder builder; + + @ApiStatus.Internal + public ColorResolvers(ImmutableList.Builder builder) + { + this.builder = builder; + } + + public void register(ColorResolver resolver) + { + this.builder.add(resolver); + } + + } + } diff --git a/src/test/java/net/minecraftforge/debug/client/CustomColorResolverTest.java b/src/test/java/net/minecraftforge/debug/client/CustomColorResolverTest.java new file mode 100644 index 0000000000..0556ac91e6 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/client/CustomColorResolverTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.debug.client; + +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.ColorResolver; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.Material; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.RegisterColorHandlersEvent; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +/** + * This mod tests custom {@link ColorResolver ColorResolvers} using {@link RegisterColorHandlersEvent.ColorResolvers}. + * To test, place the registered test block, it should be tinted blue in biomes with precipitation and red in others. + * The color should blend according to the biome blend setting. + */ +@Mod(CustomColorResolverTest.MOD_ID) +public class CustomColorResolverTest +{ + static final String MOD_ID = "custom_color_resolver_test"; + private static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID); + private static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MOD_ID); + + private static final RegistryObject BLOCK = BLOCKS.register("test_block", () -> new Block(BlockBehaviour.Properties.of(Material.STONE))); + + public CustomColorResolverTest() + { + final IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus(); + ITEMS.register(modBus); + BLOCKS.register(modBus); + + ITEMS.register("test_block", () -> new BlockItem(BLOCK.get(), new Item.Properties())); + } + + @Mod.EventBusSubscriber(value = Dist.CLIENT, modid=MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) + private static class ClientHandler + { + + private static final ColorResolver COLOR_RESOLVER = (biome, x, z) -> biome.getPrecipitation() == Biome.Precipitation.NONE ? 0xFF0000 : 0x0000FF; + + @SubscribeEvent + static void registerColorResolver(RegisterColorHandlersEvent.ColorResolvers event) + { + event.register(COLOR_RESOLVER); + } + + @SubscribeEvent + static void registerBlockColor(RegisterColorHandlersEvent.Block event) + { + event.register(((state, btGetter, pos, tintIndex) -> btGetter == null || pos == null ? 0 : btGetter.getBlockTint(pos, COLOR_RESOLVER)), BLOCK.get()); + } + } +} diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml index 7df8333233..9d9ec51a00 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/META-INF/mods.toml @@ -244,6 +244,8 @@ modId="mega_model_test" modId="emissive_elements_test" [[mods]] modId="anvil_update_event_fix" +[[mods]] +modId="custom_color_resolver_test" diff --git a/src/test/resources/assets/custom_color_resolver_test/blockstates/test_block.json b/src/test/resources/assets/custom_color_resolver_test/blockstates/test_block.json new file mode 100644 index 0000000000..0b2138cbd7 --- /dev/null +++ b/src/test/resources/assets/custom_color_resolver_test/blockstates/test_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "custom_color_resolver_test:block/block" + } + } +} \ No newline at end of file diff --git a/src/test/resources/assets/custom_color_resolver_test/models/block/block.json b/src/test/resources/assets/custom_color_resolver_test/models/block/block.json new file mode 100644 index 0000000000..f54d345a26 --- /dev/null +++ b/src/test/resources/assets/custom_color_resolver_test/models/block/block.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:block/grass_block" +} \ No newline at end of file