This commit is contained in:
modmuss50 2025-04-08 18:03:59 +01:00
parent f5df0b8b1d
commit 9ec45cd8da
75 changed files with 132 additions and 1409 deletions

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-command-api-v2": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-command-api-v2": "*"
},

View file

@ -21,7 +21,7 @@
]
},
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.18.2"
},
"description": "Contains common tags used by mods for vanilla things.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-key-binding-api-v1": "*"
},
"description": "Keybinding registry API.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-resource-loader-v0": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-block-view-api-v2": "*"
},
"description": "Thread-safe hooks for block entity data use during terrain rendering.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Contains the essentials for Fabric API modules.",
"custom": {

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-lifecycle-events-v1": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.16.2"
},
"description": "Hooks for adding biomes to the default world generator.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"entrypoints": {
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Hooks for block views",
"mixins": [

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.15-alpha.19.38.b",
"fabric-api-base": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-resource-loader-v0": "*"
},
"description": "Allows registration of client game tests.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Adds the ability to load tags from the local mods.",
"custom": {

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"minecraft": ">1.19-alpha.22.11.a"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-lifecycle-events-v1": "*",
"fabric-resource-loader-v0": "*"

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.18.2"
},
"description": "Contains common tags used by mods for vanilla things.",

View file

@ -21,7 +21,7 @@
]
},
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.20.5-beta.1",
"fabric-lifecycle-events-v1": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Adds Fabric-related debug info to crash reports.",
"mixins": [

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-entity-events-v1": "*",
"fabric-object-builder-api-v1": "*",
"fabric-networking-api-v1": "*"

View file

@ -96,6 +96,8 @@ transitive-accessible method net/minecraft/data/recipe/RecipeGenerator offerCarp
transitive-accessible method net/minecraft/data/recipe/RecipeGenerator offerBedRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/recipe/RecipeGenerator offerBannerRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/recipe/RecipeGenerator offerStainedGlassDyeingRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/recipe/RecipeGenerator method_70962 (Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/recipe/RecipeGenerator method_70963 (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/recipe/RecipeGenerator offerStainedGlassPaneRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/recipe/RecipeGenerator offerStainedGlassPaneDyeingRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/recipe/RecipeGenerator offerTerracottaDyeingRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-tag-api-v1": "*"
},
"description": "Allows for automatic data generation.",

View file

@ -15,7 +15,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.16-rc.3",
"fabric-api-base": "*"
},

View file

@ -34,10 +34,10 @@ abstract class EntityMixin {
@Shadow
private World world;
@WrapOperation(method = "teleportTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;teleportCrossDimension(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/TeleportTarget;)Lnet/minecraft/entity/Entity;"))
private Entity afterWorldChanged(Entity instance, ServerWorld targetWorld, TeleportTarget teleportTarget, Operation<Entity> original) {
@WrapOperation(method = "teleportTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;teleportCrossDimension(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/TeleportTarget;)Lnet/minecraft/entity/Entity;"))
private Entity afterWorldChanged(Entity instance, ServerWorld sourceWorld, ServerWorld targetWorld, TeleportTarget teleportTarget, Operation<Entity> original) {
// Ret will only have an entity if the teleport worked (entity not removed, teleportTarget was valid, entity was successfully created)
Entity ret = original.call(instance, targetWorld, teleportTarget);
Entity ret = original.call(instance, sourceWorld, targetWorld, teleportTarget);
if (ret != null) {
ServerEntityWorldChangeEvents.AFTER_ENTITY_CHANGE_WORLD.invoker().afterChangeWorld((Entity) (Object) this, ret, (ServerWorld) this.world, (ServerWorld) ret.getWorld());

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Events to hook into entities.",
"mixins": [

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-networking-api-v1": "*",
"minecraft": ">=1.15-alpha.19.37.a"

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Allows registration of custom game rules.",
"mixins": [

View file

@ -21,7 +21,7 @@
]
},
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-resource-loader-v0": "*"
},
"description": "Allows registration of custom game tests.",

View file

@ -23,7 +23,7 @@
}
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*"
},
"description": "Hooks for items",

View file

@ -22,10 +22,10 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.registry.Registries;
@ -66,7 +66,7 @@ public class FabricCreativeGuiComponents {
int u = active && this.isHovered() ? 20 : 0;
int v = active ? 0 : 12;
drawContext.drawTexture(RenderLayer::getGuiTextured, BUTTON_TEX, this.getX(), this.getY(), u + (type == Type.NEXT ? 10 : 0), v, 10, 12, 256, 256);
drawContext.drawTexture(RenderPipelines.GUI_TEXTURED, BUTTON_TEX, this.getX(), this.getY(), u + (type == Type.NEXT ? 10 : 0), v, 10, 12, 256, 256);
if (this.isHovered()) {
drawContext.drawTooltip(MinecraftClient.getInstance().textRenderer, Text.translatable("fabric.gui.creativeTabPage", screen.getCurrentPage() + 1, getPageCount()), mouseX, mouseY);

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-resource-loader-v0": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Key Binding registry API.",
"mixins": [

View file

@ -31,7 +31,7 @@
}
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*"
},
"description": "Events for the game's lifecycle.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-resource-loader-v0": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*"
},
"description": "Adds message-related hooks.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-renderer-api-v1": "*"
},

View file

@ -26,7 +26,7 @@
},
"accessWidener": "fabric-networking-api-v1.accesswidener",
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*"
},
"description": "Low-level, vanilla protocol oriented networking hooks.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*"
},
"description": "Builders for objects vanilla has locked down.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Hooks for registering custom particles.",
"mixins": [

View file

@ -20,7 +20,7 @@
],
"accessWidener": "fabric-recipe-api-v1.accesswidener",
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-networking-api-v1": "*"
},
"entrypoints": {

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-networking-api-v1": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.21.5-beta.1",
"fabric-api-base": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.21.5-beta.1",
"fabric-api-base": "*",
"fabric-renderer-api-v1": "*"

View file

@ -15,7 +15,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*"
},
"description": "Hooks for registering fluid renders.",

View file

@ -1,62 +0,0 @@
/*
* 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.
*
* <p>To register a layer, register a listener to this event and register your layers in the listener.
* For common use cases, see {@link LayeredDrawerWrapper}.
*
* <p>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<HudLayerRegistrationCallback> EVENT = EventFactory.createArrayBacked(HudLayerRegistrationCallback.class, callbacks -> layeredDrawer -> {
for (HudLayerRegistrationCallback callback : callbacks) {
callback.register(layeredDrawer);
}
});
/**
* Called when registering hud layers.
*
* @param layeredDrawer the layered drawer to register layers to
* @see LayeredDrawerWrapper
*/
void register(LayeredDrawerWrapper layeredDrawer);
}

View file

@ -1,114 +0,0 @@
/*
* 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.minecraft.client.gui.LayeredDrawer;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.impl.client.rendering.WrappedLayer;
/**
* A hud layer that has an identifier attached for use in {@link LayeredDrawerWrapper}.
*
* <p>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.client.option.GameOptions#hudHidden}).
* 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.
*
* <p>For common use cases and more details on how this API deals with render condition, see {@link LayeredDrawerWrapper}.
*/
public interface IdentifiedLayer extends LayeredDrawer.Layer {
/**
* The identifier for the vanilla miscellaneous overlays (such as vignette, spyglass, and powder snow) layer.
*/
Identifier MISC_OVERLAYS = Identifier.ofVanilla("misc_overlays");
/**
* The identifier for the vanilla crosshair layer.
*/
Identifier CROSSHAIR = Identifier.ofVanilla("crosshair");
/**
* The identifier for the vanilla hotbar, spectator hud, experience bar, and status bars layer.
*/
Identifier HOTBAR_AND_BARS = Identifier.ofVanilla("hotbar_and_bars");
/**
* The identifier for the vanilla experience level layer.
*/
Identifier EXPERIENCE_LEVEL = Identifier.ofVanilla("experience_level");
/**
* The identifier for the vanilla status effects layer.
*/
Identifier STATUS_EFFECTS = Identifier.ofVanilla("status_effects");
/**
* The identifier for the vanilla boss bar layer.
*/
Identifier BOSS_BAR = Identifier.ofVanilla("boss_bar");
/**
* The identifier for the vanilla sleep overlay layer.
*/
Identifier SLEEP = Identifier.ofVanilla("sleep");
/**
* The identifier for the vanilla demo timer layer.
*/
Identifier DEMO_TIMER = Identifier.ofVanilla("demo_timer");
/**
* The identifier for the vanilla debug hud layer.
*/
Identifier DEBUG = Identifier.ofVanilla("debug");
/**
* The identifier for the vanilla scoreboard layer.
*/
Identifier SCOREBOARD = Identifier.ofVanilla("scoreboard");
/**
* The identifier for the vanilla overlay message layer.
*/
Identifier OVERLAY_MESSAGE = Identifier.ofVanilla("overlay_message");
/**
* The identifier for the vanilla title and subtitle layer.
*
* <p>Note that this is not the sound subtitles.
*/
Identifier TITLE_AND_SUBTITLE = Identifier.ofVanilla("title_and_subtitle");
/**
* The identifier for the vanilla chat layer.
*/
Identifier CHAT = Identifier.ofVanilla("chat");
/**
* The identifier for the vanilla player list layer.
*/
Identifier PLAYER_LIST = Identifier.ofVanilla("player_list");
/**
* The identifier for the vanilla sound subtitles layer.
*/
Identifier SUBTITLES = Identifier.ofVanilla("subtitles");
/**
* @return the identifier of the layer
*/
Identifier 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(Identifier id, LayeredDrawer.Layer layer) {
return new WrappedLayer(id, layer);
}
}

View file

@ -1,153 +0,0 @@
/*
* 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 org.jetbrains.annotations.Contract;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.util.Identifier;
/**
* A layered drawer that has an identifier attached to each layer and methods to add layers in specific positions.
*
* <p>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.client.option.GameOptions#hudHidden}.
* 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}.
*
* <p>Common places to add layers (as of 1.21.4):
* <table>
* <tr>
* <th>Injection Point</th>
* <th>Use Case</th>
* </tr>
* <tr>
* <td>Before {@link IdentifiedLayer#MISC_OVERLAYS MISC_OVERLAYS}</td>
* <td>Render before everything</td>
* </tr>
* <tr>
* <td>After {@link IdentifiedLayer#MISC_OVERLAYS MISC_OVERLAYS}</td>
* <td>Render after misc overlays (vignette, spyglass, and powder snow) and before the crosshair</td>
* </tr>
* <tr>
* <td>After {@link IdentifiedLayer#EXPERIENCE_LEVEL EXPERIENCE_LEVEL}</td>
* <td>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</td>
* </tr>
* <tr>
* <td>Before {@link IdentifiedLayer#DEMO_TIMER DEMO_TIMER}</td>
* <td>Render after sleep overlay and before the demo timer, debug HUD, scoreboard, overlay message (action bar), and title and subtitle</td>
* </tr>
* <tr>
* <td>Before {@link IdentifiedLayer#CHAT CHAT}</td>
* <td>Render after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle and before {@link net.minecraft.client.gui.hud.ChatHud ChatHud}, player list, and sound subtitles</td>
* </tr>
* <tr>
* <td>After {@link IdentifiedLayer#SUBTITLES SUBTITLES}</td>
* <td>Render after everything</td>
* </tr>
* </table>
*
* @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.
*
* <p>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(Identifier beforeThis, IdentifiedLayer layer);
/**
* Attaches a layer before the layer with the specified identifier.
*
* <p>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(Identifier beforeThis, Identifier identifier, LayeredDrawer.Layer layer) {
return attachLayerBefore(beforeThis, IdentifiedLayer.of(identifier, layer));
}
/**
* Attaches a layer after the layer with the specified identifier.
*
* <p>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(Identifier afterThis, IdentifiedLayer layer);
/**
* Attaches a layer after the layer with the specified identifier.
*
* <p>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(Identifier afterThis, Identifier identifier, LayeredDrawer.Layer 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(Identifier identifier);
/**
* Replaces a layer with the specified identifier.
*
* <p>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(Identifier identifier, Function<IdentifiedLayer, IdentifiedLayer> replacer);
}

View file

@ -1,83 +0,0 @@
/*
* 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.impl.client.rendering;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.spongepowered.asm.mixin.injection.InjectionPoint;
import org.spongepowered.asm.mixin.injection.struct.InjectionPointData;
import org.spongepowered.asm.mixin.injection.struct.MemberInfo;
public final class LayerInjectionPoint extends InjectionPoint {
private final MemberInfo target;
public LayerInjectionPoint(InjectionPointData data) {
super(data);
this.target = (MemberInfo) data.getTarget();
}
@Override
public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) {
List<AbstractInsnNode> targetNodes = new ArrayList<>();
ListIterator<AbstractInsnNode> iterator = insns.iterator();
outer: while (iterator.hasNext()) {
AbstractInsnNode insn = iterator.next();
if (insn.getOpcode() == Opcodes.INVOKEDYNAMIC && matchesInvokeDynamic((InvokeDynamicInsnNode) insn)) {
// We have found our target InvokeDynamicInsnNode, now we need to find the next INVOKEVIRTUAL
while (iterator.hasNext()) {
insn = iterator.next();
if (insn.getOpcode() == Opcodes.INVOKEVIRTUAL) {
targetNodes.add(insn);
break outer;
}
}
}
}
nodes.addAll(targetNodes);
return !targetNodes.isEmpty();
}
private boolean matchesInvokeDynamic(InvokeDynamicInsnNode insnNode) {
for (Object bsmArg : insnNode.bsmArgs) {
if (bsmArg instanceof Handle handle && matchesHandle(handle)) {
return true;
}
}
return false;
}
private boolean matchesHandle(Handle handle) {
return handle.getOwner().equals(target.getOwner())
&& handle.getName().equals(target.getName())
&& handle.getDesc().equals(target.getDesc());
}
}

View file

@ -1,178 +0,0 @@
/*
* 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.impl.client.rendering;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Function;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.jetbrains.annotations.VisibleForTesting;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer;
import net.fabricmc.fabric.api.client.rendering.v1.LayeredDrawerWrapper;
import net.fabricmc.fabric.mixin.client.rendering.LayeredDrawerAccessor;
public final class LayeredDrawerWrapperImpl implements LayeredDrawerWrapper {
private final LayeredDrawer base;
public LayeredDrawerWrapperImpl(LayeredDrawer base) {
this.base = base;
}
private static List<LayeredDrawer.Layer> getLayers(LayeredDrawer drawer) {
return ((LayeredDrawerAccessor) drawer).getLayers();
}
@Override
public LayeredDrawerWrapper addLayer(IdentifiedLayer layer) {
validateUnique(layer);
getLayers(this.base).add(layer);
return this;
}
@Override
public LayeredDrawerWrapper attachLayerAfter(Identifier afterThis, IdentifiedLayer layer) {
validateUnique(layer);
boolean didChange = findLayer(afterThis, (l, iterator) -> {
iterator.add(layer);
return true;
});
if (!didChange) {
throw new IllegalArgumentException("Layer with identifier " + afterThis + " not found");
}
return this;
}
@Override
public LayeredDrawerWrapper attachLayerBefore(Identifier beforeThis, IdentifiedLayer layer) {
validateUnique(layer);
boolean didChange = findLayer(beforeThis, (l, iterator) -> {
iterator.previous();
iterator.add(layer);
iterator.next();
return true;
});
if (!didChange) {
throw new IllegalArgumentException("Layer with identifier " + beforeThis + " not found");
}
return this;
}
@Override
public LayeredDrawerWrapper removeLayer(Identifier identifier) {
boolean didChange = findLayer(identifier, (l, iterator) -> {
iterator.remove();
return true;
});
if (!didChange) {
throw new IllegalArgumentException("Layer with identifier " + identifier + " not found");
}
return this;
}
@Override
public LayeredDrawerWrapper replaceLayer(Identifier identifier, Function<IdentifiedLayer, IdentifiedLayer> replacer) {
boolean didChange = findLayer(identifier, (l, iterator) -> {
iterator.set(replacer.apply((IdentifiedLayer) l));
return true;
});
if (!didChange) {
throw new IllegalArgumentException("Layer with identifier " + identifier + " not found");
}
return this;
}
@VisibleForTesting
void validateUnique(IdentifiedLayer layer) {
visitLayers((l, iterator) -> {
if (matchesIdentifier(l, layer.id())) {
throw new IllegalArgumentException("Layer with identifier " + layer.id() + " already exists");
}
return false;
});
}
/**
* @return true if a layer with the given identifier was found
*/
@VisibleForTesting
boolean findLayer(Identifier identifier, LayerVisitor visitor) {
MutableBoolean found = new MutableBoolean(false);
visitLayers((l, iterator) -> {
if (matchesIdentifier(l, identifier)) {
found.setTrue();
return visitor.visit(l, iterator);
}
return false;
});
return found.booleanValue();
}
@VisibleForTesting
boolean visitLayers(LayerVisitor visitor) {
return visitLayers(getLayers(base), visitor);
}
private boolean visitLayers(List<LayeredDrawer.Layer> layers, LayerVisitor visitor) {
MutableBoolean modified = new MutableBoolean(false);
ListIterator<LayeredDrawer.Layer> iterator = layers.listIterator();
while (iterator.hasNext()) {
LayeredDrawer.Layer layer = iterator.next();
if (visitor.visit(layer, iterator)) {
modified.setTrue();
continue; // Skip visiting children if the current layer was modified
}
if (layer instanceof SubLayer subLayer) {
modified.setValue(visitLayers(getLayers(subLayer.delegate()), visitor));
}
}
return modified.booleanValue();
}
private static boolean matchesIdentifier(LayeredDrawer.Layer layer, Identifier identifier) {
return layer instanceof IdentifiedLayer il && il.id().equals(identifier);
}
@VisibleForTesting
interface LayerVisitor {
/**
* @return true if the list has been modified, false if not modified
*/
boolean visit(LayeredDrawer.Layer layer, ListIterator<LayeredDrawer.Layer> iterator);
}
}

View file

@ -1,46 +0,0 @@
/*
* 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.impl.client.rendering;
import java.util.function.BooleanSupplier;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.client.render.RenderTickCounter;
import net.fabricmc.fabric.mixin.client.rendering.LayeredDrawerAccessor;
/**
* A layer that wraps another layered drawer that can be added to {@link net.fabricmc.fabric.api.client.rendering.v1.LayeredDrawerWrapper LayeredDrawerWrapper}.
*
* <p>This wraps the vanilla sub drawers, so we can retrieve sub layers as needed in the layered drawer wrapper.
*
* @param delegate the layered drawer to wrap
* @param shouldRender a boolean supplier that determines if the layer should render
*/
public record SubLayer(LayeredDrawer delegate, BooleanSupplier shouldRender, LayeredDrawerAccessor layeredDrawerAccessor) implements LayeredDrawer.Layer {
public SubLayer(LayeredDrawer delegate, BooleanSupplier shouldRender) {
this(delegate, shouldRender, (LayeredDrawerAccessor) delegate);
}
@Override
public void render(DrawContext context, RenderTickCounter tickCounter) {
if (shouldRender.getAsBoolean()) {
layeredDrawerAccessor.invokeRenderInternal(context, tickCounter);
}
}
}

View file

@ -1,37 +0,0 @@
/*
* 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.impl.client.rendering;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer;
/**
* A simple layer that wraps a {@link LayeredDrawer.Layer} that can be added to {@link net.fabricmc.fabric.api.client.rendering.v1.LayeredDrawerWrapper LayeredDrawerWrapper}.
*
* @param id the identifier of the layer
* @param layer the layer to wrap
*/
public record WrappedLayer(Identifier id, LayeredDrawer.Layer layer) implements IdentifiedLayer {
@Override
public void render(DrawContext context, RenderTickCounter tickCounter) {
layer.render(context, tickCounter);
}
}

View file

@ -16,182 +16,21 @@
package net.fabricmc.fabric.mixin.client.rendering;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.BOSS_BAR;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.CHAT;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.CROSSHAIR;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.DEBUG;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.DEMO_TIMER;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.EXPERIENCE_LEVEL;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.HOTBAR_AND_BARS;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.MISC_OVERLAYS;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.OVERLAY_MESSAGE;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.PLAYER_LIST;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.SCOREBOARD;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.SLEEP;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.STATUS_EFFECTS;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.SUBTITLES;
import static net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer.TITLE_AND_SUBTITLE;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer;
import net.fabricmc.fabric.impl.client.rendering.LayeredDrawerWrapperImpl;
@Mixin(InGameHud.class)
public class InGameHudMixin {
@Shadow
@Final
private LayeredDrawer layeredDrawer;
@Inject(method = "render", at = @At(value = "TAIL"))
public void render(DrawContext drawContext, RenderTickCounter tickCounter, CallbackInfo callbackInfo) {
HudRenderCallback.EVENT.invoker().onHudRender(drawContext, tickCounter);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderMiscOverlays(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapMiscOverlays(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(MISC_OVERLAYS, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderCrosshair(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapCrosshair(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(CROSSHAIR, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderMainHud(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapHotbarAndBars(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(HOTBAR_AND_BARS, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderExperienceLevel(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapExperienceLevel(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(EXPERIENCE_LEVEL, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderStatusEffectOverlay(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapStatusEffects(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(STATUS_EFFECTS, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;method_55808(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapBossBar(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(BOSS_BAR, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderDemoTimer(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapDemoTimer(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(DEMO_TIMER, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;method_55807(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapDebug(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(DEBUG, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderScoreboardSidebar(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapScoreboard(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(SCOREBOARD, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderOverlayMessage(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapOverlayMessage(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(OVERLAY_MESSAGE, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderTitleAndSubtitle(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapTitleAndSubtitle(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(TITLE_AND_SUBTITLE, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderChat(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapChat(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(CHAT, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderPlayerList(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapPlayerList(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(PLAYER_LIST, instance, layer);
}
@Redirect(method = "<init>", at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;method_55806(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V")
)
private LayeredDrawer wrapSubtitlesHud(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(SUBTITLES, instance, layer);
}
@Redirect(method = "<init>",
at = @At(
value = "net.fabricmc.fabric.impl.client.rendering.LayerInjectionPoint",
target = "Lnet/minecraft/client/gui/hud/InGameHud;renderSleepOverlay(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/client/render/RenderTickCounter;)V"
)
)
private LayeredDrawer wrapSleepOverlay(LayeredDrawer instance, LayeredDrawer.Layer layer) {
return wrap(SLEEP, instance, layer);
}
@Inject(method = "<init>", at = @At("RETURN"))
private void registerLayers(CallbackInfo ci) {
HudLayerRegistrationCallback.EVENT.invoker().register(new LayeredDrawerWrapperImpl(layeredDrawer));
}
@Unique
private static LayeredDrawer wrap(Identifier identifier, LayeredDrawer instance, LayeredDrawer.Layer layer) {
return instance.addLayer(IdentifiedLayer.of(identifier, layer));
}
}

View file

@ -1,36 +0,0 @@
/*
* 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.mixin.client.rendering;
import java.util.List;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.client.render.RenderTickCounter;
@Mixin(LayeredDrawer.class)
public interface LayeredDrawerAccessor {
@Accessor
List<LayeredDrawer.Layer> getLayers();
@Invoker("renderInternal")
void invokeRenderInternal(DrawContext context, RenderTickCounter tickCounter);
}

View file

@ -1,41 +0,0 @@
/*
* 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.mixin.client.rendering;
import java.util.function.BooleanSupplier;
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.CallbackInfoReturnable;
import net.minecraft.client.gui.LayeredDrawer;
import net.fabricmc.fabric.impl.client.rendering.SubLayer;
@Mixin(LayeredDrawer.class)
public abstract class LayeredDrawerMixin {
@Shadow
public abstract LayeredDrawer addLayer(LayeredDrawer.Layer layer);
@Inject(method = "addSubDrawer", at = @At("HEAD"), cancellable = true)
private void wrapSubDrawer(LayeredDrawer drawer, BooleanSupplier shouldRender, CallbackInfoReturnable<LayeredDrawer> cir) {
addLayer(new SubLayer(drawer, shouldRender));
cir.setReturnValue((LayeredDrawer) (Object) this);
}
}

View file

@ -14,8 +14,6 @@
"EntityModelsMixin",
"EntityRenderersMixin",
"InGameHudMixin",
"LayeredDrawerAccessor",
"LayeredDrawerMixin",
"LivingEntityRendererAccessor",
"SpecialModelTypesMixin",
"TooltipComponentMixin",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*"
},
"description": "Hooks and registries for rendering-related things.",

View file

@ -1,194 +0,0 @@
/*
* 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.impl.client.rendering;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer;
public class LayeredDrawerWrapperTest {
private List<String> drawnLayers;
private LayeredDrawer base;
private LayeredDrawerWrapperImpl layers;
@BeforeEach
void setUp() {
drawnLayers = new ArrayList<>();
base = new LayeredDrawer();
layers = new LayeredDrawerWrapperImpl(base);
}
@Test
void addLayer() {
layers.addLayer(testLayer("layer1"))
.addLayer(testLayer("layer2"))
.addLayer(testLayer("layer3"));
assertOrder(base, List.of("layer1", "layer2", "layer3"));
}
@Test
void addBefore() {
layers.addLayer(testLayer("layer1"))
.addLayer(testLayer("layer2"));
layers.attachLayerBefore(testIdentifier("layer1"), testLayer("before1"));
assertOrder(base, List.of("before1", "layer1", "layer2"));
}
@Test
void addAfter() {
layers.addLayer(testLayer("layer1"))
.addLayer(testLayer("layer2"));
layers.attachLayerAfter(testIdentifier("layer1"), testLayer("after1"));
assertOrder(base, List.of("layer1", "after1", "layer2"));
}
@Test
void removeLayer() {
layers.addLayer(testLayer("layer1"))
.addLayer(testLayer("layer2"))
.addLayer(testLayer("layer3"))
.addLayer(testLayer("layer4"));
layers.removeLayer(testIdentifier("layer2"))
.removeLayer(testIdentifier("layer4"));
assertOrder(base, List.of("layer1", "layer3"));
}
@Test
void replaceLayer() {
layers.addLayer(testLayer("layer1"))
.addLayer(testLayer("layer2"))
.addLayer(testLayer("layer3"));
layers.replaceLayer(testIdentifier("layer2"), layer -> testLayer("temp"))
.replaceLayer(testIdentifier("temp"), layer -> testLayer("replaced"));
assertOrder(base, List.of("layer1", "replaced", "layer3"));
}
@Test
void validateUnique() {
layers.addLayer(testLayer("layer1"))
.addLayer(testLayer("layer2"))
.addLayer(testLayer("layer3"));
Assertions.assertDoesNotThrow(() -> layers.validateUnique(testLayer("layer4")));
Assertions.assertThrows(IllegalArgumentException.class, () -> layers.validateUnique(testLayer("layer2")));
}
@Test
void findLayer() {
layers.addLayer(testLayer("layer1"))
.addLayer(testLayer("layer2"))
.addLayer(testLayer("layer3"));
Assertions.assertTrue(layers.findLayer(testIdentifier("layer2"), (layer, iterator) -> {
iterator.add(testLayer("found"));
return true;
}));
assertOrder(base, List.of("layer1", "layer2", "found", "layer3"));
}
@Test
void visitLayers() {
layers.addLayer(testLayer("layer1"))
.addLayer(testLayer("layer2"))
.addLayer(testLayer("layer3"));
Assertions.assertTrue(layers.visitLayers((layer, iterator) -> {
String name = ((IdentifiedLayer) layer).id().getPath();
iterator.add(testLayer("visited" + name.substring(name.length() - 1)));
return true;
}));
assertOrder(base, List.of("layer1", "visited1", "layer2", "visited2", "layer3", "visited3"));
}
@Test
void replaceSubLayer() {
layers.addLayer(testLayer("layer1"));
base.addLayer(new SubLayer(
new LayeredDrawer().addLayer(testLayer("layer2"))
.addLayer(testLayer("layer3")),
() -> true
));
layers.addLayer(testLayer("layer4"));
layers.replaceLayer(testIdentifier("layer2"), layer -> testLayer("replaced"));
assertOrder(base, List.of("layer1", "replaced", "layer3", "layer4"));
}
@Test
void visitSubLayers() {
layers.addLayer(testLayer("layer1"));
base.addLayer(new SubLayer(
new LayeredDrawer().addLayer(testLayer("layer2"))
.addLayer(testLayer("layer3")),
() -> true
));
layers.addLayer(testLayer("layer4"));
// Return true when we encounter layer3, which is in a sub drawer
// Even though it's not modified. This is just for testing.
Assertions.assertTrue(layers.visitLayers((layer, iterator) -> layer instanceof IdentifiedLayer il && il.id().equals(testIdentifier("layer3"))));
assertOrder(base, List.of("layer1", "layer2", "layer3", "layer4"));
}
private IdentifiedLayer testLayer(String name) {
return IdentifiedLayer.of(testIdentifier(name), (context, tickCounter) -> drawnLayers.add(name));
}
private Identifier testIdentifier(String name) {
return Identifier.of("test", name);
}
private void assertOrder(LayeredDrawer drawer, List<String> expectedLayers) {
DrawContext drawContext = mock(DrawContext.class);
RenderTickCounter tickCounter = mock(RenderTickCounter.class);
MatrixStack matrixStack = mock(MatrixStack.class);
when(drawContext.getMatrices()).thenReturn(matrixStack);
drawnLayers.clear();
drawer.render(drawContext, tickCounter);
assertEquals(drawnLayers, expectedLayers);
}
}

View file

@ -18,13 +18,9 @@
"net.fabricmc.fabric.test.rendering.client.DimensionalRenderingTest",
"net.fabricmc.fabric.test.rendering.client.FeatureRendererTest",
"net.fabricmc.fabric.test.rendering.client.HudAndShaderTest",
"net.fabricmc.fabric.test.rendering.client.HudLayerTests",
"net.fabricmc.fabric.test.rendering.client.SpecialBlockRendererTest",
"net.fabricmc.fabric.test.rendering.client.TooltipComponentTests",
"net.fabricmc.fabric.test.rendering.client.WorldRenderEventsTests"
],
"fabric-client-gametest": [
"net.fabricmc.fabric.test.rendering.client.HudLayerTests"
]
}
}

View file

@ -1,147 +0,0 @@
/*
* 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.test.rendering.client;
import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.util.InputUtil;
import net.minecraft.text.Text;
import net.minecraft.util.Colors;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.gametest.v1.FabricClientGameTest;
import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext;
import net.fabricmc.fabric.api.client.gametest.v1.context.TestSingleplayerContext;
import net.fabricmc.fabric.api.client.gametest.v1.screenshot.TestScreenshotComparisonOptions;
import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback;
import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer;
public class HudLayerTests implements ClientModInitializer, FabricClientGameTest {
private static final String MOD_ID = "fabric";
private static final String BEFORE_MISC_OVERLAY = "test_before_misc_overlay";
private static final String AFTER_MISC_OVERLAY = "test_after_misc_overlay";
private static final String AFTER_EXPERIENCE_LEVEL = "test_after_experience_level";
private static final String BEFORE_DEMO_TIMER = "test_before_demo_timer";
private static final String BEFORE_CHAT = "test_before_chat";
private static final String AFTER_SUBTITLES = "test_after_subtitles";
private static boolean shouldRender = false;
@Override
public void onInitializeClient() {
HudLayerRegistrationCallback.EVENT.register(layeredDrawer -> layeredDrawer
.attachLayerBefore(IdentifiedLayer.MISC_OVERLAYS, Identifier.of(MOD_ID, BEFORE_MISC_OVERLAY), HudLayerTests::renderBeforeMiscOverlay)
.attachLayerAfter(IdentifiedLayer.MISC_OVERLAYS, Identifier.of(MOD_ID, AFTER_MISC_OVERLAY), HudLayerTests::renderAfterMiscOverlay)
.attachLayerAfter(IdentifiedLayer.EXPERIENCE_LEVEL, Identifier.of(MOD_ID, AFTER_EXPERIENCE_LEVEL), HudLayerTests::renderAfterExperienceLevel)
.attachLayerBefore(IdentifiedLayer.DEMO_TIMER, Identifier.of(MOD_ID, BEFORE_DEMO_TIMER), HudLayerTests::renderBeforeDemoTimer)
.attachLayerBefore(IdentifiedLayer.CHAT, Identifier.of(MOD_ID, BEFORE_CHAT), HudLayerTests::renderBeforeChat)
.attachLayerAfter(IdentifiedLayer.SUBTITLES, Identifier.of(MOD_ID, AFTER_SUBTITLES), HudLayerTests::renderAfterSubtitles)
);
}
private static void renderBeforeMiscOverlay(DrawContext context, RenderTickCounter tickCounter) {
if (!shouldRender) return;
// Render a blue rectangle at the top right of the screen, and it should be blocked by misc overlays such as vignette, spyglass, and powder snow
context.fill(context.getScaledWindowWidth() - 200, 0, context.getScaledWindowWidth(), 30, Colors.BLUE);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "1. Blue rectangle blocked by overlays", context.getScaledWindowWidth() - 196, 10, Colors.WHITE);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "such as powder snow", context.getScaledWindowWidth() - 111, 20, Colors.WHITE);
}
private static void renderAfterMiscOverlay(DrawContext context, RenderTickCounter tickCounter) {
if (!shouldRender) return;
// Render a red square in the center of the screen underneath the crosshair
context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() / 2 + 10, context.getScaledWindowHeight() / 2 + 10, Colors.RED);
context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "2. Red square underneath crosshair", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() / 2 + 10, Colors.WHITE);
}
private static void renderAfterExperienceLevel(DrawContext context, RenderTickCounter tickCounter) {
if (!shouldRender) return;
// Render a green rectangle at the bottom of the screen, and it should block the hotbar and status bars
context.fill(context.getScaledWindowWidth() / 2 - 50, context.getScaledWindowHeight() - 50, context.getScaledWindowWidth() / 2 + 50, context.getScaledWindowHeight() - 10, Colors.GREEN);
context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "3. This green rectangle should block the hotbar and status bars.", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() - 40, Colors.WHITE);
}
private static void renderBeforeDemoTimer(DrawContext context, RenderTickCounter tickCounter) {
if (!shouldRender) return;
// Render a yellow rectangle at the right of the screen, and it should be above the sleep overlay but below the scoreboard
context.fill(context.getScaledWindowWidth() - 240, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth(), context.getScaledWindowHeight() / 2 + 10, Colors.YELLOW);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "4. This yellow rectangle should be above", context.getScaledWindowWidth() - 236, context.getScaledWindowHeight() / 2 - 10, Colors.WHITE);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "the sleep overlay but below the scoreboard.", context.getScaledWindowWidth() - 236, context.getScaledWindowHeight() / 2, Colors.WHITE);
}
private static void renderBeforeChat(DrawContext context, RenderTickCounter tickCounter) {
if (!shouldRender) return;
// Render a blue rectangle at the bottom left of the screen, and it should be blocked by the chat
context.fill(0, context.getScaledWindowHeight() - 40, 300, context.getScaledWindowHeight() - 50, Colors.BLUE);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "5. This blue rectangle should be blocked by the chat.", 0, context.getScaledWindowHeight() - 50, Colors.WHITE);
}
private static void renderAfterSubtitles(DrawContext context, RenderTickCounter tickCounter) {
if (!shouldRender) return;
// Render a yellow rectangle at the top of the screen, and it should block the player list
context.fill(context.getScaledWindowWidth() / 2 - 150, 0, context.getScaledWindowWidth() / 2 + 150, 15, Colors.YELLOW);
context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "6. This yellow rectangle should block the player list.", context.getScaledWindowWidth() / 2, 0, Colors.WHITE);
}
@Override
public void runTest(ClientGameTestContext context) {
// Set up required test environment
context.getInput().resizeWindow(1708, 960); // Twice the default dimensions
context.runOnClient(client -> {
client.options.hudHidden = false;
client.options.getGuiScale().setValue(2);
});
shouldRender = true;
try (TestSingleplayerContext singleplayer = context.worldBuilder().create()) {
// Set up the test world
singleplayer.getServer().runCommand("/tp @a 0 -60 0");
singleplayer.getServer().runCommand("/scoreboard objectives add hud_layer_test dummy");
singleplayer.getServer().runCommand("/scoreboard objectives setdisplay list hud_layer_test"); // Hack to show player list
singleplayer.getServer().runCommand("/scoreboard objectives setdisplay sidebar hud_layer_test"); // Hack to show sidebar
singleplayer.getServer().runOnServer(server -> server.getOverworld().setBlockState(new BlockPos(0, -59, 0), Blocks.POWDER_SNOW.getDefaultState()));
// Wait for stuff to load
singleplayer.getClientWorld().waitForChunksRender();
singleplayer.getServer().runOnServer(server -> server.getPlayerManager().broadcast(Text.of("hud_layer_" + BEFORE_CHAT), false)); // Chat messages disappear in 200 ticks so we send one 150 ticks in advance to test the before chat layer
context.waitTicks(150); // The powder snow frosty vignette takes 140 ticks to fully appear, so we additionally wait for a total of 150 ticks
// Take and assert screenshots
context.assertScreenshotEquals(TestScreenshotComparisonOptions.of("hud_layer_" + BEFORE_MISC_OVERLAY).withRegion(1308, 0, 400, 60).save());
context.assertScreenshotEquals(TestScreenshotComparisonOptions.of("hud_layer_" + AFTER_MISC_OVERLAY).withRegion(668, 460, 372, 56).save());
context.assertScreenshotEquals(TestScreenshotComparisonOptions.of("hud_layer_" + AFTER_EXPERIENCE_LEVEL).withRegion(754, 860, 200, 80).save());
// The sleep overlay takes 100 ticks to fully appear, so we start sleeping and wait for 100 ticks
context.runOnClient(client -> client.player.setSleepingPosition(new BlockPos(0, -59, 0)));
context.waitTicks(100);
context.assertScreenshotEquals(TestScreenshotComparisonOptions.of("hud_layer_" + BEFORE_DEMO_TIMER).withRegion(1228, 460, 480, 40).save());
context.assertScreenshotEquals(TestScreenshotComparisonOptions.of("hud_layer_" + BEFORE_CHAT).withRegion(0, 860, 600, 20).save());
context.runOnClient(client -> client.player.clearSleepingPosition());
context.waitTick();
context.getInput().holdKey(InputUtil.GLFW_KEY_TAB); // Show player list
context.waitTick();
context.assertScreenshotEquals(TestScreenshotComparisonOptions.of("hud_layer_" + AFTER_SUBTITLES).withRegion(554, 0, 600, 30).save());
}
shouldRender = false;
}
}

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Allows conditionally loading resources.",
"entrypoints": {

View file

@ -184,7 +184,7 @@ public final class ModResourcePackUtil {
switch (filename) {
case "pack.mcmeta":
String description = Objects.requireNonNullElse(container.getMetadata().getId(), "");
String metadata = serializeMetadata(SharedConstants.getGameVersion().getResourceVersion(type), description);
String metadata = serializeMetadata(SharedConstants.getGameVersion().method_70592(type), description);
return IOUtils.toInputStream(metadata, Charsets.UTF_8);
case "pack.png":
Optional<Path> path = container.getMetadata().getIconPath(512).flatMap(container::findPath);

View file

@ -44,7 +44,7 @@ public record PlaceholderResourcePack(ResourceType type, ResourcePackInfo metada
public PackResourceMetadata getMetadata() {
return ModResourcePackUtil.getMetadataPack(
SharedConstants.getGameVersion().getResourceVersion(type),
SharedConstants.getGameVersion().method_70592(type),
DESCRIPTION_TEXT
);
}

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Asset and data resource loading.",
"mixins": [

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*"
},
"description": "Adds screen related hooks.",

View file

@ -21,13 +21,14 @@ import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.minecraft.class_11227;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
@ -80,7 +81,9 @@ public final class ScreenTests implements ClientModInitializer {
// Register render event to draw an icon on the screen
ScreenEvents.afterRender(screen).register((_screen, drawContext, mouseX, mouseY, tickDelta) -> {
// Render an armor icon to test
drawContext.drawGuiTexture(RenderLayer::getGuiTextured, ScreenTests.ARMOR_FULL_TEXTURE, (screen.width / 2) - 124, (screen.height / 4) + 96, 20, 20);
drawContext.method_70850(class_11227.HUD);
drawContext.drawGuiTexture(RenderPipelines.GUI_TEXTURED, ScreenTests.ARMOR_FULL_TEXTURE, (screen.width / 2) - 124, (screen.height / 4) + 96, 20, 20);
drawContext.method_70860();
});
ScreenKeyboardEvents.allowKeyPress(screen).register((_screen, key, scancode, modifiers) -> {

View file

@ -17,10 +17,10 @@
package net.fabricmc.fabric.test.screen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.widget.PressableWidget;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.text.Text;
class StopSoundButton extends PressableWidget {
@ -30,7 +30,7 @@ class StopSoundButton extends PressableWidget {
@Override
protected void renderWidget(DrawContext drawContext, int mouseX, int mouseY, float delta) {
drawContext.drawGuiTexture(RenderLayer::getGuiTextured, ScreenTests.ARMOR_FULL_TEXTURE, this.getX(), this.getY(), this.width, this.height);
drawContext.drawGuiTexture(RenderPipelines.GUI_TEXTURED, ScreenTests.ARMOR_FULL_TEXTURE, this.getX(), this.getY(), this.width, this.height);
if (this.isHovered()) {
drawContext.drawTooltip(MinecraftClient.getInstance().textRenderer, Text.literal("Click to stop all sounds"), this.getX(), this.getY());

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-networking-api-v1": "*"
},

View file

@ -20,9 +20,9 @@ import java.util.Optional;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.text.Text;
@ -66,6 +66,6 @@ public class PositionedScreen extends HandledScreen<ScreenHandler> {
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
int x = (width - backgroundWidth) / 2;
int y = (height - backgroundHeight) / 2;
drawContext.drawTexture(RenderLayer::getGuiTextured, TEXTURE, x, y, 0, 0, backgroundWidth, backgroundHeight, backgroundWidth, backgroundHeight);
drawContext.drawTexture(RenderPipelines.GUI_TEXTURED, TEXTURE, x, y, 0, 0, backgroundWidth, backgroundHeight, backgroundWidth, backgroundHeight);
}
}

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"minecraft": ">=1.19.2"
},
"description": "Hooks for modifying Minecraft's sound system.",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-base": "*",
"fabric-resource-loader-v0": "*"
},

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"fabric-api-lookup-api-v1": "*",
"fabric-rendering-fluids-v1": "*"
},

View file

@ -18,13 +18,11 @@ package net.fabricmc.fabric.test.transfer.ingame.client;
import java.util.List;
import net.minecraft.class_11227;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluids;
import net.minecraft.text.Text;
@ -56,10 +54,12 @@ public class FluidVariantRenderTest implements ClientModInitializer {
Sprite[] sprites = FluidVariantRendering.getSprites(variant);
int color = FluidVariantRendering.getColor(variant, player.getWorld(), player.getBlockPos());
drawContext.method_70850(class_11227.SCREEN_TOOLTIP);
if (sprites != null) {
drawFluidInGui(drawContext, sprites[0], color, 0, renderY);
drawContext.drawSpriteStretched(RenderPipelines.GUI_TEXTURED, sprites[0], 0, renderY, 16, 16, color);
renderY += 16;
drawFluidInGui(drawContext, sprites[1], color, 0, renderY);
drawContext.drawSpriteStretched(RenderPipelines.GUI_TEXTURED, sprites[1], 0, renderY, 16, 16, color);
renderY += 16;
}
@ -72,33 +72,9 @@ public class FluidVariantRenderTest implements ClientModInitializer {
renderY += 10;
drawContext.drawTooltip(textRenderer, line, -8, renderY);
}
drawContext.method_70860();
}
});
}
private static void drawFluidInGui(DrawContext drawContext, Sprite sprite, int color, int i, int j) {
if (sprite == null) return;
float r = ((color >> 16) & 255) / 255f;
float g = ((color >> 8) & 255) / 255f;
float b = (color & 255) / 255f;
float x0 = (float) i;
float y0 = (float) j;
float x1 = x0 + 16;
float y1 = y0 + 16;
float z = 0.5f;
float u0 = sprite.getMinU();
float v0 = sprite.getMinV();
float u1 = sprite.getMaxU();
float v1 = sprite.getMaxV();
drawContext.draw(vertexConsumerProvider -> {
VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RenderLayer.getGuiTextured(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE));
vertexConsumer.vertex(x0, y1, z).color(r, g, b, 1).texture(u0, v1);
vertexConsumer.vertex(x1, y1, z).color(r, g, b, 1).texture(u1, v1);
vertexConsumer.vertex(x1, y0, z).color(r, g, b, 1).texture(u1, v0);
vertexConsumer.vertex(x0, y0, z).color(r, g, b, 1).texture(u0, v0);
});
}
}

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10"
"fabricloader": ">=0.16.13"
},
"description": "Contains transitive access wideners that provide access to otherwise inaccessible Minecraft code.",
"accessWidener": "fabric-transitive-access-wideners-v1.accesswidener",

View file

@ -1,62 +1,62 @@
org.gradle.jvmargs=-Xmx2560M
org.gradle.parallel=true
version=0.119.9
minecraft_version=1.21.5
version=0.119.10
minecraft_version=25w15a
yarn_version=+build.1
loader_version=0.16.10
loader_version=0.16.13
installer_version=1.0.1
prerelease=false
curseforge_minecraft_version=1.21.5
prerelease=true
curseforge_minecraft_version=1.21.5-Snapshot
# Do not manually update, use the bumpversions task:
fabric-api-base-version=0.4.62
fabric-api-lookup-api-v1-version=1.6.95
fabric-biome-api-v1-version=16.0.7
fabric-block-api-v1-version=1.0.37
fabric-block-view-api-v2-version=1.0.26
fabric-blockrenderlayer-v1-version=2.0.16
fabric-client-gametest-api-v1-version=4.1.10
fabric-command-api-v1-version=1.2.70
fabric-command-api-v2-version=2.2.49
fabric-commands-v0-version=0.2.87
fabric-content-registries-v0-version=10.0.11
fabric-crash-report-info-v1-version=0.3.12
fabric-data-attachment-api-v1-version=1.6.6
fabric-data-generation-api-v1-version=22.3.3
fabric-dimensions-v1-version=4.0.16
fabric-entity-events-v1-version=2.0.25
fabric-events-interaction-v0-version=4.0.13
fabric-game-rule-api-v1-version=1.0.70
fabric-gametest-api-v1-version=3.1.2
fabric-item-api-v1-version=11.3.2
fabric-item-group-api-v1-version=4.2.8
fabric-key-binding-api-v1-version=1.0.63
fabric-keybindings-v0-version=0.2.61
fabric-lifecycle-events-v1-version=2.5.13
fabric-loot-api-v2-version=3.0.47
fabric-loot-api-v3-version=1.0.35
fabric-message-api-v1-version=6.0.33
fabric-model-loading-api-v1-version=5.0.3
fabric-networking-api-v1-version=4.4.0
fabric-object-builder-api-v1-version=21.0.0
fabric-particles-v1-version=4.0.22
fabric-recipe-api-v1-version=8.1.6
fabric-registry-sync-v0-version=6.1.20
fabric-renderer-api-v1-version=6.0.0
fabric-renderer-indigo-version=3.0.1
fabric-rendering-data-attachment-v1-version=0.3.64
fabric-rendering-fluids-v1-version=3.1.27
fabric-rendering-v1-version=11.1.11
fabric-resource-conditions-api-v1-version=5.0.21
fabric-resource-loader-v0-version=3.1.6
fabric-screen-api-v1-version=2.0.46
fabric-screen-handler-api-v1-version=1.3.127
fabric-sound-api-v1-version=1.0.38
fabric-tag-api-v1-version=1.0.16
fabric-transfer-api-v1-version=5.4.23
fabric-transitive-access-wideners-v1-version=6.3.17
fabric-convention-tags-v1-version=2.1.29
fabric-convention-tags-v2-version=2.14.3
fabric-client-tags-api-v1-version=1.1.37
fabric-api-base-version=0.4.63
fabric-api-lookup-api-v1-version=1.6.96
fabric-biome-api-v1-version=16.0.8
fabric-block-api-v1-version=1.0.38
fabric-block-view-api-v2-version=1.0.27
fabric-blockrenderlayer-v1-version=2.0.17
fabric-client-gametest-api-v1-version=4.1.11
fabric-command-api-v1-version=1.2.71
fabric-command-api-v2-version=2.2.50
fabric-commands-v0-version=0.2.88
fabric-content-registries-v0-version=10.0.12
fabric-crash-report-info-v1-version=0.3.13
fabric-data-attachment-api-v1-version=1.6.7
fabric-data-generation-api-v1-version=22.3.4
fabric-dimensions-v1-version=4.0.17
fabric-entity-events-v1-version=2.0.26
fabric-events-interaction-v0-version=4.0.14
fabric-game-rule-api-v1-version=1.0.71
fabric-gametest-api-v1-version=3.1.3
fabric-item-api-v1-version=11.3.3
fabric-item-group-api-v1-version=4.2.9
fabric-key-binding-api-v1-version=1.0.64
fabric-keybindings-v0-version=0.2.62
fabric-lifecycle-events-v1-version=2.5.14
fabric-loot-api-v2-version=3.0.48
fabric-loot-api-v3-version=1.0.36
fabric-message-api-v1-version=6.0.34
fabric-model-loading-api-v1-version=5.0.4
fabric-networking-api-v1-version=4.4.1
fabric-object-builder-api-v1-version=21.0.1
fabric-particles-v1-version=4.0.23
fabric-recipe-api-v1-version=8.1.7
fabric-registry-sync-v0-version=6.1.21
fabric-renderer-api-v1-version=6.0.1
fabric-renderer-indigo-version=3.0.2
fabric-rendering-data-attachment-v1-version=0.3.65
fabric-rendering-fluids-v1-version=3.1.28
fabric-rendering-v1-version=12.0.0
fabric-resource-conditions-api-v1-version=5.0.22
fabric-resource-loader-v0-version=3.1.7
fabric-screen-api-v1-version=2.0.47
fabric-screen-handler-api-v1-version=1.3.128
fabric-sound-api-v1-version=1.0.39
fabric-tag-api-v1-version=1.0.17
fabric-transfer-api-v1-version=5.4.24
fabric-transitive-access-wideners-v1-version=6.3.18
fabric-convention-tags-v1-version=2.1.30
fabric-convention-tags-v2-version=2.14.4
fabric-client-tags-api-v1-version=1.1.38

View file

@ -19,9 +19,9 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.16.10",
"fabricloader": ">=0.16.13",
"java": ">=21",
"minecraft": ">=1.21.5- <1.21.6-"
"minecraft": ">=1.21.6- <1.21.7-"
},
"description": "Core API module providing key hooks and intercompatibility features."
}