diff --git a/CHANGELOG.md b/CHANGELOG.md index c2c98a7..ca0b34d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,2 @@ ## Change -- sync with `sakura-ryoko/itemscroller` 1.21-0.24.51 \ No newline at end of file +- sync with `sakura-ryoko/itemscroller` 1.21.3-0.25.0-sakura.3 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 43d8952..4681013 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,12 +1,12 @@ [versions] # Base properties -minecraft_version="1.21.1" -yarn_mappings="1.21.1+build.3" +minecraft_version="1.21.3" +yarn_mappings="1.21.3+build.2" mappings_patch="1.21+build.4" -neoforge="21.1.31" +neoforge="21.3.12-beta" # Mod properties -version="0.1.9" +version="0.1.10" maven-group="org.thinkingstudio.rocknroller" archives-name="RocknRoller" @@ -15,7 +15,7 @@ id-modrinth="hYq29QmW" id-curseforge="916852" # Mod dependencies -mafglib="0.1.24-mc1.21.1" +mafglib="0.1.25-mc1.21.3" badpackets="neo-0.8.1" # Libraries diff --git a/src/main/java/fi/dy/masa/itemscroller/InitHandler.java b/src/main/java/fi/dy/masa/itemscroller/InitHandler.java index 11a226f..463d1ea 100644 --- a/src/main/java/fi/dy/masa/itemscroller/InitHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/InitHandler.java @@ -1,14 +1,14 @@ package fi.dy.masa.itemscroller; -import fi.dy.masa.itemscroller.config.Configs; -import fi.dy.masa.itemscroller.event.InputHandler; -import fi.dy.masa.itemscroller.event.KeybindCallbacks; -import fi.dy.masa.itemscroller.event.WorldLoadListener; import fi.dy.masa.malilib.config.ConfigManager; import fi.dy.masa.malilib.event.InputEventHandler; import fi.dy.masa.malilib.event.TickHandler; import fi.dy.masa.malilib.event.WorldLoadHandler; import fi.dy.masa.malilib.interfaces.IInitializationHandler; +import fi.dy.masa.itemscroller.config.Configs; +import fi.dy.masa.itemscroller.event.InputHandler; +import fi.dy.masa.itemscroller.event.KeybindCallbacks; +import fi.dy.masa.itemscroller.event.WorldLoadListener; public class InitHandler implements IInitializationHandler { diff --git a/src/main/java/fi/dy/masa/itemscroller/ItemScroller.java b/src/main/java/fi/dy/masa/itemscroller/ItemScroller.java index 25eaa9f..bf6ced1 100644 --- a/src/main/java/fi/dy/masa/itemscroller/ItemScroller.java +++ b/src/main/java/fi/dy/masa/itemscroller/ItemScroller.java @@ -3,6 +3,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import fi.dy.masa.malilib.event.InitializationHandler; +import fi.dy.masa.itemscroller.config.Configs; public class ItemScroller { @@ -13,7 +14,6 @@ public static void onInitialize() InitializationHandler.getInstance().registerInitializationHandler(new InitHandler()); } - /* public static void printDebug(String key, Object... args) { if (Configs.Generic.DEBUG_MESSAGES.getBooleanValue()) @@ -21,5 +21,4 @@ public static void printDebug(String key, Object... args) logger.info(key, args); } } - */ } diff --git a/src/main/java/fi/dy/masa/itemscroller/config/Configs.java b/src/main/java/fi/dy/masa/itemscroller/config/Configs.java index ff291f4..f7b8c38 100644 --- a/src/main/java/fi/dy/masa/itemscroller/config/Configs.java +++ b/src/main/java/fi/dy/masa/itemscroller/config/Configs.java @@ -7,9 +7,11 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; + import net.minecraft.client.gui.screen.ingame.CraftingScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.screen.slot.CraftingResultSlot; + import fi.dy.masa.malilib.config.ConfigUtils; import fi.dy.masa.malilib.config.IConfigBase; import fi.dy.masa.malilib.config.IConfigHandler; @@ -30,39 +32,40 @@ public class Configs implements IConfigHandler private static final ImmutableList DEFAULT_TOP_SORTING = ImmutableList.of("minecraft:diamond_sword","minecraft:diamond_pickaxe","minecraft:diamond_axe","minecraft:diamond_shovel","minecraft:diamond_hoe","minecraft:netherite_sword","minecraft:netherite_pickaxe","minecraft:netherite_axe","minecraft:netherite_shovel","minecraft:netherite_hoe"); private static final ImmutableList DEFAULT_BOTTOM_SORTING = ImmutableList.of(); + private static final String GENERIC_KEY = Reference.ID+".config.generic"; public static class Generic { - public static final ConfigBoolean CARPET_CTRL_Q_CRAFTING = new ConfigBoolean("carpetCtrlQCraftingEnabledOnServer", false, "itemscroller.config.generic.comment.carpetCtrlQCraftingEnabledOnServer").translatedName("itemscroller.config.generic.name.carpetCtrlQCraftingEnabledOnServer"); - public static final ConfigBoolean CLIENT_CRAFTING_FIX = new ConfigBoolean("clientCraftingFixOn1.12", true, "itemscroller.config.generic.comment.clientCraftingFixOn1_12").translatedName("itemscroller.config.generic.name.clientCraftingFixOn1_12"); - public static final ConfigBoolean CRAFTING_RENDER_RECIPE_ITEMS = new ConfigBoolean("craftingRenderRecipeItems", true, "itemscroller.config.generic.comment.craftingRenderRecipeItems").translatedName("itemscroller.config.generic.name.craftingRenderRecipeItems"); - public static final ConfigBoolean DEBUG_MESSAGES = new ConfigBoolean("debugMessages", false, "itemscroller.config.generic.comment.debugMessages").translatedName("itemscroller.config.generic.name.debugMessages"); - public static final ConfigBoolean MOD_MAIN_TOGGLE = new ConfigBoolean("modMainToggle", true, "itemscroller.config.generic.comment.modMainToggle").translatedName("itemscroller.config.generic.name.modMainToggle"); - public static final ConfigBoolean MASS_CRAFT_INHIBIT_MID_UPDATES = new ConfigBoolean("massCraftInhibitMidUpdates", true, "itemscroller.config.generic.comment.massCraftInhibitMidUpdates").translatedName("itemscroller.config.generic.name.massCraftInhibitMidUpdates"); - public static final ConfigInteger MASS_CRAFT_INTERVAL = new ConfigInteger("massCraftInterval", 2, 1, 60, "itemscroller.config.generic.comment.massCraftInterval").translatedName("itemscroller.config.generic.name.massCraftInterval"); - public static final ConfigInteger MASS_CRAFT_ITERATIONS = new ConfigInteger("massCraftIterations", 36, 1, 256, "itemscroller.config.generic.comment.massCraftIterations").translatedName("itemscroller.config.generic.name.massCraftIterations"); - public static final ConfigBoolean MASS_CRAFT_SWAPS = new ConfigBoolean("massCraftSwapsOnly", false, "itemscroller.config.generic.comment.massCraftSwapsOnly").translatedName("itemscroller.config.generic.name.massCraftSwapsOnly"); - public static final ConfigBoolean MASS_CRAFT_RECIPE_BOOK = new ConfigBoolean("massCraftUseRecipeBook", false, "itemscroller.config.generic.comment.massCraftUseRecipeBook").translatedName("itemscroller.config.generic.name.massCraftUseRecipeBook"); - public static final ConfigInteger PACKET_RATE_LIMIT = new ConfigInteger("packetRateLimit", 4, 1, 1024, "itemscroller.config.generic.comment.packetRateLimit").translatedName("itemscroller.config.generic.name.packetRateLimit"); - public static final ConfigBoolean SCROLL_CRAFT_STORE_RECIPES_TO_FILE = new ConfigBoolean("craftingRecipesSaveToFile", true, "itemscroller.config.generic.comment.craftingRecipesSaveToFile").translatedName("itemscroller.config.generic.name.craftingRecipesSaveToFile"); - public static final ConfigBoolean SCROLL_CRAFT_RECIPE_FILE_GLOBAL = new ConfigBoolean("craftingRecipesSaveFileIsGlobal", false, "itemscroller.config.generic.comment.craftingRecipesSaveFileIsGlobal").translatedName("itemscroller.config.generic.name.craftingRecipesSaveFileIsGlobal"); - public static final ConfigBoolean RATE_LIMIT_CLICK_PACKETS = new ConfigBoolean("rateLimitClickPackets", false, "itemscroller.config.generic.comment.rateLimitClickPackets").translatedName("itemscroller.config.generic.name.rateLimitClickPackets"); - public static final ConfigBoolean REVERSE_SCROLL_DIRECTION_SINGLE = new ConfigBoolean("reverseScrollDirectionSingle", false, "itemscroller.config.generic.comment.reverseScrollDirectionSingle").translatedName("itemscroller.config.generic.name.reverseScrollDirectionSingle"); - public static final ConfigBoolean REVERSE_SCROLL_DIRECTION_STACKS = new ConfigBoolean("reverseScrollDirectionStacks", false, "itemscroller.config.generic.comment.reverseScrollDirectionStacks").translatedName("itemscroller.config.generic.name.reverseScrollDirectionStacks"); - public static final ConfigBoolean USE_RECIPE_CACHING = new ConfigBoolean("useRecipeCaching", true, "itemscroller.config.generic.comment.useRecipeCaching").translatedName("itemscroller.config.generic.name.useRecipeCaching"); - public static final ConfigBoolean SLOT_POSITION_AWARE_SCROLL_DIRECTION = new ConfigBoolean("useSlotPositionAwareScrollDirection", false, "itemscroller.config.generic.comment.useSlotPositionAwareScrollDirection").translatedName("itemscroller.config.generic.name.useSlotPositionAwareScrollDirection"); - public static final ConfigBoolean VILLAGER_TRADE_USE_GLOBAL_FAVORITES = new ConfigBoolean("villagerTradeUseGlobalFavorites", true, "itemscroller.config.generic.comment.villagerTradeUseGlobalFavorites").translatedName("itemscroller.config.generic.name.villagerTradeUseGlobalFavorites"); - public static final ConfigBoolean VILLAGER_TRADE_LIST_REMEMBER_SCROLL = new ConfigBoolean("villagerTradeListRememberScrollPosition", true, "itemscroller.config.generic.comment.villagerTradeListRememberScrollPosition").translatedName("itemscroller.config.generic.name.villagerTradeListRememberScrollPosition"); - - public static final ConfigBoolean SORT_INVENTORY_TOGGLE = new ConfigBoolean("sortInventoryToggle", false, "itemscroller.config.generic.comment.sortInventoryToggle").translatedName("itemscroller.config.generic.name.sortInventoryToggle"); - public static final ConfigBoolean SORT_ASSUME_EMPTY_BOX_STACKS = new ConfigBoolean("sortAssumeEmptyBoxStacks", true, "itemscroller.config.generic.comment.sortAssumeEmptyBoxStacks").translatedName("itemscroller.config.generic.name.sortAssumeEmptyBoxStacks"); - public static final ConfigBoolean SORT_SHULKER_BOXES_AT_END = new ConfigBoolean("sortShulkerBoxesAtEnd", true, "itemscroller.config.generic.comment.sortShulkerBoxesAtEnd").translatedName("itemscroller.config.generic.name.sortShulkerBoxesAtEnd"); - public static final ConfigBoolean SORT_SHULKER_BOXES_INVERTED = new ConfigBoolean("sortShulkerBoxesInverted", false, "itemscroller.config.generic.comment.sortShulkerBoxesInverted").translatedName("itemscroller.config.generic.name.sortShulkerBoxesInverted"); - public static final ConfigBoolean SORT_BUNDLES_AT_END = new ConfigBoolean("sortBundlesAtEnd", true, "itemscroller.config.generic.comment.sortBundlesAtEnd").translatedName("itemscroller.config.generic.name.sortBundlesAtEnd"); - public static final ConfigBoolean SORT_BUNDLES_INVERTED = new ConfigBoolean("sortBundlesInverted", false, "itemscroller.config.generic.comment.sortBundlesInverted").translatedName("itemscroller.config.generic.name.sortBundlesInverted"); - public static final ConfigStringList SORT_TOP_PRIORITY_INVENTORY = new ConfigStringList("sortTopPriorityInventory", DEFAULT_TOP_SORTING, "itemscroller.config.generic.comment.sortTopPriorityInventory").translatedName("itemscroller.config.generic.name.sortTopPriorityInventory"); - public static final ConfigStringList SORT_BOTTOM_PRIORITY_INVENTORY = new ConfigStringList("sortBottomPriorityInventory", DEFAULT_BOTTOM_SORTING, "itemscroller.config.generic.comment.sortBottomPriorityInventory").translatedName("itemscroller.config.generic.name.sortBottomPriorityInventory"); - public static final ConfigOptionList SORT_METHOD_DEFAULT = new ConfigOptionList("sortMethodDefault", SortingMethod.CATEGORY_NAME, "itemscroller.config.generic.comment.sortMethodDefault").translatedName("itemscroller.config.generic.name.sortMethodDefault"); - public static final ConfigLockedList SORT_CATEGORY_ORDER = new ConfigLockedList("sortCategoryOrder", SortingCategory.INSTANCE, "itemscroller.config.generic.comment.sortCategoryOrder").translatedName("itemscroller.config.generic.name.sortCategoryOrder"); + public static final ConfigBoolean CARPET_CTRL_Q_CRAFTING = new ConfigBoolean("carpetCtrlQCraftingEnabledOnServer", false).apply(GENERIC_KEY); + public static final ConfigBoolean CLIENT_CRAFTING_FIX = new ConfigBoolean("clientCraftingFixOn1.12", true).apply(GENERIC_KEY); + public static final ConfigBoolean CRAFTING_RENDER_RECIPE_ITEMS = new ConfigBoolean("craftingRenderRecipeItems", true).apply(GENERIC_KEY); + public static final ConfigBoolean DEBUG_MESSAGES = new ConfigBoolean("debugMessages", false).apply(GENERIC_KEY); + public static final ConfigBoolean MOD_MAIN_TOGGLE = new ConfigBoolean("modMainToggle", true).apply(GENERIC_KEY); + public static final ConfigBoolean MASS_CRAFT_INHIBIT_MID_UPDATES = new ConfigBoolean("massCraftInhibitMidUpdates", true).apply(GENERIC_KEY); + public static final ConfigInteger MASS_CRAFT_INTERVAL = new ConfigInteger("massCraftInterval", 2, 1, 60).apply(GENERIC_KEY); + public static final ConfigInteger MASS_CRAFT_ITERATIONS = new ConfigInteger("massCraftIterations", 36, 1, 256).apply(GENERIC_KEY); + public static final ConfigBoolean MASS_CRAFT_SWAPS = new ConfigBoolean("massCraftSwapsOnly", false).apply(GENERIC_KEY); + public static final ConfigBoolean MASS_CRAFT_RECIPE_BOOK = new ConfigBoolean("massCraftUseRecipeBook", true).apply(GENERIC_KEY); + public static final ConfigInteger PACKET_RATE_LIMIT = new ConfigInteger("packetRateLimit", 4, 1, 1024).apply(GENERIC_KEY); + public static final ConfigBoolean SCROLL_CRAFT_STORE_RECIPES_TO_FILE = new ConfigBoolean("craftingRecipesSaveToFile", true).apply(GENERIC_KEY); + public static final ConfigBoolean SCROLL_CRAFT_RECIPE_FILE_GLOBAL = new ConfigBoolean("craftingRecipesSaveFileIsGlobal", false).apply(GENERIC_KEY); + public static final ConfigBoolean RATE_LIMIT_CLICK_PACKETS = new ConfigBoolean("rateLimitClickPackets", false).apply(GENERIC_KEY); + public static final ConfigBoolean REVERSE_SCROLL_DIRECTION_SINGLE = new ConfigBoolean("reverseScrollDirectionSingle", false).apply(GENERIC_KEY); + public static final ConfigBoolean REVERSE_SCROLL_DIRECTION_STACKS = new ConfigBoolean("reverseScrollDirectionStacks", false).apply(GENERIC_KEY); + public static final ConfigBoolean USE_RECIPE_CACHING = new ConfigBoolean("useRecipeCaching", true).apply(GENERIC_KEY); + public static final ConfigBoolean SLOT_POSITION_AWARE_SCROLL_DIRECTION = new ConfigBoolean("useSlotPositionAwareScrollDirection", false).apply(GENERIC_KEY); + public static final ConfigBoolean VILLAGER_TRADE_USE_GLOBAL_FAVORITES = new ConfigBoolean("villagerTradeUseGlobalFavorites", true).apply(GENERIC_KEY); + public static final ConfigBoolean VILLAGER_TRADE_LIST_REMEMBER_SCROLL = new ConfigBoolean("villagerTradeListRememberScrollPosition", true).apply(GENERIC_KEY); + + public static final ConfigBoolean SORT_INVENTORY_TOGGLE = new ConfigBoolean("sortInventoryToggle", false).apply(GENERIC_KEY); + public static final ConfigBoolean SORT_ASSUME_EMPTY_BOX_STACKS = new ConfigBoolean("sortAssumeEmptyBoxStacks", false).apply(GENERIC_KEY); + public static final ConfigBoolean SORT_SHULKER_BOXES_AT_END = new ConfigBoolean("sortShulkerBoxesAtEnd", true).apply(GENERIC_KEY); + public static final ConfigBoolean SORT_SHULKER_BOXES_INVERTED = new ConfigBoolean("sortShulkerBoxesInverted", false).apply(GENERIC_KEY); + public static final ConfigBoolean SORT_BUNDLES_AT_END = new ConfigBoolean("sortBundlesAtEnd", true).apply(GENERIC_KEY); + public static final ConfigBoolean SORT_BUNDLES_INVERTED = new ConfigBoolean("sortBundlesInverted", false).apply(GENERIC_KEY); + public static final ConfigStringList SORT_TOP_PRIORITY_INVENTORY = new ConfigStringList("sortTopPriorityInventory", DEFAULT_TOP_SORTING).apply(GENERIC_KEY); + public static final ConfigStringList SORT_BOTTOM_PRIORITY_INVENTORY = new ConfigStringList("sortBottomPriorityInventory", DEFAULT_BOTTOM_SORTING).apply(GENERIC_KEY); + public static final ConfigOptionList SORT_METHOD_DEFAULT = new ConfigOptionList("sortMethodDefault", SortingMethod.CATEGORY_NAME).apply(GENERIC_KEY); + public static final ConfigLockedList SORT_CATEGORY_ORDER = new ConfigLockedList("sortCategoryOrder", SortingCategory.INSTANCE).apply(GENERIC_KEY); public static final ImmutableList OPTIONS = ImmutableList.of( CARPET_CTRL_Q_CRAFTING, @@ -99,20 +102,21 @@ public static class Generic ); } + private static final String TOGGLES_KEY = Reference.ID+".config.toggles"; public static class Toggles { - public static final ConfigBoolean CRAFTING_FEATURES = new ConfigBoolean("enableCraftingFeatures", true, "itemscroller.config.toggles.comment.enableCraftingFeatures").translatedName("itemscroller.config.toggles.name.enableCraftingFeatures"); - public static final ConfigBoolean DROP_MATCHING = new ConfigBoolean("enableDropkeyDropMatching", true, "itemscroller.config.toggles.comment.enableDropkeyDropMatching").translatedName("itemscroller.config.toggles.name.enableDropkeyDropMatching"); - public static final ConfigBoolean RIGHT_CLICK_CRAFT_STACK = new ConfigBoolean("enableRightClickCraftingOneStack", true, "itemscroller.config.toggles.comment.enableRightClickCraftingOneStack").translatedName("itemscroller.config.toggles.name.enableRightClickCraftingOneStack"); - public static final ConfigBoolean SCROLL_EVERYTHING = new ConfigBoolean("enableScrollingEverything", true, "itemscroller.config.toggles.comment.enableScrollingEverything").translatedName("itemscroller.config.toggles.name.enableScrollingEverything"); - public static final ConfigBoolean SCROLL_MATCHING = new ConfigBoolean("enableScrollingMatchingStacks", true, "itemscroller.config.toggles.comment.enableScrollingMatchingStacks").translatedName("itemscroller.config.toggles.name.enableScrollingMatchingStacks"); - public static final ConfigBoolean SCROLL_SINGLE = new ConfigBoolean("enableScrollingSingle", true, "itemscroller.config.toggles.comment.enableScrollingSingle").translatedName("itemscroller.config.toggles.name.enableScrollingSingle"); - public static final ConfigBoolean SCROLL_STACKS = new ConfigBoolean("enableScrollingStacks", true, "itemscroller.config.toggles.comment.enableScrollingStacks").translatedName("itemscroller.config.toggles.name.enableScrollingStacks"); - public static final ConfigBoolean SCROLL_STACKS_FALLBACK = new ConfigBoolean("enableScrollingStacksFallback", true, "itemscroller.config.toggles.comment.enableScrollingStacksFallback").translatedName("itemscroller.config.toggles.name.enableScrollingStacksFallback"); - public static final ConfigBoolean SCROLL_VILLAGER = new ConfigBoolean("enableScrollingVillager", true, "itemscroller.config.toggles.comment.enableScrollingVillager").translatedName("itemscroller.config.toggles.name.enableScrollingVillager"); - public static final ConfigBoolean SHIFT_DROP_ITEMS = new ConfigBoolean("enableShiftDropItems", true, "itemscroller.config.toggles.comment.enableShiftDropItems").translatedName("itemscroller.config.toggles.name.enableShiftDropItems"); - public static final ConfigBoolean SHIFT_PLACE_ITEMS = new ConfigBoolean("enableShiftPlaceItems", true, "itemscroller.config.toggles.comment.enableShiftPlaceItems").translatedName("itemscroller.config.toggles.name.enableShiftPlaceItems"); - public static final ConfigBoolean VILLAGER_TRADE_FEATURES = new ConfigBoolean("enableVillagerTradeFeatures", true, "itemscroller.config.toggles.comment.enableVillagerTradeFeatures").translatedName("itemscroller.config.toggles.name.enableVillagerTradeFeatures"); + public static final ConfigBoolean CRAFTING_FEATURES = new ConfigBoolean("enableCraftingFeatures", true).apply(TOGGLES_KEY); + public static final ConfigBoolean DROP_MATCHING = new ConfigBoolean("enableDropkeyDropMatching", true).apply(TOGGLES_KEY); + public static final ConfigBoolean RIGHT_CLICK_CRAFT_STACK = new ConfigBoolean("enableRightClickCraftingOneStack", true).apply(TOGGLES_KEY); + public static final ConfigBoolean SCROLL_EVERYTHING = new ConfigBoolean("enableScrollingEverything", true).apply(TOGGLES_KEY); + public static final ConfigBoolean SCROLL_MATCHING = new ConfigBoolean("enableScrollingMatchingStacks", true).apply(TOGGLES_KEY); + public static final ConfigBoolean SCROLL_SINGLE = new ConfigBoolean("enableScrollingSingle", true).apply(TOGGLES_KEY); + public static final ConfigBoolean SCROLL_STACKS = new ConfigBoolean("enableScrollingStacks", true).apply(TOGGLES_KEY); + public static final ConfigBoolean SCROLL_STACKS_FALLBACK = new ConfigBoolean("enableScrollingStacksFallback", true).apply(TOGGLES_KEY); + public static final ConfigBoolean SCROLL_VILLAGER = new ConfigBoolean("enableScrollingVillager", true).apply(TOGGLES_KEY); + public static final ConfigBoolean SHIFT_DROP_ITEMS = new ConfigBoolean("enableShiftDropItems", true).apply(TOGGLES_KEY); + public static final ConfigBoolean SHIFT_PLACE_ITEMS = new ConfigBoolean("enableShiftPlaceItems", true).apply(TOGGLES_KEY); + public static final ConfigBoolean VILLAGER_TRADE_FEATURES = new ConfigBoolean("enableVillagerTradeFeatures", true).apply(TOGGLES_KEY); public static final ImmutableList OPTIONS = ImmutableList.of( CRAFTING_FEATURES, diff --git a/src/main/java/fi/dy/masa/itemscroller/config/Hotkeys.java b/src/main/java/fi/dy/masa/itemscroller/config/Hotkeys.java index af09ad1..7389fc2 100644 --- a/src/main/java/fi/dy/masa/itemscroller/config/Hotkeys.java +++ b/src/main/java/fi/dy/masa/itemscroller/config/Hotkeys.java @@ -5,6 +5,7 @@ import fi.dy.masa.malilib.config.options.ConfigHotkey; import fi.dy.masa.malilib.hotkeys.KeyAction; import fi.dy.masa.malilib.hotkeys.KeybindSettings; +import fi.dy.masa.itemscroller.Reference; public class Hotkeys { @@ -12,45 +13,47 @@ public class Hotkeys private static final KeybindSettings GUI_RELAXED_CANCEL = KeybindSettings.create(KeybindSettings.Context.GUI, KeyAction.PRESS, true, false, false, true); private static final KeybindSettings GUI_NO_ORDER = KeybindSettings.create(KeybindSettings.Context.GUI, KeyAction.PRESS, false, false, false, true); - public static final ConfigHotkey OPEN_CONFIG_GUI = new ConfigHotkey("openConfigGui", "I,C", "itemscroller.config.hotkeys.comment.openConfigGui").translatedName("itemscroller.config.hotkeys.name.openConfigGui"); - - public static final ConfigHotkey CRAFT_EVERYTHING = new ConfigHotkey("craftEverything", "LEFT_CONTROL,C", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.craftEverything").translatedName("itemscroller.config.hotkeys.name.craftEverything"); - public static final ConfigHotkey DROP_ALL_MATCHING = new ConfigHotkey("dropAllMatching", "LEFT_CONTROL,LEFT_SHIFT,Q", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.dropAllMatching").translatedName("itemscroller.config.hotkeys.name.dropAllMatching"); - public static final ConfigHotkey MASS_CRAFT = new ConfigHotkey("massCraft", "LEFT_CONTROL,LEFT_ALT,C", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.massCraft").translatedName("itemscroller.config.hotkeys.name.massCraft"); - public static final ConfigHotkey MOVE_CRAFT_RESULTS = new ConfigHotkey("moveCraftResults", "LEFT_CONTROL,M", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.moveCraftResults").translatedName("itemscroller.config.hotkeys.name.moveCraftResults"); - public static final ConfigHotkey RECIPE_VIEW = new ConfigHotkey("recipeView", "A", GUI_RELAXED, "itemscroller.config.hotkeys.comment.recipeView").translatedName("itemscroller.config.hotkeys.name.recipeView"); - public static final ConfigHotkey SLOT_DEBUG = new ConfigHotkey("slotDebug", "LEFT_CONTROL,LEFT_ALT,LEFT_SHIFT,I", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.slotDebug").translatedName("itemscroller.config.hotkeys.name.slotDebug"); - public static final ConfigHotkey STORE_RECIPE = new ConfigHotkey("storeRecipe", "BUTTON_3", GUI_RELAXED_CANCEL, "itemscroller.config.hotkeys.comment.storeRecipe").translatedName("itemscroller.config.hotkeys.name.storeRecipe"); - public static final ConfigHotkey THROW_CRAFT_RESULTS = new ConfigHotkey("throwCraftResults", "LEFT_CONTROL,T", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.throwCraftResults").translatedName("itemscroller.config.hotkeys.name.throwCraftResults"); - public static final ConfigHotkey TOGGLE_MOD_ON_OFF = new ConfigHotkey("toggleModOnOff", "", KeybindSettings.GUI, "itemscroller.config.hotkeys.comment.toggleModOnOff").translatedName("itemscroller.config.hotkeys.name.toggleModOnOff"); - public static final ConfigHotkey VILLAGER_TRADE_FAVORITES = new ConfigHotkey("villagerTradeFavorites","", KeybindSettings.GUI, "itemscroller.config.hotkeys.comment.villagerTradeFavorites").translatedName("itemscroller.config.hotkeys.name.villagerTradeFavorites"); - - public static final ConfigHotkey KEY_DRAG_DROP_LEAVE_ONE = new ConfigHotkey("keyDragDropLeaveOne", "LEFT_SHIFT,Q,BUTTON_2", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.keyDragDropLeaveOne").translatedName("itemscroller.config.hotkeys.name.keyDragDropLeaveOne"); - public static final ConfigHotkey KEY_DRAG_DROP_SINGLE = new ConfigHotkey("keyDragDropSingle", "Q,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.keyDragDropSingle").translatedName("itemscroller.config.hotkeys.name.keyDragDropSingle"); - public static final ConfigHotkey KEY_DRAG_DROP_STACKS = new ConfigHotkey("keyDragDropStacks", "LEFT_SHIFT,Q,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.keyDragDropStacks").translatedName("itemscroller.config.hotkeys.name.keyDragDropStacks"); - - public static final ConfigHotkey KEY_DRAG_LEAVE_ONE = new ConfigHotkey("keyDragMoveLeaveOne", "LEFT_SHIFT,BUTTON_2", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.keyDragMoveLeaveOne").translatedName("itemscroller.config.hotkeys.name.keyDragMoveLeaveOne"); - public static final ConfigHotkey KEY_DRAG_MATCHING = new ConfigHotkey("keyDragMoveMatching", "LEFT_ALT,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.keyDragMoveMatching").translatedName("itemscroller.config.hotkeys.name.keyDragMoveMatching"); - public static final ConfigHotkey KEY_DRAG_MOVE_ONE = new ConfigHotkey("keyDragMoveOne", "LEFT_CONTROL,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.keyDragMoveOne").translatedName("itemscroller.config.hotkeys.name.keyDragMoveOne"); - public static final ConfigHotkey KEY_DRAG_FULL_STACKS = new ConfigHotkey("keyDragMoveStacks", "LEFT_SHIFT,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.keyDragMoveStacks").translatedName("itemscroller.config.hotkeys.name.keyDragMoveStacks"); - - public static final ConfigHotkey KEY_MOVE_EVERYTHING = new ConfigHotkey("keyMoveEverything", "LEFT_ALT,LEFT_SHIFT,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.keyMoveEverything").translatedName("itemscroller.config.hotkeys.name.keyMoveEverything"); - - public static final ConfigHotkey KEY_WS_MOVE_DOWN_LEAVE_ONE = new ConfigHotkey("wsMoveDownLeaveOne", "S,BUTTON_2", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.wsMoveDownLeaveOne").translatedName("itemscroller.config.hotkeys.name.wsMoveDownLeaveOne"); - public static final ConfigHotkey KEY_WS_MOVE_DOWN_MATCHING = new ConfigHotkey("wsMoveDownMatching", "LEFT_ALT,S,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.wsMoveDownMatching").translatedName("itemscroller.config.hotkeys.name.wsMoveDownMatching"); - public static final ConfigHotkey KEY_WS_MOVE_DOWN_SINGLE = new ConfigHotkey("wsMoveDownSingle", "S,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.wsMoveDownSingle").translatedName("itemscroller.config.hotkeys.name.wsMoveDownSingle"); - public static final ConfigHotkey KEY_WS_MOVE_DOWN_STACKS = new ConfigHotkey("wsMoveDownStacks", "LEFT_SHIFT,S,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.wsMoveDownStacks").translatedName("itemscroller.config.hotkeys.name.wsMoveDownStacks"); - public static final ConfigHotkey KEY_WS_MOVE_UP_LEAVE_ONE = new ConfigHotkey("wsMoveUpLeaveOne", "W,BUTTON_2", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.wsMoveUpLeaveOne").translatedName("itemscroller.config.hotkeys.name.wsMoveUpLeaveOne"); - public static final ConfigHotkey KEY_WS_MOVE_UP_MATCHING = new ConfigHotkey("wsMoveUpMatching", "LEFT_ALT,W,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.wsMoveUpMatching").translatedName("itemscroller.config.hotkeys.name.wsMoveUpMatching"); - public static final ConfigHotkey KEY_WS_MOVE_UP_SINGLE = new ConfigHotkey("wsMoveUpSingle", "W,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.wsMoveUpSingle").translatedName("itemscroller.config.hotkeys.name.wsMoveUpSingle"); - public static final ConfigHotkey KEY_WS_MOVE_UP_STACKS = new ConfigHotkey("wsMoveUpStacks", "LEFT_SHIFT,W,BUTTON_1", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.wsMoveUpStacks").translatedName("itemscroller.config.hotkeys.name.wsMoveUpStacks"); - - public static final ConfigHotkey MODIFIER_MOVE_EVERYTHING = new ConfigHotkey("modifierMoveEverything", "LEFT_ALT,LEFT_SHIFT", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.modifierMoveEverything").translatedName("itemscroller.config.hotkeys.name.modifierMoveEverything"); - public static final ConfigHotkey MODIFIER_MOVE_MATCHING = new ConfigHotkey("modifierMoveMatching", "LEFT_ALT", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.modifierMoveMatching").translatedName("itemscroller.config.hotkeys.name.modifierMoveMatching"); - public static final ConfigHotkey MODIFIER_MOVE_STACK = new ConfigHotkey("modifierMoveStack", "LEFT_SHIFT", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.modifierMoveStack").translatedName("itemscroller.config.hotkeys.name.modifierMoveStack"); - public static final ConfigHotkey MODIFIER_TOGGLE_VILLAGER_GLOBAL_FAVORITE = new ConfigHotkey("modifierToggleVillagerGlobalFavorite", "LEFT_SHIFT", GUI_RELAXED, "itemscroller.config.hotkeys.comment.modifierToggleVillagerGlobalFavorite").translatedName("itemscroller.config.hotkeys.name.modifierToggleVillagerGlobalFavorite"); - - public static final ConfigHotkey SORT_INVENTORY = new ConfigHotkey("sortInventory", "R", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.sortInventory").translatedName("itemscroller.config.hotkeys.name.sortInventory"); + private static final String HOTKEYS_KEY = Reference.ID+".config.hotkeys"; + + public static final ConfigHotkey OPEN_CONFIG_GUI = new ConfigHotkey("openConfigGui", "I,C").apply(HOTKEYS_KEY); + + public static final ConfigHotkey CRAFT_EVERYTHING = new ConfigHotkey("craftEverything", "LEFT_CONTROL,C", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey DROP_ALL_MATCHING = new ConfigHotkey("dropAllMatching", "LEFT_CONTROL,LEFT_SHIFT,Q", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey MASS_CRAFT = new ConfigHotkey("massCraft", "LEFT_CONTROL,LEFT_ALT,C", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey MOVE_CRAFT_RESULTS = new ConfigHotkey("moveCraftResults", "LEFT_CONTROL,M", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey RECIPE_VIEW = new ConfigHotkey("recipeView", "A", GUI_RELAXED).apply(HOTKEYS_KEY); + public static final ConfigHotkey SLOT_DEBUG = new ConfigHotkey("slotDebug", "LEFT_CONTROL,LEFT_ALT,LEFT_SHIFT,I", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey STORE_RECIPE = new ConfigHotkey("storeRecipe", "BUTTON_3", GUI_RELAXED_CANCEL).apply(HOTKEYS_KEY); + public static final ConfigHotkey THROW_CRAFT_RESULTS = new ConfigHotkey("throwCraftResults", "LEFT_CONTROL,T", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey TOGGLE_MOD_ON_OFF = new ConfigHotkey("toggleModOnOff", "", KeybindSettings.GUI).apply(HOTKEYS_KEY); + public static final ConfigHotkey VILLAGER_TRADE_FAVORITES = new ConfigHotkey("villagerTradeFavorites","", KeybindSettings.GUI).apply(HOTKEYS_KEY); + + public static final ConfigHotkey KEY_DRAG_DROP_LEAVE_ONE = new ConfigHotkey("keyDragDropLeaveOne", "LEFT_SHIFT,Q,BUTTON_2", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_DRAG_DROP_SINGLE = new ConfigHotkey("keyDragDropSingle", "Q,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_DRAG_DROP_STACKS = new ConfigHotkey("keyDragDropStacks", "LEFT_SHIFT,Q,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + + public static final ConfigHotkey KEY_DRAG_LEAVE_ONE = new ConfigHotkey("keyDragMoveLeaveOne", "LEFT_SHIFT,BUTTON_2", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_DRAG_MATCHING = new ConfigHotkey("keyDragMoveMatching", "LEFT_ALT,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_DRAG_MOVE_ONE = new ConfigHotkey("keyDragMoveOne", "LEFT_CONTROL,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_DRAG_FULL_STACKS = new ConfigHotkey("keyDragMoveStacks", "LEFT_SHIFT,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + + public static final ConfigHotkey KEY_MOVE_EVERYTHING = new ConfigHotkey("keyMoveEverything", "LEFT_ALT,LEFT_SHIFT,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + + public static final ConfigHotkey KEY_WS_MOVE_DOWN_LEAVE_ONE = new ConfigHotkey("wsMoveDownLeaveOne", "S,BUTTON_2", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_WS_MOVE_DOWN_MATCHING = new ConfigHotkey("wsMoveDownMatching", "LEFT_ALT,S,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_WS_MOVE_DOWN_SINGLE = new ConfigHotkey("wsMoveDownSingle", "S,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_WS_MOVE_DOWN_STACKS = new ConfigHotkey("wsMoveDownStacks", "LEFT_SHIFT,S,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_WS_MOVE_UP_LEAVE_ONE = new ConfigHotkey("wsMoveUpLeaveOne", "W,BUTTON_2", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_WS_MOVE_UP_MATCHING = new ConfigHotkey("wsMoveUpMatching", "LEFT_ALT,W,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_WS_MOVE_UP_SINGLE = new ConfigHotkey("wsMoveUpSingle", "W,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey KEY_WS_MOVE_UP_STACKS = new ConfigHotkey("wsMoveUpStacks", "LEFT_SHIFT,W,BUTTON_1", GUI_NO_ORDER).apply(HOTKEYS_KEY); + + public static final ConfigHotkey MODIFIER_MOVE_EVERYTHING = new ConfigHotkey("modifierMoveEverything", "LEFT_ALT,LEFT_SHIFT", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey MODIFIER_MOVE_MATCHING = new ConfigHotkey("modifierMoveMatching", "LEFT_ALT", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey MODIFIER_MOVE_STACK = new ConfigHotkey("modifierMoveStack", "LEFT_SHIFT", GUI_NO_ORDER).apply(HOTKEYS_KEY); + public static final ConfigHotkey MODIFIER_TOGGLE_VILLAGER_GLOBAL_FAVORITE = new ConfigHotkey("modifierToggleVillagerGlobalFavorite", "LEFT_SHIFT", GUI_RELAXED).apply(HOTKEYS_KEY); + + public static final ConfigHotkey SORT_INVENTORY = new ConfigHotkey("sortInventory", "R", GUI_NO_ORDER).apply(HOTKEYS_KEY); public static final List HOTKEY_LIST = ImmutableList.of( OPEN_CONFIG_GUI, diff --git a/src/main/java/fi/dy/masa/itemscroller/event/InputHandler.java b/src/main/java/fi/dy/masa/itemscroller/event/InputHandler.java index 66620dd..518fdaf 100644 --- a/src/main/java/fi/dy/masa/itemscroller/event/InputHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/event/InputHandler.java @@ -200,7 +200,9 @@ private boolean handleInputImpl(int keyCode, boolean keyState, double dWheel, Mi // Pick-blocking over a crafting output slot with the recipe view open, store the recipe else if (isPickBlock && InputUtils.isRecipeViewOpen() && InventoryUtils.isCraftingSlot(gui, slot)) { - recipes.storeCraftingRecipeToCurrentSelection(slot, gui, true); + recipes.storeCraftingRecipeToCurrentSelection(slot, gui, true, false, mc); + InventoryUtils.clearFirstCraftingGridOfAllItems(gui); + //InventoryUtils.clearCraftingGridCursorStack(gui, mc); cancel = true; } } diff --git a/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java b/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java index ffa3385..b4b8c9e 100644 --- a/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java +++ b/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java @@ -149,7 +149,9 @@ else if (key == Hotkeys.STORE_RECIPE.getKeybind()) { if (InputUtils.isRecipeViewOpen() && InventoryUtils.isCraftingSlot(gui, slot)) { - recipes.storeCraftingRecipeToCurrentSelection(slot, gui, true); + recipes.storeCraftingRecipeToCurrentSelection(slot, gui, true, true, mc); + InventoryUtils.clearFirstCraftingGridOfAllItems(gui); + //InventoryUtils.clearCraftingGridCursorStack(gui, mc); return true; } } @@ -225,6 +227,7 @@ public void onClientTick(MinecraftClient mc) InventoryUtils.bufferInvUpdates = true; Slot outputSlot = CraftingHandler.getFirstCraftingOutputSlotForGui(gui); + // FIXME if (outputSlot != null) { if (Configs.Generic.RATE_LIMIT_CLICK_PACKETS.getBooleanValue()) @@ -236,18 +239,16 @@ public void onClientTick(MinecraftClient mc) int limit = Configs.Generic.MASS_CRAFT_ITERATIONS.getIntegerValue(); - if (Configs.Generic.MASS_CRAFT_RECIPE_BOOK.getBooleanValue() && recipe.lookupVanillaRecipe(mc.world) != null) + if (Configs.Generic.MASS_CRAFT_RECIPE_BOOK.getBooleanValue() && recipe.getNetworkRecipeId() != null) { InventoryUtils.dontUpdateRecipeBook = 2; for (int i = 0; i < limit; ++i) { // todo //InventoryUtils.setInhibitCraftingOutputUpdate(true); - //InventoryUtils.tryClearCursor(gui); - //InventoryUtils.throwAllCraftingResultsToGround(recipe, gui); RecipeInputInventory craftingInv = ((IMixinCraftingResultSlot) outputSlot).itemscroller_getCraftingInventory(); - if (!recipe.getVanillaRecipe().matches(craftingInv.createRecipeInput(), mc.world)) + if (recipe.getVanillaRecipe() != null && !recipe.getVanillaRecipe().matches(craftingInv.createRecipeInput(), mc.world)) { CraftingHandler.SlotRange range = CraftingHandler.getCraftingGridSlots(gui, outputSlot); final int invSlots = gui.getScreenHandler().slots.size(); @@ -266,24 +267,18 @@ public void onClientTick(MinecraftClient mc) } } - mc.interactionManager.clickRecipe(gui.getScreenHandler().syncId, recipe.getVanillaRecipeEntry(), true); + mc.interactionManager.clickRecipe(gui.getScreenHandler().syncId, recipe.getNetworkRecipeId(), true); // InventoryUtils.setInhibitCraftingOutputUpdate(false); // InventoryUtils.updateCraftingOutputSlot(outputSlot); craftingInv = ((IMixinCraftingResultSlot) outputSlot).itemscroller_getCraftingInventory(); - if (recipe.getVanillaRecipe().matches(craftingInv.createRecipeInput(), mc.world)) + if (recipe.getVanillaRecipe() != null && recipe.getVanillaRecipe().matches(craftingInv.createRecipeInput(), mc.world)) { break; } InventoryUtils.shiftClickSlot(gui, outputSlot.id); - - // This isn't required after 1.21, it only needs a single dropStack - for (int k = 0; k < recipe.getResult().getMaxCount(); k++) - { - InventoryUtils.dropStack(gui, outputSlot.id); - } - + InventoryUtils.dropStack(gui, outputSlot.id); recipeBookClicks = true; } diff --git a/src/main/java/fi/dy/masa/itemscroller/event/RenderEventHandler.java b/src/main/java/fi/dy/masa/itemscroller/event/RenderEventHandler.java index 25c3a31..e928c3c 100644 --- a/src/main/java/fi/dy/masa/itemscroller/event/RenderEventHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/event/RenderEventHandler.java @@ -1,14 +1,12 @@ package fi.dy.masa.itemscroller.event; -import org.joml.Matrix4fStack; -import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.render.DiffuseLighting; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; + import fi.dy.masa.malilib.render.InventoryOverlay; import fi.dy.masa.malilib.render.RenderUtils; import fi.dy.masa.malilib.util.GuiUtils; @@ -41,11 +39,11 @@ public static RenderEventHandler instance() return INSTANCE; } - public void renderRecipeView(DrawContext drawContext) + public void renderRecipeView(MinecraftClient mc, DrawContext drawContext, int mouseX, int mouseY) { - if (GuiUtils.getCurrentScreen() instanceof HandledScreen && InputUtils.isRecipeViewOpen()) + if (GuiUtils.getCurrentScreen() instanceof HandledScreen gui && + InputUtils.isRecipeViewOpen()) { - HandledScreen gui = (HandledScreen) GuiUtils.getCurrentScreen(); RecipeStorage recipes = RecipeStorage.getInstance(); final int first = recipes.getFirstVisibleRecipeId(); final int countPerPage = recipes.getRecipeCountPerPage(); @@ -53,14 +51,21 @@ public void renderRecipeView(DrawContext drawContext) this.calculateRecipePositions(gui); + drawContext.getMatrices().push(); + drawContext.getMatrices().translate(this.recipeListX, this.recipeListY, 0); + drawContext.getMatrices().scale((float) this.scale, (float) this.scale, 1); + + /* Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack(); matrix4fStack.pushMatrix(); matrix4fStack.translate(this.recipeListX, this.recipeListY, 0); matrix4fStack.scale((float) this.scale, (float) this.scale, 1); + */ String str = StringUtils.translate("itemscroller.gui.label.recipe_page", (first / countPerPage) + 1, recipes.getTotalRecipeCount() / countPerPage); drawContext.drawText(this.mc.textRenderer, str, 16, -12, 0xC0C0C0C0, false); + RenderUtils.forceDraw(drawContext); for (int i = 0, recipeId = first; recipeId <= lastOnPage; ++i, ++recipeId) { @@ -74,28 +79,24 @@ public void renderRecipeView(DrawContext drawContext) if (Configs.Generic.CRAFTING_RENDER_RECIPE_ITEMS.getBooleanValue()) { - final int mouseX = fi.dy.masa.malilib.util.InputUtils.getMouseX(); - final int mouseY = fi.dy.masa.malilib.util.InputUtils.getMouseY(); final int recipeId = this.getHoveredRecipeId(mouseX, mouseY, recipes, gui); RecipePattern recipe = recipeId >= 0 ? recipes.getRecipe(recipeId) : recipes.getSelectedRecipe(); this.renderRecipeItems(recipe, recipes.getRecipeCountPerPage(), gui, drawContext); } - matrix4fStack.popMatrix(); - RenderSystem.applyModelViewMatrix(); - RenderSystem.enableBlend(); // Fixes the crafting book icon rendering + drawContext.getMatrices().pop(); + //matrix4fStack.popMatrix(); + //RenderSystem.enableBlend(); // Fixes the crafting book icon rendering } } - public void onDrawScreenPost(MinecraftClient mc, DrawContext drawContext) + public void onDrawScreenPost(MinecraftClient mc, DrawContext drawContext, int mouseX, int mouseY) { - this.renderRecipeView(drawContext); + this.renderRecipeView(mc, drawContext, mouseX, mouseY); - if (GuiUtils.getCurrentScreen() instanceof HandledScreen) + if (GuiUtils.getCurrentScreen() instanceof HandledScreen gui) { - HandledScreen gui = (HandledScreen) this.mc.currentScreen; - int bufferedCount = ClickPacketBuffer.getBufferedActionsCount(); if (bufferedCount > 0) @@ -103,40 +104,33 @@ public void onDrawScreenPost(MinecraftClient mc, DrawContext drawContext) drawContext.drawText(mc.textRenderer, "Buffered slot clicks: " + bufferedCount, 10, 10, 0xFFD0D0D0, false); } - if (InputUtils.isRecipeViewOpen() == false) + if (InputUtils.isRecipeViewOpen()) { - return; - } - - RecipeStorage recipes = RecipeStorage.getInstance(); + RecipeStorage recipes = RecipeStorage.getInstance(); + final int recipeId = this.getHoveredRecipeId(mouseX, mouseY, recipes, gui); + float offset = 300f; - final int mouseX = fi.dy.masa.malilib.util.InputUtils.getMouseX(); - final int mouseY = fi.dy.masa.malilib.util.InputUtils.getMouseY(); - final int recipeId = this.getHoveredRecipeId(mouseX, mouseY, recipes, gui); + drawContext.getMatrices().push(); + drawContext.getMatrices().translate(0, 0, offset); - float offset = 300f; - Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack(); - matrix4fStack.pushMatrix(); - matrix4fStack.translate(0, 0, offset); - - if (recipeId >= 0) - { - RecipePattern recipe = recipes.getRecipe(recipeId); - this.renderHoverTooltip(mouseX, mouseY, recipe, gui, drawContext); - } - else if (Configs.Generic.CRAFTING_RENDER_RECIPE_ITEMS.getBooleanValue()) - { - RecipePattern recipe = recipes.getSelectedRecipe(); - ItemStack stack = this.getHoveredRecipeIngredient(mouseX, mouseY, recipe, recipes.getRecipeCountPerPage(), gui); - - if (InventoryUtils.isStackEmpty(stack) == false) + if (recipeId >= 0) { - InventoryOverlay.renderStackToolTip(mouseX, mouseY, stack, this.mc, drawContext); + RecipePattern recipe = recipes.getRecipe(recipeId); + this.renderHoverTooltip(mouseX, mouseY, recipe, gui, drawContext); } - } + else if (Configs.Generic.CRAFTING_RENDER_RECIPE_ITEMS.getBooleanValue()) + { + RecipePattern recipe = recipes.getSelectedRecipe(); + ItemStack stack = this.getHoveredRecipeIngredient(mouseX, mouseY, recipe, recipes.getRecipeCountPerPage(), gui); - matrix4fStack.popMatrix(); - RenderSystem.applyModelViewMatrix(); + if (InventoryUtils.isStackEmpty(stack) == false) + { + InventoryOverlay.renderStackToolTip(mouseX, mouseY, stack, this.mc, drawContext); + } + } + + drawContext.getMatrices().pop(); + } } } @@ -146,7 +140,6 @@ private void calculateRecipePositions(HandledScreen gui) final int gapHorizontal = 2; final int gapVertical = 2; final int stackBaseHeight = 16; - final int guiLeft = AccessorUtils.getGuiLeft(gui); this.recipesPerColumn = 9; this.columns = (int) Math.ceil((double) recipes.getRecipeCountPerPage() / (double) this.recipesPerColumn); @@ -154,7 +147,7 @@ private void calculateRecipePositions(HandledScreen gui) this.gapColumn = 4; int usableHeight = GuiUtils.getScaledWindowHeight(); - int usableWidth = guiLeft; + int usableWidth = AccessorUtils.getGuiLeft(gui); // Scale the maximum stack size by taking into account the relative gap size double gapScaleVertical = (1D - (double) gapVertical / (double) (stackBaseHeight + gapVertical)); // the +1.2 is for the gap and page text height on the top and bottom @@ -166,7 +159,7 @@ private void calculateRecipePositions(HandledScreen gui) this.scale = (double) stackDimensions / (double) stackBaseHeight; this.entryHeight = stackBaseHeight + gapVertical; - this.recipeListX = guiLeft - (int) ((this.columns * (stackBaseHeight + this.numberTextWidth + this.gapColumn) + gapHorizontal) * this.scale); + this.recipeListX = usableWidth - (int) ((this.columns * (stackBaseHeight + this.numberTextWidth + this.gapColumn) + gapHorizontal) * this.scale); this.recipeListY = (int) (this.entryHeight * this.scale); this.columnWidth = stackBaseHeight + this.numberTextWidth + this.gapColumn; } @@ -224,15 +217,14 @@ private void renderStoredRecipeStack(ItemStack stack, int recipeId, int row, int x = x - (int) (font.getWidth(indexStr) * scale) - 2; y = row * this.entryHeight + this.entryHeight / 2 - font.fontHeight / 2; - // TODO DrawContext still uses the MatrixStack type - MatrixStack matrixStack = drawContext.getMatrices(); - matrixStack.push(); - matrixStack.translate(x, y, 0); - matrixStack.scale(scale, scale, 1); + drawContext.getMatrices().push(); + drawContext.getMatrices().translate(x, y, 0); + drawContext.getMatrices().scale(scale, scale, 1); drawContext.drawText(font, indexStr, 0, 0, 0xFFC0C0C0, false); + RenderUtils.forceDraw(drawContext); - matrixStack.pop(); + drawContext.getMatrices().pop(); } private void renderRecipeItems(RecipePattern recipe, int recipeCountPerPage, HandledScreen gui, DrawContext drawContext) @@ -289,14 +281,18 @@ private ItemStack getHoveredRecipeIngredient(int mouseX, int mouseY, RecipePatte private void renderStackAt(ItemStack stack, int x, int y, boolean border, DrawContext drawContext) { final int w = 16; + int xAdj = (int) ((x) * this.scale) + this.recipeListX; + int yAdj = (int) ((y) * this.scale) + this.recipeListY; + int wAdj = (int) ((w) * this.scale); if (border) { // Draw a light/white border around the stack - RenderUtils.drawOutline(x - 1, y - 1, w + 2, w + 2, 0xFFFFFFFF); + RenderUtils.drawOutline(xAdj - 1, yAdj - 1, wAdj + 2, wAdj + 2, 0xFFFFFFFF); } - RenderUtils.drawRect(x, y, w, w, 0x20FFFFFF); // light background for the item + // light background for the item + RenderUtils.drawRect(xAdj, yAdj, wAdj, wAdj, 0x20FFFFFF); if (InventoryUtils.isStackEmpty(stack) == false) { @@ -305,14 +301,13 @@ private void renderStackAt(ItemStack stack, int x, int y, boolean border, DrawCo stack = stack.copy(); InventoryUtils.setStackSize(stack, 1); - // TODO DrawContext still uses the MatrixStack type - MatrixStack matrixStack = drawContext.getMatrices(); - matrixStack.push(); - matrixStack.translate(0, 0, 100.f); + drawContext.getMatrices().push(); + drawContext.getMatrices().translate(0, 0, 100.f); drawContext.drawItem(stack, x, y); + RenderUtils.forceDraw(drawContext); - matrixStack.pop(); + drawContext.getMatrices().pop(); } } diff --git a/src/main/java/fi/dy/masa/itemscroller/event/WorldLoadListener.java b/src/main/java/fi/dy/masa/itemscroller/event/WorldLoadListener.java index 2a88c14..1dd61ef 100644 --- a/src/main/java/fi/dy/masa/itemscroller/event/WorldLoadListener.java +++ b/src/main/java/fi/dy/masa/itemscroller/event/WorldLoadListener.java @@ -2,9 +2,11 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; + import net.minecraft.client.MinecraftClient; import net.minecraft.client.world.ClientWorld; import net.minecraft.registry.DynamicRegistryManager; + import fi.dy.masa.malilib.interfaces.IWorldLoadListener; import fi.dy.masa.itemscroller.config.Configs; import fi.dy.masa.itemscroller.recipes.RecipeStorage; diff --git a/src/main/java/fi/dy/masa/itemscroller/gui/ItemScrollerIcons.java b/src/main/java/fi/dy/masa/itemscroller/gui/ItemScrollerIcons.java index c3b1158..0c3795a 100644 --- a/src/main/java/fi/dy/masa/itemscroller/gui/ItemScrollerIcons.java +++ b/src/main/java/fi/dy/masa/itemscroller/gui/ItemScrollerIcons.java @@ -1,5 +1,6 @@ package fi.dy.masa.itemscroller.gui; +import net.minecraft.client.gui.DrawContext; import net.minecraft.util.Identifier; import fi.dy.masa.malilib.gui.interfaces.IGuiIcon; import fi.dy.masa.malilib.render.RenderUtils; @@ -62,7 +63,7 @@ public int getV() } @Override - public void renderAt(int x, int y, float zLevel, boolean enabled, boolean selected) + public void renderAt(int x, int y, float zLevel, boolean enabled, boolean selected, DrawContext drawContext) { int u = this.u; int v = this.v; diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinAbstractCraftingScreenHandler.java b/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinAbstractCraftingScreenHandler.java new file mode 100644 index 0000000..e763511 --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinAbstractCraftingScreenHandler.java @@ -0,0 +1,17 @@ +package fi.dy.masa.itemscroller.mixin; + +import net.minecraft.inventory.CraftingResultInventory; +import net.minecraft.inventory.RecipeInputInventory; +import net.minecraft.screen.AbstractCraftingScreenHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(AbstractCraftingScreenHandler.class) +public interface IMixinAbstractCraftingScreenHandler +{ + @Accessor("craftingInventory") + RecipeInputInventory itemscroller_getCraftingInventory(); + + @Accessor("craftingResultInventory") + CraftingResultInventory itemscroller_getCraftingResultInventory(); +} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinClientRecipeBook.java b/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinClientRecipeBook.java new file mode 100644 index 0000000..2f3fbdb --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinClientRecipeBook.java @@ -0,0 +1,16 @@ +package fi.dy.masa.itemscroller.mixin; + +import java.util.Map; + +import net.minecraft.client.recipebook.ClientRecipeBook; +import net.minecraft.recipe.NetworkRecipeId; +import net.minecraft.recipe.RecipeDisplayEntry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ClientRecipeBook.class) +public interface IMixinClientRecipeBook +{ + @Accessor("recipes") + Map itemscroller_getRecipeMap(); +} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinRecipeBookScreen.java b/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinRecipeBookScreen.java new file mode 100644 index 0000000..5d8baf3 --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinRecipeBookScreen.java @@ -0,0 +1,13 @@ +package fi.dy.masa.itemscroller.mixin; + +import net.minecraft.client.gui.screen.ingame.RecipeBookScreen; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(RecipeBookScreen.class) +public interface IMixinRecipeBookScreen +{ + @Accessor("recipeBook") + RecipeBookWidget itemscroller_getRecipeBookWidget(); +} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinRecipeBookWidget.java b/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinRecipeBookWidget.java new file mode 100644 index 0000000..02367ac --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/IMixinRecipeBookWidget.java @@ -0,0 +1,30 @@ +package fi.dy.masa.itemscroller.mixin; + +import net.minecraft.client.gui.screen.recipebook.GhostRecipe; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.recipe.NetworkRecipeId; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(RecipeBookWidget.class) +public interface IMixinRecipeBookWidget +{ + @Accessor("ghostRecipe") + GhostRecipe itemscroller_getGhostRecipe(); + + /* + @Accessor("recipesArea") + RecipeBookResults itemscroller_getRecipeArea(); + + @Accessor("selectedRecipeResults") + RecipeResultCollection itemscroller_getSelectedRecipeResults(); + */ + + @Accessor("selectedRecipe") + NetworkRecipeId itemscroller_getSelectedRecipe(); + + /* + @Invoker("select") + boolean itemscroller_select(RecipeResultCollection results, NetworkRecipeId recipeId); + */ +} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinAbstractCraftingRecipeBookWidget.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinAbstractCraftingRecipeBookWidget.java new file mode 100644 index 0000000..7c5b868 --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinAbstractCraftingRecipeBookWidget.java @@ -0,0 +1,45 @@ +package fi.dy.masa.itemscroller.mixin; + +import fi.dy.masa.itemscroller.util.InventoryUtils; + +import net.minecraft.client.gui.screen.recipebook.AbstractCraftingRecipeBookWidget; +import net.minecraft.client.gui.screen.recipebook.GhostRecipe; +import net.minecraft.client.gui.screen.recipebook.RecipeResultCollection; +import net.minecraft.recipe.RecipeFinder; +import net.minecraft.recipe.display.RecipeDisplay; +import net.minecraft.util.context.ContextParameterMap; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(AbstractCraftingRecipeBookWidget.class) +public class MixinAbstractCraftingRecipeBookWidget +{ + /* + @Inject(method = "populateRecipes", at = @At("HEAD"), cancellable = true) + private void itemscroller_populateRecipes(RecipeResultCollection recipeResultCollection, RecipeFinder recipeFinder, CallbackInfo ci) + { + if (InventoryUtils.dontUpdateRecipeBook > 0) + { + ci.cancel(); + } + } + */ + + // Seems to be (intended) bug from Mojang + /* + @Inject( + method = "showGhostRecipe", + at = @At("HEAD"), + cancellable = true + ) + private void itemscroller_onShowGhostRecipe(GhostRecipe ghostRecipe, RecipeDisplay display, ContextParameterMap context, CallbackInfo ci) + { + if (((IMixinRecipeBookWidget) this).itemscroller_getGhostSlots() == ghostRecipe) + { + ci.cancel(); + } + } + */ +} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinAbstractInventoryScreen.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinAbstractInventoryScreen.java deleted file mode 100644 index 3cca64d..0000000 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinAbstractInventoryScreen.java +++ /dev/null @@ -1,21 +0,0 @@ -package fi.dy.masa.itemscroller.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; -import fi.dy.masa.itemscroller.util.InputUtils; - -@Mixin(AbstractInventoryScreen.class) -public abstract class MixinAbstractInventoryScreen -{ - @Inject(method = "drawStatusEffects", at = @At("HEAD"), cancellable = true) - private void preventPotionEffectRendering(CallbackInfo ci) - { - if (InputUtils.isRecipeViewOpen()) - { - ci.cancel(); - } - } -} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java index c059be5..033cc28 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java @@ -1,12 +1,9 @@ package fi.dy.masa.itemscroller.mixin; -import fi.dy.masa.itemscroller.config.Configs; -import fi.dy.masa.itemscroller.config.Hotkeys; import fi.dy.masa.itemscroller.event.KeybindCallbacks; import fi.dy.masa.itemscroller.util.InventoryUtils; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.network.packet.s2c.play.CraftFailedResponseS2CPacket; -import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.InventoryS2CPacket; import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.StatisticsS2CPacket; @@ -39,8 +36,7 @@ private void onScreenHandlerSlotUpdate(ScreenHandlerSlotUpdateS2CPacket packet, value = "INVOKE", target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", shift = At.Shift.AFTER - ), - cancellable = true + ) ) private void onCraftFailedResponse(CraftFailedResponseS2CPacket packet, CallbackInfo ci) { diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayerInteractionManager.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayerInteractionManager.java index 1685110..4f403c8 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayerInteractionManager.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayerInteractionManager.java @@ -1,14 +1,14 @@ package fi.dy.masa.itemscroller.mixin; +import fi.dy.masa.itemscroller.util.ClickPacketBuffer; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.client.network.ClientPlayerInteractionManager; +import net.minecraft.network.packet.Packet; import org.spongepowered.asm.mixin.Mixin; 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.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.network.packet.Packet; -import fi.dy.masa.itemscroller.util.ClickPacketBuffer; @Mixin(ClientPlayerInteractionManager.class) public class MixinClientPlayerInteractionManager diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientRecipeBook.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientRecipeBook.java new file mode 100644 index 0000000..3c9a46b --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientRecipeBook.java @@ -0,0 +1,20 @@ +package fi.dy.masa.itemscroller.mixin; + +import net.minecraft.client.recipebook.ClientRecipeBook; +import net.minecraft.recipe.RecipeDisplayEntry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import fi.dy.masa.itemscroller.recipes.RecipeStorage; + +@Mixin(ClientRecipeBook.class) +public class MixinClientRecipeBook +{ + @Inject(method = "add", at = @At("RETURN")) + private void itemscroller_addToRecipeBook(RecipeDisplayEntry entry, CallbackInfo ci) + { + RecipeStorage.getInstance().onAddToRecipeBook(entry); + } +} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinCraftingScreenHandler.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinCraftingScreenHandler.java index 42cf464..062ab4f 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinCraftingScreenHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinCraftingScreenHandler.java @@ -1,49 +1,46 @@ package fi.dy.masa.itemscroller.mixin; import net.minecraft.client.MinecraftClient; -import org.spongepowered.asm.mixin.Final; -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.CallbackInfo; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.CraftingResultInventory; import net.minecraft.inventory.RecipeInputInventory; import net.minecraft.recipe.CraftingRecipe; import net.minecraft.recipe.RecipeEntry; +import net.minecraft.screen.CraftingScreenHandler; import net.minecraft.screen.ScreenHandler; -import net.minecraft.world.World; +import net.minecraft.server.world.ServerWorld; +import org.spongepowered.asm.mixin.Final; +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.CallbackInfo; + import fi.dy.masa.itemscroller.util.InventoryUtils; -@Mixin(net.minecraft.screen.CraftingScreenHandler.class) +@Mixin(CraftingScreenHandler.class) public abstract class MixinCraftingScreenHandler { - @Shadow @Final private RecipeInputInventory input; - @Shadow @Final private net.minecraft.inventory.CraftingResultInventory result; - @Shadow @Final private net.minecraft.entity.player.PlayerEntity player; + @Shadow @Final private PlayerEntity player; @Inject(method = "onContentChanged", at = @At("RETURN")) private void onSlotChangedCraftingGrid(net.minecraft.inventory.Inventory inventory, CallbackInfo ci) { if (MinecraftClient.getInstance().isOnThread()) { - InventoryUtils.onSlotChangedCraftingGrid(this.player, this.input, this.result); + InventoryUtils.onSlotChangedCraftingGrid(this.player, + ((IMixinAbstractCraftingScreenHandler) this).itemscroller_getCraftingInventory(), + ((IMixinAbstractCraftingScreenHandler) this).itemscroller_getCraftingResultInventory()); } } @Inject(method = "updateResult", at = @At("RETURN")) private static void onUpdateResult( - ScreenHandler handler, - World world, - PlayerEntity player, - RecipeInputInventory craftingInventory, - CraftingResultInventory resultInv, - RecipeEntry recipeEntry, CallbackInfo ci) + ScreenHandler handler, ServerWorld serverWorld, PlayerEntity player, RecipeInputInventory craftingInventory, CraftingResultInventory resultInventory, RecipeEntry recipe, CallbackInfo ci) { if (MinecraftClient.getInstance().isOnThread()) { - InventoryUtils.onSlotChangedCraftingGrid(player, craftingInventory, resultInv); + InventoryUtils.onSlotChangedCraftingGrid(player, craftingInventory, resultInventory); } } } diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinMerchantScreen.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinMerchantScreen.java index ea48fb5..a03239e 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinMerchantScreen.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinMerchantScreen.java @@ -3,6 +3,7 @@ import javax.annotation.Nullable; 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.callback.CallbackInfo; @@ -31,10 +32,10 @@ @Mixin(MerchantScreen.class) public abstract class MixinMerchantScreen extends HandledScreen { - @Nullable private FavoriteData favoriteData; + @Unique @Nullable private FavoriteData favoriteData; @Shadow private int selectedIndex; @Shadow int indexStartOffset; - private int indexStartOffsetLast = -1; + @Unique private int indexStartOffsetLast = -1; @Shadow protected abstract boolean canScroll(int listSize); @@ -121,7 +122,7 @@ else if (button == 2) this.favoriteData = null; // Force a re-build of the list // Rebuild the custom list based on the new favorites (See the Mixin for MerchantScreenHandler#setOffers()) - this.handler.setOffers(((IMerchantScreenHandler) this.handler).getOriginalList()); + this.handler.setOffers(((IMerchantScreenHandler) this.handler).itemscroller$getOriginalList()); cir.setReturnValue(true); } @@ -172,19 +173,21 @@ private void renderFavoriteMarker(DrawContext context, int mouseX, int mouseY, f for (int i = 0; i < (numFavorites - this.indexStartOffset); ++i) { RenderUtils.bindTexture(icon.getTexture()); - icon.renderAt(x, y, z, false, false); + icon.renderAt(x, y, z, false, false, context); y += 20; } } } } + @Unique private int getClampedIndex(int index) { int listSize = this.handler.getRecipes().size(); return Math.max(0, Math.min(index, listSize - 7)); } + @Unique private int getHoveredTradeButtonIndex(double mouseX, double mouseY) { int screenX = (this.width - this.backgroundWidth) / 2; diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinMerchantScreenHandler.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinMerchantScreenHandler.java index 1033bb1..21457f8 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinMerchantScreenHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinMerchantScreenHandler.java @@ -4,6 +4,7 @@ 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.callback.CallbackInfo; @@ -21,7 +22,7 @@ public abstract class MixinMerchantScreenHandler extends ScreenHandler implements IMerchantScreenHandler { @Shadow @Final private Merchant merchant; - @Nullable private TradeOfferList customList; + @Unique @Nullable private TradeOfferList customList; protected MixinMerchantScreenHandler(@Nullable ScreenHandlerType type, int syncId) { @@ -47,7 +48,7 @@ private void onTradeListSet(TradeOfferList offers, CallbackInfo ci) } @Override - public TradeOfferList getOriginalList() + public TradeOfferList itemscroller$getOriginalList() { return this.merchant.getOffers(); } diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java index f509e4d..11826b4 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java @@ -1,51 +1,19 @@ package fi.dy.masa.itemscroller.mixin; -import fi.dy.masa.itemscroller.util.InventoryUtils; -import net.minecraft.client.gui.screen.recipebook.RecipeBookGhostSlots; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; -import net.minecraft.recipe.RecipeEntry; -import net.minecraft.screen.slot.Slot; -import org.spongepowered.asm.mixin.Final; 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.CallbackInfo; - -import java.util.List; @Mixin(RecipeBookWidget.class) public class MixinRecipeBookWidget { - @Shadow @Final protected RecipeBookGhostSlots ghostSlots; - - @Inject(method = "slotClicked", at = @At("HEAD"), cancellable = true) - private void onSlotClicked(Slot slot, CallbackInfo ci) - { - if (InventoryUtils.dontUpdateRecipeBook > 0) - { - ci.cancel(); - } - } - + /* @Inject(method = "update", at = @At("HEAD"), cancellable = true) - private void onUpdate(CallbackInfo ci) + private void itemscroller_onUpdate(CallbackInfo ci) { if (InventoryUtils.dontUpdateRecipeBook > 0) { ci.cancel(); } } - - // Seems to be (intended) bug from Mojang - @Inject( - method = "showGhostRecipe", - at = @At("HEAD"), - cancellable = true - ) - private void onShowGhostRecipe(RecipeEntry recipe, List slots, CallbackInfo ci) { - if (this.ghostSlots.getRecipe() == recipe) { - ci.cancel(); - } - } + */ } diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinScreen.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinScreen.java index 4517594..a67a31b 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinScreen.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinScreen.java @@ -1,22 +1,32 @@ package fi.dy.masa.itemscroller.mixin; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; - import fi.dy.masa.itemscroller.event.RenderEventHandler; @Mixin(Screen.class) public abstract class MixinScreen { - @Inject(method = "renderWithTooltip", at = @At(value = "RETURN")) - private void onDrawScreenPost(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) + /* + @Inject(method = "renderWithTooltip", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/gui/screen/Screen;render(Lnet/minecraft/client/gui/DrawContext;IIF)V", + shift = At.Shift.AFTER)) + private void itemscroller_inDrawScreenPre(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) + { + RenderEventHandler.instance().onDrawCraftingScreenBackground(MinecraftClient.getInstance(), context, mouseX, mouseY); + } + */ + + @Inject(method = "renderWithTooltip", at = @At(value = "TAIL")) + private void itemscroller_onDrawScreenPost(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { - RenderEventHandler.instance().onDrawScreenPost(MinecraftClient.getInstance(), context); + RenderEventHandler.instance().onDrawScreenPost(MinecraftClient.getInstance(), context, mouseX, mouseY); } } diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinStatusEffectsDisplay.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinStatusEffectsDisplay.java new file mode 100644 index 0000000..2d75cea --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinStatusEffectsDisplay.java @@ -0,0 +1,22 @@ +package fi.dy.masa.itemscroller.mixin; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.StatusEffectsDisplay; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import fi.dy.masa.itemscroller.util.InputUtils; + +@Mixin(StatusEffectsDisplay.class) +public abstract class MixinStatusEffectsDisplay +{ + @Inject(method = "drawStatusEffects(Lnet/minecraft/client/gui/DrawContext;II)V", at = @At("HEAD"), cancellable = true) + private void preventPotionEffectRendering(DrawContext context, int mouseX, int mouseY, CallbackInfo ci) + { + if (InputUtils.isRecipeViewOpen()) + { + ci.cancel(); + } + } +} diff --git a/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java b/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java index ec862fc..6a81142 100644 --- a/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java +++ b/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java @@ -1,33 +1,48 @@ package fi.dy.masa.itemscroller.recipes; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Arrays; +import com.llamalad7.mixinextras.lib.apache.commons.tuple.Pair; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.screen.ingame.RecipeBookScreen; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtList; -import net.minecraft.recipe.CraftingRecipe; -import net.minecraft.recipe.Recipe; -import net.minecraft.recipe.RecipeEntry; -import net.minecraft.recipe.RecipeType; +import net.minecraft.recipe.*; +import net.minecraft.recipe.display.SlotDisplayContexts; import net.minecraft.recipe.input.CraftingRecipeInput; import net.minecraft.recipe.input.RecipeInput; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.slot.Slot; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.context.ContextParameterMap; +import net.minecraft.world.World; + +import fi.dy.masa.itemscroller.ItemScroller; +import fi.dy.masa.itemscroller.mixin.IMixinClientRecipeBook; +import fi.dy.masa.itemscroller.mixin.IMixinRecipeBookScreen; +import fi.dy.masa.itemscroller.mixin.IMixinRecipeBookWidget; import fi.dy.masa.itemscroller.recipes.CraftingHandler.SlotRange; import fi.dy.masa.itemscroller.util.Constants; import fi.dy.masa.itemscroller.util.InventoryUtils; -import net.minecraft.world.World; public class RecipePattern { private ItemStack result = InventoryUtils.EMPTY_STACK; private ItemStack[] recipe = new ItemStack[9]; private RecipeEntry vanillaRecipe; + private NetworkRecipeId networkRecipeId; + private NetworkRecipeId ghostNetworkRecipeId; + private RecipeDisplayEntry displayEntry; + private long lastMassCraft; + private long altTimeoutMillis = 6000L; public RecipePattern() { @@ -47,6 +62,10 @@ public void clearRecipe() Arrays.fill(this.recipe, InventoryUtils.EMPTY_STACK); this.result = InventoryUtils.EMPTY_STACK; this.vanillaRecipe = null; + this.networkRecipeId = null; + this.ghostNetworkRecipeId = null; + this.displayEntry = null; + this.lastMassCraft = -1; } public void ensureRecipeSizeAndClearRecipe(int size) @@ -57,11 +76,17 @@ public void ensureRecipeSizeAndClearRecipe(int size) @SuppressWarnings("unchecked") @Nullable - public Recipe lookupVanillaRecipe(World world) { + public Recipe lookupVanillaRecipe(World world) + { //Assume all recipes here are of type CraftingRecipe this.vanillaRecipe = null; - var mc = MinecraftClient.getInstance(); + MinecraftClient mc = MinecraftClient.getInstance(); int recipeSize; + + if (mc.world == null) + { + return null; + } if (recipe.length == 4) { recipeSize = 2; @@ -75,18 +100,285 @@ else if (recipe.length == 9) return null; } - for (RecipeEntry match : mc.world.getRecipeManager().getAllMatches(RecipeType.CRAFTING, CraftingRecipeInput.create(recipeSize, recipeSize, Arrays.asList(recipe)), world)) + ServerWorld serverWorld = mc.getServer() != null ? mc.getServer().getWorld(mc.world.getRegistryKey()) : null; + + if (mc.isIntegratedServerRunning() && serverWorld != null) + { + CraftingRecipeInput input = CraftingRecipeInput.create(recipeSize, recipeSize, Arrays.asList(recipe)); + Optional> opt = serverWorld.getRecipeManager().getFirstMatch(RecipeType.CRAFTING, input, serverWorld); + + if (opt.isPresent()) + { + RecipeEntry recipeEntry = opt.get(); + Recipe match = opt.get().value(); + ItemStack result = match.craft(input, serverWorld.getRegistryManager()); + + if (result != null && !result.isEmpty()) + { + this.vanillaRecipe = recipeEntry; + this.storeIdFromClientRecipeBook(mc); + return (Recipe) match; + } + } + } + else + { + this.storeIdFromClientRecipeBook(mc); + } + + return null; + } + + public void storeIdFromClientRecipeBook(MinecraftClient mc) + { + Pair pair = this.matchClientRecipeBook(mc); + + if (pair == null || pair.getLeft() == null || pair.getRight() == null) + { + return; + } + + this.storeNetworkRecipeId(pair.getLeft(), false); + this.storeRecipeDisplayEntry(pair.getRight()); + } + + public void storeNetworkRecipeId(NetworkRecipeId id, boolean saveGhost) + { + if (this.networkRecipeId != null && id.index() != this.networkRecipeId.index() && saveGhost) + { + this.storeGhostNetworkRecipeId(this.networkRecipeId); + } + else + { + this.ghostNetworkRecipeId = null; + } + + this.networkRecipeId = id; + } + + public void storeGhostNetworkRecipeId(NetworkRecipeId id) + { + this.ghostNetworkRecipeId = id; + } + + public void swapGhostNetworkRecipeId() + { + // The 'Ghost' RecipeId is usually a higher index() number than the real recipe, or the "Inverse" recipe of the one being crafted. + // We just need to be able to handle the swap at the correct time. + if (this.getGhostNetworkRecipeId() != null) + { + NetworkRecipeId last = this.getNetworkRecipeId(); + this.storeNetworkRecipeId(this.getGhostNetworkRecipeId(), false); + this.storeGhostNetworkRecipeId(last); + } + } + + public void storeRecipeDisplayEntry(RecipeDisplayEntry entry) + { + this.displayEntry = entry; + } + + public @Nullable NetworkRecipeId getNetworkRecipeId() + { + return this.networkRecipeId; + } + + public @Nullable NetworkRecipeId getGhostNetworkRecipeId() + { + return this.ghostNetworkRecipeId; + } + + public @Nullable RecipeDisplayEntry getRecipeDisplayEntry() + { + return this.displayEntry; + } + + public @Nullable Pair matchClientRecipeBook(MinecraftClient mc) + { + Pair pair = null; + + if (mc.player == null || mc.world == null) + { + return null; + } + ClientRecipeBook recipeBook = mc.player.getRecipeBook(); + ContextParameterMap ctx = SlotDisplayContexts.createParameters(mc.world); + Map recipeMap = ((IMixinClientRecipeBook) recipeBook).itemscroller_getRecipeMap(); + List recipeStacks = this.combineStacks(Arrays.stream(this.getRecipeItems()).toList(), 3); + + if (recipeMap.size() < 1) { - if (InventoryUtils.areStacksEqual(result, match.value().getResult(world.getRegistryManager()))) + return null; + } + + for (NetworkRecipeId id : recipeMap.keySet()) + { + List stacks = recipeMap.get(id).getStacks(ctx); + + if (this.compareRecipeStacks(recipeStacks, this.combineStacks(stacks, 3))) { - this.vanillaRecipe = match; - return (Recipe) match.value(); + pair = Pair.of(id, recipeMap.get(id)); + return pair; } } + return null; } - public void storeCraftingRecipe(Slot slot, HandledScreen gui, boolean clearIfEmpty) + public static List combineStacks(List stacks, int iterations) + { + if (iterations > 3 || iterations < 1) + { + iterations = 3; + } + + List list = new ArrayList<>(stacks); + int i = 0; + + while (i < iterations) + { + list = combineStacksEach(list); + i++; + } + + return list; + } + + private static List combineStacksEach(List stacks) + { + List list = new ArrayList<>(); + ItemStack previous = ItemStack.EMPTY; + ItemStack entry = ItemStack.EMPTY; + + for (int i = 0; i < stacks.size(); i++) + { + entry = stacks.get(i); + + if (!previous.isEmpty() && ItemStack.areItemsAndComponentsEqual(previous, entry)) + { + int prevCount = previous.getCount(); + int maxCount = previous.getMaxCount(); + int entryCount = entry.getCount(); + + if ((prevCount + entryCount) <= maxCount) + { + previous.setCount(prevCount + entryCount); + entry = ItemStack.EMPTY; + } + else + { + previous.setCount(maxCount); + entry.setCount((prevCount + entryCount) - maxCount); + list.add(previous.copy()); + previous = entry.copy(); + entry = ItemStack.EMPTY; + } + } + else + { + if (!previous.isEmpty()) + { + list.add(previous.copy()); + } + + previous = entry.copy(); + entry = ItemStack.EMPTY; + } + } + + if (!previous.isEmpty()) + { + list.add(previous.copy()); + } + if (!entry.isEmpty()) + { + list.add(entry.copy()); + } + + return list; + } + + private boolean compareRecipeStacks(List left, List right) + { + if (left.size() != right.size()) + { + return false; + } + + for (int i = 0; i < left.size(); i++) + { + ItemStack l = left.get(i); + ItemStack r = right.get(i); + + //System.out.printf("compare() [%d] left [%s] / right [%s] --> ", i, l.toString(), r.toString()); + + if (ItemStack.areItemsEqual(l, r) == false) + { + //System.out.print(" not equal\n"); + return false; + } + else if (l.getCount() != r.getCount()) + { + //System.out.print(" count not equal\n"); + return false; + } + } + + //System.out.print(" PASS\n"); + return true; + } + + public boolean verifyClientRecipeBook(MinecraftClient mc, @Nullable NetworkRecipeId id) + { + if (id != null) + { + if (id.equals(this.getNetworkRecipeId())) + { + return true; + } + + return false; + } + + Pair pair = this.matchClientRecipeBook(mc); + + if (pair == null || pair.getLeft() == null) + { + return false; + } + + if (this.getNetworkRecipeId() != null && pair.getLeft().index() == this.getNetworkRecipeId().index()) + { + return true; + } + else if (this.getGhostNetworkRecipeId() != null && pair.getLeft().index() == this.getGhostNetworkRecipeId().index()) + { + return true; + } + + return false; + } + + public boolean matchClientRecipeBookEntry(RecipeDisplayEntry entry, MinecraftClient mc) + { + if (mc.world == null) + { + return false; + } + + // Compact the stacks so that they equal + List recipeStacks = this.combineStacks(Arrays.stream(this.getRecipeItems()).toList(), 3); + List stacks = this.combineStacks(entry.getStacks(SlotDisplayContexts.createParameters(mc.world)), 3); + + if (this.compareRecipeStacks(recipeStacks, stacks)) + { + return true; + } + + return false; + } + + public void storeCraftingRecipe(Slot slot, HandledScreen gui, boolean clearIfEmpty, boolean fromKeybind, MinecraftClient mc) { SlotRange range = CraftingHandler.getCraftingGridSlots(gui, slot); @@ -95,18 +387,23 @@ public void storeCraftingRecipe(Slot slot, HandledScreen gui) + { + MinecraftClient mc = MinecraftClient.getInstance(); + + if (gui instanceof RecipeBookScreen rbs) + { + RecipeBookWidget widget = ((IMixinRecipeBookScreen) rbs).itemscroller_getRecipeBookWidget(); + + if (widget != null) + { + NetworkRecipeId id = ((IMixinRecipeBookWidget) widget).itemscroller_getSelectedRecipe(); + + if (id != null) + { + ClientRecipeBook recipeBook = mc.player.getRecipeBook(); + Map recipeMap = ((IMixinClientRecipeBook) recipeBook).itemscroller_getRecipeMap(); + + this.storeNetworkRecipeId(id, false); + + if (recipeMap.containsKey(id)) + { + this.storeRecipeDisplayEntry(recipeMap.get(id)); + } + + // Clear crafting grid + InventoryUtils.clearFirstCraftingGridOfAllItems(gui); + } + } + } + } + public void copyRecipeFrom(RecipePattern other) { int size = other.getRecipeLength(); @@ -129,6 +457,8 @@ public void copyRecipeFrom(RecipePattern other) this.result = InventoryUtils.isStackEmpty(other.getResult()) == false ? other.getResult().copy() : InventoryUtils.EMPTY_STACK; this.vanillaRecipe = other.vanillaRecipe; + this.networkRecipeId = other.networkRecipeId; + this.displayEntry = other.displayEntry; } public void readFromNBT(@Nonnull NbtCompound nbt, @Nonnull DynamicRegistryManager registryManager) @@ -166,7 +496,7 @@ public NbtCompound writeToNBT(@Nonnull DynamicRegistryManager registryManager) if (this.isValid()) { - NbtCompound tag = (NbtCompound) this.result.encode(registryManager); + NbtCompound tag = (NbtCompound) this.result.toNbt(registryManager); nbt.putInt("Length", this.recipe.length); nbt.put("Result", tag); @@ -178,7 +508,7 @@ public NbtCompound writeToNBT(@Nonnull DynamicRegistryManager registryManager) if (this.recipe[i].isEmpty() == false && InventoryUtils.isStackEmpty(this.recipe[i]) == false) { tag = new NbtCompound(); - tag.copyFrom((NbtCompound) this.recipe[i].encode(registryManager)); + tag.copyFrom((NbtCompound) this.recipe[i].toNbt(registryManager)); tag.putInt("Slot", i); tagIngredients.add(tag); @@ -213,6 +543,21 @@ public ItemStack[] getRecipeItems() return this.recipe; } + public boolean hasRecipeItems() + { + boolean empty = true; + + for (int i = 0; i < this.getRecipeLength(); i++) + { + if (this.getRecipeItems()[i].isEmpty() == false) + { + empty = false; + } + } + + return empty; + } + public boolean isValid() { return InventoryUtils.isStackEmpty(this.getResult()) == false; @@ -221,7 +566,7 @@ public boolean isValid() @Nullable public RecipeEntry getVanillaRecipeEntry() { - return vanillaRecipe; + return this.vanillaRecipe; } @SuppressWarnings("unchecked") @@ -232,6 +577,12 @@ public Recipe getVanillaRecipe() { return null; } - return (Recipe) vanillaRecipe.value(); + + if (this.vanillaRecipe != null) + { + return (Recipe) this.vanillaRecipe.value(); + } + + return null; } } diff --git a/src/main/java/fi/dy/masa/itemscroller/recipes/RecipeStorage.java b/src/main/java/fi/dy/masa/itemscroller/recipes/RecipeStorage.java index e846f84..e9d73e7 100644 --- a/src/main/java/fi/dy/masa/itemscroller/recipes/RecipeStorage.java +++ b/src/main/java/fi/dy/masa/itemscroller/recipes/RecipeStorage.java @@ -5,11 +5,14 @@ import java.io.FileOutputStream; import javax.annotation.Nonnull; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtSizeTracker; +import net.minecraft.recipe.NetworkRecipeId; +import net.minecraft.recipe.RecipeDisplayEntry; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.screen.slot.Slot; @@ -124,14 +127,14 @@ public RecipePattern getSelectedRecipe() return this.getRecipe(this.getSelection()); } - public void storeCraftingRecipeToCurrentSelection(Slot slot, HandledScreen gui, boolean clearIfEmpty) + public void storeCraftingRecipeToCurrentSelection(Slot slot, HandledScreen gui, boolean clearIfEmpty, boolean fromKeybind, MinecraftClient mc) { - this.storeCraftingRecipe(this.getSelection(), slot, gui, clearIfEmpty); + this.storeCraftingRecipe(this.getSelection(), slot, gui, clearIfEmpty, fromKeybind, mc); } - public void storeCraftingRecipe(int index, Slot slot, HandledScreen gui, boolean clearIfEmpty) + public void storeCraftingRecipe(int index, Slot slot, HandledScreen gui, boolean clearIfEmpty, boolean fromKeybind, MinecraftClient mc) { - this.getRecipe(index).storeCraftingRecipe(slot, gui, clearIfEmpty); + this.getRecipe(index).storeCraftingRecipe(slot, gui, clearIfEmpty, fromKeybind, mc); this.dirty = true; } @@ -141,6 +144,21 @@ public void clearRecipe(int index) this.dirty = true; } + public void onAddToRecipeBook(RecipeDisplayEntry entry) + { + MinecraftClient mc = MinecraftClient.getInstance(); + + for (RecipePattern recipe : this.recipes) + { + if (recipe.matchClientRecipeBookEntry(entry, mc)) + { + recipe.storeNetworkRecipeId(entry.id(), true); + recipe.swapGhostNetworkRecipeId(); + recipe.storeRecipeDisplayEntry(entry); + } + } + } + private void readFromNBT(NbtCompound nbt, @Nonnull DynamicRegistryManager registryManager) { if (nbt == null || nbt.contains("Recipes", Constants.NBT.TAG_LIST) == false) @@ -166,13 +184,14 @@ private void readFromNBT(NbtCompound nbt, @Nonnull DynamicRegistryManager regist { this.recipes[index].readFromNBT(tag, registryManager); - // TODO 1.21.2+ - /* if (tag.contains("LastNetworkId")) { - this.recipes[index].storeNetworkRecipeId(new NetworkRecipeId(tag.getInt("LastNetworkId"))); + this.recipes[index].storeNetworkRecipeId(new NetworkRecipeId(tag.getInt("LastNetworkId")), false); + } + if (tag.contains("GhostNetworkId")) + { + this.recipes[index].storeGhostNetworkRecipeId(new NetworkRecipeId(tag.getInt("GhostNetworkId"))); } - */ } } @@ -192,13 +211,15 @@ private NbtCompound writeToNBT(@Nonnull DynamicRegistryManager registryManager) NbtCompound tag = entry.writeToNBT(registryManager); tag.putByte("RecipeIndex", (byte) i); - // TODO 1.21.2+ - /* if (entry.getNetworkRecipeId() != null) { tag.putInt("LastNetworkId", entry.getNetworkRecipeId().index()); } - */ + if (entry.getGhostNetworkRecipeId() != null) + { + tag.putInt("GhostNetworkId", entry.getGhostNetworkRecipeId().index()); + } + tagRecipes.add(tag); } } diff --git a/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java b/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java index b485791..dd2a514 100644 --- a/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java +++ b/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java @@ -1,13 +1,11 @@ package fi.dy.masa.itemscroller.util; -import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.*; - +import javax.annotation.Nullable; import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntComparator; - import it.unimi.dsi.fastutil.ints.IntIntMutablePair; import org.apache.commons.lang3.math.Fraction; @@ -17,8 +15,6 @@ import net.minecraft.client.gui.screen.ingame.*; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.world.ClientWorld; -import net.minecraft.component.ComponentChanges; -import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.BundleContentsComponent; import net.minecraft.component.type.ContainerComponent; @@ -27,7 +23,10 @@ import net.minecraft.inventory.CraftingResultInventory; import net.minecraft.inventory.Inventory; import net.minecraft.inventory.RecipeInputInventory; -import net.minecraft.item.*; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.network.listener.ClientPlayPacketListener; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.c2s.play.ClientStatusC2SPacket; @@ -43,13 +42,14 @@ import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.SlotActionType; import net.minecraft.screen.slot.TradeOutputSlot; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; -import net.minecraft.util.collection.DefaultedList; import net.minecraft.village.TradeOffer; import net.minecraft.village.TradeOfferList; import net.minecraft.world.GameRules; import net.minecraft.world.World; +import fi.dy.masa.malilib.util.GuiUtils; import fi.dy.masa.itemscroller.ItemScroller; import fi.dy.masa.itemscroller.config.Configs; import fi.dy.masa.itemscroller.config.Hotkeys; @@ -60,7 +60,6 @@ import fi.dy.masa.itemscroller.recipes.RecipeStorage; import fi.dy.masa.itemscroller.villager.VillagerDataStorage; import fi.dy.masa.itemscroller.villager.VillagerUtils; -import fi.dy.masa.malilib.util.GuiUtils; public class InventoryUtils { @@ -126,6 +125,8 @@ public static void updateCraftingOutputSlot(PlayerEntity player, CraftingResultInventory inventoryCraftResult, boolean setEmptyStack) { + MinecraftClient mc = MinecraftClient.getInstance(); + ServerWorld serverWorld = mc.getServer() != null ? mc.getServer().getWorld(mc.world.getRegistryKey()) : null; World world = player.getEntityWorld(); if ((world instanceof ClientWorld) && player instanceof ClientPlayerEntity) @@ -135,18 +136,20 @@ public static void updateCraftingOutputSlot(PlayerEntity player, RecipeEntry recipeEntry = null; CraftingRecipeInput recipeInput = craftMatrix.createRecipeInput(); - if (recipe == null || recipe.matches(recipeInput, world) == false) + if ((recipe == null || recipe.matches(recipeInput, world) == false) && + (serverWorld != null)) { - Optional> optional = world.getRecipeManager().getFirstMatch(RecipeType.CRAFTING, recipeInput, world); - recipe = optional.map(RecipeEntry::value).orElse(null); - recipeEntry = optional.orElse(null); + Optional> opt = serverWorld.getRecipeManager().getFirstMatch(RecipeType.CRAFTING, recipeInput, serverWorld); + recipe = opt.map(RecipeEntry::value).orElse(null); + recipeEntry = opt.orElse(null); } if (recipe != null) { + GameRules rules = new GameRules(((ClientPlayerEntity) player).networkHandler.getEnabledFeatures()); + if ((recipe.isIgnoredInRecipeBook() || - world.getGameRules().getBoolean(GameRules.DO_LIMITED_CRAFTING) == false || - ((ClientPlayerEntity) player).getRecipeBook().contains(recipeEntry))) + rules.getBoolean(GameRules.DO_LIMITED_CRAFTING) == false)) { inventoryCraftResult.setLastRecipe(recipeEntry); stack = recipe.craft(recipeInput, world.getRegistryManager()); @@ -156,7 +159,6 @@ public static void updateCraftingOutputSlot(PlayerEntity player, { inventoryCraftResult.setStack(0, stack); } - } lastRecipe = recipe; @@ -1420,6 +1422,20 @@ private static boolean clearCraftingGridOfAllItems(HandledScreen gui, MinecraftClient mc) + { + ItemStack stack = gui.getScreenHandler().getCursorStack(); + PlayerEntity player = mc.player; + + if (stack.isEmpty() == false && player != null) + { + ((IMixinScreenHandler) gui).itemscroller_offerOrDropStack(player, stack); + gui.getScreenHandler().setCursorStack(ItemStack.EMPTY); + } + } + */ + private static boolean tryMoveItemsToCraftingGridSlots(RecipePattern recipe, Slot slot, HandledScreen gui, @@ -2658,7 +2674,7 @@ public static void sortInventory(HandledScreen gui) // Might cause an endless loop if hotbar is full. if (focusedSlot.id < 27) { - /* + /* if (tryFreeHotbarForShulkerSwaps(gui, container) == false) { ItemScroller.logger.warn("sortInventory: Free Hotbar slots are required in order to complete a Shulker box sorting task."); @@ -3016,8 +3032,7 @@ else if (index2 < 0) if (method.equals(SortingMethod.CATEGORY_NAME) || method.equals(SortingMethod.ITEM_NAME)) { // Sort by Item Name - int result = stack1.getName().getString().compareTo(stack2.getName().getString()) >= 0 ? 1 : -1; - return result == 0 ? Integer.compare(Registries.ITEM.getRawId(stack1.getItem()), Registries.ITEM.getRawId(stack2.getItem())) : result; + return stack1.getName().getString().compareTo(stack2.getName().getString()) >= 0 ? 1 : -1; } else if (method.equals(SortingMethod.CATEGORY_COUNT) || method.equals(SortingMethod.ITEM_COUNT)) { diff --git a/src/main/java/fi/dy/masa/itemscroller/villager/IMerchantScreenHandler.java b/src/main/java/fi/dy/masa/itemscroller/villager/IMerchantScreenHandler.java index fb09b39..56e62be 100644 --- a/src/main/java/fi/dy/masa/itemscroller/villager/IMerchantScreenHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/villager/IMerchantScreenHandler.java @@ -4,5 +4,5 @@ public interface IMerchantScreenHandler { - TradeOfferList getOriginalList(); + TradeOfferList itemscroller$getOriginalList(); } diff --git a/src/main/java/fi/dy/masa/itemscroller/villager/TradeType.java b/src/main/java/fi/dy/masa/itemscroller/villager/TradeType.java index 60f683f..6aa6eb3 100644 --- a/src/main/java/fi/dy/masa/itemscroller/villager/TradeType.java +++ b/src/main/java/fi/dy/masa/itemscroller/villager/TradeType.java @@ -1,5 +1,6 @@ package fi.dy.masa.itemscroller.villager; +import java.util.Optional; import javax.annotation.Nullable; import net.minecraft.item.Item; @@ -7,6 +8,7 @@ import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; import net.minecraft.registry.Registries; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.Identifier; import net.minecraft.village.TradeOffer; @@ -66,7 +68,17 @@ public static Item getItemForName(String name) try { Identifier id = Identifier.tryParse(name); - return Registries.ITEM.get(id); + //return Registries.ITEM.get(id); + Optional> opt = Registries.ITEM.getEntry(id); + + if (opt.isPresent()) + { + return opt.get().value(); + } + else + { + return Items.AIR; + } } catch (Exception e) { diff --git a/src/main/java/fi/dy/masa/itemscroller/villager/VillagerDataStorage.java b/src/main/java/fi/dy/masa/itemscroller/villager/VillagerDataStorage.java index 0647aad..f2d220f 100644 --- a/src/main/java/fi/dy/masa/itemscroller/villager/VillagerDataStorage.java +++ b/src/main/java/fi/dy/masa/itemscroller/villager/VillagerDataStorage.java @@ -107,7 +107,7 @@ public void toggleGlobalFavorite(TradeOffer trade) public FavoriteData getFavoritesForCurrentVillager(MerchantScreenHandler handler) { - return this.getFavoritesForCurrentVillager(((IMerchantScreenHandler) handler).getOriginalList()); + return this.getFavoritesForCurrentVillager(((IMerchantScreenHandler) handler).itemscroller$getOriginalList()); } public FavoriteData getFavoritesForCurrentVillager(TradeOfferList originalTrades) diff --git a/src/main/java/fi/dy/masa/itemscroller/villager/VillagerUtils.java b/src/main/java/fi/dy/masa/itemscroller/villager/VillagerUtils.java index acb4319..f7243b3 100644 --- a/src/main/java/fi/dy/masa/itemscroller/villager/VillagerUtils.java +++ b/src/main/java/fi/dy/masa/itemscroller/villager/VillagerUtils.java @@ -47,7 +47,7 @@ public static int getRealTradeIndexFor(int visibleIndex, MerchantScreenHandler h { if (handler instanceof IMerchantScreenHandler) { - TradeOfferList originalList = ((IMerchantScreenHandler) handler).getOriginalList(); + TradeOfferList originalList = ((IMerchantScreenHandler) handler).itemscroller$getOriginalList(); TradeOfferList customList = handler.getRecipes(); if (originalList != null && customList != null && diff --git a/src/main/resources/rocknroller.mixins.json b/src/main/resources/rocknroller.mixins.json index 7a108c4..eea8b52 100644 --- a/src/main/resources/rocknroller.mixins.json +++ b/src/main/resources/rocknroller.mixins.json @@ -1,25 +1,28 @@ { "required": true, "package": "fi.dy.masa.itemscroller.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "minVersion": "0.8", "client": [ + "IMixinAbstractCraftingScreenHandler", + "IMixinClientRecipeBook", "IMixinCraftingResultSlot", "IMixinMerchantScreen", + "IMixinRecipeBookScreen", + "IMixinRecipeBookWidget", "IMixinScreenWithHandler", "IMixinSlot", - "MixinAbstractInventoryScreen", + "MixinAbstractCraftingRecipeBookWidget", "MixinClientPlayerInteractionManager", "MixinClientPlayNetworkHandler", + "MixinClientRecipeBook", "MixinCraftingScreenHandler", "MixinItemStack", "MixinMerchantScreen", "MixinMerchantScreenHandler", "MixinRecipeBookWidget", - "MixinScreen" - ], - "mixins": [ - "debug.MixinServerPlayNetworkHandler" + "MixinScreen", + "MixinStatusEffectsDisplay" ], "injectors": { "defaultRequire": 1