diff --git a/net/fabricmc/fabric/api/client/rendering/v1/HudLayerRegistrationCallback.java b/net/fabricmc/fabric/api/client/rendering/v1/HudLayerRegistrationCallback.java new file mode 100644 index 0000000..0a7b048 --- /dev/null +++ b/net/fabricmc/fabric/api/client/rendering/v1/HudLayerRegistrationCallback.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.client.rendering.v1; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +/** + * Callback for when hud layers are registered. + * + *
To register a layer, register a listener to this event and register your layers in the listener. + * For common use cases, see {@link LayeredDrawerWrapper}. + * + *
For example, the following code registers a layer after {@link IdentifiedLayer#MISC_OVERLAYS}:
+ * {@snippet :
+ * // @link region substring=HudLayerRegistrationCallback target=HudLayerRegistrationCallback
+ * // @link region substring=EVENT target="HudLayerRegistrationCallback#EVENT"
+ * // @link region substring=layeredDrawer target="LayeredDrawerWrapper"
+ * // @link region substring=attachLayerAfter target="LayeredDrawerWrapper#attachLayerAfter"
+ * // @link region substring=IdentifiedLayer target=IdentifiedLayer
+ * // @link region substring=MISC_OVERLAYS target="IdentifiedLayer#MISC_OVERLAYS"
+ * // @link region substring=Identifier target="net.minecraft.util.Identifier"
+ * // @link region substring=of target="net.minecraft.util.Identifier#of"
+ * // @link region substring=context target="net.minecraft.client.gui.DrawContext"
+ * // @link region substring=tickCounter target="net.minecraft.client.render.RenderTickCounter"
+ * HudLayerRegistrationCallback.EVENT.register(layeredDrawer -> layeredDrawer.attachLayerAfter(IdentifiedLayer.MISC_OVERLAYS, Identifier.of("example", "example_layer_after_misc_overlays"), (context, tickCounter) -> {
+ * // Your rendering code here
+ * }));
+ * // @end @end @end @end @end @end @end @end @end @end
+ * }
+ *
+ * @see LayeredDrawerWrapper
+ */
+public interface HudLayerRegistrationCallback {
+ Event The identifiers in this interface are the vanilla hud layers in the order they are drawn in.
+ * The first layer is drawn first, which means it is at the bottom.
+ * All vanilla layers except {@link #SLEEP} are in sub drawers and have a render condition attached ({@link net.minecraft.class_315#field_1842}).
+ * Operations relative to any layer will generally inherit that layer's render condition.
+ * There is currently no mechanism to change the render condition of a layer.
+ *
+ * For common use cases and more details on how this API deals with render condition, see {@link LayeredDrawerWrapper}.
+ */
+public interface IdentifiedLayer extends class_9080.class_9081 {
+ /**
+ * The identifier for the vanilla miscellaneous overlays (such as vignette, spyglass, and powder snow) layer.
+ */
+ class_2960 MISC_OVERLAYS = class_2960.method_60656("misc_overlays");
+ /**
+ * The identifier for the vanilla crosshair layer.
+ */
+ class_2960 CROSSHAIR = class_2960.method_60656("crosshair");
+ /**
+ * The identifier for the vanilla hotbar, spectator hud, experience bar, and status bars layer.
+ */
+ class_2960 HOTBAR_AND_BARS = class_2960.method_60656("hotbar_and_bars");
+ /**
+ * The identifier for the vanilla experience level layer.
+ */
+ class_2960 EXPERIENCE_LEVEL = class_2960.method_60656("experience_level");
+ /**
+ * The identifier for the vanilla status effects layer.
+ */
+ class_2960 STATUS_EFFECTS = class_2960.method_60656("status_effects");
+ /**
+ * The identifier for the vanilla boss bar layer.
+ */
+ class_2960 BOSS_BAR = class_2960.method_60656("boss_bar");
+ /**
+ * The identifier for the vanilla sleep overlay layer.
+ */
+ class_2960 SLEEP = class_2960.method_60656("sleep");
+ /**
+ * The identifier for the vanilla demo timer layer.
+ */
+ class_2960 DEMO_TIMER = class_2960.method_60656("demo_timer");
+ /**
+ * The identifier for the vanilla debug hud layer.
+ */
+ class_2960 DEBUG = class_2960.method_60656("debug");
+ /**
+ * The identifier for the vanilla scoreboard layer.
+ */
+ class_2960 SCOREBOARD = class_2960.method_60656("scoreboard");
+ /**
+ * The identifier for the vanilla overlay message layer.
+ */
+ class_2960 OVERLAY_MESSAGE = class_2960.method_60656("overlay_message");
+ /**
+ * The identifier for the vanilla title and subtitle layer.
+ *
+ * Note that this is not the sound subtitles.
+ */
+ class_2960 TITLE_AND_SUBTITLE = class_2960.method_60656("title_and_subtitle");
+ /**
+ * The identifier for the vanilla chat layer.
+ */
+ class_2960 CHAT = class_2960.method_60656("chat");
+ /**
+ * The identifier for the vanilla player list layer.
+ */
+ class_2960 PLAYER_LIST = class_2960.method_60656("player_list");
+ /**
+ * The identifier for the vanilla sound subtitles layer.
+ */
+ class_2960 SUBTITLES = class_2960.method_60656("subtitles");
+
+ /**
+ * @return the identifier of the layer
+ */
+ class_2960 id();
+
+ /**
+ * Wraps a hud layer in an identified layer.
+ *
+ * @param id the identifier to give the layer
+ * @param layer the layer to wrap
+ * @return the identified layer
+ */
+ static IdentifiedLayer of(class_2960 id, class_9080.class_9081 layer) {
+ return new WrappedLayer(id, layer);
+ }
+}
diff --git a/net/fabricmc/fabric/api/client/rendering/v1/LayeredDrawerWrapper.java b/net/fabricmc/fabric/api/client/rendering/v1/LayeredDrawerWrapper.java
new file mode 100644
index 0000000..a5ceb45
--- /dev/null
+++ b/net/fabricmc/fabric/api/client/rendering/v1/LayeredDrawerWrapper.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.client.rendering.v1;
+
+import java.util.function.Function;
+import net.minecraft.class_2960;
+import net.minecraft.class_9080;
+import org.jetbrains.annotations.Contract;
+
+/**
+ * A layered drawer that has an identifier attached to each layer and methods to add layers in specific positions.
+ *
+ * Operations relative to a layer will generally inherit that layer's render condition.
+ * The render condition for all vanilla layers except {@link IdentifiedLayer#SLEEP} is {@link net.minecraft.class_315#field_1842}.
+ * Only {@link #addLayer(IdentifiedLayer)} will not inherit any render condition.
+ * There is currently no mechanism to change the render condition of a layer.
+ * For vanilla layers, see {@link IdentifiedLayer}.
+ *
+ * Common places to add layers (as of 1.21.4):
+ * The render condition of the layer being attached to, if any, also applies to the new layer.
+ *
+ * @param beforeThis the identifier of the layer to add the new layer before
+ * @param layer the layer to add
+ * @return this layered drawer
+ */
+ @Contract("_, _ -> this")
+ LayeredDrawerWrapper attachLayerBefore(class_2960 beforeThis, IdentifiedLayer layer);
+
+ /**
+ * Attaches a layer before the layer with the specified identifier.
+ *
+ * The render condition of the layer being attached to, if any, also applies to the new layer.
+ *
+ * @param beforeThis the identifier of the layer to add the new layer before
+ * @param identifier the identifier of the new layer
+ * @param layer the layer to add
+ * @return this layered drawer
+ */
+ @Contract("_, _, _ -> this")
+ default LayeredDrawerWrapper attachLayerBefore(class_2960 beforeThis, class_2960 identifier, class_9080.class_9081 layer) {
+ return attachLayerBefore(beforeThis, IdentifiedLayer.of(identifier, layer));
+ }
+
+ /**
+ * Attaches a layer after the layer with the specified identifier.
+ *
+ * The render condition of the layer being attached to, if any, also applies to the new layer.
+ *
+ * @param afterThis the identifier of the layer to add the new layer after
+ * @param layer the layer to add
+ * @return this layered drawer
+ */
+ @Contract("_, _ -> this")
+ LayeredDrawerWrapper attachLayerAfter(class_2960 afterThis, IdentifiedLayer layer);
+
+ /**
+ * Attaches a layer after the layer with the specified identifier.
+ *
+ * The render condition of the layer being attached to, if any, also applies to the new layer.
+ *
+ * @param afterThis the identifier of the layer to add the new layer after
+ * @param identifier the identifier of the new layer
+ * @param layer the layer to add
+ * @return this layered drawer
+ */
+ @Contract("_, _, _ -> this")
+ default LayeredDrawerWrapper attachLayerAfter(class_2960 afterThis, class_2960 identifier, class_9080.class_9081 layer) {
+ return attachLayerAfter(afterThis, IdentifiedLayer.of(identifier, layer));
+ }
+
+ /**
+ * Removes a layer with the specified identifier.
+ *
+ * @param identifier the identifier of the layer to remove
+ * @return this layered drawer
+ */
+ @Contract("_ -> this")
+ LayeredDrawerWrapper removeLayer(class_2960 identifier);
+
+ /**
+ * Replaces a layer with the specified identifier.
+ *
+ * The render condition of the layer being replaced, if any, also applies to the new layer.
+ *
+ * @param identifier the identifier of the layer to replace
+ * @param replacer a function that takes the old layer and returns the new layer
+ * @return this layered drawer
+ */
+ @Contract("_, _ -> this")
+ LayeredDrawerWrapper replaceLayer(class_2960 identifier, Function HUD elements should be registered using {@link HudElementRegistry}
+ */
+public interface HudElement {
+ /**
+ * Renders the HUD element.
+ *
+ * @param context the {@link class_332} used for rendering
+ * @param tickCounter the {@link class_9779} providing timing information
+ */
+ void render(class_332 context, class_9779 tickCounter);
+}
diff --git a/net/fabricmc/fabric/api/client/rendering/v1/hud/HudElementRegistry.java b/net/fabricmc/fabric/api/client/rendering/v1/hud/HudElementRegistry.java
new file mode 100644
index 0000000..ff253ff
--- /dev/null
+++ b/net/fabricmc/fabric/api/client/rendering/v1/hud/HudElementRegistry.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.client.rendering.v1.hud;
+
+import java.util.Objects;
+import java.util.function.Function;
+import net.fabricmc.fabric.impl.client.rendering.hud.HudElementRegistryImpl;
+import net.minecraft.class_2960;
+
+/**
+ * A registry of identified hud layers with methods to add layers in specific positions.
+ *
+ * Operations relative to a vanilla element will inherit that element's render condition.
+ *
+ * The render condition for all vanilla layers except {@link VanillaHudElements#SLEEP} is
+ * {@link net.minecraft.class_315#field_1842}.
+ *
+ * Only {@link #addFirst(class_2960, HudElement)} and {@link #addLast(class_2960, HudElement)} will not inherit any
+ * render condition.
+ *
+ * There is currently no mechanism to change the render condition of a vanilla element.
+ *
+ * For vanilla layers, see {@link VanillaHudElements}.
+ *
+ * Common places to add layers (as of 1.21.6):
+ * The render condition of the vanilla element being attached to, if any, also applies to the new element.
+ *
+ * @param beforeThis the identifier of the element to add the new element before
+ * @param identifier the identifier of the new element
+ * @param element the element to add
+ */
+ static void attachElementBefore(class_2960 beforeThis, class_2960 identifier, HudElement element) {
+ Objects.requireNonNull(beforeThis, "beforeThis");
+ Objects.requireNonNull(identifier, "identifier");
+ Objects.requireNonNull(element, "hudElement");
+ HudElementRegistryImpl.attachElementBefore(beforeThis, identifier, element);
+ }
+
+ /**
+ * Attaches an element after the element with the specified identifier.
+ *
+ * The render condition of the vanilla element being attached to, if any, also applies to the new element.
+ *
+ * @param afterThis the identifier of the element to add the new element after
+ * @param identifier the identifier of the new element
+ * @param element the element to add
+ */
+ static void attachElementAfter(class_2960 afterThis, class_2960 identifier, HudElement element) {
+ Objects.requireNonNull(afterThis, "afterThis");
+ Objects.requireNonNull(identifier, "identifier");
+ Objects.requireNonNull(element, "hudElement");
+ HudElementRegistryImpl.attachElementAfter(afterThis, identifier, element);
+ }
+
+ /**
+ * Removes an element with the specified identifier.
+ *
+ * @param identifier the identifier of the element to remove
+ */
+ static void removeElement(class_2960 identifier) {
+ Objects.requireNonNull(identifier, "identifier");
+ HudElementRegistryImpl.removeElement(identifier);
+ }
+
+ /**
+ * Replaces an element with the specified identifier, the element retains its original identifier.
+ *
+ * The render condition of the vanilla element being replaced, if any, also applies to the new element.
+ *
+ * If the replaced element is a status bar (like {@link VanillaHudElements#HEALTH_BAR HEALTH_BAR},
+ * {@link VanillaHudElements#ARMOR_BAR ARMOR_BAR} or {@link VanillaHudElements#FOOD_BAR FOOD_BAR}), it may be
+ * necessary to register a new {@link StatusBarHeightProvider} in {@link HudStatusBarHeightRegistry}.
+ *
+ * @param identifier the identifier of the element to replace
+ * @param replacer a function that takes the old element and returns the new element
+ */
+ static void replaceElement(class_2960 identifier, Function The identifiers in this interface are the vanilla hud layers in the order they are drawn in.
+ * The first element is drawn first, which means it is at the bottom.
+ * All vanilla layers except {@link #SLEEP} are in sub drawers and have a render condition attached ({@link net.minecraft.class_315#field_1842}).
+ * Operations relative to any element will generally inherit that element's render condition.
+ * There is currently no mechanism to change the render condition of an element.
+ *
+ * For common use cases and more details on how this API deals with render condition, see {@link HudElementRegistry}.
+ */
+public final class VanillaHudElements {
+ /**
+ * The identifier for the vanilla miscellaneous overlays (such as vignette, spyglass, and powder snow) element.
+ */
+ public static final class_2960 MISC_OVERLAYS = class_2960.method_60656("misc_overlays");
+ /**
+ * The identifier for the vanilla crosshair element.
+ */
+ public static final class_2960 CROSSHAIR = class_2960.method_60656("crosshair");
+ /**
+ * The identifier for the vanilla spectator menu.
+ */
+ public static final class_2960 SPECTATOR_MENU = class_2960.method_60656("spectator_menu");
+ /**
+ * The identifier for the vanilla hotbar.
+ */
+ public static final class_2960 HOTBAR = class_2960.method_60656("hotbar");
+ /**
+ * The identifier for the player armor level bar.
+ */
+ public static final class_2960 ARMOR_BAR = class_2960.method_60656("armor_bar");
+ /**
+ * The identifier for the player health bar.
+ */
+ public static final class_2960 HEALTH_BAR = class_2960.method_60656("health_bar");
+ /**
+ * The identifier for the player hunger level bar.
+ */
+ public static final class_2960 FOOD_BAR = class_2960.method_60656("food_bar");
+ /**
+ * The identifier for the player air level bar.
+ */
+ public static final class_2960 AIR_BAR = class_2960.method_60656("air_bar");
+ /**
+ * The identifier for the vanilla mount health.
+ */
+ public static final class_2960 MOUNT_HEALTH = class_2960.method_60656("mount_health");
+ /**
+ * The identifier for the info bar, either empty, experience bar, locator, or jump bar.
+ */
+ public static final class_2960 INFO_BAR = class_2960.method_60656("info_bar");
+ /**
+ * The identifier for experience level tooltip.
+ */
+ public static final class_2960 EXPERIENCE_LEVEL = class_2960.method_60656("experience_level");
+ /**
+ * The identifier for held item tooltip.
+ */
+ public static final class_2960 HELD_ITEM_TOOLTIP = class_2960.method_60656("held_item_tooltip");
+ /**
+ * The identifier for the vanilla spectator tooltip.
+ */
+ public static final class_2960 SPECTATOR_TOOLTIP = class_2960.method_60656("spectator_tooltip");
+ /**
+ * The identifier for the vanilla status effects element.
+ */
+ public static final class_2960 STATUS_EFFECTS = class_2960.method_60656("status_effects");
+ /**
+ * The identifier for the vanilla boss bar element.
+ */
+ public static final class_2960 BOSS_BAR = class_2960.method_60656("boss_bar");
+ /**
+ * The identifier for the vanilla sleep overlay element.
+ */
+ public static final class_2960 SLEEP = class_2960.method_60656("sleep");
+ /**
+ * The identifier for the vanilla demo timer element.
+ */
+ public static final class_2960 DEMO_TIMER = class_2960.method_60656("demo_timer");
+ /**
+ * The identifier for the vanilla debug hud element.
+ */
+ public static final class_2960 DEBUG = class_2960.method_60656("debug");
+ /**
+ * The identifier for the vanilla scoreboard element.
+ */
+ public static final class_2960 SCOREBOARD = class_2960.method_60656("scoreboard");
+ /**
+ * The identifier for the vanilla overlay message element.
+ */
+ public static final class_2960 OVERLAY_MESSAGE = class_2960.method_60656("overlay_message");
+ /**
+ * The identifier for the vanilla title and subtitle element.
+ *
+ * Note that this is not the sound subtitles.
+ */
+ public static final class_2960 TITLE_AND_SUBTITLE = class_2960.method_60656("title_and_subtitle");
+ /**
+ * The identifier for the vanilla chat element.
+ */
+ public static final class_2960 CHAT = class_2960.method_60656("chat");
+ /**
+ * The identifier for the vanilla player list element.
+ */
+ public static final class_2960 PLAYER_LIST = class_2960.method_60656("player_list");
+ /**
+ * The identifier for the vanilla sound subtitles element.
+ */
+ public static final class_2960 SUBTITLES = class_2960.method_60656("subtitles");
+
+ private VanillaHudElements() {
+ }
+}
diff --git a/src/client/java/dev/dekin/iconsenhanced/client/BorderRenderer.java b/src/client/java/dev/dekin/iconsenhanced/client/BorderRenderer.java
index d725321..de6f5c4 100644
--- a/src/client/java/dev/dekin/iconsenhanced/client/BorderRenderer.java
+++ b/src/client/java/dev/dekin/iconsenhanced/client/BorderRenderer.java
@@ -58,6 +58,46 @@ public final class BorderRenderer {
}
}
+ public static void renderHud(GuiGraphics graphics) {
+ IconsEnhancedConfig config = ConfigManager.get();
+ if (!config.borders.enabled) {
+ return;
+ }
+ Minecraft client = Minecraft.getInstance();
+ if (client.player == null || client.level == null || client.options.hideGui) {
+ return;
+ }
+ if (client.screen != null) {
+ return;
+ }
+
+ int thickness = clamp(config.borders.thickness, 1, 3);
+ boolean redrawItems = config.tooltips.enabled && config.tooltips.showIcons;
+ Font font = redrawItems ? client.font : null;
+ int width = client.getWindow().getGuiScaledWidth();
+ int height = client.getWindow().getGuiScaledHeight();
+ int left = (width / 2) - 91;
+ int top = height - 22;
+
+ for (int i = 0; i < 9; i++) {
+ ItemStack stack = client.player.getInventory().getItem(i);
+ if (stack.isEmpty()) {
+ continue;
+ }
+ int slotX = left + (i * 20) + 3;
+ int slotY = top + 3;
+ int color = COLOR_LOGIC.resolve(stack);
+ if ((color >>> 24) == 0) {
+ continue;
+ }
+ drawBorder(graphics, slotX, slotY, thickness, color);
+ if (redrawItems) {
+ graphics.renderItem(stack, slotX, slotY);
+ graphics.renderItemDecorations(font, stack, slotX, slotY);
+ }
+ }
+ }
+
private static void drawBorder(GuiGraphics graphics, int x, int y, int thickness, int color) {
int left = x;
int top = y;
diff --git a/src/client/java/dev/dekin/iconsenhanced/client/ClientInit.java b/src/client/java/dev/dekin/iconsenhanced/client/ClientInit.java
index b3e7b7c..d06bfcd 100644
--- a/src/client/java/dev/dekin/iconsenhanced/client/ClientInit.java
+++ b/src/client/java/dev/dekin/iconsenhanced/client/ClientInit.java
@@ -1,9 +1,22 @@
package dev.dekin.iconsenhanced.client;
+import dev.dekin.iconsenhanced.IconsEnhanced;
import dev.dekin.iconsenhanced.common.ConfigManager;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
+//? if >=1.20.5 {
+import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElementRegistry;
+import net.fabricmc.fabric.api.client.rendering.v1.hud.VanillaHudElements;
+//?} else {
+/*import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback;
+import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer;
+*///?}
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
+//? if >=1.21.11 {
+import net.minecraft.resources.Identifier;
+//?} else {
+/*import net.minecraft.resources.ResourceLocation;
+*///?}
public final class ClientInit implements ClientModInitializer {
@Override
@@ -12,6 +25,7 @@ public final class ClientInit implements ClientModInitializer {
BorderRenderer.applyConfig();
TooltipAugmenter.register();
ClientTickEvents.END_CLIENT_TICK.register(client -> TooltipAugmenter.registerLate());
+ registerHudBorders();
ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
ScreenEvents.beforeRender(screen).register((current, graphics, mouseX, mouseY, delta) -> {
@@ -24,4 +38,20 @@ public final class ClientInit implements ClientModInitializer {
});
});
}
+
+ private static void registerHudBorders() {
+ //? if >=1.21.11 {
+ Identifier id = Identifier.fromNamespaceAndPath(IconsEnhanced.MOD_ID, "hotbar_borders");
+ //?} else if >=1.21 {
+ /*ResourceLocation id = ResourceLocation.fromNamespaceAndPath(IconsEnhanced.MOD_ID, "hotbar_borders");
+ *///?} else {
+ /*ResourceLocation id = new ResourceLocation(IconsEnhanced.MOD_ID, "hotbar_borders");
+ *///?}
+ //? if >=1.20.5 {
+ HudElementRegistry.attachElementAfter(VanillaHudElements.HOTBAR, id, (graphics, tickCounter) -> BorderRenderer.renderHud(graphics));
+ //?} else {
+ /*HudLayerRegistrationCallback.EVENT.register(layeredDrawer ->
+ layeredDrawer.attachLayerAfter(IdentifiedLayer.HOTBAR_AND_BARS, id, (graphics, tickCounter) -> BorderRenderer.renderHud(graphics)));
+ *///?}
+ }
}
+ *
+ *
+ * @see HudLayerRegistrationCallback
+ */
+public interface LayeredDrawerWrapper {
+ /**
+ * Adds a layer to the end of the layered drawer.
+ *
+ * @param layer the layer to add
+ * @return this layered drawer
+ */
+ @Contract("_ -> this")
+ LayeredDrawerWrapper addLayer(IdentifiedLayer layer);
+
+ /**
+ * Attaches a layer before the layer with the specified identifier.
+ *
+ *
+ *
+ * Injection Point
+ * Use Case
+ *
+ *
+ * Before {@link IdentifiedLayer#MISC_OVERLAYS MISC_OVERLAYS}
+ * Render before everything
+ *
+ *
+ * After {@link IdentifiedLayer#MISC_OVERLAYS MISC_OVERLAYS}
+ * Render after misc overlays (vignette, spyglass, and powder snow) and before the crosshair
+ *
+ *
+ * After {@link IdentifiedLayer#EXPERIENCE_LEVEL EXPERIENCE_LEVEL}
+ * Render after most main hud elements like hotbar, spectator hud, status bars, experience bar, status effects overlays, and boss bar and before the sleep overlay
+ *
+ *
+ * Before {@link IdentifiedLayer#DEMO_TIMER DEMO_TIMER}
+ * Render after sleep overlay and before the demo timer, debug HUD, scoreboard, overlay message (action bar), and title and subtitle
+ *
+ *
+ * Before {@link IdentifiedLayer#CHAT CHAT}
+ * Render after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle and before {@link net.minecraft.class_338 ChatHud}, player list, and sound subtitles
+ *
+ *
+ * After {@link IdentifiedLayer#SUBTITLES SUBTITLES}
+ * Render after everything
+ *
+ *
+ */
+public interface HudElementRegistry {
+ /**
+ * Adds an element to the front.
+ *
+ * @param element the element to add
+ */
+ static void addFirst(class_2960 id, HudElement element) {
+ Objects.requireNonNull(id, "identifier");
+ Objects.requireNonNull(element, "hudElement");
+ HudElementRegistryImpl.addFirst(id, element);
+ }
+
+ /**
+ * Adds an element to the end.
+ *
+ * @param element the element to add
+ */
+ static void addLast(class_2960 id, HudElement element) {
+ Objects.requireNonNull(id, "identifier");
+ Objects.requireNonNull(element, "hudElement");
+ HudElementRegistryImpl.addLast(id, element);
+ }
+
+ /**
+ * Attaches an element before the element with the specified identifier.
+ *
+ *
+ *
+ * Injection Point
+ * Use Case
+ *
+ *
+ * Before {@link VanillaHudElements#MISC_OVERLAYS MISC_OVERLAYS}
+ * Render before everything
+ *
+ *
+ * After {@link VanillaHudElements#MISC_OVERLAYS MISC_OVERLAYS}
+ * Render after misc overlays (vignette, spyglass, and powder snow) and before the crosshair
+ *
+ *
+ * After {@link VanillaHudElements#BOSS_BAR BOSS_BAR}
+ * Render after most main hud layers like hotbar, spectator hud, status bars, experience bar, status effects overlays, and boss bar and before the sleep overlay
+ *
+ *
+ * Before {@link VanillaHudElements#DEMO_TIMER DEMO_TIMER}
+ * Render after sleep overlay and before the demo timer, debug HUD, scoreboard, overlay message (action bar), and title and subtitle
+ *
+ *
+ * Before {@link VanillaHudElements#CHAT CHAT}
+ * Render after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle and before {@link net.minecraft.class_338 ChatHud}, player list, and sound subtitles
+ *
+ *
+ * After {@link VanillaHudElements#SUBTITLES SUBTITLES}
+ * Render after everything
+ *