mirror of
https://github.com/FabricMC/fabric
synced 2026-08-19 06:26:07 -04:00
25w15a
This commit is contained in:
parent
f5df0b8b1d
commit
9ec45cd8da
75 changed files with 132 additions and 1409 deletions
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-command-api-v2": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-command-api-v2": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-key-binding-api-v1": "*"
|
||||
},
|
||||
"description": "Keybinding registry API.",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Contains the essentials for Fabric API modules.",
|
||||
"custom": {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-lifecycle-events-v1": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"entrypoints": {
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Hooks for block views",
|
||||
"mixins": [
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"minecraft": ">=1.15-alpha.19.38.b",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"minecraft": ">1.19-alpha.22.11.a"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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": "*"
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
]
|
||||
},
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"minecraft": ">=1.20.5-beta.1",
|
||||
"fabric-lifecycle-events-v1": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Adds Fabric-related debug info to crash reports.",
|
||||
"mixins": [
|
||||
|
|
|
|||
|
|
@ -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": "*"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-tag-api-v1": "*"
|
||||
},
|
||||
"description": "Allows for automatic data generation.",
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"minecraft": ">=1.16-rc.3",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Events to hook into entities.",
|
||||
"mixins": [
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Allows registration of custom game rules.",
|
||||
"mixins": [
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
]
|
||||
},
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
"description": "Allows registration of custom game tests.",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
}
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Hooks for items",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Key Binding registry API.",
|
||||
"mixins": [
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
}
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Events for the game's lifecycle.",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Adds message-related hooks.",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-renderer-api-v1": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Hooks for registering custom particles.",
|
||||
"mixins": [
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
],
|
||||
"accessWidener": "fabric-recipe-api-v1.accesswidener",
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-networking-api-v1": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-networking-api-v1": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"minecraft": ">=1.21.5-beta.1",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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": "*"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Hooks for registering fluid renders.",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,8 +14,6 @@
|
|||
"EntityModelsMixin",
|
||||
"EntityRenderersMixin",
|
||||
"InGameHudMixin",
|
||||
"LayeredDrawerAccessor",
|
||||
"LayeredDrawerMixin",
|
||||
"LivingEntityRendererAccessor",
|
||||
"SpecialModelTypesMixin",
|
||||
"TooltipComponentMixin",
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Allows conditionally loading resources.",
|
||||
"entrypoints": {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10"
|
||||
"fabricloader": ">=0.16.13"
|
||||
},
|
||||
"description": "Asset and data resource loading.",
|
||||
"mixins": [
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Adds screen related hooks.",
|
||||
|
|
|
|||
|
|
@ -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) -> {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-networking-api-v1": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"fabricloader": ">=0.16.13",
|
||||
"fabric-api-lookup-api-v1": "*",
|
||||
"fabric-rendering-fluids-v1": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue