diff --git a/build.gradle b/build.gradle index c37e1e9..d18e253 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,8 @@ repositories { dependencies { // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + mappings loom.officialMojangMappings() + //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 d897916..5b5fba4 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.recipebook.RecipeBookGroup; +import net.minecraft.client.RecipeBookCategories; 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 6b6d9fc..fc7bac8 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.recipebook.RecipeBookGroup; -import net.minecraft.item.ItemStack; +import net.minecraft.client.RecipeBookCategories; +import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; -@Mixin(RecipeBookGroup.class) +@Mixin(RecipeBookCategories.class) public interface Accessor { @Invoker("") - static RecipeBookGroup newGroup(String internalName, int internalId, ItemStack... stacks) { + static RecipeBookCategories 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 51675a9..a08cd87 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.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 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 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 = "getGroupForRecipe", cancellable = true) - private static void recipe_book_is_pain$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { + @Inject(at = @At("HEAD"), method = "getCategory", 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.getOutput(); - ItemGroup group = itemStack.getItem().getGroup(); + ItemStack itemStack = recipe.getResultItem(); + CreativeModeTab group = itemStack.getItem().getItemCategory(); if (group != null) { - if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) - cir.setReturnValue(RecipeBookIsPainClient.ADDED_GROUPS.get("P_CRAFTING_" + group.getName().toUpperCase().replace(".", "_"))); + 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(".", "_"))); } } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java index 80659fd..da93398 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.recipebook.RecipeBookGroup; -import net.minecraft.item.ItemGroup; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.book.RecipeBookCategory; +import net.minecraft.client.RecipeBookCategories; +import net.minecraft.world.inventory.RecipeBookType; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; 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(RecipeBookGroup.class) +@Mixin(RecipeBookCategories.class) @Unique public class RecipeBookGroupMixin { //me when I can't use Fabric ASM @Shadow @Final @Mutable - private static RecipeBookGroup[] field_1805; + private static RecipeBookCategories[] $VALUES; @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 == RecipeBookGroup.CRAFTING_EQUIPMENT) { + if (e1 == RecipeBookCategories.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/recipebook/RecipeBookGroup;field_1805:[Lnet/minecraft/client/recipebook/RecipeBookGroup;", shift = At.Shift.AFTER), method = "") + @Inject(at = @At(value = "FIELD", opcode = Opcodes.PUTSTATIC, target = "Lnet/minecraft/client/RecipeBookCategories;$VALUES:[Lnet/minecraft/client/RecipeBookCategories;", shift = At.Shift.AFTER), method = "") private static void recipe_book_is_pain$addCustomGroups(CallbackInfo ci) { - var groups = new ArrayList<>(Arrays.asList(field_1805)); + var groups = new ArrayList<>(Arrays.asList($VALUES)); var last = groups.get(groups.size() - 1); - 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); + 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); groups.add(group1); } } - List craftingMap = new ArrayList<>(); - List craftingSearchMap = new ArrayList<>(); - craftingMap.add(RecipeBookGroup.CRAFTING_SEARCH); - for (RecipeBookGroup bookGroup : groups) { + List craftingMap = new ArrayList<>(); + List craftingSearchMap = new ArrayList<>(); + craftingMap.add(RecipeBookCategories.CRAFTING_SEARCH); + for (RecipeBookCategories 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; - field_1805 = groups.toArray(new RecipeBookGroup[0]); + $VALUES = groups.toArray(new RecipeBookCategories[0]); RecipeBookIsPainClient.LOGGER.info("[RBIP] recipe book init complete"); } - @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); + @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); } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java index 88d79ca..8c377f0 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 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 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 org.apache.commons.compress.utils.Lists; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -21,67 +21,69 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.List; -@Mixin(RecipeBookWidget.class) +@Mixin(RecipeBookComponent.class) public abstract class RecipeBookWidgetMixin { @Shadow @Final - protected static Identifier TEXTURE; + protected static ResourceLocation RECIPE_BOOK_LOCATION; @Unique private int page = 0; @Unique - public List> groupTab = Lists.newArrayList(); + public List> groupTab = Lists.newArrayList(); @Shadow - protected MinecraftClient client; + protected Minecraft minecraft; @Shadow - private int parentHeight; + private int height; @Shadow - private int leftOffset; + private int xOffset; @Shadow - private ClientRecipeBook recipeBook; + private ClientRecipeBook book; @Shadow @Final - private List tabButtons; + private List tabButtons; @Shadow - private int parentWidth; + private int width; @Unique private int pages; @Unique - private ToggleButtonWidget nextPageButton; + private StateSwitchingButton nextPageButton; @Unique - private ToggleButtonWidget prevPageButton; + private StateSwitchingButton prevPageButton; @Shadow - public abstract boolean isOpen(); + private boolean visible; - @Inject(at = @At("RETURN"), method = "reset") + @Shadow public abstract boolean isVisible(); + + @Inject(at = @At("RETURN"), method = "init") private void recipe_book_is_pain$init(CallbackInfo ci) { - 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); + 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); page = 0; } - @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) { + @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) { updatePageSwitchButtons(); - this.prevPageButton.render(matrices, mouseX, mouseY, delta); - this.nextPageButton.render(matrices, mouseX, mouseY, delta); + this.prevPageButton.render(poseStack, i, j, f); + this.nextPageButton.render(poseStack, i, j, f); updatePages(); } @Unique private void updatePages() { - 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) { + 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) { widget.visible = true; - } else if (widget.hasKnownRecipes(recipeBook)) { - widget.checkForNewRecipes(this.client); + } else if (widget.updateVisibility(book)) { + widget.startAnimation(this.minecraft); } } else { widget.visible = false; @@ -91,7 +93,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.isOpen() && !this.client.player.isSpectator()) { + if (this.isVisible() && !this.minecraft.player.isSpectator()) { if (nextPageButton.mouseClicked(mouseX, mouseY, button)) { if (this.page <= this.pages) ++this.page; updatePageSwitchButtons(); @@ -112,21 +114,21 @@ public abstract class RecipeBookWidgetMixin { @SuppressWarnings("IntegerDivisionInFloatingPointContext") - @Inject(at = @At("HEAD"), method = "refreshTabButtons", cancellable = true) + @Inject(at = @At("HEAD"), method = "updateTabs", cancellable = true) private void recipe_book_is_pain$refresh(CallbackInfo ci) { groupTab.clear(); this.pages = 0; int p = 0; - int c = (this.parentWidth - 147) / 2 - this.leftOffset - 30; - int b = (this.parentHeight - 166) / 2 + 3; + int c = (this.width - 147) / 2 - this.xOffset - 30; + int b = (this.height - 166) / 2 + 3; int l = 0; - 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)); + 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)); widget.visible = false; - widget.setPos(c, b + 27 * l++); + widget.setPosition(c, b + 27 * l++); if (l == 6) { l = 0; }