mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-08-29 08:42:17 +00:00
Use vanilla's nine-slice sprites for border rendering
- Move remaining sprites to the vanilla GUI atlas. - Convert our computer border/sidebar sprites to use vanilla's nine-sliced mcmeta files. I thought I'd have to do something custom here for the sidebar, as that has no right border, but vanilla supports that natively! - Use the normal GuiGraphics.blitSprite for rendering computer border/sidebar. - Obey nine-slice scaling within the pocket computer renderer.
This commit is contained in:
@@ -40,7 +40,6 @@ import net.minecraft.client.renderer.item.ClampedItemPropertyFunction;
|
||||
import net.minecraft.client.renderer.item.ItemProperties;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||
import net.minecraft.server.packs.resources.ResourceProvider;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
@@ -146,10 +145,6 @@ public final class ClientRegistry {
|
||||
void register(Item item, ResourceLocation name, ClampedItemPropertyFunction property);
|
||||
}
|
||||
|
||||
public static void registerReloadListeners(Consumer<PreparableReloadListener> register, Minecraft minecraft) {
|
||||
register.accept(GuiSprites.initialise(minecraft.getTextureManager()));
|
||||
}
|
||||
|
||||
private static final ResourceLocation[] EXTRA_MODELS = {
|
||||
TurtleOverlay.ELF_MODEL,
|
||||
TurtleBlockEntityRenderer.COLOUR_TURTLE_MODEL,
|
||||
|
@@ -6,9 +6,7 @@ package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
|
||||
import dan200.computercraft.client.gui.widgets.TerminalWidget;
|
||||
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
||||
import dan200.computercraft.client.render.RenderTypes;
|
||||
import dan200.computercraft.client.render.SpriteRenderer;
|
||||
import dan200.computercraft.core.util.Nullability;
|
||||
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -40,14 +38,15 @@ public final class ComputerScreen<T extends AbstractComputerMenu> extends Abstra
|
||||
public void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) {
|
||||
// Draw a border around the terminal
|
||||
var terminal = getTerminal();
|
||||
var spriteRenderer = SpriteRenderer.createForGui(graphics, RenderTypes.GUI_SPRITES);
|
||||
var computerTextures = GuiSprites.getComputerTextures(family);
|
||||
|
||||
ComputerBorderRenderer.render(
|
||||
spriteRenderer, computerTextures,
|
||||
terminal.getX(), terminal.getY(), terminal.getWidth(), terminal.getHeight(), false
|
||||
graphics.blitSprite(
|
||||
computerTextures.border(),
|
||||
terminal.getX() - BORDER, terminal.getY() - BORDER, terminal.getWidth() + BORDER * 2, terminal.getHeight() + BORDER * 2
|
||||
);
|
||||
graphics.blitSprite(
|
||||
Nullability.assertNonNull(computerTextures.sidebar()),
|
||||
leftPos, topPos + sidebarYOffset, AbstractComputerMenu.SIDEBAR_WIDTH, ComputerSidebar.HEIGHT
|
||||
);
|
||||
ComputerSidebar.renderBackground(spriteRenderer, computerTextures, leftPos, topPos + sidebarYOffset);
|
||||
graphics.flush(); // Flush to ensure background textures are drawn before foreground.
|
||||
}
|
||||
}
|
||||
|
@@ -7,9 +7,6 @@ package dan200.computercraft.client.gui;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.TextureAtlasHolder;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@@ -19,10 +16,7 @@ import java.util.stream.Stream;
|
||||
/**
|
||||
* Sprite sheet for all GUI texutres in the mod.
|
||||
*/
|
||||
public final class GuiSprites extends TextureAtlasHolder {
|
||||
public static final ResourceLocation SPRITE_SHEET = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "gui");
|
||||
public static final ResourceLocation TEXTURE = SPRITE_SHEET.withPath(x -> "textures/atlas/" + x + ".png");
|
||||
|
||||
public final class GuiSprites {
|
||||
public static final ButtonTextures TURNED_OFF = button("turned_off");
|
||||
public static final ButtonTextures TURNED_ON = button("turned_on");
|
||||
public static final ButtonTextures TERMINATE = button("terminate");
|
||||
@@ -32,6 +26,9 @@ public final class GuiSprites extends TextureAtlasHolder {
|
||||
public static final ComputerTextures COMPUTER_COMMAND = computer("command", false, true);
|
||||
public static final ComputerTextures COMPUTER_COLOUR = computer("colour", true, false);
|
||||
|
||||
private GuiSprites() {
|
||||
}
|
||||
|
||||
private static ButtonTextures button(String name) {
|
||||
return new ButtonTextures(
|
||||
ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "buttons/" + name),
|
||||
@@ -47,34 +44,6 @@ public final class GuiSprites extends TextureAtlasHolder {
|
||||
);
|
||||
}
|
||||
|
||||
private static @Nullable GuiSprites instance;
|
||||
|
||||
private GuiSprites(TextureManager textureManager) {
|
||||
super(textureManager, TEXTURE, SPRITE_SHEET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the singleton {@link GuiSprites} instance.
|
||||
*
|
||||
* @param textureManager The current texture manager.
|
||||
* @return The singleton {@link GuiSprites} instance, to register as resource reload listener.
|
||||
*/
|
||||
public static GuiSprites initialise(TextureManager textureManager) {
|
||||
if (instance != null) throw new IllegalStateException("GuiSprites has already been initialised");
|
||||
return instance = new GuiSprites(textureManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a texture on the atlas.
|
||||
*
|
||||
* @param texture The texture to find.
|
||||
* @return The sprite on the atlas.
|
||||
*/
|
||||
public static TextureAtlasSprite get(ResourceLocation texture) {
|
||||
if (instance == null) throw new IllegalStateException("GuiSprites has not been initialised");
|
||||
return instance.getSprite(texture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate textures to use for a particular computer family.
|
||||
*
|
||||
|
@@ -7,8 +7,7 @@ package dan200.computercraft.client.gui;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
|
||||
import dan200.computercraft.client.gui.widgets.TerminalWidget;
|
||||
import dan200.computercraft.client.render.RenderTypes;
|
||||
import dan200.computercraft.client.render.SpriteRenderer;
|
||||
import dan200.computercraft.core.util.Nullability;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
|
||||
import dan200.computercraft.shared.turtle.inventory.TurtleMenu;
|
||||
@@ -64,8 +63,9 @@ public class TurtleScreen extends AbstractComputerScreen<TurtleMenu> {
|
||||
}
|
||||
|
||||
// Render sidebar
|
||||
var spriteRenderer = SpriteRenderer.createForGui(graphics, RenderTypes.GUI_SPRITES);
|
||||
ComputerSidebar.renderBackground(spriteRenderer, GuiSprites.getComputerTextures(family), leftPos, topPos + sidebarYOffset);
|
||||
graphics.flush(); // Flush to ensure background textures are drawn before foreground.
|
||||
graphics.blitSprite(
|
||||
Nullability.assertNonNull(GuiSprites.getComputerTextures(family).sidebar()),
|
||||
leftPos, topPos + sidebarYOffset, AbstractComputerMenu.SIDEBAR_WIDTH, ComputerSidebar.HEIGHT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -6,9 +6,7 @@ package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
import dan200.computercraft.client.gui.GuiSprites;
|
||||
import dan200.computercraft.client.gui.widgets.DynamicImageButton.HintedMessage;
|
||||
import dan200.computercraft.client.render.SpriteRenderer;
|
||||
import dan200.computercraft.shared.computer.core.InputHandler;
|
||||
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
@@ -24,12 +22,9 @@ public final class ComputerSidebar {
|
||||
private static final int ICON_MARGIN = 2;
|
||||
|
||||
private static final int CORNERS_BORDER = 3;
|
||||
private static final int FULL_BORDER = CORNERS_BORDER + ICON_MARGIN;
|
||||
|
||||
private static final int BUTTONS = 2;
|
||||
private static final int HEIGHT = (ICON_HEIGHT + ICON_MARGIN * 2) * BUTTONS + CORNERS_BORDER * 2;
|
||||
|
||||
private static final int TEX_HEIGHT = 14;
|
||||
public static final int HEIGHT = (ICON_HEIGHT + ICON_MARGIN * 2) * BUTTONS + CORNERS_BORDER * 2;
|
||||
|
||||
private ComputerSidebar() {
|
||||
}
|
||||
@@ -63,14 +58,6 @@ public final class ComputerSidebar {
|
||||
));
|
||||
}
|
||||
|
||||
public static void renderBackground(SpriteRenderer renderer, GuiSprites.ComputerTextures textures, int x, int y) {
|
||||
var texture = textures.sidebar();
|
||||
if (texture == null) throw new NullPointerException(textures + " has no sidebar texture");
|
||||
var sprite = GuiSprites.get(texture);
|
||||
|
||||
renderer.blitVerticalSliced(sprite, x, y, AbstractComputerMenu.SIDEBAR_WIDTH, HEIGHT, FULL_BORDER, FULL_BORDER, TEX_HEIGHT);
|
||||
}
|
||||
|
||||
private static void toggleComputer(BooleanSupplier isOn, InputHandler input) {
|
||||
if (isOn.getAsBoolean()) {
|
||||
input.shutdown();
|
||||
|
@@ -1,17 +1,14 @@
|
||||
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: LicenseRef-CCPL
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import dan200.computercraft.client.gui.GuiSprites;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
|
||||
import static dan200.computercraft.client.render.SpriteRenderer.u;
|
||||
import static dan200.computercraft.client.render.SpriteRenderer.v;
|
||||
import dan200.computercraft.client.gui.ComputerScreen;
|
||||
import net.minecraft.client.resources.metadata.gui.GuiSpriteScaling;
|
||||
|
||||
/**
|
||||
* Renders the borders of computers, either for a GUI ({@link dan200.computercraft.client.gui.ComputerScreen}) or
|
||||
* Constants for the borders of computers, either for a {@linkplain ComputerScreen GUI} or
|
||||
* {@linkplain PocketItemRenderer in-hand pocket computers}.
|
||||
*/
|
||||
public final class ComputerBorderRenderer {
|
||||
@@ -21,55 +18,13 @@ public final class ComputerBorderRenderer {
|
||||
public static final int MARGIN = 2;
|
||||
|
||||
/**
|
||||
* The width of the terminal border.
|
||||
* The size of the terminal border.
|
||||
* <p>
|
||||
* This is only used for layout of elements within UI. When rendering, the size of the computer's border is
|
||||
* determined by its {@link GuiSpriteScaling}.
|
||||
*/
|
||||
public static final int BORDER = 12;
|
||||
|
||||
public static final int LIGHT_HEIGHT = 8;
|
||||
|
||||
private static final int TEX_SIZE = 36;
|
||||
|
||||
private ComputerBorderRenderer() {
|
||||
}
|
||||
|
||||
public static void render(SpriteRenderer renderer, GuiSprites.ComputerTextures textures, int x, int y, int width, int height, boolean withLight) {
|
||||
var endX = x + width;
|
||||
var endY = y + height;
|
||||
|
||||
var border = GuiSprites.get(textures.border());
|
||||
|
||||
// Top bar
|
||||
blitBorder(renderer, border, x - BORDER, y - BORDER, 0, 0, BORDER, BORDER);
|
||||
blitBorder(renderer, border, x, y - BORDER, BORDER, 0, width, BORDER);
|
||||
blitBorder(renderer, border, endX, y - BORDER, BORDER * 2, 0, BORDER, BORDER);
|
||||
|
||||
// Vertical bars
|
||||
blitBorder(renderer, border, x - BORDER, y, 0, BORDER, BORDER, height);
|
||||
blitBorder(renderer, border, endX, y, BORDER * 2, BORDER, BORDER, height);
|
||||
|
||||
// Bottom bar. We allow for drawing a stretched version, which allows for additional elements (such as the
|
||||
// pocket computer's lights).
|
||||
if (withLight) {
|
||||
var pocketBottomTexture = textures.pocketBottom();
|
||||
if (pocketBottomTexture == null) throw new NullPointerException(textures + " has no pocket texture");
|
||||
var pocketBottom = GuiSprites.get(pocketBottomTexture);
|
||||
|
||||
renderer.blitHorizontalSliced(
|
||||
pocketBottom, x - BORDER, endY, width + BORDER * 2, BORDER + LIGHT_HEIGHT,
|
||||
BORDER, BORDER, BORDER * 3
|
||||
);
|
||||
} else {
|
||||
blitBorder(renderer, border, x - BORDER, endY, 0, BORDER * 2, BORDER, BORDER);
|
||||
blitBorder(renderer, border, x, endY, BORDER, BORDER * 2, width, BORDER);
|
||||
blitBorder(renderer, border, endX, endY, BORDER * 2, BORDER * 2, BORDER, BORDER);
|
||||
}
|
||||
}
|
||||
|
||||
private static void blitBorder(SpriteRenderer renderer, TextureAtlasSprite sprite, int x, int y, int u, int v, int width, int height) {
|
||||
renderer.blit(
|
||||
x, y, width, height,
|
||||
u(sprite, u, TEX_SIZE), v(sprite, v, TEX_SIZE),
|
||||
u(sprite, u + BORDER, TEX_SIZE), v(sprite, v + BORDER, TEX_SIZE)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -13,13 +13,16 @@ import dan200.computercraft.core.util.Colour;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.config.Config;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.resources.metadata.gui.GuiSpriteScaling;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.DyedItemColor;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.*;
|
||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
|
||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
|
||||
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_WIDTH;
|
||||
|
||||
@@ -29,6 +32,11 @@ import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FON
|
||||
public final class PocketItemRenderer extends ItemMapLikeRenderer {
|
||||
public static final PocketItemRenderer INSTANCE = new PocketItemRenderer();
|
||||
|
||||
/**
|
||||
* The height of the pocket computer's light.
|
||||
*/
|
||||
private static final int LIGHT_HEIGHT = 8;
|
||||
|
||||
private PocketItemRenderer() {
|
||||
}
|
||||
|
||||
@@ -83,14 +91,69 @@ public final class PocketItemRenderer extends ItemMapLikeRenderer {
|
||||
}
|
||||
|
||||
private static void renderFrame(Matrix4f transform, MultiBufferSource render, ComputerFamily family, int colour, int light, int width, int height) {
|
||||
var texture = colour != -1 ? GuiSprites.COMPUTER_COLOUR : GuiSprites.getComputerTextures(family);
|
||||
var textures = colour != -1 ? GuiSprites.COMPUTER_COLOUR : GuiSprites.getComputerTextures(family);
|
||||
var spriteRenderer = new SpriteRenderer(transform, render, 0, light, colour);
|
||||
renderBorder(spriteRenderer, textures, width, height);
|
||||
}
|
||||
|
||||
var r = (colour >>> 16) & 0xFF;
|
||||
var g = (colour >>> 8) & 0xFF;
|
||||
var b = colour & 0xFF;
|
||||
private static void renderBorder(SpriteRenderer renderer, GuiSprites.ComputerTextures textures, int width, int height) {
|
||||
var sprites = Minecraft.getInstance().getGuiSprites();
|
||||
|
||||
var spriteRenderer = new SpriteRenderer(transform, render.getBuffer(RenderTypes.GUI_SPRITES), 0, light, r, g, b);
|
||||
ComputerBorderRenderer.render(spriteRenderer, texture, 0, 0, width, height, true);
|
||||
// Find our border, forcing it to be a nine-sliced texture.
|
||||
var borderSprite = sprites.getSprite(textures.border());
|
||||
var borderSlice = getSlice(sprites.getSpriteScaling(borderSprite), DEFAULT_BORDER);
|
||||
var borderBounds = borderSlice.border();
|
||||
|
||||
// And take the separate bottom bit of the pocket computer.
|
||||
var bottomTexture = textures.pocketBottom();
|
||||
if (bottomTexture == null) throw new NullPointerException(textures + " has no pocket texture");
|
||||
var bottomSprite = sprites.getSprite(bottomTexture);
|
||||
var bottomSlice = getSlice(sprites.getSpriteScaling(bottomSprite), DEFAULT_BOTTOM);
|
||||
var bottomBounds = bottomSlice.border();
|
||||
|
||||
// Now draw a nine-sliced texture, by stitching together the top parts of the border with the pocket bottom.
|
||||
|
||||
// Top bar
|
||||
renderer.blit(
|
||||
borderSprite, -borderBounds.left(), -borderBounds.top(), borderBounds.left(), borderBounds.top(),
|
||||
0, 0, borderSlice.width(), borderSlice.height()
|
||||
);
|
||||
renderer.blitTiled(
|
||||
borderSprite, 0, -borderBounds.top(), width, borderBounds.top(),
|
||||
borderBounds.left(), 0, borderSlice.width() - borderBounds.left() - borderBounds.right(), borderBounds.top(),
|
||||
borderSlice.width(), borderSlice.height()
|
||||
);
|
||||
renderer.blit(
|
||||
borderSprite, width, -borderBounds.top(), borderBounds.right(), borderBounds.top(),
|
||||
borderSlice.width() - borderBounds.right(), 0, borderSlice.width(), borderSlice.height()
|
||||
);
|
||||
|
||||
// Vertical bars
|
||||
renderer.blitTiled(
|
||||
borderSprite, -borderBounds.left(), 0, borderBounds.left(), height,
|
||||
0, borderBounds.top(), borderBounds.left(), borderSlice.height() - borderBounds.top() - borderBounds.bottom(),
|
||||
borderSlice.width(), borderSlice.height()
|
||||
);
|
||||
renderer.blitTiled(
|
||||
borderSprite, width, 0, borderBounds.right(), height,
|
||||
borderSlice.width() - borderBounds.right(), borderBounds.top(), borderBounds.right(), borderSlice.height() - borderBounds.top() - borderBounds.bottom(),
|
||||
borderSlice.width(), borderSlice.height()
|
||||
);
|
||||
|
||||
// Bottom
|
||||
renderer.blit(
|
||||
bottomSprite, -bottomBounds.left(), height, bottomBounds.left(), bottomSlice.height(),
|
||||
0, 0, bottomSlice.width(), bottomSlice.height()
|
||||
);
|
||||
renderer.blitTiled(
|
||||
bottomSprite, 0, height, width, bottomSlice.height(),
|
||||
bottomBounds.left(), 0, bottomSlice.width() - bottomBounds.left() - bottomBounds.right(), bottomSlice.height(),
|
||||
bottomSlice.width(), bottomSlice.height()
|
||||
);
|
||||
renderer.blit(
|
||||
bottomSprite, width, height, bottomBounds.right(), bottomSlice.height(),
|
||||
bottomSlice.width() - bottomBounds.right(), 0, bottomSlice.width(), bottomSlice.height()
|
||||
);
|
||||
}
|
||||
|
||||
private static void renderLight(PoseStack transform, MultiBufferSource render, int colour, int width, int height) {
|
||||
@@ -101,4 +164,16 @@ public final class PocketItemRenderer extends ItemMapLikeRenderer {
|
||||
FastColor.ARGB32.opaque(colour), RenderTypes.FULL_BRIGHT_LIGHTMAP
|
||||
);
|
||||
}
|
||||
|
||||
private static final GuiSpriteScaling.NineSlice DEFAULT_BORDER = new GuiSpriteScaling.NineSlice(
|
||||
36, 36, new GuiSpriteScaling.NineSlice.Border(12, 12, 12, 12)
|
||||
);
|
||||
|
||||
private static final GuiSpriteScaling.NineSlice DEFAULT_BOTTOM = new GuiSpriteScaling.NineSlice(
|
||||
36, 20, new GuiSpriteScaling.NineSlice.Border(12, 0, 12, 0)
|
||||
);
|
||||
|
||||
private static GuiSpriteScaling.NineSlice getSlice(GuiSpriteScaling scaling, GuiSpriteScaling.NineSlice fallback) {
|
||||
return scaling instanceof GuiSpriteScaling.NineSlice slice ? slice : fallback;
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@ package dan200.computercraft.client.render;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.client.gui.GuiSprites;
|
||||
import dan200.computercraft.client.render.monitor.MonitorTextureBufferShader;
|
||||
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
@@ -54,11 +53,6 @@ public class RenderTypes {
|
||||
*/
|
||||
public static final RenderType PRINTOUT_BACKGROUND = RenderType.text(ResourceLocation.fromNamespaceAndPath("computercraft", "textures/gui/printout.png"));
|
||||
|
||||
/**
|
||||
* Render type for {@linkplain GuiSprites GUI sprites}.
|
||||
*/
|
||||
public static final RenderType GUI_SPRITES = RenderType.text(GuiSprites.TEXTURE);
|
||||
|
||||
public static MonitorTextureBufferShader getMonitorTextureBufferShader() {
|
||||
if (monitorTboShader == null) throw new NullPointerException("MonitorTboShader has not been registered");
|
||||
return monitorTboShader;
|
||||
|
@@ -6,129 +6,69 @@ package dan200.computercraft.client.render;
|
||||
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
/**
|
||||
* A {@link GuiGraphics}-equivalent which is suitable for both rendering in to a GUI and in-world (as part of an entity
|
||||
* renderer).
|
||||
* A {@link GuiGraphics}-equivalent renders to a {@link VertexConsumer}. This is suitable for rendering outside of a
|
||||
* GUI, such as part of an entity renderer.
|
||||
* <p>
|
||||
* This batches all render calls together, though requires that all {@link TextureAtlasSprite}s are on the same sprite
|
||||
* sheet.
|
||||
*/
|
||||
public class SpriteRenderer {
|
||||
public static final ResourceLocation TEXTURE = ResourceLocation.withDefaultNamespace("textures/atlas/gui.png");
|
||||
|
||||
private final Matrix4f transform;
|
||||
private final VertexConsumer builder;
|
||||
private final MultiBufferSource buffers;
|
||||
private final int light;
|
||||
private final int z;
|
||||
private final int r, g, b;
|
||||
private final int colour;
|
||||
|
||||
public SpriteRenderer(Matrix4f transform, VertexConsumer builder, int z, int light, int r, int g, int b) {
|
||||
public SpriteRenderer(Matrix4f transform, MultiBufferSource buffers, int z, int light, int colour) {
|
||||
this.transform = transform;
|
||||
this.builder = builder;
|
||||
this.buffers = buffers;
|
||||
this.z = z;
|
||||
this.light = light;
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.colour = colour;
|
||||
}
|
||||
|
||||
public static SpriteRenderer createForGui(GuiGraphics graphics, RenderType renderType) {
|
||||
return new SpriteRenderer(
|
||||
graphics.pose().last().pose(), graphics.bufferSource().getBuffer(renderType),
|
||||
0, RenderTypes.FULL_BRIGHT_LIGHTMAP, 255, 255, 255
|
||||
);
|
||||
public void blit(TextureAtlasSprite sprite, int x0, int y0, int width, int height, int spriteX, int spriteY, int spriteWidth, int spriteHeight) {
|
||||
if (width == 0 || height == 0) return;
|
||||
|
||||
var x1 = x0 + width;
|
||||
var y1 = y0 + height;
|
||||
var u0 = sprite.getU((float) spriteX / spriteWidth);
|
||||
var u1 = sprite.getU((float) (spriteX + width) / spriteWidth);
|
||||
var v0 = sprite.getV((float) spriteY / spriteHeight);
|
||||
var v1 = sprite.getV((float) (spriteY + height) / spriteHeight);
|
||||
|
||||
var vertices = buffers.getBuffer(RenderType.text(sprite.atlasLocation()));
|
||||
vertices.addVertex(transform, x0, y1, z).setColor(colour).setUv(u0, v1).setLight(light);
|
||||
vertices.addVertex(transform, x1, y1, z).setColor(colour).setUv(u1, v1).setLight(light);
|
||||
vertices.addVertex(transform, x1, y0, z).setColor(colour).setUv(u1, v0).setLight(light);
|
||||
vertices.addVertex(transform, x0, y0, z).setColor(colour).setUv(u0, v0).setLight(light);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single sprite.
|
||||
*
|
||||
* @param sprite The texture to draw.
|
||||
* @param x The x position of the rectangle we'll draw.
|
||||
* @param y The x position of the rectangle we'll draw.
|
||||
* @param width The width of the rectangle we'll draw.
|
||||
* @param height The height of the rectangle we'll draw.
|
||||
*/
|
||||
public void blit(TextureAtlasSprite sprite, int x, int y, int width, int height) {
|
||||
blit(x, y, width, height, sprite.getU0(), sprite.getV0(), sprite.getU1(), sprite.getV1());
|
||||
public void blitTiled(
|
||||
TextureAtlasSprite sprite,
|
||||
int x, int y, int width, int height,
|
||||
int tileX, int tileY, int tileWidth, int tileHeight, int spriteWidth, int spriteHeight
|
||||
) {
|
||||
if (width <= 0 || height <= 0) return;
|
||||
if (tileWidth <= 0 || tileHeight <= 0) {
|
||||
throw new IllegalArgumentException("Tiled sprite texture size must be positive, got " + tileWidth + "x" + tileHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a horizontal 3-sliced texture (i.e. split into left, middle and right). Unlike {@link GuiGraphics#blitNineSliced},
|
||||
* the middle texture is stretched rather than repeated.
|
||||
*
|
||||
* @param sprite The texture to draw.
|
||||
* @param x The x position of the rectangle we'll draw.
|
||||
* @param y The x position of the rectangle we'll draw.
|
||||
* @param width The width of the rectangle we'll draw.
|
||||
* @param height The height of the rectangle we'll draw.
|
||||
* @param leftBorder The width of the left border.
|
||||
* @param rightBorder The width of the right border.
|
||||
* @param textureWidth The width of the whole texture.
|
||||
*/
|
||||
public void blitHorizontalSliced(TextureAtlasSprite sprite, int x, int y, int width, int height, int leftBorder, int rightBorder, int textureWidth) {
|
||||
// TODO(1.20.2)/TODO(1.21.0): Drive this from mcmeta files, like vanilla does.
|
||||
if (width < leftBorder + rightBorder) throw new IllegalArgumentException("width is less than two borders");
|
||||
|
||||
var centerStart = SpriteRenderer.u(sprite, leftBorder, textureWidth);
|
||||
var centerEnd = SpriteRenderer.u(sprite, textureWidth - rightBorder, textureWidth);
|
||||
|
||||
blit(x, y, leftBorder, height, sprite.getU0(), sprite.getV0(), centerStart, sprite.getV1());
|
||||
blit(x + leftBorder, y, width - leftBorder - rightBorder, height, centerStart, sprite.getV0(), centerEnd, sprite.getV1());
|
||||
blit(x + width - rightBorder, y, rightBorder, height, centerEnd, sprite.getV0(), sprite.getU1(), sprite.getV1());
|
||||
for (var xOffset = 0; xOffset < width; xOffset += tileWidth) {
|
||||
var sliceWidth = Math.min(tileWidth, width - xOffset);
|
||||
for (var yOffset = 0; yOffset < height; yOffset += tileHeight) {
|
||||
var sliceHeight = Math.min(tileHeight, height - yOffset);
|
||||
blit(sprite, x + xOffset, y + yOffset, sliceWidth, sliceHeight, tileX, tileY, spriteWidth, spriteHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a vertical 3-sliced texture (i.e. split into top, middle and bottom). Unlike {@link GuiGraphics#blitNineSliced},
|
||||
* the middle texture is stretched rather than repeated.
|
||||
*
|
||||
* @param sprite The texture to draw.
|
||||
* @param x The x position of the rectangle we'll draw.
|
||||
* @param y The x position of the rectangle we'll draw.
|
||||
* @param width The width of the rectangle we'll draw.
|
||||
* @param height The height of the rectangle we'll draw.
|
||||
* @param topBorder The height of the top border.
|
||||
* @param bottomBorder The height of the bottom border.
|
||||
* @param textureHeight The height of the whole texture.
|
||||
*/
|
||||
public void blitVerticalSliced(TextureAtlasSprite sprite, int x, int y, int width, int height, int topBorder, int bottomBorder, int textureHeight) {
|
||||
// TODO(1.20.2)/TODO(1.21.0): Drive this from mcmeta files, like vanilla does.
|
||||
if (width < topBorder + bottomBorder) throw new IllegalArgumentException("height is less than two borders");
|
||||
|
||||
var centerStart = SpriteRenderer.v(sprite, topBorder, textureHeight);
|
||||
var centerEnd = SpriteRenderer.v(sprite, textureHeight - bottomBorder, textureHeight);
|
||||
|
||||
blit(x, y, width, topBorder, sprite.getU0(), sprite.getV0(), sprite.getU1(), centerStart);
|
||||
blit(x, y + topBorder, width, height - topBorder - bottomBorder, sprite.getU0(), centerStart, sprite.getU1(), centerEnd);
|
||||
blit(x, y + height - bottomBorder, width, bottomBorder, sprite.getU0(), centerEnd, sprite.getU1(), sprite.getV1());
|
||||
}
|
||||
|
||||
/**
|
||||
* The low-level blit function, used to render a portion of the sprite sheet. Unlike other functions, this takes uvs rather than a single sprite.
|
||||
*
|
||||
* @param x The x position of the rectangle we'll draw.
|
||||
* @param y The x position of the rectangle we'll draw.
|
||||
* @param width The width of the rectangle we'll draw.
|
||||
* @param height The height of the rectangle we'll draw.
|
||||
* @param u0 The first U coordinate.
|
||||
* @param v0 The first V coordinate.
|
||||
* @param u1 The second U coordinate.
|
||||
* @param v1 The second V coordinate.
|
||||
*/
|
||||
public void blit(
|
||||
int x, int y, int width, int height, float u0, float v0, float u1, float v1) {
|
||||
builder.addVertex(transform, x, y + height, z).setColor(r, g, b, 255).setUv(u0, v1).setLight(light);
|
||||
builder.addVertex(transform, x + width, y + height, z).setColor(r, g, b, 255).setUv(u1, v1).setLight(light);
|
||||
builder.addVertex(transform, x + width, y, z).setColor(r, g, b, 255).setUv(u1, v0).setLight(light);
|
||||
builder.addVertex(transform, x, y, z).setColor(r, g, b, 255).setUv(u0, v0).setLight(light);
|
||||
}
|
||||
|
||||
public static float u(TextureAtlasSprite sprite, int x, int width) {
|
||||
return sprite.getU((float) x / width);
|
||||
}
|
||||
|
||||
public static float v(TextureAtlasSprite sprite, int y, int height) {
|
||||
return sprite.getV((float) y / height);
|
||||
}
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ public final class DataProviders {
|
||||
LecternPocketModel.TEXTURE_NORMAL, LecternPocketModel.TEXTURE_ADVANCED,
|
||||
LecternPocketModel.TEXTURE_COLOUR, LecternPocketModel.TEXTURE_FRAME, LecternPocketModel.TEXTURE_LIGHT
|
||||
)));
|
||||
out.accept(GuiSprites.SPRITE_SHEET, makeSprites(
|
||||
out.accept(ResourceLocation.withDefaultNamespace("gui"), makeSprites(
|
||||
// Computers
|
||||
GuiSprites.COMPUTER_NORMAL.textures(),
|
||||
GuiSprites.COMPUTER_ADVANCED.textures(),
|
||||
@@ -85,6 +85,8 @@ public final class DataProviders {
|
||||
));
|
||||
});
|
||||
|
||||
generator.add(ResourceMetadataProvider::new);
|
||||
|
||||
generator.add(pack -> new ExtraModelsProvider(pack, fullRegistries) {
|
||||
@Override
|
||||
public Stream<ResourceLocation> getModels(HolderLookup.Provider registries) {
|
||||
|
@@ -0,0 +1,110 @@
|
||||
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import dan200.computercraft.client.gui.GuiSprites;
|
||||
import net.minecraft.client.resources.metadata.gui.GuiMetadataSection;
|
||||
import net.minecraft.client.resources.metadata.gui.GuiSpriteScaling;
|
||||
import net.minecraft.data.CachedOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.metadata.PackMetadataGenerator;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.metadata.MetadataSectionType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Similar to {@link PackMetadataGenerator}, but for individual resources.
|
||||
*/
|
||||
final class ResourceMetadataProvider implements DataProvider {
|
||||
private final PackOutput output;
|
||||
|
||||
ResourceMetadataProvider(PackOutput output) {
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
private void register(Builder builder) {
|
||||
for (var computerTextures : List.of(
|
||||
GuiSprites.COMPUTER_ADVANCED,
|
||||
GuiSprites.COMPUTER_COLOUR,
|
||||
GuiSprites.COMPUTER_COMMAND,
|
||||
GuiSprites.COMPUTER_NORMAL
|
||||
)) {
|
||||
builder.texture(computerTextures.border()).add(GuiMetadataSection.TYPE, new GuiMetadataSection(
|
||||
new GuiSpriteScaling.NineSlice(36, 36, simpleNineSlicedBorder(12))
|
||||
));
|
||||
|
||||
var sidebar = computerTextures.sidebar();
|
||||
if (sidebar != null) {
|
||||
builder.texture(sidebar).add(GuiMetadataSection.TYPE, new GuiMetadataSection(
|
||||
new GuiSpriteScaling.NineSlice(17, 14, new GuiSpriteScaling.NineSlice.Border(3, 4, 0, 3))
|
||||
));
|
||||
}
|
||||
|
||||
var pocketBottom = computerTextures.pocketBottom();
|
||||
if (pocketBottom != null) {
|
||||
builder.texture(pocketBottom).add(GuiMetadataSection.TYPE, new GuiMetadataSection(
|
||||
new GuiSpriteScaling.NineSlice(36, 20, new GuiSpriteScaling.NineSlice.Border(12, 0, 12, 0))
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static GuiSpriteScaling.NineSlice.Border simpleNineSlicedBorder(int size) {
|
||||
return new GuiSpriteScaling.NineSlice.Border(size, size, size, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> run(CachedOutput cachedOutput) {
|
||||
var builder = new Builder();
|
||||
register(builder);
|
||||
|
||||
var outputPath = output.getOutputFolder(PackOutput.Target.RESOURCE_PACK);
|
||||
return CompletableFuture.allOf(builder.metadata.entrySet().stream().map(entry -> {
|
||||
var json = new JsonObject();
|
||||
entry.getValue().elements.forEach((name, element) -> json.add(name, element.get()));
|
||||
return DataProvider.saveStable(cachedOutput, json, outputPath.resolve(entry.getKey().getNamespace()).resolve(entry.getKey().getPath() + ".mcmeta"));
|
||||
}).toArray(CompletableFuture[]::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Resource Metadata";
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for a set of {@code mcmeta} files.
|
||||
*/
|
||||
private static final class Builder {
|
||||
private final Map<ResourceLocation, FileMetadata> metadata = new HashMap<>();
|
||||
|
||||
FileMetadata texture(ResourceLocation texture) {
|
||||
return file(texture.withPrefix("textures/").withSuffix(".png"));
|
||||
}
|
||||
|
||||
FileMetadata file(ResourceLocation path) {
|
||||
return metadata.computeIfAbsent(path, p -> new FileMetadata());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for a given file's {@code mcmeta} file.
|
||||
*/
|
||||
private static final class FileMetadata {
|
||||
private final Map<String, Supplier<JsonElement>> elements = new HashMap<>();
|
||||
|
||||
<T> FileMetadata add(MetadataSectionType<T> type, T value) {
|
||||
elements.put(type.getMetadataSectionName(), () -> type.toJson(value));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
10
projects/common/src/generated/resources/assets/computercraft/textures/gui/border_advanced.png.mcmeta
generated
Normal file
10
projects/common/src/generated/resources/assets/computercraft/textures/gui/border_advanced.png.mcmeta
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": 12,
|
||||
"height": 36,
|
||||
"width": 36
|
||||
}
|
||||
}
|
||||
}
|
10
projects/common/src/generated/resources/assets/computercraft/textures/gui/border_colour.png.mcmeta
generated
Normal file
10
projects/common/src/generated/resources/assets/computercraft/textures/gui/border_colour.png.mcmeta
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": 12,
|
||||
"height": 36,
|
||||
"width": 36
|
||||
}
|
||||
}
|
||||
}
|
10
projects/common/src/generated/resources/assets/computercraft/textures/gui/border_command.png.mcmeta
generated
Normal file
10
projects/common/src/generated/resources/assets/computercraft/textures/gui/border_command.png.mcmeta
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": 12,
|
||||
"height": 36,
|
||||
"width": 36
|
||||
}
|
||||
}
|
||||
}
|
10
projects/common/src/generated/resources/assets/computercraft/textures/gui/border_normal.png.mcmeta
generated
Normal file
10
projects/common/src/generated/resources/assets/computercraft/textures/gui/border_normal.png.mcmeta
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": 12,
|
||||
"height": 36,
|
||||
"width": 36
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": {
|
||||
"bottom": 0,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 0
|
||||
},
|
||||
"height": 20,
|
||||
"width": 36
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": {
|
||||
"bottom": 0,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 0
|
||||
},
|
||||
"height": 20,
|
||||
"width": 36
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": {
|
||||
"bottom": 0,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 0
|
||||
},
|
||||
"height": 20,
|
||||
"width": 36
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": {
|
||||
"bottom": 3,
|
||||
"left": 3,
|
||||
"right": 0,
|
||||
"top": 4
|
||||
},
|
||||
"height": 14,
|
||||
"width": 17
|
||||
}
|
||||
}
|
||||
}
|
15
projects/common/src/generated/resources/assets/computercraft/textures/gui/sidebar_command.png.mcmeta
generated
Normal file
15
projects/common/src/generated/resources/assets/computercraft/textures/gui/sidebar_command.png.mcmeta
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": {
|
||||
"bottom": 3,
|
||||
"left": 3,
|
||||
"right": 0,
|
||||
"top": 4
|
||||
},
|
||||
"height": 14,
|
||||
"width": 17
|
||||
}
|
||||
}
|
||||
}
|
15
projects/common/src/generated/resources/assets/computercraft/textures/gui/sidebar_normal.png.mcmeta
generated
Normal file
15
projects/common/src/generated/resources/assets/computercraft/textures/gui/sidebar_normal.png.mcmeta
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"border": {
|
||||
"bottom": 3,
|
||||
"left": 3,
|
||||
"right": 0,
|
||||
"top": 4
|
||||
},
|
||||
"height": 14,
|
||||
"width": 17
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,25 +5,16 @@
|
||||
package dan200.computercraft.mixin.client;
|
||||
|
||||
import dan200.computercraft.client.ClientHooks;
|
||||
import dan200.computercraft.client.ClientRegistry;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.main.GameConfig;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
class MinecraftMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private ReloadableResourceManager resourceManager;
|
||||
|
||||
@Inject(method = "updateLevelInEngines", at = @At("HEAD"))
|
||||
@SuppressWarnings("unused")
|
||||
private void updateLevelInEngines(ClientLevel screen, CallbackInfo ci) {
|
||||
@@ -35,17 +26,4 @@ class MinecraftMixin {
|
||||
private void disconnect(Screen screen, boolean keepResourcePacks, CallbackInfo ci) {
|
||||
ClientHooks.onDisconnect();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "<init>(Lnet/minecraft/client/main/GameConfig;)V",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/ResourceLoadStateTracker;startReload(Lnet/minecraft/client/ResourceLoadStateTracker$ReloadReason;Ljava/util/List;)V",
|
||||
ordinal = 0
|
||||
)
|
||||
)
|
||||
@SuppressWarnings("unused")
|
||||
private void beforeInitialResourceReload(GameConfig gameConfig, CallbackInfo ci) {
|
||||
ClientRegistry.registerReloadListeners(resourceManager::registerReloadListener, (Minecraft) (Object) this);
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,10 @@ import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.ModLoader;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.*;
|
||||
import net.neoforged.neoforge.client.event.ModelEvent;
|
||||
import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent;
|
||||
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
|
||||
import net.neoforged.neoforge.client.event.RegisterShadersEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -82,11 +85,6 @@ public final class ForgeClientRegistry {
|
||||
ClientRegistry.registerMenuScreens(event::register);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerReloadListeners(RegisterClientReloadListenersEvent event) {
|
||||
ClientRegistry.registerReloadListeners(event::registerReloadListener, Minecraft.getInstance());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void setupClient(FMLClientSetupEvent event) {
|
||||
ClientRegistry.register();
|
||||
|
Reference in New Issue
Block a user