diff options
| author | Anthony Hilyard <anthony.hilyard@gmail.com> | 2023-01-14 16:03:02 -0800 |
|---|---|---|
| committer | Anthony Hilyard <anthony.hilyard@gmail.com> | 2023-01-14 16:03:02 -0800 |
| commit | b0d1aa6d5076738965f1f0fd9df98c6cd5bf946f (patch) | |
| tree | 35a2e2b6ff94425459bead944b4b73b87d51c460 /src | |
| parent | 7a93277b92f834c5a27f627cd0f873417cdbe95e (diff) | |
| download | Iceberg-b0d1aa6d5076738965f1f0fd9df98c6cd5bf946f.tar.gz Iceberg-b0d1aa6d5076738965f1f0fd9df98c6cd5bf946f.tar.bz2 Iceberg-b0d1aa6d5076738965f1f0fd9df98c6cd5bf946f.zip | |
Ported 1.1.4 changes from Forge.
Diffstat (limited to 'src')
14 files changed, 1339 insertions, 251 deletions
diff --git a/src/main/java/com/anthonyhilyard/iceberg/IcebergClient.java b/src/main/java/com/anthonyhilyard/iceberg/IcebergClient.java index 8218f71..8e3c31b 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/IcebergClient.java +++ b/src/main/java/com/anthonyhilyard/iceberg/IcebergClient.java @@ -1,12 +1,26 @@ package com.anthonyhilyard.iceberg; +import java.util.List; + +import com.anthonyhilyard.iceberg.events.RenderTooltipEvents; +import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.GatherResult; +import com.anthonyhilyard.iceberg.util.Tooltips.TitleBreakComponent; +import com.mojang.datafixers.util.Either; + import net.fabricmc.api.ClientModInitializer; +import net.minecraft.network.chat.FormattedText; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.inventory.tooltip.TooltipComponent; +import net.minecraft.world.item.ItemStack; public class IcebergClient implements ClientModInitializer { @Override public void onInitializeClient() { + TitleBreakComponent.registerFactory(); + RenderTooltipEvents.GATHER.register(IcebergClient::onGatherComponentsEventEnd); + // Event testing. // CriterionCallback.EVENT.register((player, advancement, criterion) -> { Loader.LOGGER.info("CriterionCallback: {}, {}, {}", player.getName().getString(), advancement.getId().toString(), criterion); }); // NewItemPickupCallback.EVENT.register((uuid, itemStack) -> { Loader.LOGGER.info("NewItemPickupCallback: {}, {}", uuid.toString(), itemStack.getDisplayName().getString()); }); @@ -23,4 +37,22 @@ public class IcebergClient implements ClientModInitializer // Loader.LOGGER.info("RenderTooltipEvents.POST: {}, {}, {}, {}, {}, {}, {}, {}, {}", stack.getDisplayName().getString(), components.stream().map(Object::toString).collect(Collectors.joining()), poseStack, x, y, font, width, height, comparison); // }); } + + public static GatherResult onGatherComponentsEventEnd(ItemStack itemStack, int screenWidth, int screenHeight, List<Either<FormattedText, TooltipComponent>> tooltipElements, int maxWidth, int index) + { + if (tooltipElements.size() > 1) + { + // Insert a title break component after the first formattedText component. + for (int i = 0; i < tooltipElements.size(); i++) + { + if (tooltipElements.get(i).left().isPresent()) + { + tooltipElements.add(i + 1, Either.<FormattedText, TooltipComponent>right(new TitleBreakComponent())); + break; + } + } + } + + return new GatherResult(InteractionResult.PASS, maxWidth, tooltipElements); + } } diff --git a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java index 622d3e0..c5a10a8 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java +++ b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java @@ -23,7 +23,7 @@ public final class RenderTooltipEvents GatherResult result = new GatherResult(InteractionResult.PASS, maxWidth, tooltipElements); for (RenderTooltipEvents.Gather callback : callbacks) { - result = callback.onGather(itemStack, screenWidth, screenHeight, tooltipElements, maxWidth, index); + result = callback.onGather(itemStack, screenWidth, screenHeight, result.tooltipElements, result.maxWidth, index); if (result.result != InteractionResult.PASS) { @@ -38,7 +38,7 @@ public final class RenderTooltipEvents PreExtResult result = new PreExtResult(InteractionResult.PASS, x, y, screenWidth, screenHeight, font); for (RenderTooltipEvents.PreExt callback : callbacks) { - result = callback.onPre(stack, components, poseStack, x, y, screenWidth, screenHeight, font, comparison, index); + result = callback.onPre(stack, components, poseStack, result.x, result.y, screenWidth, screenHeight, result.font, comparison, index); if (result.result != InteractionResult.PASS) { diff --git a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java index a797c9f..bc3674f 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java +++ b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java @@ -9,16 +9,12 @@ import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorResult; import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.PreExtResult; import com.anthonyhilyard.iceberg.util.Tooltips; import com.google.common.collect.Lists; -import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.math.Matrix4f; 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.Redirect; import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -29,9 +25,11 @@ import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner; +import net.minecraft.client.gui.screens.inventory.tooltip.TooltipRenderUtil; +import net.minecraft.network.chat.TextColor; import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionResult; -import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemStack; @@ -60,12 +58,24 @@ public class ScreenMixin extends AbstractContainerEventHandler } @Inject(method = "renderTooltip(Lcom/mojang/blaze3d/vertex/PoseStack;Ljava/util/List;Ljava/util/Optional;II)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;renderTooltipInternal(Lcom/mojang/blaze3d/vertex/PoseStack;Ljava/util/List;II)V"), - locals = LocalCapture.CAPTURE_FAILEXCEPTION) + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;renderTooltipInternal(Lcom/mojang/blaze3d/vertex/PoseStack;Ljava/util/List;IILnet/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipPositioner;)V", + shift = Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILEXCEPTION) public void renderTooltip(PoseStack poseStack, List<Component> textComponents, Optional<TooltipComponent> itemComponent, int x, int y, CallbackInfo info, List<ClientTooltipComponent> components) { Screen self = (Screen)(Object)this; + if (self instanceof AbstractContainerScreen<?> containerScreen) + { + Slot hoveredSlot = containerScreen.hoveredSlot; + + // If the tooltip stack is empty, try to get the stack from the slot under the mouse. + // This is needed for the creative inventory screen, which doesn't set the tooltip stack. + if (tooltipStack.isEmpty() && hoveredSlot != null) + { + tooltipStack = hoveredSlot.getItem(); + } + } + List<ClientTooltipComponent> newComponents = Tooltips.gatherTooltipComponents(tooltipStack, textComponents, itemComponent, x, self.width, self.height, null, font, -1); if (newComponents != null && !newComponents.isEmpty()) { @@ -74,93 +84,65 @@ public class ScreenMixin extends AbstractContainerEventHandler } } - @SuppressWarnings({"unchecked", "deprecation"}) + @SuppressWarnings("deprecation") @Inject(method = "renderTooltipInternal", at = @At(value = "HEAD"), cancellable = true) - private void preRenderTooltipInternal(PoseStack poseStack, List<ClientTooltipComponent> components, int x, int y, CallbackInfo info) + private void preRenderTooltipInternal(PoseStack poseStack, List<ClientTooltipComponent> components, int x, int y, ClientTooltipPositioner positioner, CallbackInfo info) { - PreExtResult eventResult = null; Screen self = (Screen)(Object)this; - if (self instanceof AbstractContainerScreen) + + if (!components.isEmpty()) { - if (!components.isEmpty()) + PreExtResult eventResult = null; + InteractionResult result = InteractionResult.PASS; + + eventResult = RenderTooltipEvents.PREEXT.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, font, false, 0); + result = eventResult.result(); + + if (result != InteractionResult.PASS) { - Slot hoveredSlot = ((AbstractContainerScreen<AbstractContainerMenu>)self).hoveredSlot; - if (hoveredSlot != null) - { - ItemStack tooltipStack = hoveredSlot.getItem(); - InteractionResult result = InteractionResult.PASS; - eventResult = RenderTooltipEvents.PREEXT.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, font, false, 0); - result = eventResult.result(); - - if (result != InteractionResult.PASS) - { - info.cancel(); - } - - // Fire a pre event as well for compatibility. - result = RenderTooltipEvents.PRE.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, -1, font, false); - if (result != InteractionResult.PASS) - { - info.cancel(); - } - } + info.cancel(); } - } - } - @SuppressWarnings("unchecked") - @Redirect(method = "renderTooltipInternal", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/gui/screens/Screen;fillGradient(Lcom/mojang/math/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIIIII)V")) - private void fillGradientProxy(Matrix4f matrix4f, BufferBuilder bufferBuilder, int left, int top, int right, int bottom, int zIndex, int colorStart, int colorEnd) - { - Screen self = (Screen)(Object)this; - ItemStack tooltipStack = ItemStack.EMPTY; - if (self instanceof AbstractContainerScreen) - { - Slot hoveredSlot = ((AbstractContainerScreen<AbstractContainerMenu>)self).hoveredSlot; - - if (hoveredSlot != null) + // Fire a pre event as well for compatibility. + result = RenderTooltipEvents.PRE.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, -1, font, false); + if (result != InteractionResult.PASS) { - tooltipStack = hoveredSlot.getItem(); + info.cancel(); } } - if (tooltipStack == ItemStack.EMPTY) - { - // Do standard functionality if this isn't a container screen. - Screen.fillGradient(matrix4f, bufferBuilder, left, top, right, bottom, zIndex, colorStart, colorEnd); - } - else - { - // Otherwise do nothing to disable the default calls. - } } - @SuppressWarnings({"unchecked", "deprecation"}) - @Inject(method = "renderTooltipInternal", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/gui/screens/Screen;fillGradient(Lcom/mojang/math/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIIIII)V", ordinal = 0, shift = Shift.BEFORE), - locals = LocalCapture.CAPTURE_FAILEXCEPTION) - private void preFillGradient(PoseStack poseStack, List<ClientTooltipComponent> components, int x, int y, CallbackInfo info, - int __, int ___, int left, int top, int width, int height, int background, int borderStart, int borderEnd, - int zIndex, float blitOffset, Tesselator tesselator, BufferBuilder bufferBuilder, Matrix4f matrix4f) + @SuppressWarnings("deprecation") + @Inject(method = "renderTooltipInternal", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil;renderTooltipBackground(Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil$BlitPainter;Lorg/joml/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIII)V", + ordinal = 0, shift = Shift.BEFORE)) + private void preFillGradient(PoseStack poseStack, List<ClientTooltipComponent> components, int x, int y, ClientTooltipPositioner positioner, CallbackInfo info) { Screen self = (Screen)(Object)this; - ItemStack tooltipStack = ItemStack.EMPTY; - if (self instanceof AbstractContainerScreen) + ItemStack containerStack = ItemStack.EMPTY; + if (self instanceof AbstractContainerScreen<?> containerScreen) { - Slot hoveredSlot = ((AbstractContainerScreen<AbstractContainerMenu>)self).hoveredSlot; - + Slot hoveredSlot = containerScreen.hoveredSlot; if (hoveredSlot != null) { - tooltipStack = hoveredSlot.getItem(); + containerStack = hoveredSlot.getItem(); } } - if (tooltipStack != ItemStack.EMPTY) + if (containerStack.isEmpty()) { + containerStack = tooltipStack; + } + + if (!containerStack.isEmpty()) + { + int background = TooltipRenderUtil.BACKGROUND_COLOR; int backgroundEnd = background; + int borderStart = TooltipRenderUtil.BORDER_COLOR_TOP; + int borderEnd = TooltipRenderUtil.BORDER_COLOR_BOTTOM; // Do colors now, sure why not. - ColorExtResult result = RenderTooltipEvents.COLOREXT.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, backgroundEnd, borderStart, borderEnd, false, 0); + ColorExtResult result = RenderTooltipEvents.COLOREXT.invoker().onColor(containerStack, components, poseStack, x, y, font, background, backgroundEnd, borderStart, borderEnd, false, 0); if (result != null) { background = result.backgroundStart(); @@ -170,7 +152,7 @@ public class ScreenMixin extends AbstractContainerEventHandler } // Fire a colors event as well for compatibility. - ColorResult colorResult = RenderTooltipEvents.COLOR.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, borderStart, borderEnd, false); + ColorResult colorResult = RenderTooltipEvents.COLOR.invoker().onColor(containerStack, components, poseStack, x, y, font, background, borderStart, borderEnd, false); if (colorResult != null) { background = colorResult.background(); @@ -178,35 +160,37 @@ public class ScreenMixin extends AbstractContainerEventHandler borderEnd = colorResult.borderEnd(); } - Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 4, left + width + 3, top - 3, zIndex, background, background); - Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top + height + 3, left + width + 3, top + height + 4, zIndex, backgroundEnd, backgroundEnd); - Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top + height + 3, zIndex, background, backgroundEnd); - Screen.fillGradient(matrix4f, bufferBuilder, left - 4, top - 3, left - 3, top + height + 3, zIndex, background, backgroundEnd); - Screen.fillGradient(matrix4f, bufferBuilder, left + width + 3, top - 3, left + width + 4, top + height + 3, zIndex, background, backgroundEnd); - Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3 + 1, left - 3 + 1, top + height + 3 - 1, zIndex, borderStart, borderEnd); - Screen.fillGradient(matrix4f, bufferBuilder, left + width + 2, top - 3 + 1, left + width + 3, top + height + 3 - 1, zIndex, borderStart, borderEnd); - Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top - 3 + 1, zIndex, borderStart, borderStart); - Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top + height + 2, left + width + 3, top + height + 3, zIndex, borderEnd, borderEnd); + Tooltips.currentColors = new Tooltips.TooltipColors(TextColor.fromRgb(background), TextColor.fromRgb(backgroundEnd), TextColor.fromRgb(borderStart), TextColor.fromRgb(borderEnd)); } } - @SuppressWarnings({"unchecked", "deprecation"}) + @SuppressWarnings("deprecation") @Inject(method = "renderTooltipInternal", at = @At(value = "TAIL"), locals = LocalCapture.CAPTURE_FAILEXCEPTION) - private void renderTooltipInternal(PoseStack poseStack, List<ClientTooltipComponent> components, int x, int y, CallbackInfo info, int tooltipWidth, int tooltipHeight, int postX, int postY) + private void renderTooltipInternal(PoseStack poseStack, List<ClientTooltipComponent> components, int x, int y, ClientTooltipPositioner positioner, CallbackInfo info, int tooltipWidth, int tooltipHeight, int postX, int postY) { - if ((Screen)(Object)this instanceof AbstractContainerScreen) + Screen self = (Screen)(Object)this; + ItemStack containerStack = ItemStack.EMPTY; + if (self instanceof AbstractContainerScreen<?> containerScreen) { - if (!components.isEmpty()) + Slot hoveredSlot = containerScreen.hoveredSlot; + if (hoveredSlot != null) { - Slot hoveredSlot = ((AbstractContainerScreen<AbstractContainerMenu>)(Object)this).hoveredSlot; - if (hoveredSlot != null) - { - ItemStack tooltipStack = hoveredSlot.getItem(); - RenderTooltipEvents.POSTEXT.invoker().onPost(tooltipStack, components, poseStack, postX, postY, font, tooltipWidth, tooltipHeight, false, 0); - RenderTooltipEvents.POST.invoker().onPost(tooltipStack, components, poseStack, postX, postY, font, tooltipWidth, tooltipHeight, false); - } + containerStack = hoveredSlot.getItem(); } } + + if (containerStack.isEmpty()) + { + containerStack = tooltipStack; + } + + if (!containerStack.isEmpty() && !components.isEmpty()) + { + RenderTooltipEvents.POSTEXT.invoker().onPost(containerStack, components, poseStack, postX, postY, font, tooltipWidth, tooltipHeight, false, 0); + RenderTooltipEvents.POST.invoker().onPost(containerStack, components, poseStack, postX, postY, font, tooltipWidth, tooltipHeight, false); + } + + tooltipStack = ItemStack.EMPTY; } @Override diff --git a/src/main/java/com/anthonyhilyard/iceberg/mixin/TooltipRenderUtilMixin.java b/src/main/java/com/anthonyhilyard/iceberg/mixin/TooltipRenderUtilMixin.java new file mode 100644 index 0000000..18ef9e4 --- /dev/null +++ b/src/main/java/com/anthonyhilyard/iceberg/mixin/TooltipRenderUtilMixin.java @@ -0,0 +1,120 @@ +package com.anthonyhilyard.iceberg.mixin; + +import org.joml.Matrix4f; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.anthonyhilyard.iceberg.util.Tooltips; +import com.mojang.blaze3d.vertex.BufferBuilder; + +import net.minecraft.client.gui.screens.inventory.tooltip.TooltipRenderUtil; +import net.minecraft.network.chat.TextColor; + +@Mixin(TooltipRenderUtil.class) +public class TooltipRenderUtilMixin +{ + @Unique + private static TextColor horizontalLineColor; + + @Shadow + @Final + private static int BACKGROUND_COLOR; + + @Shadow + @Final + private static int BORDER_COLOR_TOP; + + @Shadow + @Final + private static int BORDER_COLOR_BOTTOM; + + @Inject(method = "renderTooltipBackground", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil;renderHorizontalLine(Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil$BlitPainter;Lorg/joml/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIII)V", shift = At.Shift.BEFORE, ordinal = 0)) + private static void icebergRenderTooltipBackgroundOne(TooltipRenderUtil.BlitPainter painter, Matrix4f matrix, BufferBuilder bufferbuilder, int x, int y, int width, int height, int z, CallbackInfo info) + { + horizontalLineColor = Tooltips.currentColors.backgroundColorStart(); + } + + @Inject(method = "renderTooltipBackground", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil;renderHorizontalLine(Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil$BlitPainter;Lorg/joml/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIII)V", shift = At.Shift.BEFORE, ordinal = 1)) + private static void icebergRenderTooltipBackgroundTwo(TooltipRenderUtil.BlitPainter painter, Matrix4f matrix, BufferBuilder bufferbuilder, int x, int y, int width, int height, int z, CallbackInfo info) + { + horizontalLineColor = Tooltips.currentColors.backgroundColorEnd(); + } + + @Inject(method = "renderFrameGradient", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil;renderHorizontalLine(Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil$BlitPainter;Lorg/joml/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIII)V", shift = At.Shift.BEFORE, ordinal = 0)) + private static void icebergRenderFrameGradientOne(TooltipRenderUtil.BlitPainter painter, Matrix4f matrix, BufferBuilder bufferbuilder, int x, int y, int width, int height, int z, int color1, int color2, CallbackInfo info) + { + horizontalLineColor = Tooltips.currentColors.borderColorStart(); + } + + @Inject(method = "renderFrameGradient", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil;renderHorizontalLine(Lnet/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil$BlitPainter;Lorg/joml/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIII)V", shift = At.Shift.BEFORE, ordinal = 1)) + private static void icebergRenderFrameGradientTwo(TooltipRenderUtil.BlitPainter painter, Matrix4f matrix, BufferBuilder bufferbuilder, int x, int y, int width, int height, int z, int color1, int color2, CallbackInfo info) + { + horizontalLineColor = Tooltips.currentColors.borderColorEnd(); + } + + @Inject(method = "renderHorizontalLine", at = @At(value = "HEAD"), cancellable = true) + private static void icebergRenderHorizontalLine(TooltipRenderUtil.BlitPainter painter, Matrix4f matrix, BufferBuilder bufferbuilder, int x, int y, int width, int z, int color, CallbackInfo info) + { + if (color != BACKGROUND_COLOR && color != BORDER_COLOR_TOP && color != BORDER_COLOR_BOTTOM) + { + // Do default behavior so other mods that change colors can still work. + } + else + { + // Replace the rendered colors with the ones previously stored. + int renderColor = horizontalLineColor.getValue(); + painter.blit(matrix, bufferbuilder, x, y, x + width, y + 1, z, renderColor, renderColor); + info.cancel(); + } + } + + @Inject(method = "renderRectangle", at = @At(value = "HEAD"), cancellable = true) + private static void icebergRenderRectangle(TooltipRenderUtil.BlitPainter painter, Matrix4f matrix, BufferBuilder bufferbuilder, int x, int y, int width, int height, int z, int color, CallbackInfo info) + { + if (color != BACKGROUND_COLOR) + { + // Do default behavior so other mods that change colors can still work. + } + else + { + // Replace the rendered colors with the ones previously stored. + painter.blit(matrix, bufferbuilder, x, y, x + width, y + height, z, Tooltips.currentColors.backgroundColorStart().getValue(), Tooltips.currentColors.backgroundColorEnd().getValue()); + info.cancel(); + } + } + + @Inject(method = "renderVerticalLine", at = @At(value = "HEAD"), cancellable = true) + private static void icebergRenderVerticalLine(TooltipRenderUtil.BlitPainter painter, Matrix4f matrix, BufferBuilder bufferbuilder, int x, int y, int height, int z, int color, CallbackInfo info) + { + if (color != BACKGROUND_COLOR) + { + // Do default behavior so other mods that change colors can still work. + } + else + { + // Replace the rendered colors with the ones previously stored. + painter.blit(matrix, bufferbuilder, x, y, x + 1, y + height, z, Tooltips.currentColors.backgroundColorStart().getValue(), Tooltips.currentColors.backgroundColorEnd().getValue()); + info.cancel(); + } + } + + @Inject(method = "renderVerticalLineGradient", at = @At(value = "HEAD"), cancellable = true) + private static void icebergRenderVerticalLineGradient(TooltipRenderUtil.BlitPainter painter, Matrix4f matrix, BufferBuilder bufferbuilder, int x, int y, int height, int z, int startColor, int endColor, CallbackInfo info) + { + if (startColor != BORDER_COLOR_TOP || endColor != BORDER_COLOR_BOTTOM) + { + // Do default behavior so other mods that change colors can still work. + } + else + { + // Replace the rendered colors with the ones previously stored. + painter.blit(matrix, bufferbuilder, x, y, x + 1, y + height, z, Tooltips.currentColors.borderColorStart().getValue(), Tooltips.currentColors.borderColorEnd().getValue()); + info.cancel(); + } + } +}
\ No newline at end of file diff --git a/src/main/java/com/anthonyhilyard/iceberg/renderer/CheckedBufferSource.java b/src/main/java/com/anthonyhilyard/iceberg/renderer/CheckedBufferSource.java new file mode 100644 index 0000000..b8f5fde --- /dev/null +++ b/src/main/java/com/anthonyhilyard/iceberg/renderer/CheckedBufferSource.java @@ -0,0 +1,68 @@ +package com.anthonyhilyard.iceberg.renderer; + +import com.mojang.blaze3d.vertex.VertexConsumer; + +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; + +public final class CheckedBufferSource implements MultiBufferSource +{ + private boolean hasRendered = false; + private final MultiBufferSource bufferSource; + + public CheckedBufferSource(MultiBufferSource bufferSource) + { + this.bufferSource = bufferSource; + } + + @Override + public VertexConsumer getBuffer(RenderType renderType) + { + final VertexConsumer vertexConsumer = bufferSource.getBuffer(renderType); + VertexConsumer vertexConsumerWrap = new VertexConsumer() + { + @Override + public VertexConsumer vertex(double x, double y, double z) + { + hasRendered = true; + return vertexConsumer.vertex(x, y, z); + } + + @Override + public VertexConsumer color(int r, int g, int b, int a) { return vertexConsumer.color(r, g, b, a); } + + @Override + public VertexConsumer uv(float u, float v) { return vertexConsumer.uv(u, v); } + + @Override + public VertexConsumer overlayCoords(int x, int y) { return vertexConsumer.overlayCoords(x, y); } + + @Override + public VertexConsumer uv2(int u, int v) { return vertexConsumer.uv2(u, v); } + + @Override + public VertexConsumer normal(float x, float y, float z) { return vertexConsumer.normal(x, y, z); } + + @Override + public void endVertex() { vertexConsumer.endVertex(); } + + @Override + public void defaultColor(int r, int g, int b, int a) { vertexConsumer.defaultColor(r, g, b, a); } + + @Override + public void unsetDefaultColor() { vertexConsumer.unsetDefaultColor(); } + }; + + return vertexConsumerWrap; + } + + public boolean hasRendered() + { + return hasRendered; + } + + public void reset() + { + hasRendered = false; + } +}
\ No newline at end of file diff --git a/src/main/java/com/anthonyhilyard/iceberg/renderer/CustomItemRenderer.java b/src/main/java/com/anthonyhilyard/iceberg/renderer/CustomItemRenderer.java index b77bb09..c3cc4b5 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/renderer/CustomItemRenderer.java +++ b/src/main/java/com/anthonyhilyard/iceberg/renderer/CustomItemRenderer.java @@ -1,50 +1,122 @@ package com.anthonyhilyard.iceberg.renderer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +import com.google.common.collect.Maps; + +import org.joml.Matrix4f; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +import org.lwjgl.opengl.GL11; + import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.datafixers.util.Pair; +import com.mojang.math.MatrixUtil; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.pipeline.MainTarget; import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.platform.Lighting; +import com.mojang.blaze3d.platform.GlStateManager.SourceFactor; +import com.mojang.blaze3d.platform.GlStateManager.DestFactor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.lwjgl.opengl.GL11; - +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; +import net.minecraft.ReportedException; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.TextureManager; - -import com.mojang.blaze3d.platform.GlStateManager.SourceFactor; -import com.mojang.blaze3d.platform.GlStateManager.DestFactor; -import com.mojang.math.Matrix4f; - import net.minecraft.client.color.item.ItemColors; import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.MultiBufferSource.BufferSource; import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.packs.resources.ReloadableResourceManager; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.animal.horse.Horse; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.vehicle.AbstractMinecart; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.entity.vehicle.ChestBoat; import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.BoatItem; +import net.minecraft.world.item.HorseArmorItem; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.MinecartItem; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.HalfTransparentBlock; +import net.minecraft.world.level.block.StainedGlassPaneBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; + /** - * An extended ItemRenderer that allows items to be rendered to RenderTarget before drawing to screen. - * This allows alpha values to be supported properly by all item types, even semi-transparent items. + * An extended ItemRenderer with extended functionality, such as allowing items to be rendered to a RenderTarget + * before drawing to screen for alpha support, and allowing handheld item models to be rendered into the gui. */ public class CustomItemRenderer extends ItemRenderer { - @SuppressWarnings("unused") - private static final Logger LOGGER = LogManager.getLogger(); + /* Cylindrical bounds for a model. */ + private record ModelBounds(Vector3f center, float height, float radius) {} private static RenderTarget iconFrameBuffer = null; + private static ArmorStand armorStand = null; + private static AbstractMinecart minecart = null; + private static Boat boat = null; + private static Horse horse = null; + private static Pair<Item, CompoundTag> cachedArmorStandItem = null; + private static Pair<Item, CompoundTag> cachedHorseArmorItem = null; + private static Map<Item, ModelBounds> modelBoundsCache = Maps.newHashMap(); + + private static final List<Direction> quadDirections; + static { + quadDirections = new ArrayList<>(Arrays.asList(Direction.values())); + quadDirections.add(null); + } + private Minecraft mc; - + private final ModelManager modelManager; + private final BlockEntityWithoutLevelRenderer blockEntityRenderer; + public CustomItemRenderer(TextureManager textureManagerIn, ModelManager modelManagerIn, ItemColors itemColorsIn, BlockEntityWithoutLevelRenderer blockEntityRendererIn, Minecraft mcIn) { super(textureManagerIn, modelManagerIn, itemColorsIn, blockEntityRendererIn); mc = mcIn; + modelManager = modelManagerIn; + blockEntityRenderer = blockEntityRendererIn; + if (mc.getResourceManager() instanceof ReloadableResourceManager resourceManager) + { + resourceManager.registerReloadListener(this); + } // Initialize the icon framebuffer if needed. if (iconFrameBuffer == null) @@ -56,6 +128,515 @@ public class CustomItemRenderer extends ItemRenderer } } + private void renderGuiModel(ItemStack itemStack, int x, int y, Quaternionf rotation, BakedModel bakedModel) + { + mc.getTextureManager().getTexture(InventoryMenu.BLOCK_ATLAS).setFilter(false, false); + RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS); + RenderSystem.enableBlend(); + RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + + PoseStack modelViewStack = RenderSystem.getModelViewStack(); + modelViewStack.pushPose(); + modelViewStack.translate(x, y, 100.0f + blitOffset); + + modelViewStack.translate(8.0f, 8.0f, 0.0f); + modelViewStack.scale(1.0f, -1.0f, 1.0f); + modelViewStack.scale(16.0f, 16.0f, 16.0f); + RenderSystem.applyModelViewMatrix(); + + BufferSource bufferSource = Minecraft.getInstance().renderBuffers().bufferSource(); + boolean flatLighting = !bakedModel.usesBlockLight(); |
