From bddfdf9cfdf5228d60c5479d0db04302589f5f1e Mon Sep 17 00:00:00 2001 From: deirn Date: Sat, 23 Mar 2024 17:14:08 +0700 Subject: [PATCH] add target redirector api (cherry picked from commit 3af621dc45f8ab2adc4a9f15c6178eea868ff479) --- .../waila/api/IBlockComponentProvider.java | 19 ++ .../waila/api/IEntityComponentProvider.java | 19 ++ .../java/mcp/mobius/waila/api/IRegistrar.java | 52 +++++ .../mobius/waila/api/ITargetRedirector.java | 55 ++++++ .../waila/gui/hud/TargetRedirector.java | 51 +++++ .../mobius/waila/gui/hud/TooltipHandler.java | 179 ++++++++++++------ .../mcp/mobius/waila/registry/Registrar.java | 22 +++ .../waila/plugin/test/RedirectTest.java | 35 ++++ .../waila/plugin/test/WailaPluginTest.java | 3 + 9 files changed, 376 insertions(+), 59 deletions(-) create mode 100644 src/api/java/mcp/mobius/waila/api/ITargetRedirector.java create mode 100644 src/main/java/mcp/mobius/waila/gui/hud/TargetRedirector.java create mode 100644 src/pluginTest/java/mcp/mobius/waila/plugin/test/RedirectTest.java diff --git a/src/api/java/mcp/mobius/waila/api/IBlockComponentProvider.java b/src/api/java/mcp/mobius/waila/api/IBlockComponentProvider.java index 3a7af5768..f98e8b6f3 100644 --- a/src/api/java/mcp/mobius/waila/api/IBlockComponentProvider.java +++ b/src/api/java/mcp/mobius/waila/api/IBlockComponentProvider.java @@ -28,6 +28,25 @@ public interface IBlockComponentProvider { */ BlockState EMPTY_BLOCK_STATE = Internals.unsafeAlloc(BlockState.class); + /** + * Redirect the ray cast hit result to target other object. + * + * @param redirect the redirector + * @param accessor contains most of the relevant information about the current environment. + * Note that {@link IBlockAccessor#getData()} will always be empty at this time + * @param config current plugin configuration + * + * @return {@code null} if this method doesn't redirect to anything, + * any result from one of {@link ITargetRedirector}'s methods otherwise + * + * @see IRegistrar#addRedirect(IBlockComponentProvider, Class) + */ + @Nullable + @ApiStatus.Experimental + default ITargetRedirector.Result redirect(ITargetRedirector redirect, IBlockAccessor accessor, IPluginConfig config) { + return null; + } + /** * Callback used to send additional context to {@link IDataProvider}s. * diff --git a/src/api/java/mcp/mobius/waila/api/IEntityComponentProvider.java b/src/api/java/mcp/mobius/waila/api/IEntityComponentProvider.java index dd9f3567b..ac68e4d1d 100644 --- a/src/api/java/mcp/mobius/waila/api/IEntityComponentProvider.java +++ b/src/api/java/mcp/mobius/waila/api/IEntityComponentProvider.java @@ -27,6 +27,25 @@ public interface IEntityComponentProvider { */ Entity EMPTY_ENTITY = Internals.unsafeAlloc(AreaEffectCloud.class); + /** + * Redirect the ray cast hit result to target other object. + * + * @param redirect the redirector + * @param accessor contains most of the relevant information about the current environment. + * Note that {@link IEntityAccessor#getData()} will always be empty at this time + * @param config current plugin configuration + * + * @return {@code null} if this method doesn't redirect to anything, + * any result from one of {@link ITargetRedirector}'s methods otherwise + * + * @see IRegistrar#addRedirect(IEntityComponentProvider, Class) + */ + @Nullable + @ApiStatus.Experimental + default ITargetRedirector.Result redirect(ITargetRedirector redirect, IEntityAccessor accessor, IPluginConfig config) { + return null; + } + /** * Callback used to send additional context to {@link IDataProvider}s. * diff --git a/src/api/java/mcp/mobius/waila/api/IRegistrar.java b/src/api/java/mcp/mobius/waila/api/IRegistrar.java index 0303ab367..8ce2fccd9 100644 --- a/src/api/java/mcp/mobius/waila/api/IRegistrar.java +++ b/src/api/java/mcp/mobius/waila/api/IRegistrar.java @@ -322,6 +322,33 @@ default void addEventListener(IEventListener listener) { */ void addBlacklist(BlockEntityType... blockEntityTypes); + /** + * Registers an {@link IBlockComponentProvider} instance to allow redirecting the object being displayed. + * A {@link BlockEntity} is also an acceptable class type. + * + * @param provider the data provider instance + * @param clazz the highest level class to apply to + * @param priority the priority of this provider 0 is the minimum, lower number will be called first + * + * @see #DEFAULT_PRIORITY + */ + @ApiStatus.Experimental + void addRedirect(IBlockComponentProvider provider, Class clazz, int priority); + + /** + * Registers an {@link IBlockComponentProvider} instance to allow redirecting the object being displayed. + * A {@link BlockEntity} is also an acceptable class type. + * + * @param provider the data provider instance + * @param clazz the highest level class to apply to + * + * @see #DEFAULT_PRIORITY + */ + @ApiStatus.Experimental + default void addRedirect(IBlockComponentProvider provider, Class clazz) { + addRedirect(provider, clazz, DEFAULT_PRIORITY); + } + /** * Registers an {@link IBlockComponentProvider} instance to allow overriding the block being displayed. * A {@link BlockEntity} is also an acceptable class type. @@ -441,6 +468,31 @@ default void addBlockData(IDataProvider provider */ void addBlacklist(EntityType... entityTypes); + /** + * Registers an {@link IEntityComponentProvider} instance to allow redirecting the object being displayed. + * + * @param provider the data provider instance + * @param clazz the highest level class to apply to + * @param priority the priority of this provider 0 is the minimum, lower number will be called first + * + * @see #DEFAULT_PRIORITY + */ + @ApiStatus.Experimental + void addRedirect(IEntityComponentProvider provider, Class clazz, int priority); + + /** + * Registers an {@link IEntityComponentProvider} instance to allow redirecting the object being displayed. + * + * @param provider the data provider instance + * @param clazz the highest level class to apply to + * + * @see #DEFAULT_PRIORITY + */ + @ApiStatus.Experimental + default void addRedirect(IEntityComponentProvider provider, Class clazz) { + addRedirect(provider, clazz, DEFAULT_PRIORITY); + } + /** * Registers an {@link IEntityComponentProvider} instance to allow overriding the entity being displayed. * diff --git a/src/api/java/mcp/mobius/waila/api/ITargetRedirector.java b/src/api/java/mcp/mobius/waila/api/ITargetRedirector.java new file mode 100644 index 000000000..6699883e4 --- /dev/null +++ b/src/api/java/mcp/mobius/waila/api/ITargetRedirector.java @@ -0,0 +1,55 @@ +package mcp.mobius.waila.api; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import org.jetbrains.annotations.ApiStatus; + +/** + * Used to redirect the targeted objet to other object. + * + * @see IBlockComponentProvider#redirect(ITargetRedirector, IBlockAccessor, IPluginConfig) + * @see IEntityComponentProvider#redirect(ITargetRedirector, IEntityAccessor, IPluginConfig) + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface ITargetRedirector { + + /** + * Redirect the current object to itself. + *

+ * This also restrict lower priority provider from redirecting the object, + * return {@code null} instead if the caller doesn't redirect. + */ + Result toSelf(); + + /** + * Redirect to nowhere, disabling the tooltip to be displayed. + */ + Result toNowhere(); + + /** + * Redirect to whatever object behind this object, essentially making this object appear invisible. + */ + Result toBehind(); + + /** + * Redirect to specific object at the hit result's position. + *

+ * Note: {@link BlockHitResult#withPosition(BlockPos)} will have the original + * {@linkplain HitResult#getLocation() hit location} (not to be confused with + * {@linkplain BlockHitResult#getBlockPos() block position}), you need to take + * account if the redirect target is not from something you own (e.g. redirecting + * to other mod's block). + */ + Result to(HitResult hitResult); + + /** + * Redirection result, only here to make sure it's not called multiple times. + */ + @ApiStatus.NonExtendable + interface Result { + + } + +} diff --git a/src/main/java/mcp/mobius/waila/gui/hud/TargetRedirector.java b/src/main/java/mcp/mobius/waila/gui/hud/TargetRedirector.java new file mode 100644 index 000000000..20b7dee3b --- /dev/null +++ b/src/main/java/mcp/mobius/waila/gui/hud/TargetRedirector.java @@ -0,0 +1,51 @@ +package mcp.mobius.waila.gui.hud; + +import mcp.mobius.waila.api.ITargetRedirector; +import net.minecraft.world.phys.HitResult; +import org.jetbrains.annotations.Nullable; + +public class TargetRedirector implements ITargetRedirector { + + private static final TargetRedirector INSTANCE = new TargetRedirector(); + private static final Result RESULT = new Result(); + + public boolean self, nowhere, behind; + public @Nullable HitResult to; + + public static TargetRedirector get() { + INSTANCE.self = false; + INSTANCE.nowhere = false; + INSTANCE.behind = false; + INSTANCE.to = null; + return INSTANCE; + } + + @Override + public Result toSelf() { + self = true; + return RESULT; + } + + @Override + public Result toNowhere() { + nowhere = true; + return RESULT; + } + + @Override + public Result toBehind() { + behind = true; + return RESULT; + } + + @Override + public Result to(HitResult hitResult) { + to = hitResult; + return RESULT; + } + + public static class Result implements ITargetRedirector.Result { + + } + +} diff --git a/src/main/java/mcp/mobius/waila/gui/hud/TooltipHandler.java b/src/main/java/mcp/mobius/waila/gui/hud/TooltipHandler.java index 779727f77..bf06954f5 100644 --- a/src/main/java/mcp/mobius/waila/gui/hud/TooltipHandler.java +++ b/src/main/java/mcp/mobius/waila/gui/hud/TooltipHandler.java @@ -6,6 +6,7 @@ import mcp.mobius.waila.api.IBlacklistConfig; import mcp.mobius.waila.api.IBlockComponentProvider; import mcp.mobius.waila.api.IEntityComponentProvider; +import mcp.mobius.waila.api.ITargetRedirector; import mcp.mobius.waila.api.ITheme; import mcp.mobius.waila.api.IWailaConfig; import mcp.mobius.waila.api.IWailaConfig.Overlay.Position.Align; @@ -25,6 +26,7 @@ import net.minecraft.world.level.block.LiquidBlock; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; import static mcp.mobius.waila.api.TooltipPosition.BODY; import static mcp.mobius.waila.api.TooltipPosition.HEAD; @@ -40,6 +42,10 @@ public class TooltipHandler { private static final Tooltip TOOLTIP = new Tooltip(); private static final Component SNEAK_DETAIL = Component.translatable(Tl.Tooltip.SNEAK_FOR_DETAILS).withStyle(ChatFormatting.ITALIC); + private enum ProcessResult { + CONTINUE, BREAK + } + public static void tick() { STATE.render = false; @@ -87,94 +93,149 @@ public static void tick() { if (castOrigin == null) return; for (var target : results) { - var accessor = ClientAccessor.INSTANCE; - accessor.set(client.level, player, target, client.cameraEntity, castOrigin, castDirection, pickRange, client.getFrameTime()); + if (processTarget(target, client, player, castOrigin, castDirection, pickRange, config) == ProcessResult.BREAK) break; + } + } - TooltipRenderer.beginBuild(STATE); + private static ProcessResult redirectTarget(HitResult target, TargetRedirector redirector, Minecraft client, Player player, Vec3 castOrigin, Vec3 castDirection, float pickRange, WailaConfig.General config) { + if (redirector.nowhere) return ProcessResult.BREAK; + if (redirector.behind) return ProcessResult.CONTINUE; - if (target.getType() == HitResult.Type.BLOCK) { - var block = accessor.getBlock(); + var redirect = redirector.to; + if (redirect == null) return ProcessResult.CONTINUE; + if (redirect.getType() == HitResult.Type.MISS) return ProcessResult.CONTINUE; - if (block instanceof LiquidBlock) { - if (!PluginConfig.CLIENT.getBoolean(WailaConstants.CONFIG_SHOW_FLUID)) continue; - } else if (!PluginConfig.CLIENT.getBoolean(WailaConstants.CONFIG_SHOW_BLOCK)) { - continue; - } + return processTarget( + redirect, client, player, + castOrigin.subtract(target.getLocation().subtract(redirect.getLocation())), + castDirection, pickRange, config); + } - if (IBlacklistConfig.get().contains(block)) continue; + private static ProcessResult processTarget(HitResult target, Minecraft client, Player player, Vec3 castOrigin, Vec3 castDirection, float pickRange, WailaConfig.General config) { + var accessor = ClientAccessor.INSTANCE; + accessor.set(client.level, player, target, client.cameraEntity, castOrigin, castDirection, pickRange, client.getFrameTime()); - var blockEntity = accessor.getBlockEntity(); - if (blockEntity != null && IBlacklistConfig.get().contains(blockEntity)) continue; + TooltipRenderer.beginBuild(STATE); - var state = ComponentHandler.getOverrideBlock(target); - if (state == IBlockComponentProvider.EMPTY_BLOCK_STATE) continue; + if (target.getType() == HitResult.Type.BLOCK) { + var block = accessor.getBlock(); + var blockEntity = accessor.getBlockEntity(); - accessor.setState(state); + var redirector = TargetRedirector.get(); + var redirectPriority = Integer.MAX_VALUE; + @Nullable ITargetRedirector.Result redirectResult = null; - requestBlockData(accessor); + for (var entry : Registrar.get().blockRedirect.get(block)) { + redirectResult = entry.instance().redirect(redirector, accessor, PluginConfig.CLIENT); + redirectPriority = entry.priority(); + if (redirectResult != null) break; + } - TOOLTIP.clear(); - gatherBlock(accessor, TOOLTIP, HEAD); - TooltipRenderer.add(TOOLTIP); + var hasBeRedirector = false; + for (var entry : Registrar.get().blockRedirect.get(blockEntity)) { + if (entry.priority() >= redirectPriority) break; + if (!hasBeRedirector) { + hasBeRedirector = true; + redirector = TargetRedirector.get(); + } + redirectResult = entry.instance().redirect(redirector, accessor, PluginConfig.CLIENT); + if (redirectResult != null) break; + } - TOOLTIP.clear(); - gatherBlock(accessor, TOOLTIP, BODY); + if (redirectResult != null && !redirector.self) { + return redirectTarget(target, redirector, client, player, castOrigin, castDirection, pickRange, config); + } - if (config.isShiftForDetails() && !TOOLTIP.isEmpty() && !player.isShiftKeyDown()) { - if (!config.isHideShiftText()) { - TooltipRenderer.add(new Line(null).with(SNEAK_DETAIL)); - } - } else { - TooltipRenderer.add(TOOLTIP); - } + if (block instanceof LiquidBlock) { + if (!PluginConfig.CLIENT.getBoolean(WailaConstants.CONFIG_SHOW_FLUID)) return ProcessResult.CONTINUE; + } else if (!PluginConfig.CLIENT.getBoolean(WailaConstants.CONFIG_SHOW_BLOCK)) { + return ProcessResult.CONTINUE; + } - TOOLTIP.clear(); - gatherBlock(accessor, TOOLTIP, TAIL); - } else if (target.getType() == HitResult.Type.ENTITY) { - if (!PluginConfig.CLIENT.getBoolean(WailaConstants.CONFIG_SHOW_ENTITY)) continue; + if (IBlacklistConfig.get().contains(block)) return ProcessResult.CONTINUE; - var actualEntity = accessor.getEntity(); - if (actualEntity == null) continue; - if (IBlacklistConfig.get().contains(actualEntity)) continue; + if (blockEntity != null && IBlacklistConfig.get().contains(blockEntity)) return ProcessResult.CONTINUE; - var targetEnt = ComponentHandler.getOverrideEntity(target); - if (targetEnt == IEntityComponentProvider.EMPTY_ENTITY) continue; + var state = ComponentHandler.getOverrideBlock(target); + if (state == IBlockComponentProvider.EMPTY_BLOCK_STATE) return ProcessResult.CONTINUE; - accessor.setEntity(targetEnt); - if (targetEnt == null) continue; + accessor.setState(state); - requestEntityData(targetEnt, accessor); + requestBlockData(accessor); - TOOLTIP.clear(); - gatherEntity(targetEnt, accessor, TOOLTIP, HEAD); - TooltipRenderer.add(TOOLTIP); + TOOLTIP.clear(); + gatherBlock(accessor, TOOLTIP, HEAD); + TooltipRenderer.add(TOOLTIP); - TOOLTIP.clear(); - gatherEntity(targetEnt, accessor, TOOLTIP, BODY); + TOOLTIP.clear(); + gatherBlock(accessor, TOOLTIP, BODY); - if (config.isShiftForDetails() && !TOOLTIP.isEmpty() && !player.isShiftKeyDown()) { - if (!config.isHideShiftText()) { - TooltipRenderer.add(new Line(null).with(SNEAK_DETAIL)); - } - } else { - TooltipRenderer.add(TOOLTIP); + if (config.isShiftForDetails() && !TOOLTIP.isEmpty() && !player.isShiftKeyDown()) { + if (!config.isHideShiftText()) { + TooltipRenderer.add(new Line(null).with(SNEAK_DETAIL)); } + } else { + TooltipRenderer.add(TOOLTIP); + } + + TOOLTIP.clear(); + gatherBlock(accessor, TOOLTIP, TAIL); + } else if (target.getType() == HitResult.Type.ENTITY) { + var actualEntity = accessor.getEntity(); + + var redirector = TargetRedirector.get(); + @Nullable ITargetRedirector.Result redirectResult = null; + + for (var entry : Registrar.get().entityRedirect.get(actualEntity)) { + redirectResult = entry.instance().redirect(redirector, accessor, PluginConfig.CLIENT); + if (redirectResult != null) break; + } - TOOLTIP.clear(); - gatherEntity(targetEnt, accessor, TOOLTIP, TAIL); + if (redirectResult != null && !redirector.self) { + return redirectTarget(target, redirector, client, player, castOrigin, castDirection, pickRange, config); } + if (!PluginConfig.CLIENT.getBoolean(WailaConstants.CONFIG_SHOW_ENTITY)) return ProcessResult.CONTINUE; + + if (actualEntity == null) return ProcessResult.CONTINUE; + if (IBlacklistConfig.get().contains(actualEntity)) return ProcessResult.CONTINUE; + + var targetEnt = ComponentHandler.getOverrideEntity(target); + if (targetEnt == IEntityComponentProvider.EMPTY_ENTITY) return ProcessResult.CONTINUE; + + accessor.setEntity(targetEnt); + if (targetEnt == null) return ProcessResult.CONTINUE; + + requestEntityData(targetEnt, accessor); + + TOOLTIP.clear(); + gatherEntity(targetEnt, accessor, TOOLTIP, HEAD); TooltipRenderer.add(TOOLTIP); - if (PluginConfig.CLIENT.getBoolean(WailaConstants.CONFIG_SHOW_ICON)) { - TooltipRenderer.setIcon(ComponentHandler.getIcon(target)); + TOOLTIP.clear(); + gatherEntity(targetEnt, accessor, TOOLTIP, BODY); + + if (config.isShiftForDetails() && !TOOLTIP.isEmpty() && !player.isShiftKeyDown()) { + if (!config.isHideShiftText()) { + TooltipRenderer.add(new Line(null).with(SNEAK_DETAIL)); + } + } else { + TooltipRenderer.add(TOOLTIP); } - STATE.render = true; - TooltipRenderer.endBuild(); + TOOLTIP.clear(); + gatherEntity(targetEnt, accessor, TOOLTIP, TAIL); + } + + TooltipRenderer.add(TOOLTIP); - break; + if (PluginConfig.CLIENT.getBoolean(WailaConstants.CONFIG_SHOW_ICON)) { + TooltipRenderer.setIcon(ComponentHandler.getIcon(target)); } + + STATE.render = true; + TooltipRenderer.endBuild(); + return ProcessResult.BREAK; } private static class ConfigTooltipRendererState implements TooltipRenderer.State { diff --git a/src/main/java/mcp/mobius/waila/registry/Registrar.java b/src/main/java/mcp/mobius/waila/registry/Registrar.java index 3c497f8df..eb47b2a71 100644 --- a/src/main/java/mcp/mobius/waila/registry/Registrar.java +++ b/src/main/java/mcp/mobius/waila/registry/Registrar.java @@ -48,6 +48,7 @@ public class Registrar implements IRegistrar { private static final Log LOG = Log.create(); + public final InstanceRegistry blockRedirect = new InstanceRegistry<>(); public final InstanceRegistry blockOverride = new InstanceRegistry<>(); public final InstanceRegistry blockIcon = new InstanceRegistry<>(); public final InstanceRegistry blockDataCtx = new InstanceRegistry<>(); @@ -58,6 +59,7 @@ public class Registrar implements IRegistrar { } }); + public final InstanceRegistry entityRedirect = new InstanceRegistry<>(); public final InstanceRegistry entityOverride = new InstanceRegistry<>(); public final InstanceRegistry entityIcon = new InstanceRegistry<>(); public final InstanceRegistry entityDataCtx = new InstanceRegistry<>(); @@ -193,6 +195,16 @@ public void addBlacklist(BlockEntityType... blockEntityTypes) { addBlacklist(blacklist.blockEntityTypes, Registry.BLOCK_ENTITY_TYPE, blockEntityTypes); } + @Override + public void addRedirect(IBlockComponentProvider provider, Class clazz, int priority) { + if (skip()) return; + if (Waila.CLIENT_SIDE) { + assertLock(); + assertPriority(priority); + blockRedirect.add(clazz, provider, priority); + } + } + @Override public void addOverride(IBlockComponentProvider provider, Class clazz, int priority) { if (skip()) return; @@ -250,6 +262,16 @@ public void addBlacklist(EntityType... entityTypes) { addBlacklist(blacklist.entityTypes, Registry.ENTITY_TYPE, entityTypes); } + @Override + public void addRedirect(IEntityComponentProvider provider, Class clazz, int priority) { + if (skip()) return; + if (Waila.CLIENT_SIDE) { + assertLock(); + assertPriority(priority); + entityRedirect.add(clazz, provider, priority); + } + } + @Override public void addOverride(IEntityComponentProvider provider, Class clazz, int priority) { if (skip()) return; diff --git a/src/pluginTest/java/mcp/mobius/waila/plugin/test/RedirectTest.java b/src/pluginTest/java/mcp/mobius/waila/plugin/test/RedirectTest.java new file mode 100644 index 000000000..63348fdb2 --- /dev/null +++ b/src/pluginTest/java/mcp/mobius/waila/plugin/test/RedirectTest.java @@ -0,0 +1,35 @@ +package mcp.mobius.waila.plugin.test; + +import mcp.mobius.waila.api.IBlockAccessor; +import mcp.mobius.waila.api.IBlockComponentProvider; +import mcp.mobius.waila.api.IPluginConfig; +import mcp.mobius.waila.api.ITargetRedirector; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Blocks; +import org.jetbrains.annotations.Nullable; + +public enum RedirectTest implements IBlockComponentProvider { + + INSTANCE; + + public static final ResourceLocation TARGET = new ResourceLocation("test:redirect.target"); + + public enum Target { + NONE, SELF, BEHIND, HIT, NOWHERE + } + + @Override + public @Nullable ITargetRedirector.Result redirect(ITargetRedirector redirect, IBlockAccessor accessor, IPluginConfig config) { + if (accessor.getBlock() != Blocks.BLACK_WOOL) return null; + + Target target = config.getEnum(TARGET); + return switch (target) { + case NONE -> null; + case SELF -> redirect.toSelf(); + case BEHIND -> redirect.toBehind(); + case HIT -> redirect.to(accessor.getBlockHitResult().withPosition(accessor.getPosition().above())); + case NOWHERE -> redirect.toNowhere(); + }; + } + +} diff --git a/src/pluginTest/java/mcp/mobius/waila/plugin/test/WailaPluginTest.java b/src/pluginTest/java/mcp/mobius/waila/plugin/test/WailaPluginTest.java index fc9aa043e..15f8a68f1 100644 --- a/src/pluginTest/java/mcp/mobius/waila/plugin/test/WailaPluginTest.java +++ b/src/pluginTest/java/mcp/mobius/waila/plugin/test/WailaPluginTest.java @@ -96,6 +96,9 @@ public void register(IRegistrar registrar) { registrar.addDataContext(RequestDataTest.INSTANCE, BarrelBlockEntity.class); registrar.addBlockData(RequestDataTest.INSTANCE, BarrelBlockEntity.class); registrar.addComponent(RequestDataTest.INSTANCE, TooltipPosition.BODY, BarrelBlockEntity.class); + + registrar.addConfig(RedirectTest.TARGET, RedirectTest.Target.NONE); + registrar.addRedirect(RedirectTest.INSTANCE, Block.class); } }