From 25fc2880397167719d15bd7469a97efaf46c365e Mon Sep 17 00:00:00 2001
From: Pyrofab <pyrofab@ladysnake.org>
Date: Sun, 16 Jun 2024 13:37:38 +0200
Subject: [PATCH] Update to 1.20.4

---
 build.gradle                                  |  7 ++-
 changelog.md                                  |  5 ++
 gradle.properties                             | 19 ++++---
 .../org/ladysnake/locki/impl/LockiClient.java |  4 +-
 .../impl/mixin/InputSlotFillerMixin.java      |  2 +-
 .../impl/mixin/client/InGameHudMixin.java     | 49 +++++++++----------
 .../mixin/client/InventoryScreenMixin.java    |  4 +-
 .../mixin/client/RecipeBookWidgetMixin.java   |  2 +-
 .../lockii/tests/LockiTestSuite.java          |  8 +--
 9 files changed, 51 insertions(+), 49 deletions(-)

diff --git a/build.gradle b/build.gradle
index 9dce2fd..1ca987c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,7 +2,7 @@ import net.fabricmc.loom.task.RemapJarTask
 
 plugins {
 	id 'org.quiltmc.loom' version '1.6.+'
-	id 'io.github.ladysnake.chenille' version '0.13.0'
+	id 'io.github.ladysnake.chenille' version '0.13.1'
 	id 'maven-publish'
 }
 
@@ -52,8 +52,7 @@ dependencies {
 	mappings "org.quiltmc:quilt-mappings:${minecraft_version}+build.${quilt_mappings}:intermediary-v2"
 	modImplementation "org.quiltmc:quilt-loader:${project.loader_version}"
 
-	modImplementation "org.quiltmc:qsl:${qsl_version}+${minecraft_version}"
-	modImplementation "org.quiltmc.quilted-fabric-api:quilted-fabric-api:${quilted_fabric_api_version}-${minecraft_version}"
+	modImplementation "org.quiltmc.quilted-fabric-api:quilted-fabric-api:${quilted_fabric_api_version}"
 
 	modIncludeImplementation ("dev.onyxstudios.cardinal-components-api:cardinal-components-base:${cca_version}") { transitive = false }
 	modIncludeImplementation ("dev.onyxstudios.cardinal-components-api:cardinal-components-entity:${cca_version}") { transitive = false }
@@ -65,7 +64,7 @@ dependencies {
 	modLocalRuntime ("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") { transitive = false }
 
 	modLocalRuntime ("com.terraformersmc:modmenu:${modmenu_version}") { transitive = false }
-	modLocalImplementation("io.github.ladysnake:elmendorf:${elmendorf_version}") { transitive = false }
+	modLocalImplementation("org.ladysnake:elmendorf:${elmendorf_version}") { transitive = false }
 
 	testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
 	testImplementation project(":junit-loader")
diff --git a/changelog.md b/changelog.md
index d33e26e..377e90d 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,8 @@
+------------------------------------------------------
+Version 0.12.0
+------------------------------------------------------
+Updated to 1.20.4
+
 ------------------------------------------------------
 Version 0.11.1
 ------------------------------------------------------
diff --git a/gradle.properties b/gradle.properties
index dadfa70..2dee7cd 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,25 +3,24 @@ org.gradle.jvmargs=-Xmx3G
 
 # Fabric Properties
 	# check these on https://fabricmc.net/use
-	minecraft_version = 1.20.1
-	quilt_mappings = 23
-	loader_version=0.23.0-beta.1
+	minecraft_version = 1.20.4
+	quilt_mappings = 3
+	loader_version=0.26.0
 
 # Mod Properties
-	mod_version = 0.11.1
+	mod_version = 0.12.0
 	maven_group = org.ladysnake
 	archives_base_name = locki
 
 # Dependencies
-	qsl_version = 6.1.2
-	quilted_fabric_api_version = 7.4.0+0.90.0
-	cca_version = 5.2.2
+	quilted_fabric_api_version = 9.0.0-alpha.8+0.97.0-1.20.4
+	cca_version = 5.4.0
 	fpa_version=0.2-SNAPSHOT
     # V1.2.12
 	backslot_version=4178145
 	cloth_config_version=11.1.118
-	modmenu_version=7.2.2
-	elmendorf_version=0.11.0
+	modmenu_version=9.2.0-beta.2
+	elmendorf_version=0.12.0
 # Publishing
 	owners = Ladysnake
 	display_name = Locki
@@ -29,7 +28,7 @@ org.gradle.jvmargs=-Xmx3G
 	gpl_version = 3
 	curseforge_id = 483059
 	modrinth_id = qS8U15sj
-	curseforge_versions = 1.20.1
+	curseforge_versions = 1.20.4
 	cf_requirements = qsl
 	cf_embeddeds = cardinal-components-api
 	release_type = beta
diff --git a/src/main/java/org/ladysnake/locki/impl/LockiClient.java b/src/main/java/org/ladysnake/locki/impl/LockiClient.java
index 312ea5e..52a25f1 100644
--- a/src/main/java/org/ladysnake/locki/impl/LockiClient.java
+++ b/src/main/java/org/ladysnake/locki/impl/LockiClient.java
@@ -19,8 +19,8 @@
 
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.ingame.InventoryScreen;
-import net.minecraft.client.gui.screen.recipe.book.RecipeBookProvider;
-import net.minecraft.client.gui.screen.recipe.book.RecipeBookWidget;
+import net.minecraft.client.gui.screen.recipe_book.RecipeBookProvider;
+import net.minecraft.client.gui.widget.recipe_book.RecipeBookWidget;
 import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.util.Identifier;
 import org.ladysnake.locki.DefaultInventoryNodes;
diff --git a/src/main/java/org/ladysnake/locki/impl/mixin/InputSlotFillerMixin.java b/src/main/java/org/ladysnake/locki/impl/mixin/InputSlotFillerMixin.java
index 9b000b8..243dceb 100644
--- a/src/main/java/org/ladysnake/locki/impl/mixin/InputSlotFillerMixin.java
+++ b/src/main/java/org/ladysnake/locki/impl/mixin/InputSlotFillerMixin.java
@@ -35,7 +35,7 @@
 public abstract class InputSlotFillerMixin {
     @Shadow protected AbstractRecipeScreenHandler<?> handler;
 
-    @WrapOperation(method = "fillInputSlots(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/recipe/Recipe;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/recipe/RecipeMatcher;match(Lnet/minecraft/recipe/Recipe;Lit/unimi/dsi/fastutil/ints/IntList;)Z"))
+    @WrapOperation(method = "fillInputSlots(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/recipe/RecipeHolder;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/recipe/RecipeMatcher;match(Lnet/minecraft/recipe/Recipe;Lit/unimi/dsi/fastutil/ints/IntList;)Z"))
     private boolean blockInventoryCrafting(RecipeMatcher instance, Recipe<?> recipe, IntList output, Operation<Boolean> original, ServerPlayerEntity entity) {
         if (this.handler == entity.playerScreenHandler && InventoryKeeper.get(entity).isLocked(DefaultInventoryNodes.CRAFTING_GRID)) {
             return false;
diff --git a/src/main/java/org/ladysnake/locki/impl/mixin/client/InGameHudMixin.java b/src/main/java/org/ladysnake/locki/impl/mixin/client/InGameHudMixin.java
index 0a64304..13a549f 100644
--- a/src/main/java/org/ladysnake/locki/impl/mixin/client/InGameHudMixin.java
+++ b/src/main/java/org/ladysnake/locki/impl/mixin/client/InGameHudMixin.java
@@ -17,10 +17,13 @@
  */
 package org.ladysnake.locki.impl.mixin.client;
 
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
 import net.minecraft.client.gui.GuiGraphics;
-import net.minecraft.client.gui.hud.InGameHud;
+import net.minecraft.client.gui.hud.in_game.InGameHud;
 import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.item.ItemStack;
+import net.minecraft.util.Identifier;
 import org.ladysnake.locki.DefaultInventoryNodes;
 import org.ladysnake.locki.InventoryKeeper;
 import org.ladysnake.locki.impl.PlayerInventoryKeeper;
@@ -38,7 +41,9 @@
 @Mixin(value = InGameHud.class, priority = 995)
 public abstract class InGameHudMixin {
     @Unique
-    private static final int X_CENTER_SHIFT = 77;
+    private static final int LOCKI$X_CENTER_SHIFT = 77;
+    @Unique
+    private static final int LOCKI$SINGLE_SLOT_WIDTH = 21;
 
     @Unique
     private boolean cancelNextItem;
@@ -50,7 +55,8 @@ public abstract class InGameHudMixin {
 
     @Inject(
         method = "renderHotbar",
-        at = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/hud/InGameHud;WIDGETS_TEXTURE:Lnet/minecraft/util/Identifier;"),
+        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;push()V"),
+        allow = 1,
         cancellable = true
     )
     private void checkInventoryLimit(float tickDelta, GuiGraphics graphics, CallbackInfo ci) {
@@ -71,42 +77,33 @@ private ItemStack lockOffHand(ItemStack base) {
         return base;
     }
 
-    @ModifyArg(
+    @WrapOperation(
         method = "renderHotbar",
-        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawTexture(Lnet/minecraft/util/Identifier;IIIIII)V", ordinal = 0),
-        index = 1
+        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V", ordinal = 0)
     )
-    private int centerCroppedHotbar(int x) {
+    private void centerCroppedHotbar(GuiGraphics instance, Identifier texture, int x, int y, int width, int height, Operation<Void> original) {
         if (this.renderMainHandOnly) {
-            return x + X_CENTER_SHIFT;
+            int centeredX = x + LOCKI$X_CENTER_SHIFT;
+            instance.enableScissor(centeredX, y, centeredX + LOCKI$SINGLE_SLOT_WIDTH, y + height);
+            instance.drawGuiTexture(texture, centeredX, y, width, height);
+            instance.disableScissor();
+        } else {
+            original.call(instance, texture, x, y, width, height);
         }
-        return x;
     }
 
     @ModifyArg(
         method = "renderHotbar",
-        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawTexture(Lnet/minecraft/util/Identifier;IIIIII)V", ordinal = 1),
+        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V", ordinal = 1),
         index = 1
     )
     private int centerSelectedSlot(int x) {
         if (this.renderMainHandOnly) {
-            return x + X_CENTER_SHIFT;
+            return x + LOCKI$X_CENTER_SHIFT;
         }
         return x;
     }
 
-    @ModifyArg(
-        method = "renderHotbar",
-        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawTexture(Lnet/minecraft/util/Identifier;IIIIII)V", ordinal = 0),
-        index = 5
-    )
-    private int cropHotbar_width(int width) {
-        if (this.renderMainHandOnly) {
-            return 21;
-        }
-        return width;
-    }
-
     @ModifyArg(
         method = "renderHotbar",
         slice = @Slice(
@@ -126,7 +123,7 @@ private int cancelLockedItemRender(int index) {
             from = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V"),
             to = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isEmpty()Z", ordinal = 1)
         ),
-        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/GuiGraphics;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V")
+        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/in_game/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/GuiGraphics;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V")
     )
     private ItemStack cancelLockedItemRender(ItemStack stack) {
         if (this.cancelNextItem) {
@@ -141,12 +138,12 @@ private ItemStack cancelLockedItemRender(ItemStack stack) {
             from = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V"),
             to = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isEmpty()Z", ordinal = 1)
         ),
-        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/GuiGraphics;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V"),
+        at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/in_game/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/GuiGraphics;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V"),
         index = 1
     )
     private int shiftMainHandItem(int x) {
         if (this.renderMainHandOnly && !this.cancelNextItem) {
-            return x + X_CENTER_SHIFT;
+            return x + LOCKI$X_CENTER_SHIFT;
         }
         return x;
     }
diff --git a/src/main/java/org/ladysnake/locki/impl/mixin/client/InventoryScreenMixin.java b/src/main/java/org/ladysnake/locki/impl/mixin/client/InventoryScreenMixin.java
index 202cfa4..f48c288 100644
--- a/src/main/java/org/ladysnake/locki/impl/mixin/client/InventoryScreenMixin.java
+++ b/src/main/java/org/ladysnake/locki/impl/mixin/client/InventoryScreenMixin.java
@@ -28,11 +28,13 @@
 import org.ladysnake.locki.InventoryKeeper;
 import org.ladysnake.locki.impl.InventoryScreenAccessor;
 import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
 import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.ModifyArg;
 
 @Mixin(InventoryScreen.class)
 public abstract class InventoryScreenMixin extends AbstractInventoryScreen<PlayerScreenHandler> implements InventoryScreenAccessor {
+    @Unique
     private ClickableWidget locki$craftingBookButton;
 
     public InventoryScreenMixin(PlayerScreenHandler screenHandler, PlayerInventory playerInventory, Text text) {
@@ -44,7 +46,7 @@ public InventoryScreenMixin(PlayerScreenHandler screenHandler, PlayerInventory p
         return this.locki$craftingBookButton;
     }
 
-    @ModifyArg(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/InventoryScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;"), allow = 1)
+    @ModifyArg(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/InventoryScreen;addDrawableSelectableElement(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;"), allow = 1)
     private Element captureCraftingBookButton(Element button) {
         this.locki$craftingBookButton = (ClickableWidget) button;
 
diff --git a/src/main/java/org/ladysnake/locki/impl/mixin/client/RecipeBookWidgetMixin.java b/src/main/java/org/ladysnake/locki/impl/mixin/client/RecipeBookWidgetMixin.java
index f5dc65a..4830da9 100644
--- a/src/main/java/org/ladysnake/locki/impl/mixin/client/RecipeBookWidgetMixin.java
+++ b/src/main/java/org/ladysnake/locki/impl/mixin/client/RecipeBookWidgetMixin.java
@@ -19,7 +19,7 @@
 
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.ingame.InventoryScreen;
-import net.minecraft.client.gui.screen.recipe.book.RecipeBookWidget;
+import net.minecraft.client.gui.widget.recipe_book.RecipeBookWidget;
 import org.ladysnake.locki.DefaultInventoryNodes;
 import org.ladysnake.locki.InventoryKeeper;
 import org.spongepowered.asm.mixin.Mixin;
diff --git a/src/testmod/java/org/ladysnake/lockii/tests/LockiTestSuite.java b/src/testmod/java/org/ladysnake/lockii/tests/LockiTestSuite.java
index 2d43bc8..f51b91f 100644
--- a/src/testmod/java/org/ladysnake/lockii/tests/LockiTestSuite.java
+++ b/src/testmod/java/org/ladysnake/lockii/tests/LockiTestSuite.java
@@ -17,7 +17,6 @@
  */
 package org.ladysnake.lockii.tests;
 
-import io.github.ladysnake.elmendorf.GameTestUtil;
 import me.lucko.fabric.api.permissions.v0.Permissions;
 import net.minecraft.entity.EntityType;
 import net.minecraft.entity.EquipmentSlot;
@@ -27,6 +26,7 @@
 import net.minecraft.test.GameTest;
 import net.minecraft.test.TestContext;
 import net.minecraft.util.Identifier;
+import org.ladysnake.elmendorf.GameTestUtil;
 import org.ladysnake.locki.DefaultInventoryNodes;
 import org.ladysnake.locki.InventoryLock;
 import org.ladysnake.locki.InventoryNode;
@@ -36,7 +36,7 @@
 import org.quiltmc.qsl.testing.api.game.QuiltGameTest;
 import org.quiltmc.qsl.testing.api.game.QuiltTestContext;
 
-import static io.github.ladysnake.elmendorf.ByteBufChecker.any;
+import static org.ladysnake.elmendorf.ByteBufChecker.any;
 
 public class LockiTestSuite implements QuiltGameTest {
     public static final InventoryLock lock = Locki.registerLock(Lockii.id("test_suite"));
@@ -74,7 +74,7 @@ public void checkPermission(TestContext ctx) {
     public void lockingPreventsItemPickup(QuiltTestContext ctx) {
         ServerPlayerEntity player = ctx.spawnServerPlayer(1, 0, 1);
         player.getInventory().addLock(lock, DefaultInventoryNodes.INVENTORY);
-        ctx.spawnItemEntity(Items.DIAMOND, 1, 0, 2);
+        ctx.spawnItemEntity(Items.DIAMOND, 1, 1, 2);
         ctx.expectEntity(EntityType.ITEM);
         player.playerTick();
         ctx.expectEntity(EntityType.ITEM);
@@ -103,7 +103,7 @@ public void lockingPreventsDropFromMainHand(QuiltTestContext ctx) {
     @GameTest(structureName = EMPTY_STRUCTURE)
     public void itemPickupWorks(QuiltTestContext ctx) {
         ServerPlayerEntity player = ctx.spawnServerPlayer(1, 0, 1);
-        ctx.spawnItemEntity(Items.REDSTONE, 1, 0, 1);
+        ctx.spawnItemEntity(Items.REDSTONE, 1, 1, 1);
         ctx.expectEntity(EntityType.ITEM);
         player.playerTick();
         ctx.expectNoEntity(EntityType.ITEM);