diff --git a/build.gradle b/build.gradle index d18e253..c37e1e9 100644 --- a/build.gradle +++ b/build.gradle @@ -21,8 +21,7 @@ repositories { dependencies { // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings loom.officialMojangMappings() - //mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" } diff --git a/src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java index 5b5fba4..d897916 100644 --- a/src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java @@ -3,7 +3,7 @@ package me.melontini.recipebookispain.client; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.RecipeBookCategories; +import net.minecraft.client.recipebook.RecipeBookGroup; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -15,7 +15,7 @@ public class RecipeBookIsPainClient implements ClientModInitializer { public static final Logger LOGGER = LogManager.getLogger("RBIP"); - public static Map ADDED_GROUPS = new HashMap<>(); + public static Map ADDED_GROUPS = new HashMap<>(); @Override public void onInitializeClient() { } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/Accessor.java b/src/main/java/me/melontini/recipebookispain/mixin/Accessor.java index fc7bac8..6b6d9fc 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/Accessor.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/Accessor.java @@ -1,14 +1,14 @@ package me.melontini.recipebookispain.mixin; -import net.minecraft.client.RecipeBookCategories; -import net.minecraft.world.item.ItemStack; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; -@Mixin(RecipeBookCategories.class) +@Mixin(RecipeBookGroup.class) public interface Accessor { @Invoker("") - static RecipeBookCategories newGroup(String internalName, int internalId, ItemStack... stacks) { + static RecipeBookGroup newGroup(String internalName, int internalId, ItemStack... stacks) { throw new AssertionError(); } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index a08cd87..51675a9 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,12 +1,12 @@ package me.melontini.recipebookispain.mixin; import me.melontini.recipebookispain.client.RecipeBookIsPainClient; -import net.minecraft.client.ClientRecipeBook; -import net.minecraft.client.RecipeBookCategories; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.client.recipebook.ClientRecipeBook; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -14,15 +14,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(value = ClientRecipeBook.class, priority = 999) public class ClientRecipeBookMixin { - @Inject(at = @At("HEAD"), method = "getCategory", cancellable = true) - private static void recipe_book_is_pain$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { + @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) + private static void recipe_book_is_pain$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { RecipeType recipeType = recipe.getType(); if (recipeType == RecipeType.CRAFTING) { - ItemStack itemStack = recipe.getResultItem(); - CreativeModeTab group = itemStack.getItem().getItemCategory(); + ItemStack itemStack = recipe.getOutput(); + ItemGroup group = itemStack.getItem().getGroup(); if (group != null) { - if (group != CreativeModeTab.TAB_HOTBAR && group != CreativeModeTab.TAB_INVENTORY && group != CreativeModeTab.TAB_SEARCH) - cir.setReturnValue(RecipeBookIsPainClient.ADDED_GROUPS.get("P_CRAFTING_" + group.getDisplayName().toString().toUpperCase().replace(".", "_"))); + if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) + cir.setReturnValue(RecipeBookIsPainClient.ADDED_GROUPS.get("P_CRAFTING_" + group.getName().toUpperCase().replace(".", "_"))); } } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java index da93398..80659fd 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java @@ -2,10 +2,10 @@ package me.melontini.recipebookispain.mixin; import com.google.common.collect.ImmutableList; import me.melontini.recipebookispain.client.RecipeBookIsPainClient; -import net.minecraft.client.RecipeBookCategories; -import net.minecraft.world.inventory.RecipeBookType; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.ItemStack; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.book.RecipeBookCategory; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; @@ -18,45 +18,45 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -@Mixin(RecipeBookCategories.class) +@Mixin(RecipeBookGroup.class) @Unique public class RecipeBookGroupMixin { //me when I can't use Fabric ASM @Shadow @Final @Mutable - private static RecipeBookCategories[] $VALUES; + private static RecipeBookGroup[] field_1805; @Unique - private static List CRAFTING_SEARCH_MAP; + private static List CRAFTING_SEARCH_MAP; @Unique - private static List CRAFTING_MAP; + private static List CRAFTING_MAP; // pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work @Redirect(at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableList;"), remap = false, method = "") private static ImmutableList listOf(E e1, E e2, E e3, E e4) { - if (e1 == RecipeBookCategories.CRAFTING_EQUIPMENT) { + if (e1 == RecipeBookGroup.CRAFTING_EQUIPMENT) { return (ImmutableList) ImmutableList.copyOf(CRAFTING_SEARCH_MAP); } return ImmutableList.of(e1, e2, e3, e4); } - @Inject(at = @At(value = "FIELD", opcode = Opcodes.PUTSTATIC, target = "Lnet/minecraft/client/RecipeBookCategories;$VALUES:[Lnet/minecraft/client/RecipeBookCategories;", shift = At.Shift.AFTER), method = "") + @Inject(at = @At(value = "FIELD", opcode = Opcodes.PUTSTATIC, target = "Lnet/minecraft/client/recipebook/RecipeBookGroup;field_1805:[Lnet/minecraft/client/recipebook/RecipeBookGroup;", shift = At.Shift.AFTER), method = "") private static void recipe_book_is_pain$addCustomGroups(CallbackInfo ci) { - var groups = new ArrayList<>(Arrays.asList($VALUES)); + var groups = new ArrayList<>(Arrays.asList(field_1805)); var last = groups.get(groups.size() - 1); - for (CreativeModeTab group : CreativeModeTab.TABS) { - if (group != CreativeModeTab.TAB_HOTBAR && group != CreativeModeTab.TAB_INVENTORY && group != CreativeModeTab.TAB_SEARCH) { - var group1 = Accessor.newGroup("P_CRAFTING_" + group.getDisplayName().toString().toUpperCase().replace(".", "_"), last.ordinal() + 1, new ItemStack(group.getIconItem().getItem())); - RecipeBookIsPainClient.ADDED_GROUPS.put("P_CRAFTING_" + group.getDisplayName().toString().toUpperCase().replace(".", "_"), group1); + for (ItemGroup group : ItemGroup.GROUPS) { + if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) { + var group1 = Accessor.newGroup("P_CRAFTING_" + group.getName().toUpperCase().replace(".", "_"), last.ordinal() + 1, new ItemStack(group.getIcon().getItem())); + RecipeBookIsPainClient.ADDED_GROUPS.put("P_CRAFTING_" + group.getName().toUpperCase().replace(".", "_"), group1); groups.add(group1); } } - List craftingMap = new ArrayList<>(); - List craftingSearchMap = new ArrayList<>(); - craftingMap.add(RecipeBookCategories.CRAFTING_SEARCH); - for (RecipeBookCategories bookGroup : groups) { + List craftingMap = new ArrayList<>(); + List craftingSearchMap = new ArrayList<>(); + craftingMap.add(RecipeBookGroup.CRAFTING_SEARCH); + for (RecipeBookGroup bookGroup : groups) { if (bookGroup.toString().contains("P_CRAFTING")) { craftingMap.add(bookGroup); craftingSearchMap.add(bookGroup); @@ -65,13 +65,13 @@ public class RecipeBookGroupMixin { CRAFTING_SEARCH_MAP = craftingSearchMap; CRAFTING_MAP = craftingMap; - $VALUES = groups.toArray(new RecipeBookCategories[0]); + field_1805 = groups.toArray(new RecipeBookGroup[0]); RecipeBookIsPainClient.LOGGER.info("[RBIP] recipe book init complete"); } - @Inject(at = @At("HEAD"), method = "getCategories", cancellable = true) - private static void recipe_book_is_pain$getGroups(RecipeBookType recipeBookType, CallbackInfoReturnable> cir) { - if (recipeBookType == RecipeBookType.CRAFTING) cir.setReturnValue(CRAFTING_MAP); + @Inject(at = @At("HEAD"), method = "getGroups", cancellable = true) + private static void recipe_book_is_pain$getGroups(RecipeBookCategory category, CallbackInfoReturnable> cir) { + if (category == RecipeBookCategory.CRAFTING) cir.setReturnValue(CRAFTING_MAP); } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java index 8c377f0..88d79ca 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java @@ -1,14 +1,14 @@ package me.melontini.recipebookispain.mixin; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.ClientRecipeBook; -import net.minecraft.client.Minecraft; -import net.minecraft.client.RecipeBookCategories; -import net.minecraft.client.gui.components.StateSwitchingButton; -import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; -import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Tuple; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; +import net.minecraft.client.gui.widget.ToggleButtonWidget; +import net.minecraft.client.recipebook.ClientRecipeBook; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.Identifier; +import net.minecraft.util.Pair; import org.apache.commons.compress.utils.Lists; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -21,69 +21,67 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.List; -@Mixin(RecipeBookComponent.class) +@Mixin(RecipeBookWidget.class) public abstract class RecipeBookWidgetMixin { @Shadow @Final - protected static ResourceLocation RECIPE_BOOK_LOCATION; + protected static Identifier TEXTURE; @Unique private int page = 0; @Unique - public List> groupTab = Lists.newArrayList(); + public List> groupTab = Lists.newArrayList(); @Shadow - protected Minecraft minecraft; + protected MinecraftClient client; @Shadow - private int height; + private int parentHeight; @Shadow - private int xOffset; + private int leftOffset; @Shadow - private ClientRecipeBook book; + private ClientRecipeBook recipeBook; @Shadow @Final - private List tabButtons; + private List tabButtons; @Shadow - private int width; + private int parentWidth; @Unique private int pages; @Unique - private StateSwitchingButton nextPageButton; + private ToggleButtonWidget nextPageButton; @Unique - private StateSwitchingButton prevPageButton; + private ToggleButtonWidget prevPageButton; @Shadow - private boolean visible; + public abstract boolean isOpen(); - @Shadow public abstract boolean isVisible(); - - @Inject(at = @At("RETURN"), method = "init") + @Inject(at = @At("RETURN"), method = "reset") private void recipe_book_is_pain$init(CallbackInfo ci) { - int a = (this.width - 147) / 2 - this.xOffset; - int s = (this.height + 166) / 2; - this.nextPageButton = new StateSwitchingButton(a + 10, s, 12, 17, false); - this.nextPageButton.initTextureValues(1, 208, 13, 18, RECIPE_BOOK_LOCATION); - this.prevPageButton = new StateSwitchingButton(a - 10, s, 12, 17, true); - this.prevPageButton.initTextureValues(1, 208, 13, 18, RECIPE_BOOK_LOCATION); + int a = (this.parentWidth - 147) / 2 - this.leftOffset; + int s = (this.parentHeight + 166) / 2; + this.nextPageButton = new ToggleButtonWidget(a + 10, s, 12, 17, false); + this.nextPageButton.setTextureUV(1, 208, 13, 18, TEXTURE); + this.prevPageButton = new ToggleButtonWidget(a - 10, s, 12, 17, true); + this.prevPageButton.setTextureUV(1, 208, 13, 18, TEXTURE); page = 0; } - @Inject(at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;popPose()V", shift = At.Shift.BEFORE), method = "render") - private void recipe_book_is_pain$render(PoseStack poseStack, int i, int j, float f, CallbackInfo ci) { + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V", shift = At.Shift.BEFORE), method = "render") + private void recipe_book_is_pain$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { updatePageSwitchButtons(); - this.prevPageButton.render(poseStack, i, j, f); - this.nextPageButton.render(poseStack, i, j, f); + this.prevPageButton.render(matrices, mouseX, mouseY, delta); + this.nextPageButton.render(matrices, mouseX, mouseY, delta); updatePages(); } @Unique private void updatePages() { - for (Tuple pair : groupTab) { - RecipeBookTabButton widget = pair.getB(); - if (pair.getA() == page) { - RecipeBookCategories recipeBookGroup = widget.getCategory(); - if (recipeBookGroup == RecipeBookCategories.CRAFTING_SEARCH || recipeBookGroup == RecipeBookCategories.FURNACE_SEARCH) { + for (Pair pair : groupTab) { + RecipeGroupButtonWidget widget = pair.getRight(); + if (pair.getLeft() == page) { + RecipeBookGroup recipeBookGroup = widget.getCategory(); + if (recipeBookGroup == RecipeBookGroup.CRAFTING_SEARCH || recipeBookGroup == RecipeBookGroup.FURNACE_SEARCH) { widget.visible = true; - } else if (widget.updateVisibility(book)) { - widget.startAnimation(this.minecraft); + } else if (widget.hasKnownRecipes(recipeBook)) { + widget.checkForNewRecipes(this.client); } } else { widget.visible = false; @@ -93,7 +91,7 @@ public abstract class RecipeBookWidgetMixin { @Inject(at = @At("HEAD"), method = "mouseClicked", cancellable = true) private void recipe_book_is_pain$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { - if (this.isVisible() && !this.minecraft.player.isSpectator()) { + if (this.isOpen() && !this.client.player.isSpectator()) { if (nextPageButton.mouseClicked(mouseX, mouseY, button)) { if (this.page <= this.pages) ++this.page; updatePageSwitchButtons(); @@ -114,21 +112,21 @@ public abstract class RecipeBookWidgetMixin { @SuppressWarnings("IntegerDivisionInFloatingPointContext") - @Inject(at = @At("HEAD"), method = "updateTabs", cancellable = true) + @Inject(at = @At("HEAD"), method = "refreshTabButtons", cancellable = true) private void recipe_book_is_pain$refresh(CallbackInfo ci) { groupTab.clear(); this.pages = 0; int p = 0; - int c = (this.width - 147) / 2 - this.xOffset - 30; - int b = (this.height - 166) / 2 + 3; + int c = (this.parentWidth - 147) / 2 - this.leftOffset - 30; + int b = (this.parentHeight - 166) / 2 + 3; int l = 0; - for (RecipeBookTabButton widget : this.tabButtons) { - RecipeBookCategories recipeBookGroup = widget.getCategory(); - if (recipeBookGroup == RecipeBookCategories.CRAFTING_SEARCH || recipeBookGroup == RecipeBookCategories.FURNACE_SEARCH || widget.updateVisibility(book)) { - groupTab.add(new Tuple<>((int) Math.ceil(p / 6), widget)); + for (RecipeGroupButtonWidget widget : this.tabButtons) { + RecipeBookGroup recipeBookGroup = widget.getCategory(); + if (recipeBookGroup == RecipeBookGroup.CRAFTING_SEARCH || recipeBookGroup == RecipeBookGroup.FURNACE_SEARCH || widget.hasKnownRecipes(recipeBook)) { + groupTab.add(new Pair<>((int) Math.ceil(p / 6), widget)); widget.visible = false; - widget.setPosition(c, b + 27 * l++); + widget.setPos(c, b + 27 * l++); if (l == 6) { l = 0; }