diff --git a/src/main/java/twilightforest/client/BakedMultiPartRenderers.java b/src/main/java/twilightforest/client/BakedMultiPartRenderers.java index 3cf0f0e96c..5d9e5d3b67 100644 --- a/src/main/java/twilightforest/client/BakedMultiPartRenderers.java +++ b/src/main/java/twilightforest/client/BakedMultiPartRenderers.java @@ -1,10 +1,11 @@ package twilightforest.client; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.NoopRenderer; import net.minecraft.resources.Identifier; -import net.minecraft.util.LazyLoadedValue; import twilightforest.client.model.TFModelLayers; import twilightforest.client.model.entity.HydraHeadModel; import twilightforest.client.model.entity.HydraNeckModel; @@ -19,19 +20,18 @@ import java.util.HashMap; import java.util.Map; -@SuppressWarnings("deprecation") public class BakedMultiPartRenderers { - private static final Map>> renderers = new HashMap<>(); + private static final Map>> renderers = new HashMap<>(); public static void bakeMultiPartRenderers(EntityRendererProvider.Context context) { - renderers.put(TFPart.RENDERER, new LazyLoadedValue<>(() -> new NoopRenderer<>(context))); - renderers.put(HydraHead.RENDERER, new LazyLoadedValue<>(() -> new HydraHeadRenderer<>(context, new HydraHeadModel<>(context.bakeLayer(TFModelLayers.HYDRA_HEAD))))); - renderers.put(HydraNeck.RENDERER, new LazyLoadedValue<>(() -> new HydraNeckRenderer<>(context, new HydraNeckModel(context.bakeLayer(TFModelLayers.HYDRA_NECK))))); - renderers.put(SnowQueenIceShield.RENDERER, new LazyLoadedValue<>(() -> new SnowQueenIceShieldRenderer<>(context))); - renderers.put(NagaSegment.RENDERER, new LazyLoadedValue<>(() -> new NagaSegmentRenderer<>(context, new NagaModel<>(context.bakeLayer(TFModelLayers.NAGA_BODY))))); + renderers.put(TFPart.RENDERER, Suppliers.memoize(() -> new NoopRenderer<>(context))); + renderers.put(HydraHead.RENDERER, Suppliers.memoize(() -> new HydraHeadRenderer(context, new HydraHeadModel(context.bakeLayer(TFModelLayers.HYDRA_HEAD))))); + renderers.put(HydraNeck.RENDERER, Suppliers.memoize(() -> new HydraNeckRenderer(context, new HydraNeckModel(context.bakeLayer(TFModelLayers.HYDRA_NECK))))); + renderers.put(SnowQueenIceShield.RENDERER, Suppliers.memoize(() -> new SnowQueenIceShieldRenderer(context))); + renderers.put(NagaSegment.RENDERER, Suppliers.memoize(() -> new NagaSegmentRenderer(context, new NagaModel<>(context.bakeLayer(TFModelLayers.NAGA_BODY))))); } - public static EntityRenderer lookup(Identifier location) { + public static EntityRenderer lookup(Identifier location) { return renderers.get(location).get(); } } diff --git a/src/main/java/twilightforest/client/FoliageColorHandler.java b/src/main/java/twilightforest/client/FoliageColorHandler.java index ad4911e80d..ae5b84fd89 100644 --- a/src/main/java/twilightforest/client/FoliageColorHandler.java +++ b/src/main/java/twilightforest/client/FoliageColorHandler.java @@ -2,7 +2,6 @@ import com.google.common.collect.MapMaker; import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.Biome; @@ -47,17 +46,13 @@ public int get(int o, Biome biome, double x, double z) { if (handler == null) { handler = REGISTRY.getOrDefault( Minecraft.getInstance().level == null ? null : - Minecraft.getInstance().level.registryAccess().registryOrThrow(Registries.BIOME).getResourceKey(biome).orElse(null), + Minecraft.getInstance().level.registryAccess().lookupOrThrow(Registries.BIOME).getResourceKey(biome).orElse(null), Handler.DEFAULT); HANDLES.put(biome, handler); } return handler.apply(o, x, z); } - public static int getTintColorAtPosition(BlockPos pos) { - - } - @FunctionalInterface private interface Handler { Handler DEFAULT = (o, x, z) -> o; diff --git a/src/main/java/twilightforest/client/LockedBiomeToast.java b/src/main/java/twilightforest/client/LockedBiomeToast.java index 6d367b7415..95853028f6 100644 --- a/src/main/java/twilightforest/client/LockedBiomeToast.java +++ b/src/main/java/twilightforest/client/LockedBiomeToast.java @@ -1,25 +1,48 @@ package twilightforest.client; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.toasts.Toast; -import net.minecraft.client.gui.components.toasts.ToastComponent; +import net.minecraft.client.gui.components.toasts.ToastManager; +import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import net.minecraft.world.item.ItemStack; -public record LockedBiomeToast(ItemStack item) implements Toast { +public class LockedBiomeToast implements Toast { private static final Component TITLE = Component.translatable("misc.twilightforest.biome_locked"); private static final Component DESCRIPTION = Component.translatable("misc.twilightforest.biome_locked_2"); private static final Identifier BACKGROUND_SPRITE = Identifier.withDefaultNamespace("toast/advancement"); + private final ItemStack item; + private Toast.Visibility wantedVisibility = Toast.Visibility.SHOW; + + public LockedBiomeToast(ItemStack item) { + this.item = item; + } + + public ItemStack item() { + return this.item; + } + @Override - public Visibility render(GuiGraphics graphics, ToastComponent component, long timer) { - graphics.blitSprite(BACKGROUND_SPRITE, 0, 0, this.width(), this.height()); - graphics.renderFakeItem(this.item(), 6, 8); - graphics.drawString(component.getMinecraft().font, TITLE, 25, 7, -256, false); - graphics.drawString(component.getMinecraft().font, DESCRIPTION, 25, 18, 16777215, false); + public Toast.Visibility getWantedVisibility() { + return this.wantedVisibility; + } - return timer >= 10000L ? Toast.Visibility.HIDE : Toast.Visibility.SHOW; + @Override + public void update(ToastManager toastManager, long timer) { + if (timer >= 10000L) { + this.wantedVisibility = Toast.Visibility.HIDE; + } + } + + @Override + public void extractRenderState(GuiGraphicsExtractor graphics, Font font, long timer) { + graphics.blitSprite(RenderPipelines.GUI_TEXTURED, BACKGROUND_SPRITE, 0, 0, this.width(), this.height()); + graphics.fakeItem(this.item(), 6, 8); + graphics.text(font, TITLE, 25, 7, -256, false); + graphics.text(font, DESCRIPTION, 25, 18, 16777215, false); } } diff --git a/src/main/java/twilightforest/client/MissingAdvancementToast.java b/src/main/java/twilightforest/client/MissingAdvancementToast.java index 56820a60fa..50cb63291e 100644 --- a/src/main/java/twilightforest/client/MissingAdvancementToast.java +++ b/src/main/java/twilightforest/client/MissingAdvancementToast.java @@ -1,17 +1,13 @@ package twilightforest.client; -import com.mojang.blaze3d.pipeline.RenderPipeline; import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.toasts.Toast; -import net.minecraft.client.gui.components.toasts.ToastComponent; import net.minecraft.client.gui.components.toasts.ToastManager; import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.ItemStackTemplate; import twilightforest.init.TFBlocks; public class MissingAdvancementToast implements Toast { diff --git a/src/main/java/twilightforest/client/OptifineWarningScreen.java b/src/main/java/twilightforest/client/OptifineWarningScreen.java index 464599b477..08175f8e24 100644 --- a/src/main/java/twilightforest/client/OptifineWarningScreen.java +++ b/src/main/java/twilightforest/client/OptifineWarningScreen.java @@ -2,21 +2,24 @@ import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.gui.TextAlignment; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.MultiLineLabel; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.MouseButtonEvent; import net.minecraft.network.chat.*; import org.jetbrains.annotations.Nullable; -public class OptifineWarningScreen extends Screen { +import java.net.URI; +public class OptifineWarningScreen extends Screen { private final Screen lastScreen; private int ticksUntilEnable = 20 * 10; private MultiLineLabel message = MultiLineLabel.EMPTY; private MultiLineLabel suggestions = MultiLineLabel.EMPTY; private static final Component text = Component.translatable("gui.twilightforest.optifine.message"); - private static final MutableComponent url = Component.translatable("gui.twilightforest.optifine.suggestions").withStyle(style -> style.withColor(ChatFormatting.GREEN).applyFormat(ChatFormatting.UNDERLINE).withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/NordicGamerFE/usefulmods"))); + private static final MutableComponent url = Component.translatable("gui.twilightforest.optifine.suggestions").withStyle(style -> style.withColor(ChatFormatting.GREEN).applyFormat(ChatFormatting.UNDERLINE).withClickEvent(new ClickEvent.OpenUrl(URI.create("https://github.com/NordicGamerFE/usefulmods")))); private Button exitButton; public OptifineWarningScreen(Screen screen) { @@ -32,7 +35,7 @@ public Component getNarrationMessage() { @Override protected void init() { super.init(); - this.exitButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_PROCEED, (pressed) -> Minecraft.getInstance().setScreen(this.lastScreen)).bounds(this.width / 2 - 75, this.height * 3 / 4, 150, 20).build()); + this.exitButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_PROCEED, (_) -> Minecraft.getInstance().setScreen(this.lastScreen)).bounds(this.width / 2 - 75, this.height * 3 / 4, 150, 20).build()); this.exitButton.active = false; this.message = MultiLineLabel.create(this.font, text, this.width - 50); @@ -40,14 +43,14 @@ protected void init() { } @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - graphics.drawCenteredString(this.font, this.title, this.width / 2, 30, 16777215); - this.message.renderCentered(graphics, this.width / 2, 70); - this.suggestions.renderCentered(graphics, this.width / 2, 160); - super.render(graphics, mouseX, mouseY, partialTicks); + public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { + this.extractBackground(graphics, mouseX, mouseY, partialTicks); + graphics.centeredText(this.font, this.title, this.width / 2, 30, 16777215); + this.message.visitLines(TextAlignment.CENTER, this.width / 2, 70, this.font.lineHeight, graphics.textRenderer()); + this.suggestions.visitLines(TextAlignment.CENTER, this.width / 2, 160, this.font.lineHeight, graphics.textRenderer()); + super.extractRenderState(graphics, mouseX, mouseY, partialTicks); - this.exitButton.render(graphics, mouseX, mouseY, partialTicks); + this.exitButton.extractRenderState(graphics, mouseX, mouseY, partialTicks); } @Override @@ -69,16 +72,17 @@ public void onClose() { } @Override - public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + double pMouseX = event.x(); + double pMouseY = event.y(); if (pMouseY > 160 && pMouseY < 170) { Style style = this.getClickedComponentStyleAt((int) pMouseX); - if (style != null && style.getClickEvent() != null && style.getClickEvent().getAction() == ClickEvent.Action.OPEN_URL) { - this.handleComponentClicked(style); + if (style != null && style.getClickEvent() != null && style.getClickEvent().action() == ClickEvent.Action.OPEN_URL) { return false; } } - return super.mouseClicked(pMouseX, pMouseY, pButton); + return super.mouseClicked(event, doubleClick); } @Nullable @@ -86,6 +90,6 @@ private Style getClickedComponentStyleAt(int xPos) { int wid = Minecraft.getInstance().font.width(url); int left = this.width / 2 - wid / 2; int right = this.width / 2 + wid / 2; - return xPos >= left && xPos <= right ? Minecraft.getInstance().font.getSplitter().componentStyleAtWidth(url, xPos - left) : null; + return xPos >= left && xPos <= right ? url.getStyle() : null; } } diff --git a/src/main/java/twilightforest/client/TFShaders.java b/src/main/java/twilightforest/client/TFShaders.java index 7952d1178e..2d46520956 100644 --- a/src/main/java/twilightforest/client/TFShaders.java +++ b/src/main/java/twilightforest/client/TFShaders.java @@ -1,124 +1,18 @@ package twilightforest.client; -import com.mojang.blaze3d.shaders.Uniform; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.*; -import net.minecraft.client.renderer.ShaderInstance; -import net.minecraft.resources.Identifier; -import net.minecraft.server.packs.resources.ResourceProvider; -import net.neoforged.neoforge.client.event.RegisterShadersEvent; -import org.jetbrains.annotations.Nullable; -import twilightforest.TwilightForestMod; - -import java.io.IOException; +import net.minecraft.client.renderer.rendertype.RenderSetup; +import net.minecraft.client.renderer.rendertype.RenderType; +import twilightforest.client.renderer.TFRenderPipelines; public class TFShaders { - public static ShaderInstance RED_THREAD; - public static PositionAwareShaderInstance AURORA; - - public static void registerShaders(RegisterShadersEvent event) { - try { - event.registerShader(new ShaderInstance(event.getResourceProvider(), TwilightForestMod.prefix("red_thread/red_thread"), DefaultVertexFormat.BLOCK), - shader -> RED_THREAD = shader); - event.registerShader(new PositionAwareShaderInstance(event.getResourceProvider(), TwilightForestMod.prefix("aurora/aurora"), DefaultVertexFormat.POSITION_COLOR), - shader -> AURORA = (PositionAwareShaderInstance) shader); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static class BindableShaderInstance extends ShaderInstance { - - private ShaderInstance last; - - public BindableShaderInstance(ResourceProvider p_173336_, Identifier shaderLocation, VertexFormat p_173338_) throws IOException { - super(p_173336_, shaderLocation, p_173338_); - } - - ShaderInstance getSelf() { - return this; - } - - public final void bind(@Nullable Runnable exec) { - last = RenderSystem.getShader(); - RenderSystem.setShader(this::getSelf); - if (exec != null) - exec.run(); - apply(); - } - - public final void runThenClear(Runnable exec) { - exec.run(); - clear(); - RenderSystem.setShader(() -> last); - last = null; - } - - public final void invokeThenClear(@Nullable Runnable execBind, Runnable execPost) { - bind(execBind); - runThenClear(execPost); - } - - public final void invokeThenClear(Runnable execPost) { - invokeThenClear(null, execPost); - } - - public final void invokeThenEndTesselator(@Nullable Runnable execBind, BufferBuilder builder) { - invokeThenClear(execBind, () -> BufferUploader.drawWithShader(builder.buildOrThrow())); - } - - public final void invokeThenEndTesselator(BufferBuilder builder) { - invokeThenClear(() -> BufferUploader.drawWithShader(builder.buildOrThrow())); - } - - } - - public static class PositionAwareShaderInstance extends BindableShaderInstance { - - @Nullable - public final Uniform SEED; - - @Nullable - public final Uniform POSITION; - - public PositionAwareShaderInstance(ResourceProvider p_173336_, Identifier shaderLocation, VertexFormat p_173338_) throws IOException { - super(p_173336_, shaderLocation, p_173338_); - SEED = getUniform("SeedContext"); - POSITION = getUniform("PositionContext"); - } - - public final void setValue(int seed, float x, float y, float z) { - if (SEED != null) { - SEED.set(seed); - } - if (POSITION != null) { - POSITION.set(x, y, z); - } - } - - public final void setValueBindApply(int seed, float x, float y, float z) { - bind(() -> setValue(seed, x, y, z)); - } - - public final void reset() { - setValue(0, 0, 0, 0); - } - - public final void resetClear() { - runThenClear(this::reset); - } - - public final void invokeThenClear(int seed, float x, float y, float z, Runnable exec) { - setValueBindApply(seed, x, y, z); - exec.run(); - resetClear(); - } - - public final void invokeThenEndTesselator(int seed, float x, float y, float z, BufferBuilder builder) { - invokeThenClear(seed, x, y, z, () -> BufferUploader.drawWithShader(builder.buildOrThrow())); - } - - } + public static final RenderType AURORA = RenderType.create( + "twilightforest_aurora", + RenderSetup.builder(TFRenderPipelines.AURORA_PIPELINE).createRenderSetup() + ); + public static final RenderType RED_THREAD = RenderType.create( + "twilightforest_red_thread", + RenderSetup.builder(TFRenderPipelines.RED_THREAD).createRenderSetup() + ); } diff --git a/src/main/java/twilightforest/client/TextureGeneratorReloadListener.java b/src/main/java/twilightforest/client/TextureGeneratorReloadListener.java index 1b965eb8ce..65083da9b9 100644 --- a/src/main/java/twilightforest/client/TextureGeneratorReloadListener.java +++ b/src/main/java/twilightforest/client/TextureGeneratorReloadListener.java @@ -15,6 +15,7 @@ import java.util.EnumMap; import java.util.concurrent.atomic.AtomicReference; +// FIXME public class TextureGeneratorReloadListener implements ResourceManagerReloadListener { public static final TextureGeneratorReloadListener INSTANCE = new TextureGeneratorReloadListener(); private static final EnumMap BOAT_CACHE = new EnumMap<>(Boat.Type.class); diff --git a/src/main/java/twilightforest/client/UncraftingRecipeBookComponent.java b/src/main/java/twilightforest/client/UncraftingRecipeBookComponent.java index be413f853b..8019258377 100644 --- a/src/main/java/twilightforest/client/UncraftingRecipeBookComponent.java +++ b/src/main/java/twilightforest/client/UncraftingRecipeBookComponent.java @@ -1,21 +1,97 @@ package twilightforest.client; +import net.minecraft.client.gui.components.WidgetSprites; +import net.minecraft.client.gui.screens.recipebook.GhostSlots; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; +import net.minecraft.client.gui.screens.recipebook.RecipeCollection; +import net.minecraft.core.Holder; +import net.minecraft.network.chat.Component; +import net.minecraft.util.context.ContextMap; +import net.minecraft.world.entity.player.StackedItemContents; +import net.minecraft.world.inventory.RecipeBookMenu; import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.display.RecipeDisplay; +import net.minecraft.world.item.crafting.display.SlotDisplay; +import org.jetbrains.annotations.Nullable; import twilightforest.inventory.UncraftingPlaceRecipe; import java.util.List; -public class UncraftingRecipeBookComponent extends RecipeBookComponent implements UncraftingPlaceRecipe { +public class UncraftingRecipeBookComponent extends RecipeBookComponent implements UncraftingPlaceRecipe { + @Nullable + private GhostSlots currentGhostSlots = new GhostSlots(() -> 0); + + public UncraftingRecipeBookComponent(RecipeBookMenu menu, List list) { + super(menu, list); + } + + @Override + protected WidgetSprites getFilterButtonTextures() { + return RecipeBookComponent.RECIPE_BUTTON_SPRITES; + } + + + @Override + protected boolean isCraftingSlot(Slot slot) { + return slot.index >= 11 && slot.index <= 19; + } + + @Override + protected void selectMatchingRecipes(RecipeCollection recipeCollection, StackedItemContents stackedItemContents) { + recipeCollection.selectRecipes(stackedItemContents, _ -> true); + this.recipesUpdated(); + } + + + @Override + protected Component getRecipeFilterName() { + return Component.translatable("gui.recipebook.toggleRecipes.craftable"); + } + + @Override + protected void fillGhostRecipe(GhostSlots ghostSlots, RecipeDisplay recipeDisplay, ContextMap contextMap) { + this.currentGhostSlots = ghostSlots; + + Slot resultSlot = this.menu.slots.get(1); + SlotDisplay resultDisplay = recipeDisplay.result(); + + ghostSlots.setResult(resultSlot, contextMap, resultDisplay); + + List ingredients = recipeDisplay.craftingStation().resolveForStacks(contextMap); + int matrixStartSlot = 11; + + for (int i = 0; i < ingredients.size(); i++) { + if (i >= 9) break; + + Slot inputSlot = this.menu.slots.get(matrixStartSlot + i); + ItemStack ingredientDisplay = ingredients.get(i); + + if (!ingredientDisplay.isEmpty()) { + ghostSlots.setInput(inputSlot, contextMap, new SlotDisplay.ItemStackSlotDisplay(ItemStackTemplate.fromNonEmptyStack(ingredientDisplay))); + } + } + + this.currentGhostSlots = null; + } @Override - public void setupGhostRecipe(RecipeHolder recipe, List slots) { - ItemStack itemstack = recipe.value().getResultItem(this.minecraft.level.registryAccess()); - this.ghostRecipe.setRecipe(recipe); - this.ghostRecipe.addIngredient(Ingredient.of(itemstack), slots.get(1).x, slots.get(1).y); - this.placeRecipe(this.menu.getGridWidth(), this.menu.getGridHeight(), this.menu.getResultSlotIndex(), recipe, recipe.value().getIngredients().iterator(), 0); + public void addItemToSlot(Ingredient ingredient, int slotIndex, int maxAmount, int gridY, int gridX) { + if (currentGhostSlots != null && !ingredient.isEmpty()) { + Slot targetSlot = this.menu.slots.get(slotIndex); + + List> items = ingredient.getValues().stream().toList(); + if (!items.isEmpty()) { + Item item = items.getFirst().value(); + ItemStack stack = new ItemStack(item); + ItemStackTemplate template = ItemStackTemplate.fromNonEmptyStack(stack); + SlotDisplay.ItemStackSlotDisplay display = new SlotDisplay.ItemStackSlotDisplay(template); + + this.currentGhostSlots.setInput(targetSlot, ContextMap.EMPTY, display); + } + } } } diff --git a/src/main/java/twilightforest/client/UncraftingScreen.java b/src/main/java/twilightforest/client/UncraftingScreen.java index bc79d66984..27932742a2 100644 --- a/src/main/java/twilightforest/client/UncraftingScreen.java +++ b/src/main/java/twilightforest/client/UncraftingScreen.java @@ -1,32 +1,40 @@ package twilightforest.client; -import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.ChatFormatting; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.ImageButton; import net.minecraft.client.gui.components.Tooltip; 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.DefaultTooltipPositioner; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; import net.minecraft.client.gui.screens.recipebook.RecipeUpdateListener; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.Identifier; import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.ContainerInput; +import net.minecraft.world.inventory.RecipeBookMenu; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import net.neoforged.neoforge.network.PacketDistributor; +import net.minecraft.world.item.crafting.display.RecipeDisplay; +import net.neoforged.neoforge.client.network.ClientPacketDistributor; import twilightforest.TwilightForestMod; import twilightforest.config.TFConfig; import twilightforest.tags.TFItemTags; import twilightforest.inventory.UncraftingMenu; import twilightforest.network.UncraftingGuiPacket; +import java.util.List; + public class UncraftingScreen extends AbstractContainerScreen implements RecipeUpdateListener { private static final Identifier TEXTURE = TwilightForestMod.getGuiTexture("guigoblintinkering.png"); - private final RecipeBookComponent recipeBookComponent = new UncraftingRecipeBookComponent(); + private final RecipeBookComponent recipeBookComponent = new UncraftingRecipeBookComponent(menu, List.of()); private boolean widthTooNarrow; public UncraftingScreen(UncraftingMenu container, Inventory player, Component name) { @@ -38,7 +46,7 @@ protected void init() { super.init(); this.widthTooNarrow = this.width < 379; - this.recipeBookComponent.init(this.width, this.height, this.minecraft, this.widthTooNarrow, this.menu); + this.recipeBookComponent.init(this.width, this.height, this.minecraft, this.widthTooNarrow); this.leftPos = this.recipeBookComponent.updateScreenPosition(this.width, this.imageWidth); this.addRenderableWidget(new ImageButton(this.leftPos + 145, this.topPos + 7, 20, 18, RecipeBookComponent.RECIPE_BUTTON_SPRITES, button -> { this.recipeBookComponent.toggleVisibility(); @@ -48,36 +56,36 @@ protected void init() { this.setInitialFocus(this.recipeBookComponent); this.addRenderableWidget(new CycleButton(this.leftPos + 40, this.topPos + 22, true, button -> { - PacketDistributor.sendToServer(new UncraftingGuiPacket(0)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(0)); this.menu.unrecipeInCycle++; this.menu.slotsChanged(this.menu.tinkerInput); }, Component.translatable("container.twilightforest.uncrafting_table.cycle_next_uncraft"))); this.addRenderableWidget(new CycleButton(this.leftPos + 40, this.topPos + 55, false, button -> { - PacketDistributor.sendToServer(new UncraftingGuiPacket(1)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(1)); this.menu.unrecipeInCycle--; this.menu.slotsChanged(this.menu.tinkerInput); }, Component.translatable("container.twilightforest.uncrafting_table.cycle_back_uncraft"))); if (!TFConfig.disableIngredientSwitching) { this.addRenderableWidget(new CycleButtonMini(this.leftPos + 27, this.topPos + 56, true, button -> { - PacketDistributor.sendToServer(new UncraftingGuiPacket(2)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(2)); this.menu.ingredientsInCycle++; this.menu.slotsChanged(this.menu.tinkerInput); }, Component.translatable("container.twilightforest.uncrafting_table.cycle_next_ingredient"))); this.addRenderableWidget(new CycleButtonMini(this.leftPos + 27, this.topPos + 63, false, button -> { - PacketDistributor.sendToServer(new UncraftingGuiPacket(3)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(3)); this.menu.ingredientsInCycle--; this.menu.slotsChanged(this.menu.tinkerInput); }, Component.translatable("container.twilightforest.uncrafting_table.cycle_back_ingredient"))); } this.addRenderableWidget(new CycleButton(this.leftPos + 121, this.topPos + 22, true, button -> { - PacketDistributor.sendToServer(new UncraftingGuiPacket(4)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(4)); this.menu.recipeInCycle++; this.menu.slotsChanged(this.menu.assemblyMatrix); }, Component.translatable("container.twilightforest.uncrafting_table.cycle_next_recipe"))); this.addRenderableWidget(new CycleButton(this.leftPos + 121, this.topPos + 55, false, button -> { - PacketDistributor.sendToServer(new UncraftingGuiPacket(5)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(5)); this.menu.recipeInCycle--; this.menu.slotsChanged(this.menu.assemblyMatrix); }, Component.translatable("container.twilightforest.uncrafting_table.cycle_back_recipe"))); @@ -97,10 +105,10 @@ public boolean mouseScrolled(double x, double y, double vertScroll, double horiz if (!TFConfig.disableIngredientSwitching) { if (x > this.leftPos + 27 && x < this.leftPos + 33 && y > this.topPos + 56 && y < this.topPos + 69) { if (vertScroll > 0) { - PacketDistributor.sendToServer(new UncraftingGuiPacket(2)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(2)); this.menu.ingredientsInCycle++; } else { - PacketDistributor.sendToServer(new UncraftingGuiPacket(3)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(3)); this.menu.ingredientsInCycle--; } this.menu.slotsChanged(this.menu.tinkerInput); @@ -110,10 +118,10 @@ public boolean mouseScrolled(double x, double y, double vertScroll, double horiz //uncrafting recipe buttons if (x > this.leftPos + 40 && x < this.leftPos + 54 && y > this.topPos + 22 && y < this.topPos + 64) { if (vertScroll > 0) { - PacketDistributor.sendToServer(new UncraftingGuiPacket(0)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(0)); this.menu.unrecipeInCycle++; } else { - PacketDistributor.sendToServer(new UncraftingGuiPacket(1)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(1)); this.menu.unrecipeInCycle--; } this.menu.slotsChanged(this.menu.tinkerInput); @@ -122,10 +130,10 @@ public boolean mouseScrolled(double x, double y, double vertScroll, double horiz //recrafting recipe buttons if (x > this.leftPos + 121 && x < this.leftPos + 135 && y > this.topPos + 22 && y < this.topPos + 64) { if (vertScroll > 0) { - PacketDistributor.sendToServer(new UncraftingGuiPacket(4)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(4)); this.menu.recipeInCycle++; } else { - PacketDistributor.sendToServer(new UncraftingGuiPacket(5)); + ClientPacketDistributor.sendToServer(new UncraftingGuiPacket(5)); this.menu.recipeInCycle--; } this.menu.slotsChanged(this.menu.assemblyMatrix); @@ -135,41 +143,41 @@ public boolean mouseScrolled(double x, double y, double vertScroll, double horiz } @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { if (this.recipeBookComponent.isVisible() && this.widthTooNarrow) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - this.recipeBookComponent.render(graphics, mouseX, mouseY, partialTicks); + this.extractBackground(graphics, mouseX, mouseY, partialTicks); + this.recipeBookComponent.extractRenderState(graphics, mouseX, mouseY, partialTicks); } else { - super.render(graphics, mouseX, mouseY, partialTicks); - this.recipeBookComponent.render(graphics, mouseX, mouseY, partialTicks); - this.recipeBookComponent.renderGhostRecipe(graphics, this.leftPos, this.topPos, true, partialTicks); + super.extractRenderState(graphics, mouseX, mouseY, partialTicks); + this.recipeBookComponent.extractRenderState(graphics, mouseX, mouseY, partialTicks); + this.recipeBookComponent.extractGhostRecipe(graphics, true); } - this.renderTooltip(graphics, mouseX, mouseY); - this.recipeBookComponent.renderTooltip(graphics, this.leftPos, this.topPos, mouseX, mouseY); + this.extractTooltip(graphics, mouseX, mouseY); + this.recipeBookComponent.extractTooltip(graphics, mouseX, mouseY, this.hoveredSlot); } @Override - protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) { - graphics.drawString(this.font, this.title, 6, 6, 4210752, false); + protected void extractLabels(GuiGraphicsExtractor graphics, int mouseX, int mouseY) { + graphics.text(this.font, this.title, 6, 6, 4210752, false); if (TFConfig.disableUncraftingOnly) { - graphics.drawString(this.font, Component.translatable("container.twilightforest.uncrafting_table.uncrafting_disabled").withStyle(ChatFormatting.DARK_RED), 6, this.imageHeight - 96 + 2, 4210752, false); + graphics.text(this.font, Component.translatable("container.twilightforest.uncrafting_table.uncrafting_disabled").withStyle(ChatFormatting.DARK_RED), 6, this.imageHeight - 96 + 2, 4210752, false); } else { - graphics.drawString(this.font, I18n.get("container.inventory"), 7, this.imageHeight - 96 + 2, 4210752, false); + graphics.text(this.font, I18n.get("container.inventory"), 7, this.imageHeight - 96 + 2, 4210752, false); } } @Override - protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) { + public void extractBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { int frameX = this.leftPos; int frameY = (this.height - this.imageHeight) / 2; - graphics.blit(TEXTURE, frameX, frameY, 0, 0, this.imageWidth, this.imageHeight); + graphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, frameX, frameY, 0, 0, this.imageWidth, this.imageHeight, 256, 256); UncraftingMenu tfContainer = this.menu; // show uncrafting ingredients as background - graphics.pose().pushPose(); - graphics.pose().translate(this.leftPos, this.topPos, 0); + graphics.pose().pushMatrix(); + graphics.pose().translate(this.leftPos, this.topPos); for (int i = 0; i < 9; i++) { Slot uncrafting = tfContainer.getSlot(2 + i); @@ -179,7 +187,7 @@ protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, in this.drawSlotAsBackground(graphics, uncrafting, assembly); } } - graphics.pose().popPose(); + graphics.pose().popMatrix(); int costVal = tfContainer.getUncraftingCost(); if (costVal > 0) { @@ -190,7 +198,7 @@ protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, in } else { color = 0x80FF20; } - graphics.drawString(this.font, cost, frameX + 48 - this.font.width(cost), frameY + 38, color); + graphics.text(this.font, cost, frameX + 48 - this.font.width(cost), frameY + 38, color); } costVal = tfContainer.getRecraftingCost(); @@ -202,7 +210,7 @@ protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, in } else { color = 0x80FF20; } - graphics.drawString(this.font, cost, frameX + 130 - this.font.width(cost), frameY + 38, color); + graphics.text(this.font, cost, frameX + 130 - this.font.width(cost), frameY + 38, color); } } @@ -212,60 +220,73 @@ protected boolean isHovering(int x, int y, int width, int height, double mouseX, } @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (this.recipeBookComponent.mouseClicked(mouseX, mouseY, button)) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + if (this.recipeBookComponent.mouseClicked(event, doubleClick)) { this.setFocused(this.recipeBookComponent); return true; } else { - return this.widthTooNarrow && this.recipeBookComponent.isVisible() || super.mouseClicked(mouseX, mouseY, button); + return this.widthTooNarrow && this.recipeBookComponent.isVisible() || super.mouseClicked(event, doubleClick); } } @Override - protected boolean hasClickedOutside(double mouseX, double mouseY, int guiLeft, int guiTop, int mouseButton) { - return this.recipeBookComponent.hasClickedOutside(mouseX, mouseY, this.leftPos, this.topPos, this.imageWidth, this.imageHeight, mouseButton) && super.hasClickedOutside(mouseX, mouseY, guiLeft, guiTop, mouseButton); + protected boolean hasClickedOutside(double mouseX, double mouseY, int guiLeft, int guiTop) { + return this.recipeBookComponent.hasClickedOutside(mouseX, mouseY, this.leftPos, this.topPos, this.imageWidth, this.imageHeight) && super.hasClickedOutside(mouseX, mouseY, guiLeft, guiTop); } - private void drawSlotAsBackground(GuiGraphics graphics, Slot backgroundSlot, Slot appearSlot) { - + private void drawSlotAsBackground(GuiGraphicsExtractor graphics, Slot backgroundSlot, Slot appearSlot) { int screenX = appearSlot.x; int screenY = appearSlot.y; ItemStack itemStackToRender = backgroundSlot.getItem(); - graphics.renderFakeItem(itemStackToRender, screenX, screenY); + graphics.fakeItem(itemStackToRender, screenX, screenY); boolean itemBroken = UncraftingMenu.isMarked(itemStackToRender); // draw 50% gray rectangle over the item - RenderSystem.disableDepthTest(); - graphics.pose().pushPose(); - graphics.pose().translate(0.0D, 0.0D, 200.0D); + graphics.pose().pushMatrix(); + graphics.pose().translate(0.0F, 0.0F); graphics.fill(appearSlot.x, appearSlot.y, appearSlot.x + 16, appearSlot.y + 16, itemBroken ? 0x80FF8b8b : 0x9f8b8b8b); - graphics.pose().popPose(); - RenderSystem.enableDepthTest(); + graphics.pose().popMatrix(); } @Override - protected void renderTooltip(GuiGraphics graphics, int pX, int pY) { + protected void extractTooltip(GuiGraphicsExtractor graphics, int pX, int pY) { UncraftingMenu container = this.menu; + ClientTooltipPositioner positioner = DefaultTooltipPositioner.INSTANCE; for (int i = 0; i < 9; i++) { - if (container.getCarried().isEmpty() && container.slots.get(2 + i).hasItem() && this.hoveredSlot == container.slots.get(11 + i) && !container.slots.get(11 + i).hasItem()) { - graphics.renderTooltip(this.font, container.slots.get(2 + i).getItem(), pX, pY); + if (container.getCarried().isEmpty() + && container.slots.get(2 + i).hasItem() + && this.hoveredSlot == container.slots.get(11 + i) + && !container.slots.get(11 + i).hasItem()) { + + ItemStack itemStack = container.slots.get(2 + i).getItem(); + List lines = getTooltipFromItem(minecraft, itemStack).stream().map(Component::getVisualOrderText).map(ClientTooltipComponent::create).toList(); + + graphics.tooltip(this.font, lines, pX, pY, positioner, null); + return; } } //check if we're hovering over a banned uncraftable item - if (container.slots.getFirst().hasItem() && container.slots.getFirst().getItem().is(TFItemTags.BANNED_UNCRAFTABLES) && container.slots.getFirst().equals(this.hoveredSlot)) { - graphics.renderTooltip(this.font, Component.translatable("container.twilightforest.uncrafting_table.disabled_item").withStyle(ChatFormatting.RED), pX, pY); + if (container.slots.getFirst().hasItem() + && container.slots.getFirst().getItem().is(TFItemTags.BANNED_UNCRAFTABLES) + && container.slots.getFirst().equals(this.hoveredSlot)) { + + Component alertText = Component.translatable("container.twilightforest.uncrafting_table.disabled_item").withStyle(ChatFormatting.RED); + List lines = List.of(ClientTooltipComponent.create(alertText.getVisualOrderText())); + + graphics.tooltip(this.font, lines, pX, pY, positioner, null); } else { - super.renderTooltip(graphics, pX, pY); + super.extractTooltip(graphics, pX, pY); } } + @Override - protected void slotClicked(Slot slot, int slotId, int mouseButton, ClickType type) { - super.slotClicked(slot, slotId, mouseButton, type); + protected void slotClicked(Slot slot, int slotId, int mouseButton, ContainerInput containerInput) { + super.slotClicked(slot, slotId, mouseButton, containerInput); this.recipeBookComponent.slotClicked(slot); } @@ -275,8 +296,8 @@ public void recipesUpdated() { } @Override - public RecipeBookComponent getRecipeBookComponent() { - return this.recipeBookComponent; + public void fillGhostRecipe(RecipeDisplay recipeDisplay) { + } private static class CycleButton extends Button { @@ -289,7 +310,7 @@ private static class CycleButton extends Button { } @Override - public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + protected void extractContents(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { if (this.visible) { this.isHovered = mouseX >= this.getX() && mouseY >= this.getY() && mouseX < this.getX() + this.width && mouseY < this.getY() + this.height; @@ -301,7 +322,7 @@ public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float par // what's up if (!this.up) textureY += this.height; - graphics.blit(TEXTURE, this.getX(), this.getY(), textureX, textureY, this.width, this.height); + graphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, this.getX(), this.getY(), textureX, textureY, this.width, this.height, 256, 256); } } } @@ -316,7 +337,7 @@ private static class CycleButtonMini extends Button { } @Override - public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + public void extractContents(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { if (this.visible) { this.isHovered = mouseX >= this.getX() && mouseY >= this.getY() && mouseX < this.getX() + this.width && mouseY < this.getY() + this.height; @@ -328,7 +349,7 @@ public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float par // what's up if (!this.up) textureY += this.height; - graphics.blit(TEXTURE, this.getX(), this.getY(), textureX, textureY, this.width, this.height); + graphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, this.getX(), this.getY(), textureX, textureY, this.width, this.height, 256, 256); } } } diff --git a/src/main/java/twilightforest/client/particle/GhastTearParticle.java b/src/main/java/twilightforest/client/particle/GhastTearParticle.java index ba422a59b3..e83126cf8e 100644 --- a/src/main/java/twilightforest/client/particle/GhastTearParticle.java +++ b/src/main/java/twilightforest/client/particle/GhastTearParticle.java @@ -9,6 +9,7 @@ import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.sprite.Material; import net.minecraft.core.particles.ItemParticleOption; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.particles.SimpleParticleType; @@ -59,10 +60,13 @@ public void tick() { public static class Factory implements ParticleProvider { @Override public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, RandomSource random) { - TextureAtlasSprite textureatlassprite = this.calculateState(new ItemStack(Items.GHAST_TEAR), level).pickParticleIcon(random); + Material.Baked material = this.calculateState(new ItemStack(Items.GHAST_TEAR), level).pickParticleMaterial(random); + TextureAtlasSprite textureatlassprite; - if (textureatlassprite == null) { - textureatlassprite = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(MissingTextureAtlasSprite.getLocation()); + if (material != null) { + textureatlassprite = material.sprite(); + } else { + textureatlassprite = Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(TextureAtlas.LOCATION_BLOCKS).getSprite(MissingTextureAtlasSprite.getLocation()); } return new GhastTearParticle(level, x, y, z, textureatlassprite); diff --git a/src/main/java/twilightforest/client/particle/LogCoreParticle.java b/src/main/java/twilightforest/client/particle/LogCoreParticle.java index fccd349b4d..b9c0e90c7c 100644 --- a/src/main/java/twilightforest/client/particle/LogCoreParticle.java +++ b/src/main/java/twilightforest/client/particle/LogCoreParticle.java @@ -59,13 +59,12 @@ public void tick() { public record Factory(SpriteSet sprite) implements ParticleProvider { @Override public Particle createParticle(SimpleParticleType particleType, ClientLevel level, double x, double y, double z, double x2, double y2, double z2, RandomSource random) { - LogCoreParticle logCoreParticle = new LogCoreParticle(level, x, y, z, x2, y2, z2, this.sprite.get(random)); - return logCoreParticle; + return new LogCoreParticle(level, x, y, z, x2, y2, z2, this.sprite.get(random)); } } @Override - public AABB getRenderBoundingBox(float partialTicks) { + public AABB getBoundingBox() { return AABB.INFINITE; } } \ No newline at end of file diff --git a/src/main/java/twilightforest/client/particle/SortingParticle.java b/src/main/java/twilightforest/client/particle/SortingParticle.java index 90073a83e2..5f746ff2fc 100644 --- a/src/main/java/twilightforest/client/particle/SortingParticle.java +++ b/src/main/java/twilightforest/client/particle/SortingParticle.java @@ -85,13 +85,12 @@ public void tick() { public record Factory(SpriteSet sprite) implements ParticleProvider { @Override public Particle createParticle(SimpleParticleType particleType, ClientLevel level, double x, double y, double z, double x2, double y2, double z2, RandomSource random) { - SortingParticle sortingParticle = new SortingParticle(level, x, y, z, x2, y2, z2, this.sprite.get(random)); - return sortingParticle; + return new SortingParticle(level, x, y, z, x2, y2, z2, this.sprite.get(random)); } } @Override - public AABB getRenderBoundingBox(float partialTicks) { + public AABB getBoundingBox() { return AABB.INFINITE; } } \ No newline at end of file diff --git a/src/main/java/twilightforest/client/particle/TransformationParticle.java b/src/main/java/twilightforest/client/particle/TransformationParticle.java index 773b713371..186d3efc2f 100644 --- a/src/main/java/twilightforest/client/particle/TransformationParticle.java +++ b/src/main/java/twilightforest/client/particle/TransformationParticle.java @@ -85,13 +85,12 @@ public void tick() { public record Factory(SpriteSet sprite) implements ParticleProvider { @Override public Particle createParticle(SimpleParticleType particleType, ClientLevel level, double x, double y, double z, double x2, double y2, double z2, RandomSource random) { - TransformationParticle sortingParticle = new TransformationParticle(level, x, y, z, x2, y2, z2, this.sprite.get(random)); - return sortingParticle; + return new TransformationParticle(level, x, y, z, x2, y2, z2, this.sprite.get(random)); } } @Override - public AABB getRenderBoundingBox(float partialTicks) { + public AABB getBoundingBox() { return AABB.INFINITE; } } \ No newline at end of file diff --git a/src/main/java/twilightforest/client/properties/PotionFlaskDamage.java b/src/main/java/twilightforest/client/properties/PotionFlaskDamage.java index edf93e58ef..307cb1dab5 100644 --- a/src/main/java/twilightforest/client/properties/PotionFlaskDamage.java +++ b/src/main/java/twilightforest/client/properties/PotionFlaskDamage.java @@ -7,12 +7,10 @@ import net.minecraft.client.renderer.item.properties.numeric.RangeSelectItemModelProperty; import net.minecraft.util.Mth; import net.minecraft.world.entity.ItemOwner; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; import twilightforest.components.item.PotionFlaskComponent; import twilightforest.init.TFDataComponents; -import twilightforest.item.BrittleFlaskItem; import twilightforest.item.PotionFlaskItem; public record PotionFlaskDamage(boolean normalize) implements RangeSelectItemModelProperty { diff --git a/src/main/java/twilightforest/client/renderer/TFRenderPipelines.java b/src/main/java/twilightforest/client/renderer/TFRenderPipelines.java index 6d93212c1e..595b597f45 100644 --- a/src/main/java/twilightforest/client/renderer/TFRenderPipelines.java +++ b/src/main/java/twilightforest/client/renderer/TFRenderPipelines.java @@ -10,11 +10,15 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.resources.Identifier; import twilightforest.TwilightForestMod; +import java.util.Optional; + public class TFRenderPipelines { private static final BlendFunction SHADOW = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); + private static final DepthStencilState TRANSLUCENT_DEPTH = new DepthStencilState(CompareOp.GREATER_THAN_OR_EQUAL, false); public static final RenderPipeline RED_THREAD = RenderPipeline.builder(RenderPipelines.MATRICES_FOG_SNIPPET) .withLocation(TwilightForestMod.prefix("pipeline/red_thread")) @@ -46,4 +50,10 @@ public class TFRenderPipelines { .withCull(false) .withColorTargetState(new ColorTargetState(SHADOW)) .build(); + + public static final RenderPipeline AURORA_PIPELINE = RenderPipeline.builder(RenderPipelines.DEBUG_FILLED_SNIPPET) + .withLocation(Identifier.fromNamespaceAndPath("twilightforest", "aurora/aurora")) + .withVertexFormat(DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.QUADS) + .withDepthStencilState(Optional.of(TRANSLUCENT_DEPTH)) + .build(); }