diff --git a/build.gradle b/build.gradle index 6ce3ba5..d743983 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,12 @@ base.archivesName = libs.versions.archives.name version = "${libs.versions.version.get()}-mc${libs.versions.minecraft.version.get()}" group = libs.versions.maven.group +loom { + neoForge { + accessTransformer(file("src/main/resources/META-INF/accesstransformer.cfg")) + } +} + repositories { maven { url "https://www.jitpack.io" } maven { url "https://maven.neoforged.net/releases/" } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0550c32..fd1815b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,10 +6,10 @@ minecraft-range="1.21" minecraft_version="1.21" yarn_mappings="1.21+build.2" mappings_patch="1.21+build.4" -neoforge="21.0.78-beta" +neoforge="21.0.133-beta" # Mod properties -version="0.1.4" +version="0.1.5" maven-group="org.thinkingstudio.rocknroller" archives-name="RocknRoller" @@ -18,7 +18,7 @@ id-modrinth="hYq29QmW" id-curseforge="916852" # Mod dependencies -mafglib="0.1.16-mc1.21" +mafglib="0.1.18-mc1.21" badpackets="neo-0.8.1" # Libraries diff --git a/src/main/java/fi/dy/masa/itemscroller/ItemScroller.java b/src/main/java/fi/dy/masa/itemscroller/ItemScroller.java index c27ea51..25eaa9f 100644 --- a/src/main/java/fi/dy/masa/itemscroller/ItemScroller.java +++ b/src/main/java/fi/dy/masa/itemscroller/ItemScroller.java @@ -12,4 +12,14 @@ public static void onInitialize() { InitializationHandler.getInstance().registerInitializationHandler(new InitHandler()); } + + /* + public static void printDebug(String key, Object... args) + { + if (Configs.Generic.DEBUG_MESSAGES.getBooleanValue()) + { + 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 b24708d..3d74403 100644 --- a/src/main/java/fi/dy/masa/itemscroller/config/Configs.java +++ b/src/main/java/fi/dy/masa/itemscroller/config/Configs.java @@ -13,8 +13,7 @@ import fi.dy.masa.malilib.config.ConfigUtils; import fi.dy.masa.malilib.config.IConfigHandler; import fi.dy.masa.malilib.config.IConfigValue; -import fi.dy.masa.malilib.config.options.ConfigBoolean; -import fi.dy.masa.malilib.config.options.ConfigInteger; +import fi.dy.masa.malilib.config.options.*; import fi.dy.masa.malilib.util.FileUtils; import fi.dy.masa.malilib.util.JsonUtils; import fi.dy.masa.itemscroller.Reference; @@ -27,25 +26,27 @@ public class Configs implements IConfigHandler public static class Generic { - public static final ConfigBoolean CARPET_CTRL_Q_CRAFTING = new ConfigBoolean("carpetCtrlQCraftingEnabledOnServer", false, "Set to true if the server is running the Carpet mod,\nand has the ctrlQCrafting option enabled.\nThis just changes which method Item Scroller uses\nfor the Drop key + Shift + Right click crafting."); - public static final ConfigBoolean CLIENT_CRAFTING_FIX = new ConfigBoolean("clientCraftingFixOn1.12", true, "Enable updating the crafting recipe output directly on the client side.\nThis fixes the quick/mass crafting and right-click-to-craft-a-stack\nfeatures othrwise being broken in 1.12."); - public static final ConfigBoolean CRAFTING_RENDER_RECIPE_ITEMS = new ConfigBoolean("craftingRenderRecipeItems", true, "If enabled, then the recipe items are also rendered\nin the crafting recipe view."); - //public static final ConfigBoolean DEBUG_MESSAGES = new ConfigBoolean("debugMessages", false, "Enables some debug messages in the game console"); - public static final ConfigBoolean MOD_MAIN_TOGGLE = new ConfigBoolean("modMainToggle", true, "Can disable all the functionality of the entire mod"); - public static final ConfigBoolean MASS_CRAFT_INHIBIT_MID_UPDATES = new ConfigBoolean("massCraftInhibitMidUpdates", true, "Prevent recipe output slot updates in the middle of moving items\nto the crafting grid. This should reduce CPU usage\nbecause of not constantly querying the recipe after every grid change."); - public static final ConfigInteger MASS_CRAFT_INTERVAL = new ConfigInteger("massCraftInterval", 2, 1, 60, "The interval in game ticks the massCraft operation is repeated at"); - public static final ConfigInteger MASS_CRAFT_ITERATIONS = new ConfigInteger("massCraftIterations", 36, 1, 256, "How many massCraft iterations/attempts to do per execution.\nWith unstackable items or a full inventory and \"small recipe\"\nthis will need to be larger, as a shift + click craft to the inventory\nmight only craft 1 or 2 items per operation."); - public static final ConfigBoolean MASS_CRAFT_SWAPS = new ConfigBoolean("massCraftSwapsOnly", false, "Uses a newer method of filling the crafting grid,\nusing only swap slot packets.\n\nNote: Due to only using slot swap packets,\nno partial crafts are possible! And also no\nstack splitting will happen, at all."); - public static final ConfigInteger PACKET_RATE_LIMIT = new ConfigInteger("packetRateLimit", 4, 1, 1024, "The limit of sent emulated slot click packets per game tick,\nif 'rateLimitClickPackets' is enabled"); - public static final ConfigBoolean SCROLL_CRAFT_STORE_RECIPES_TO_FILE = new ConfigBoolean("craftingRecipesSaveToFile", true, "If enabled, then the crafting features recipes are saved to a file\ninside minecraft/itemscroller/recipes_worldorservername.nbt.\nThis makes the recipes persistent across game restarts."); - public static final ConfigBoolean SCROLL_CRAFT_RECIPE_FILE_GLOBAL = new ConfigBoolean("craftingRecipesSaveFileIsGlobal", false, "If true, then the recipe file is global, instead\n of being saved per-world or server"); - public static final ConfigBoolean RATE_LIMIT_CLICK_PACKETS = new ConfigBoolean("rateLimitClickPackets", false, "This is meant for compatibility with Spigot servers and similar,\nwhich apply rate limits to packets from the client.\nThis queues up the emulated slot click packets and sends\nthem rate limited over time. The limit per game tick can be set in 'packetRateLimit´."); - public static final ConfigBoolean REVERSE_SCROLL_DIRECTION_SINGLE = new ConfigBoolean("reverseScrollDirectionSingle", false, "Reverse the scrolling direction for single item mode."); - public static final ConfigBoolean REVERSE_SCROLL_DIRECTION_STACKS = new ConfigBoolean("reverseScrollDirectionStacks", false, "Reverse the scrolling direction for full stacks mode."); - public static final ConfigBoolean USE_RECIPE_CACHING = new ConfigBoolean("useRecipeCaching", true, "Enables caching the last used recipe in the crafting\nrecipe output item fetching code. This can help a lot\nwith lowering CPU usage when mass crafting stuff."); - public static final ConfigBoolean SLOT_POSITION_AWARE_SCROLL_DIRECTION = new ConfigBoolean("useSlotPositionAwareScrollDirection", false, "When enabled, the item movement direction depends\non the slots' y-position on screen. Might be derpy with more\ncomplex inventories, use with caution!"); - public static final ConfigBoolean VILLAGER_TRADE_USE_GLOBAL_FAVORITES = new ConfigBoolean("villagerTradeUseGlobalFavorites", true, "Whether or not global (per-item-type) villager trade\nfavorites should be used."); - public static final ConfigBoolean VILLAGER_TRADE_LIST_REMEMBER_SCROLL = new ConfigBoolean("villagerTradeListRememberScrollPosition", true, "Remember and restore the last scroll position in the\ntrade list when re-opening the GUI"); + 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 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_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 ImmutableList OPTIONS = ImmutableList.of( CARPET_CTRL_Q_CRAFTING, @@ -66,24 +67,27 @@ public static class Generic SLOT_POSITION_AWARE_SCROLL_DIRECTION, USE_RECIPE_CACHING, VILLAGER_TRADE_USE_GLOBAL_FAVORITES, - VILLAGER_TRADE_LIST_REMEMBER_SCROLL + VILLAGER_TRADE_LIST_REMEMBER_SCROLL, + + SORT_ASSUME_EMPTY_BOX_STACKS, + SORT_SHULKER_BOXES_AT_END ); } public static class Toggles { - public static final ConfigBoolean CRAFTING_FEATURES = new ConfigBoolean("enableCraftingFeatures", true, "Enables scrolling items to and from crafting grids,\nwith a built-in 18 recipe memory.\nHold down the Recipe key to see the stored recipes and\nto change the selection. While holding the Recipe key,\nyou can either scroll or press a number key to change the selection.\nA recipe is stored to the currently selected \"recipe slot\"\n by clicking pick block over a configured crafting output slot.\nThe supported crafting grids must be added to the scrollableCraftingGrids list."); - public static final ConfigBoolean DROP_MATCHING = new ConfigBoolean("enableDropkeyDropMatching", true, "Enables dropping all matching items from the same\ninventory with the hotkey"); - public static final ConfigBoolean RIGHT_CLICK_CRAFT_STACK = new ConfigBoolean("enableRightClickCraftingOneStack", true, "Enables crafting up to one full stack when right clicking on\na slot that has been configured as a crafting output slot."); - public static final ConfigBoolean SCROLL_EVERYTHING = new ConfigBoolean("enableScrollingEverything", true, "Enables scroll moving all items at once while\nholding the modifierMoveEverything keybind"); - public static final ConfigBoolean SCROLL_MATCHING = new ConfigBoolean("enableScrollingMatchingStacks", true, "Enables scroll moving all matching stacks at once\nwhile holding the modifierMoveMatching keybind"); - public static final ConfigBoolean SCROLL_SINGLE = new ConfigBoolean("enableScrollingSingle", true, "Enables moving items one item at a time by scrolling over a stack"); - public static final ConfigBoolean SCROLL_STACKS = new ConfigBoolean("enableScrollingStacks", true, "Enables moving entire stacks at a time by scrolling over a stack"); - public static final ConfigBoolean SCROLL_STACKS_FALLBACK = new ConfigBoolean("enableScrollingStacksFallback", true, "Enables a \"fallback\" mode for scrolling entire stacks\n(for example to a vanilla crafting table,\nwhere shift + click doesn't work)."); - public static final ConfigBoolean SCROLL_VILLAGER = new ConfigBoolean("enableScrollingVillager", true, "Enables special handling for the Villager GUIs.\n(Normally you can't shift click items in them.)\nHold shift and scroll up/down over the trade output slot."); - public static final ConfigBoolean SHIFT_DROP_ITEMS = new ConfigBoolean("enableShiftDropItems", true, "Enables dropping all matching items at once by holding\nshift while clicking to drop a stack"); - public static final ConfigBoolean SHIFT_PLACE_ITEMS = new ConfigBoolean("enableShiftPlaceItems", true, "Enables moving all matching stacks at once by holding\nshift while placing items to an empty slot"); - public static final ConfigBoolean VILLAGER_TRADE_FEATURES = new ConfigBoolean("enableVillagerTradeFeatures", true, "Enable trade favoriting and quick trade features for villagers.\nNote: The Shift + scrolling over the output slot is a separate feature\nand not affected by this option.\nThis option enables middle clicking to mark favorite trades,\nand right clicking on the trade list to fully trade that one trade."); + 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 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 37b7a26..af09ad1 100644 --- a/src/main/java/fi/dy/masa/itemscroller/config/Hotkeys.java +++ b/src/main/java/fi/dy/masa/itemscroller/config/Hotkeys.java @@ -12,43 +12,45 @@ 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", "Open the in-game config GUI"); - - public static final ConfigHotkey CRAFT_EVERYTHING = new ConfigHotkey("craftEverything", "LEFT_CONTROL,C", GUI_NO_ORDER, "Craft everything possible once with the currently selected recipe"); - public static final ConfigHotkey DROP_ALL_MATCHING = new ConfigHotkey("dropAllMatching", "LEFT_CONTROL,LEFT_SHIFT,Q", GUI_NO_ORDER, "Drop all stacks identical to the hovered stack"); - public static final ConfigHotkey MASS_CRAFT = new ConfigHotkey("massCraft", "LEFT_CONTROL,LEFT_ALT,C", GUI_NO_ORDER, "Mass craft and throw out the results with the\ncurrently selected recipe as long as this\nkeybind is held down"); - public static final ConfigHotkey MOVE_CRAFT_RESULTS = new ConfigHotkey("moveCraftResults", "LEFT_CONTROL,M", GUI_NO_ORDER, "Move all of the currently selected recipe's\noutput items from the player inventory\nto the other inventory"); - public static final ConfigHotkey RECIPE_VIEW = new ConfigHotkey("recipeView", "A", GUI_RELAXED, "Show the Item Scroller recipe GUI"); - public static final ConfigHotkey SLOT_DEBUG = new ConfigHotkey("slotDebug", "LEFT_CONTROL,LEFT_ALT,LEFT_SHIFT,I", GUI_NO_ORDER, "Print debug info for the hovered slot or GUI"); - public static final ConfigHotkey STORE_RECIPE = new ConfigHotkey("storeRecipe", "BUTTON_3", GUI_RELAXED_CANCEL, "Store a recipe while hovering over a crafting output item"); - public static final ConfigHotkey THROW_CRAFT_RESULTS = new ConfigHotkey("throwCraftResults", "LEFT_CONTROL,T", GUI_NO_ORDER, "Throw all of the currently selected recipe's\noutput items to the ground from the player inventory"); - public static final ConfigHotkey TOGGLE_MOD_ON_OFF = new ConfigHotkey("toggleModOnOff", "", KeybindSettings.GUI, "Toggle all mod functionality ON/OFF"); - public static final ConfigHotkey VILLAGER_TRADE_FAVORITES = new ConfigHotkey("villagerTradeFavorites","", KeybindSettings.GUI, "Trade everything possible with all the favorited trades\nof the current villager"); - - public static final ConfigHotkey KEY_DRAG_DROP_LEAVE_ONE = new ConfigHotkey("keyDragDropLeaveOne", "LEFT_SHIFT,Q,BUTTON_2", GUI_NO_ORDER, "Key to drop all but the last item from each stack dragged over"); - public static final ConfigHotkey KEY_DRAG_DROP_SINGLE = new ConfigHotkey("keyDragDropSingle", "Q,BUTTON_1", GUI_NO_ORDER, "Key to drop one item from each stack dragged over"); - public static final ConfigHotkey KEY_DRAG_DROP_STACKS = new ConfigHotkey("keyDragDropStacks", "LEFT_SHIFT,Q,BUTTON_1", GUI_NO_ORDER, "Key to drop the entire stacks dragged over"); - - public static final ConfigHotkey KEY_DRAG_LEAVE_ONE = new ConfigHotkey("keyDragMoveLeaveOne", "LEFT_SHIFT,BUTTON_2", GUI_NO_ORDER, "Key to move all but the last item from\nall the stacks dragged over"); - public static final ConfigHotkey KEY_DRAG_MATCHING = new ConfigHotkey("keyDragMoveMatching", "LEFT_ALT,BUTTON_1", GUI_NO_ORDER, "Key to move all matching items dragged over"); - public static final ConfigHotkey KEY_DRAG_MOVE_ONE = new ConfigHotkey("keyDragMoveOne", "LEFT_CONTROL,BUTTON_1", GUI_NO_ORDER, "Key to move one item from each stack dragged over"); - public static final ConfigHotkey KEY_DRAG_FULL_STACKS = new ConfigHotkey("keyDragMoveStacks", "LEFT_SHIFT,BUTTON_1", GUI_NO_ORDER, "Key to move the entire stacks dragged over"); - - public static final ConfigHotkey KEY_MOVE_EVERYTHING = new ConfigHotkey("keyMoveEverything", "LEFT_ALT,LEFT_SHIFT,BUTTON_1", GUI_NO_ORDER, "Key to move ALL items to the other\ninventory when clicking a stack"); - - public static final ConfigHotkey KEY_WS_MOVE_DOWN_LEAVE_ONE = new ConfigHotkey("wsMoveDownLeaveOne", "S,BUTTON_2", GUI_NO_ORDER, "The key to move all but the last item from each stack\n\"down\" in the inventory"); - public static final ConfigHotkey KEY_WS_MOVE_DOWN_MATCHING = new ConfigHotkey("wsMoveDownMatching", "LEFT_ALT,S,BUTTON_1", GUI_NO_ORDER, "The key to move all matching items \"down\" in the inventory"); - public static final ConfigHotkey KEY_WS_MOVE_DOWN_SINGLE = new ConfigHotkey("wsMoveDownSingle", "S,BUTTON_1", GUI_NO_ORDER, "The key to move single items \"down\" in the inventory"); - public static final ConfigHotkey KEY_WS_MOVE_DOWN_STACKS = new ConfigHotkey("wsMoveDownStacks", "LEFT_SHIFT,S,BUTTON_1", GUI_NO_ORDER, "The key to move stacks \"down\" in the inventory"); - public static final ConfigHotkey KEY_WS_MOVE_UP_LEAVE_ONE = new ConfigHotkey("wsMoveUpLeaveOne", "W,BUTTON_2", GUI_NO_ORDER, "The key to move all but the last item from each stack\n\"up\" in the inventory"); - public static final ConfigHotkey KEY_WS_MOVE_UP_MATCHING = new ConfigHotkey("wsMoveUpMatching", "LEFT_ALT,W,BUTTON_1", GUI_NO_ORDER, "The key to move all matching items \"up\" in the inventory"); - public static final ConfigHotkey KEY_WS_MOVE_UP_SINGLE = new ConfigHotkey("wsMoveUpSingle", "W,BUTTON_1", GUI_NO_ORDER, "The key to move single items \"up\" in the inventory"); - public static final ConfigHotkey KEY_WS_MOVE_UP_STACKS = new ConfigHotkey("wsMoveUpStacks", "LEFT_SHIFT,W,BUTTON_1", GUI_NO_ORDER, "The key to move stacks \"up\" in the inventory"); - - public static final ConfigHotkey MODIFIER_MOVE_EVERYTHING = new ConfigHotkey("modifierMoveEverything", "LEFT_ALT,LEFT_SHIFT", GUI_NO_ORDER, "Modifier key to move ALL items to the other\ninventory when scrolling over a stack"); - public static final ConfigHotkey MODIFIER_MOVE_MATCHING = new ConfigHotkey("modifierMoveMatching", "LEFT_ALT", GUI_NO_ORDER, "Modifier key to move all matching items to the other\ninventory when scrolling over a stack"); - public static final ConfigHotkey MODIFIER_MOVE_STACK = new ConfigHotkey("modifierMoveStack", "LEFT_SHIFT", GUI_NO_ORDER, "Modifier key to move the entire stack to the other\ninventory when scrolling over it"); - public static final ConfigHotkey MODIFIER_TOGGLE_VILLAGER_GLOBAL_FAVORITE = new ConfigHotkey("modifierToggleVillagerGlobalFavorite", "LEFT_SHIFT", GUI_RELAXED, "Modifier key to hold while middle clicking a trade,\nto toggle the global favorite state for that trade.\nGlobal favorites are used for villagers that don't\nhave any \"local\"/villager-specific favorites set."); + 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"); public static final List HOTKEY_LIST = ImmutableList.of( OPEN_CONFIG_GUI, @@ -87,6 +89,8 @@ public class Hotkeys KEY_WS_MOVE_UP_LEAVE_ONE, KEY_WS_MOVE_UP_MATCHING, KEY_WS_MOVE_UP_SINGLE, - KEY_WS_MOVE_UP_STACKS + KEY_WS_MOVE_UP_STACKS, + + SORT_INVENTORY ); } 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 c9b4bcf..8506a36 100644 --- a/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java +++ b/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java @@ -1,8 +1,10 @@ package fi.dy.masa.itemscroller.event; +import fi.dy.masa.itemscroller.mixin.IMixinCraftingResultSlot; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.inventory.RecipeInputInventory; import net.minecraft.screen.slot.Slot; import fi.dy.masa.malilib.config.options.ConfigHotkey; import fi.dy.masa.malilib.gui.GuiBase; @@ -164,10 +166,27 @@ else if (key == Hotkeys.SLOT_DEBUG.getKeybind()) return true; } + else if (key == Hotkeys.SORT_INVENTORY.getKeybind()) + { + InventoryUtils.sortInventory(gui); + return true; + } return false; } + private static void debugPrintInv(RecipeInputInventory inv) + { + for (int i = 0; i < inv.getHeight(); i++) + { + for (int j = 0; j < inv.getWidth(); j++) + { + System.out.print(inv.getStack(i * inv.getWidth() + j) + " "); + } + System.out.println(); + } + } + @Override public void onClientTick(MinecraftClient mc) { @@ -193,6 +212,7 @@ public void onClientTick(MinecraftClient mc) return; } + InventoryUtils.bufferInvUpdates = true; Slot outputSlot = CraftingHandler.getFirstCraftingOutputSlotForGui(gui); if (outputSlot != null) @@ -213,16 +233,31 @@ public void onClientTick(MinecraftClient mc) InventoryUtils.setInhibitCraftingOutputUpdate(true); InventoryUtils.throwAllCraftingResultsToGround(recipe, gui); InventoryUtils.throwAllNonRecipeItemsToGround(recipe, gui); + RecipeInputInventory inv = ((IMixinCraftingResultSlot) (outputSlot)).itemscroller_getCraftingInventory(); + //System.out.println("Before:"); + //debugPrintInv(inv); + try + { + Thread.sleep(0); + } catch (InterruptedException e) + { + } InventoryUtils.setCraftingGridContentsUsingSwaps(gui, mc.player.getInventory(), recipe, outputSlot); + //System.out.println("After:"); + //debugPrintInv(inv); InventoryUtils.setInhibitCraftingOutputUpdate(false); InventoryUtils.updateCraftingOutputSlot(outputSlot); + //System.out.printf("Output slot: %s\n", outputSlot.getStack()); + if (InventoryUtils.areStacksEqual(outputSlot.getStack(), recipe.getResult()) == false) { break; } InventoryUtils.shiftClickSlot(gui, outputSlot.id); + //System.out.println("Shift clicked"); + //debugPrintInv(inv); } } else @@ -259,6 +294,11 @@ public void onClientTick(MinecraftClient mc) } this.massCraftTicker = 0; + InventoryUtils.bufferInvUpdates = false; + InventoryUtils.invUpdatesBuffer.removeIf(packet -> { + packet.apply(mc.getNetworkHandler()); + return true; + }); } } } diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java new file mode 100644 index 0000000..81d1cf3 --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java @@ -0,0 +1,59 @@ +package fi.dy.masa.itemscroller.mixin; + +import fi.dy.masa.itemscroller.util.InventoryUtils; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.network.packet.s2c.play.InventoryS2CPacket; +import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; +import net.minecraft.network.packet.s2c.play.StatisticsS2CPacket; +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(ClientPlayNetworkHandler.class) +public class MixinClientPlayNetworkHandler +{ + @Inject(method = "onStatistics", at = @At("RETURN"), cancellable = true) + private void onPong(StatisticsS2CPacket packet, CallbackInfo ci) + { + if (InventoryUtils.onPong(packet)) + { + ci.cancel(); + } + } + + @Inject( + method = "onInventory", + at = @At( + 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 onInventory(InventoryS2CPacket packet, CallbackInfo ci) + { + if (InventoryUtils.bufferInvUpdates) + { + InventoryUtils.invUpdatesBuffer.add(packet); + ci.cancel(); + } + } + + @Inject( + method = "onScreenHandlerSlotUpdate", + at = @At( + 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 onScreenHandlerSlotUpdate(ScreenHandlerSlotUpdateS2CPacket packet, CallbackInfo ci) + { + if (InventoryUtils.bufferInvUpdates) + { + InventoryUtils.invUpdatesBuffer.add(packet); + ci.cancel(); + } + } +} 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 a6fe5b5..2328a64 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayerInteractionManager.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayerInteractionManager.java @@ -1,5 +1,8 @@ package fi.dy.masa.itemscroller.mixin; +import net.minecraft.client.MinecraftClient; +import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket; +import net.minecraft.screen.ScreenHandler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -26,6 +29,15 @@ private void cancelWindowClicksWhileReplayingBufferedPackets(CallbackInfo ci) target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;send(Lnet/minecraft/network/packet/Packet;)V")) private void bufferClickPacketsAndCancel(ClientPlayNetworkHandler netHandler, Packet packet) { + /* + if (packet instanceof ClickSlotC2SPacket clickPacket) + { + MinecraftClient mc = MinecraftClient.getInstance(); + System.out.printf("clickPacket: type: %s button: %d, slot: %d, (after) cursor item: %s\n", clickPacket.getActionType(), clickPacket.getButton(), clickPacket.getSlot(), clickPacket.getStack()); + clickPacket.getModifiedStacks().forEach((integer, stack) -> System.out.printf("%d = %s, ", integer, stack)); + System.out.println(); + } + */ if (ClickPacketBuffer.shouldBufferClickPackets()) { ClickPacketBuffer.bufferPacket(packet); 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 7758524..42cf464 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinCraftingScreenHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinCraftingScreenHandler.java @@ -1,5 +1,6 @@ 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; @@ -25,7 +26,10 @@ public abstract class MixinCraftingScreenHandler @Inject(method = "onContentChanged", at = @At("RETURN")) private void onSlotChangedCraftingGrid(net.minecraft.inventory.Inventory inventory, CallbackInfo ci) { - InventoryUtils.onSlotChangedCraftingGrid(this.player, this.input, this.result); + if (MinecraftClient.getInstance().isOnThread()) + { + InventoryUtils.onSlotChangedCraftingGrid(this.player, this.input, this.result); + } } @Inject(method = "updateResult", at = @At("RETURN")) @@ -37,6 +41,9 @@ private static void onUpdateResult( CraftingResultInventory resultInv, RecipeEntry recipeEntry, CallbackInfo ci) { - InventoryUtils.onSlotChangedCraftingGrid(player, craftingInventory, resultInv); + if (MinecraftClient.getInstance().isOnThread()) + { + InventoryUtils.onSlotChangedCraftingGrid(player, craftingInventory, resultInv); + } } } diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinItemStack.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinItemStack.java new file mode 100644 index 0000000..fca0f3c --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinItemStack.java @@ -0,0 +1,35 @@ +package fi.dy.masa.itemscroller.mixin; + +import fi.dy.masa.itemscroller.config.Configs; +import fi.dy.masa.itemscroller.util.InventoryUtils; +import net.minecraft.client.MinecraftClient; +import net.minecraft.item.ItemStack; +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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ItemStack.class) +public class MixinItemStack +{ + @Inject(method = "capCount", at = @At("HEAD"), cancellable = true) + private void dontCap(int maxCount, CallbackInfo ci) + { + // Client-side fx for empty shulker box stacking + if (MinecraftClient.getInstance().isOnThread() && Configs.Generic.SORT_ASSUME_EMPTY_BOX_STACKS.getBooleanValue()) + { + ci.cancel(); + } + } + + @Inject(method = "getMaxCount", at = @At("HEAD"), cancellable = true) + private void getMaxCount(CallbackInfoReturnable cir) + { + // Client-side fx for empty shulker box stacking + if (MinecraftClient.getInstance().isOnThread() && Configs.Generic.SORT_ASSUME_EMPTY_BOX_STACKS.getBooleanValue() && InventoryUtils.assumeEmptyShulkerStacking) + { + cir.setReturnValue(InventoryUtils.stackMaxSize((ItemStack) (Object) this, true)); + } + } +} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java new file mode 100644 index 0000000..d5a98e4 --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java @@ -0,0 +1,9 @@ +package fi.dy.masa.itemscroller.mixin; + +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(RecipeBookWidget.class) +public class MixinRecipeBookWidget +{ +} diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/debug/MixinServerPlayNetworkHandler.java b/src/main/java/fi/dy/masa/itemscroller/mixin/debug/MixinServerPlayNetworkHandler.java new file mode 100644 index 0000000..86030f4 --- /dev/null +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/debug/MixinServerPlayNetworkHandler.java @@ -0,0 +1,33 @@ +package fi.dy.masa.itemscroller.mixin.debug; + +import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket; +import net.minecraft.screen.slot.Slot; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; +import org.objectweb.asm.Opcodes; +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; + +@Mixin(ServerPlayNetworkHandler.class) +public class MixinServerPlayNetworkHandler +{ + /* + @Shadow public ServerPlayerEntity player; + + @Inject(method = "onClickSlot", at = @At(value = "JUMP", opcode = Opcodes.IFEQ, ordinal = 2)) + private void beforeSendUpdates(ClickSlotC2SPacket packet, CallbackInfo ci) { + for (Slot slot : this.player.currentScreenHandler.slots) + { + ItemStack clientStack = this.player.currentScreenHandler.trackedStacks.get(slot.id); + if (!ItemStack.areItemsEqual(slot.getStack(), clientStack)) + { + System.err.printf("Slot %d desync! Server: %s, Client: %s\n", slot.id, slot.getStack(), clientStack); + } + } + } + */ +} 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 30599d5..61db62e 100644 --- a/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java +++ b/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java @@ -1,22 +1,33 @@ package fi.dy.masa.itemscroller.recipes; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.Arrays; + +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.HandledScreen; 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.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 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; public RecipePattern() { @@ -35,6 +46,7 @@ public void clearRecipe() { Arrays.fill(this.recipe, InventoryUtils.EMPTY_STACK); this.result = InventoryUtils.EMPTY_STACK; + this.vanillaRecipe = null; } public void ensureRecipeSizeAndClearRecipe(int size) @@ -43,6 +55,33 @@ public void ensureRecipeSizeAndClearRecipe(int size) this.clearRecipe(); } + private void lookupVanillaRecipe(World world) { + this.vanillaRecipe = null; + var mc = MinecraftClient.getInstance(); + int recipeSize; + if (recipe.length == 4) + { + recipeSize = 2; + } + else if (recipe.length == 9) + { + recipeSize = 3; + } + else + { + return; + } + + for (RecipeEntry match : mc.world.getRecipeManager().getAllMatches(RecipeType.CRAFTING, CraftingRecipeInput.create(recipeSize, recipeSize, Arrays.asList(recipe)), world)) + { + if (InventoryUtils.areStacksEqual(result, match.value().getResult(world.getRegistryManager()))) + { + this.vanillaRecipe = match; + return; + } + } + } + public void storeCraftingRecipe(Slot slot, HandledScreen gui, boolean clearIfEmpty) { SlotRange range = CraftingHandler.getCraftingGridSlots(gui, slot); @@ -63,6 +102,7 @@ public void storeCraftingRecipe(Slot slot, HandledScreen getVanillaRecipeEntry() + { + return vanillaRecipe; + } + + @SuppressWarnings("unchecked") + @Nullable + public Recipe getVanillaRecipe() + { + if (vanillaRecipe == null) + { + return null; + } + return (Recipe) vanillaRecipe.value(); + } } 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 5623e70..eab4952 100644 --- a/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java +++ b/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java @@ -3,9 +3,13 @@ import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.*; + +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 net.minecraft.block.ShulkerBoxBlock; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; @@ -14,12 +18,19 @@ import net.minecraft.client.gui.screen.ingame.MerchantScreen; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.world.ClientWorld; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.ContainerComponent; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.CraftingResultInventory; import net.minecraft.inventory.Inventory; import net.minecraft.inventory.RecipeInputInventory; +import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; +import net.minecraft.network.listener.ClientPlayPacketListener; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.c2s.play.ClientStatusC2SPacket; +import net.minecraft.network.packet.s2c.play.StatisticsS2CPacket; import net.minecraft.recipe.CraftingRecipe; import net.minecraft.recipe.RecipeEntry; import net.minecraft.recipe.RecipeType; @@ -52,6 +63,7 @@ public class InventoryUtils { private static final Set DRAGGED_SLOTS = new HashSet<>(); + private static final int SERVER_SYNC_MAGIC = 45510; private static WeakReference sourceSlotCandidate = null; private static WeakReference sourceSlot = null; @@ -62,6 +74,10 @@ public class InventoryUtils private static int lastPosY; private static int slotNumberLast; private static boolean inhibitCraftResultUpdate; + private static Runnable selectedSlotUpdateTask; + public static boolean assumeEmptyShulkerStacking = false; + public static boolean bufferInvUpdates = false; + public static List> invUpdatesBuffer = new ArrayList<>(); public static void setInhibitCraftingOutputUpdate(boolean inhibitUpdate) { @@ -72,10 +88,10 @@ public static void onSlotChangedCraftingGrid(PlayerEntity player, RecipeInputInventory craftMatrix, CraftingResultInventory inventoryCraftResult) { - if (inhibitCraftResultUpdate && Configs.Generic.MASS_CRAFT_INHIBIT_MID_UPDATES.getBooleanValue()) - { - return; - } +// if (inhibitCraftResultUpdate && Configs.Generic.MASS_CRAFT_INHIBIT_MID_UPDATES.getBooleanValue()) +// { +// return; +// } if (Configs.Generic.CLIENT_CRAFTING_FIX.getBooleanValue()) { @@ -1419,7 +1435,7 @@ private static boolean tryMoveItemsToCraftingGridSlots(RecipePattern recipe, for (Map.Entry entry : ingredientSlots.entrySet()) { - ItemStack ingredientReference = entry.getKey().getStack(); + ItemStack ingredientReference = entry.getKey().stack(); IntArrayList recipeSlots = entry.getValue(); IntArrayList targetSlots = new IntArrayList(); @@ -1671,31 +1687,39 @@ public static void setCraftingGridContentsUsingSwaps(HandledScreen= 0) { - clickSlot(gui, slotNum, index, SlotActionType.SWAP); + Slot ingredientSlot = gui.getScreenHandler().getSlot(index); + if (ingredientSlot.inventory instanceof PlayerInventory && ingredientSlot.getIndex() < 9) + { + // hotbar + clickSlot(gui, slotNum, ingredientSlot.getIndex(), SlotActionType.SWAP); + } + else + { + swapSlots(gui, slotNum, index); + } movedSomething = true; } } } } - movedSomething |= (toRemove.isEmpty() == false); + movedSomething |= !toRemove.isEmpty(); for (int slotNum : toRemove) { @@ -2566,8 +2590,11 @@ public static void tryClearCursor(HandledScreen gui) break; } - leftClickSlot(gui, slotNum); - stackCursor = gui.getScreenHandler().getCursorStack(); + if (slot.inventory instanceof PlayerInventory) + { + leftClickSlot(gui, slotNum); + stackCursor = gui.getScreenHandler().getCursorStack(); + } } } } @@ -2589,6 +2616,288 @@ public static MoveAction getActiveMoveAction() return activeMoveAction; } + public static void sortInventory(HandledScreen gui) + { + Pair range = new IntIntMutablePair(Integer.MAX_VALUE, 0); + Slot focusedSlot = AccessorUtils.getSlotUnderMouse(gui); + if (focusedSlot == null) { + return; + } + ScreenHandler container = gui.getScreenHandler(); + if (gui instanceof CreativeInventoryScreen creative && !creative.isInventoryTabSelected()) + { + return; + } + + int focusedIndex = -1; + for (int i = 0; i < container.slots.size(); i++) + { + Slot slot = container.slots.get(i); + if (slot == focusedSlot) + { + focusedIndex = i; + } + if (slot.inventory == focusedSlot.inventory) + { + if (i < range.first()) + { + range.first(i); + } + if (i >= range.second()) + { + range.second(i + 1); + } + } + } + if (focusedIndex == -1) + { + return; + } + if (focusedSlot.inventory instanceof PlayerInventory) + { + if (range.left() == 5 && range.right() == 46) + { + // Creative, PlayerScreenHandler + if (focusedIndex >= 9 && focusedIndex < 36) + { + range.left(9).right(36); + } + else if (focusedIndex >= 36 && focusedIndex < 45) + { + range.left(36).right(45); + } + } + else if (range.right() - range.left() == 36) + { + // Normal containers + if (focusedIndex < range.left() + 27) + { + range.right(range.left() + 27); + } + else + { + range.left(range.right() - 9); + } + } + } + + //System.out.printf("Sorting [%d, %d)\n", range.first(), range.second()); + //ItemScroller.printDebug("Sorting [{}, {}]", range.first(), range.second()); + tryClearCursor(gui); + tryMergeItems(gui, range.left(), range.right() - 1); + + if (Configs.Generic.SORT_ASSUME_EMPTY_BOX_STACKS.getBooleanValue()) + { + ClientStatusC2SPacket packet = new ClientStatusC2SPacket(ClientStatusC2SPacket.Mode.REQUEST_STATS); + MinecraftClient.getInstance().getNetworkHandler().send(packet); + selectedSlotUpdateTask = () -> quickSort(gui, range.first(), range.second() - 1); + } + else + { + quickSort(gui, range.first(), range.second() - 1); + } + } + + /** + * sort inventory + */ + private static void quickSort(HandledScreen gui, int start, int end) + { + if (start >= end) return; + + ItemStack mid = gui.getScreenHandler().getSlot(end).getStack(); + int l = start; + int r = end - 1; + while (l < r) + { + while (l < r && compareStacks(gui.getScreenHandler().getSlot(l).getStack(), mid) < 0) + { + l++; + } + while (l < r && compareStacks(gui.getScreenHandler().getSlot(r).getStack(), mid) >= 0) + { + r--; + } + if (l != r) + { + swapSlots(gui, l, r); + } + } + if (compareStacks(gui.getScreenHandler().getSlot(l).getStack(), gui.getScreenHandler().getSlot(end).getStack()) >= 0) + { + swapSlots(gui, l, end); + } + else + { + l++; + } + + quickSort(gui, start, l - 1); + quickSort(gui, l + 1, end); + } + + private static int compareStacks(ItemStack stack1, ItemStack stack2) + { + if (Configs.Generic.SORT_SHULKER_BOXES_AT_END.getBooleanValue()) + { + if (isShulkerBox(stack1) && !isShulkerBox(stack2)) + { + return 1; + } + if (!isShulkerBox(stack1) && isShulkerBox(stack2)) + { + return -1; + } + } + if (stack1.isEmpty() && stack2.isEmpty()) + return 0; + else if (stack1.isEmpty()) + return 1; + else if (stack2.isEmpty()) + return -1; + + if (isShulkerBox(stack1) && isShulkerBox(stack2)) + { + List contents1 = stack1.getOrDefault(DataComponentTypes.CONTAINER, ContainerComponent.DEFAULT).streamNonEmpty().toList(); + List contents2 = stack2.getOrDefault(DataComponentTypes.CONTAINER, ContainerComponent.DEFAULT).streamNonEmpty().toList(); + if (contents1.size() != contents2.size()) + { + return Integer.compare(contents1.size(), contents2.size()); + } + } + if (stack1.getItem() != stack2.getItem()) + { + return Integer.compare(Registries.ITEM.getRawId(stack1.getItem()), Registries.ITEM.getRawId(stack2.getItem())); + } + if (!areStacksEqual(stack1, stack2)) + { + return Integer.compare(stack1.getComponents().hashCode(), stack2.getComponents().hashCode()); + } + return Integer.compare(-stack1.getCount(), -stack2.getCount()); + } + + public static boolean onPong(StatisticsS2CPacket packet) + { + if (selectedSlotUpdateTask != null) + { + selectedSlotUpdateTask.run(); + selectedSlotUpdateTask = null; + return true; + } + return false; + } + + private static boolean isShulkerBox(ItemStack stack) + { + return stack.getItem() instanceof BlockItem bi && bi.getBlock() instanceof ShulkerBoxBlock; + } + + private static boolean isEmptyShulkerBox(ItemStack stack) + { + return isShulkerBox(stack) && stack.getOrDefault(DataComponentTypes.CONTAINER, ContainerComponent.DEFAULT).streamNonEmpty().findAny().isEmpty(); + } + + public static int stackMaxSize(ItemStack stack, boolean assumeShulkerStacking) + { + if (stack.isEmpty()) + { + return 64; + } + + if (assumeShulkerStacking && Configs.Generic.SORT_ASSUME_EMPTY_BOX_STACKS.getBooleanValue()) + { + if (isEmptyShulkerBox(stack)) + { + return 64; + } + } + + return stack.getOrDefault(DataComponentTypes.MAX_STACK_SIZE, 1); + } + + /** + * @return are there still items left in the original slot? + */ + private static boolean addStackTo(HandledScreen gui, Slot slot, Slot target) + { + if (slot == null || target == null) + { + return false; + } + + ItemStack stack = slot.getStack(); + ItemStack targetStack = target.getStack(); + + if (stack.isEmpty() || !ItemStack.areItemsEqual(stack, targetStack)) + { + return !stack.isEmpty(); + } + + if (targetStack.isEmpty()) + { + clickSlot(gui, slot, slot.id, 0, SlotActionType.PICKUP); + clickSlot(gui, target, target.id, 0, SlotActionType.PICKUP); + //System.out.printf("Moved stack from slot %d to slot %d\n", slot.id, target.id); + //ItemScroller.printDebug("Moved stack from slot {} to slot {}", slot.id, target.id); + return false; + } + + int stackSize = stack.getCount(); + int targetSize = targetStack.getCount(); + assumeEmptyShulkerStacking = true; + int maxSize = stackMaxSize(stack, true); + //System.out.printf("Merging %s into %s, maxSize: %d\n", stack, targetStack, maxSize); + //ItemScroller.printDebug("Merging {} into {}, maxSize: {}", stack, targetStack, maxSize); + + if (targetSize >= maxSize) + { + return true; + } + + clickSlot(gui, slot, slot.id, 0, SlotActionType.PICKUP); + clickSlot(gui, target, target.id, 0, SlotActionType.PICKUP); + clickSlot(gui, slot, slot.id, 0, SlotActionType.PICKUP); + assumeEmptyShulkerStacking = false; + int amount = stackSize + targetSize - maxSize; + + return amount > 0; + } + + private static void tryMergeItems(HandledScreen gui, int left, int right) + { + Map nonFullStacks = new HashMap<>(); + + for (int i = left; i <= right; i++) + { + Slot slot = gui.getScreenHandler().getSlot(i); + + if (slot.hasStack()) + { + ItemStack stack = slot.getStack(); + + if (stack.getCount() >= stackMaxSize(stack, true)) { + // ignore overstacking items. + continue; + } + + ItemType key = new ItemType(stack); + int slotNum = nonFullStacks.getOrDefault(key, -1); + + if (slotNum == -1) + { + nonFullStacks.put(key, i); + } + else + { + if (addStackTo(gui, slot, gui.getScreenHandler().getSlot(slotNum))) + { + nonFullStacks.put(key, i); + } + } + } + } + } + /* private static class SlotVerticalSorterSlots implements Comparator { @@ -2732,9 +3041,9 @@ public static void dropStack(HandledScreen gui, int slo public static void swapSlots(HandledScreen gui, int slotNum, int otherSlot) { - clickSlot(gui, slotNum, 0, SlotActionType.SWAP); - clickSlot(gui, otherSlot, 0, SlotActionType.SWAP); - clickSlot(gui, slotNum, 0, SlotActionType.SWAP); + clickSlot(gui, slotNum, 8, SlotActionType.SWAP); + clickSlot(gui, otherSlot, 8, SlotActionType.SWAP); + clickSlot(gui, slotNum, 8, SlotActionType.SWAP); } private static void dragSplitItemsIntoSlots(HandledScreen gui, diff --git a/src/main/java/fi/dy/masa/itemscroller/util/ItemType.java b/src/main/java/fi/dy/masa/itemscroller/util/ItemType.java index 86bb655..f83c22a 100644 --- a/src/main/java/fi/dy/masa/itemscroller/util/ItemType.java +++ b/src/main/java/fi/dy/masa/itemscroller/util/ItemType.java @@ -11,20 +11,13 @@ * Wrapper class for ItemStack, which implements equals() * for the item, damage and NBT, but not stackSize. */ -public class ItemType +public record ItemType(ItemStack stack) { - private final ItemStack stack; - public ItemType(@Nonnull ItemStack stack) { this.stack = stack.isEmpty() ? InventoryUtils.EMPTY_STACK : InventoryUtils.copyStack(stack, false); } - public ItemStack getStack() - { - return this.stack; - } - @Override public int hashCode() { @@ -53,6 +46,7 @@ public boolean equals(Object obj) /** * Returns a map that has a list of the indices for each different item in the input list + * * @param stacks * @return */ diff --git a/src/main/java/org/thinkingstudio/rocknroller/RocknRoller.java b/src/main/java/org/thinkingstudio/rocknroller/RocknRoller.java index 94b567d..953317d 100644 --- a/src/main/java/org/thinkingstudio/rocknroller/RocknRoller.java +++ b/src/main/java/org/thinkingstudio/rocknroller/RocknRoller.java @@ -4,18 +4,19 @@ import fi.dy.masa.itemscroller.Reference; import fi.dy.masa.itemscroller.gui.GuiConfigs; import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLLoader; import org.thinkingstudio.mafglib.util.NeoUtils; @Mod(value = Reference.MOD_ID, dist = Dist.CLIENT) public class RocknRoller { - public RocknRoller() { + public RocknRoller(ModContainer modContainer) { if (FMLLoader.getDist().isClient()) { ItemScroller.onInitialize(); // Config Screen - NeoUtils.getInstance().registerModConfigScreen(Reference.MOD_ID, (screen) -> { + NeoUtils.getInstance().registerModConfigScreen(modContainer, (screen) -> { GuiConfigs gui = new GuiConfigs(); gui.setParent(screen); return gui; diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 0000000..5d25bbe --- /dev/null +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1 @@ +public net.minecraft.world.inventory.AbstractContainerMenu lastSlots # lastSlots \ No newline at end of file diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index 6120b2a..d753fb0 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -19,6 +19,9 @@ Move items in inventory GUIs by scrolling the mouse wheel or dragging over slots [[mixins]] config = "rocknroller.mixins.json" +[[accessTransformers]] +file = "META-INF/accesstransformer.cfg" + [[dependencies.rocknroller]] modId = "neoforge" type = "required" diff --git a/src/main/resources/assets/rocknroller/lang/en_us.json b/src/main/resources/assets/rocknroller/lang/en_us.json index be8259d..4d07093 100644 --- a/src/main/resources/assets/rocknroller/lang/en_us.json +++ b/src/main/resources/assets/rocknroller/lang/en_us.json @@ -1,6 +1,142 @@ { "fml.menu.mods.info.description.rocknroller": "ItemScroller unofficial (Neo)Forge port.\nMove items in inventory GUIs by scrolling the mouse wheel or dragging over slots.", + "itemscroller.config.generic.name.carpetCtrlQCraftingEnabledOnServer": "carpetCtrlQCraftingEnabledOnServer", + "itemscroller.config.generic.name.clientCraftingFixOn1_12": "clientCraftingFixOn1.12", + "itemscroller.config.generic.name.craftingRenderRecipeItems": "craftingRenderRecipeItems", + "itemscroller.config.generic.name.debugMessages": "debugMessages", + "itemscroller.config.generic.name.modMainToggle": "modMainToggle", + "itemscroller.config.generic.name.massCraftInhibitMidUpdates": "massCraftInhibitMidUpdates", + "itemscroller.config.generic.name.massCraftInterval": "massCraftInterval", + "itemscroller.config.generic.name.massCraftIterations": "massCraftIterations", + "itemscroller.config.generic.name.massCraftSwapsOnly": "massCraftSwapsOnly", + "itemscroller.config.generic.name.packetRateLimit": "packetRateLimit", + "itemscroller.config.generic.name.craftingRecipesSaveToFile": "craftingRecipesSaveToFile", + "itemscroller.config.generic.name.craftingRecipesSaveFileIsGlobal": "craftingRecipesSaveFileIsGlobal", + "itemscroller.config.generic.name.rateLimitClickPackets": "rateLimitClickPackets", + "itemscroller.config.generic.name.reverseScrollDirectionSingle": "reverseScrollDirectionSingle", + "itemscroller.config.generic.name.reverseScrollDirectionStacks": "reverseScrollDirectionStacks", + "itemscroller.config.generic.name.useRecipeCaching": "useRecipeCaching", + "itemscroller.config.generic.name.useSlotPositionAwareScrollDirection": "useSlotPositionAwareScrollDirection", + "itemscroller.config.generic.name.villagerTradeUseGlobalFavorites": "villagerTradeUseGlobalFavorites", + "itemscroller.config.generic.name.villagerTradeListRememberScrollPosition": "villagerTradeListRememberScrollPosition", + "itemscroller.config.generic.name.sortAssumeEmptyBoxStacks": "sortAssumeEmptyBoxStacks", + "itemscroller.config.generic.name.sortShulkerBoxesAtEnd": "sortShulkerBoxesAtEnd", + + "itemscroller.config.generic.comment.carpetCtrlQCraftingEnabledOnServer": "Set to true if the server is running the Carpet mod,\nand has the ctrlQCrafting option enabled.\nThis just changes which method Item Scroller uses\nfor the Drop key + Shift + Right click crafting.", + "itemscroller.config.generic.comment.clientCraftingFixOn1_12": "Enable updating the crafting recipe output directly on the client side.\nThis fixes the quick/mass crafting and right-click-to-craft-a-stack\nfeatures otherwise being broken in 1.12.", + "itemscroller.config.generic.comment.craftingRenderRecipeItems": "If enabled, then the recipe items are also rendered\nin the crafting recipe view.", + "itemscroller.config.generic.comment.debugMessages": "Enables some debug messages in the game console", + "itemscroller.config.generic.comment.modMainToggle": "Can disable all the functionality of the entire mod", + "itemscroller.config.generic.comment.massCraftInhibitMidUpdates": "Prevent recipe output slot updates in the middle of moving items\nto the crafting grid. This should reduce CPU usage\nbecause of not constantly querying the recipe after every grid change.", + "itemscroller.config.generic.comment.massCraftInterval": "The interval in game ticks the massCraft operation is repeated at", + "itemscroller.config.generic.comment.massCraftIterations": "How many massCraft iterations/attempts to do per execution.\nWith unstackable items or a full inventory and \"small recipe\"\nthis will need to be larger, as a shift + click craft to the inventory\nmight only craft 1 or 2 items per operation.", + "itemscroller.config.generic.comment.massCraftSwapsOnly": "Uses a newer method of filling the crafting grid,\nusing only swap slot packets.\n\nNote: Due to only using slot swap packets,\nno partial crafts are possible! And also no\nstack splitting will happen, at all.", + "itemscroller.config.generic.comment.packetRateLimit": "The limit of sent emulated slot click packets per game tick,\nif 'rateLimitClickPackets' is enabled", + "itemscroller.config.generic.comment.craftingRecipesSaveToFile": "If enabled, then the crafting features recipes are saved to a file\ninside minecraft/itemscroller/recipes_worldorservername.nbt.\nThis makes the recipes persistent across game restarts.", + "itemscroller.config.generic.comment.craftingRecipesSaveFileIsGlobal": "If true, then the recipe file is global, instead\n of being saved per-world or server", + "itemscroller.config.generic.comment.rateLimitClickPackets": "This is meant for compatibility with Spigot servers and similar,\nwhich apply rate limits to packets from the client.\nThis queues up the emulated slot click packets and sends\nthem rate limited over time. The limit per game tick can be set in 'packetRateLimit´.", + "itemscroller.config.generic.comment.reverseScrollDirectionSingle": "Reverse the scrolling direction for single item mode.", + "itemscroller.config.generic.comment.reverseScrollDirectionStacks": "Reverse the scrolling direction for full stacks mode.", + "itemscroller.config.generic.comment.useRecipeCaching": "Enables caching the last used recipe in the crafting\nrecipe output item fetching code. This can help a lot\nwith lowering CPU usage when mass crafting stuff.", + "itemscroller.config.generic.comment.useSlotPositionAwareScrollDirection": "When enabled, the item movement direction depends\non the slots' y-position on screen. Might be derpy with more\ncomplex inventories, use with caution!", + "itemscroller.config.generic.comment.villagerTradeUseGlobalFavorites": "Whether or not global (per-item-type) villager trade\nfavorites should be used.", + "itemscroller.config.generic.comment.villagerTradeListRememberScrollPosition": "Remember and restore the last scroll position in the\ntrade list when re-opening the GUI", + "itemscroller.config.generic.comment.sortAssumeEmptyBoxStacks": "Assume that empty boxes are stacking items\nwhen sorting the inventory.\nThis is useful if you installed mods to stack\nshulker boxes on remote server.\nThis will send an extra packet to ensure the\ninventory is synced.", + "itemscroller.config.generic.comment.sortShulkerBoxesAtEnd": "Sort shulker boxes at the end of the inventory\nwhen sorting the inventory.", + + "itemscroller.config.toggles.name.enableCraftingFeatures": "enableCraftingFeatures", + "itemscroller.config.toggles.name.enableDropkeyDropMatching": "enableDropkeyDropMatching", + "itemscroller.config.toggles.name.enableRightClickCraftingOneStack": "enableRightClickCraftingOneStack", + "itemscroller.config.toggles.name.enableScrollingEverything": "enableScrollingEverything", + "itemscroller.config.toggles.name.enableScrollingMatchingStacks": "enableScrollingMatchingStacks", + "itemscroller.config.toggles.name.enableScrollingSingle": "enableScrollingSingle", + "itemscroller.config.toggles.name.enableScrollingStacks": "enableScrollingStacks", + "itemscroller.config.toggles.name.enableScrollingStacksFallback": "enableScrollingStacksFallback", + "itemscroller.config.toggles.name.enableScrollingVillager": "enableScrollingVillager", + "itemscroller.config.toggles.name.enableShiftDropItems": "enableShiftDropItems", + "itemscroller.config.toggles.name.enableShiftPlaceItems": "enableShiftPlaceItems", + "itemscroller.config.toggles.name.enableVillagerTradeFeatures": "enableVillagerTradeFeatures", + + "itemscroller.config.toggles.comment.enableCraftingFeatures": "Enables scrolling items to and from crafting grids,\nwith a built-in 18 recipe memory.\nHold down the Recipe key to see the stored recipes and\nto change the selection. While holding the Recipe key,\nyou can either scroll or press a number key to change the selection.\nA recipe is stored to the currently selected \"recipe slot\"\n by clicking pick block over a configured crafting output slot.\nThe supported crafting grids must be added to the scrollableCraftingGrids list.", + "itemscroller.config.toggles.comment.enableDropkeyDropMatching": "Enables dropping all matching items from the same\ninventory with the hotkey", + "itemscroller.config.toggles.comment.enableRightClickCraftingOneStack": "Enables crafting up to one full stack when right clicking on\na slot that has been configured as a crafting output slot.", + "itemscroller.config.toggles.comment.enableScrollingEverything": "Enables scroll moving all items at once while\nholding the modifierMoveEverything keybind", + "itemscroller.config.toggles.comment.enableScrollingMatchingStacks": "Enables scroll moving all matching stacks at once\nwhile holding the modifierMoveMatching keybind", + "itemscroller.config.toggles.comment.enableScrollingSingle": "Enables moving items one item at a time by scrolling over a stack", + "itemscroller.config.toggles.comment.enableScrollingStacks": "Enables moving entire stacks at a time by scrolling over a stack", + "itemscroller.config.toggles.comment.enableScrollingStacksFallback": "Enables a \"fallback\" mode for scrolling entire stacks\n(for example to a vanilla crafting table,\nwhere shift + click doesn't work).", + "itemscroller.config.toggles.comment.enableScrollingVillager": "Enables special handling for the Villager GUIs.\n(Normally you can't shift click items in them.)\nHold shift and scroll up/down over the trade output slot.", + "itemscroller.config.toggles.comment.enableShiftDropItems": "Enables dropping all matching items at once by holding\nshift while clicking to drop a stack", + "itemscroller.config.toggles.comment.enableShiftPlaceItems": "Enables moving all matching stacks at once by holding\nshift while placing items to an empty slot", + "itemscroller.config.toggles.comment.enableVillagerTradeFeatures": "Enable trade favoriting and quick trade features for villagers.\nNote: The Shift + scrolling over the output slot is a separate feature\nand not affected by this option.\nThis option enables middle clicking to mark favorite trades,\nand right clicking on the trade list to fully trade that one trade.", + + "itemscroller.config.hotkeys.name.openConfigGui": "openConfigGui", + "itemscroller.config.hotkeys.name.craftEverything": "craftEverything", + "itemscroller.config.hotkeys.name.dropAllMatching": "dropAllMatching", + "itemscroller.config.hotkeys.name.massCraft": "massCraft", + "itemscroller.config.hotkeys.name.moveCraftResults": "moveCraftResults", + "itemscroller.config.hotkeys.name.recipeView": "recipeView", + "itemscroller.config.hotkeys.name.slotDebug": "slotDebug", + "itemscroller.config.hotkeys.name.storeRecipe": "storeRecipe", + "itemscroller.config.hotkeys.name.throwCraftResults": "throwCraftResults", + "itemscroller.config.hotkeys.name.toggleModOnOff": "toggleModOnOff", + "itemscroller.config.hotkeys.name.villagerTradeFavorites": "villagerTradeFavorites", + "itemscroller.config.hotkeys.name.keyDragDropLeaveOne": "keyDragDropLeaveOne", + "itemscroller.config.hotkeys.name.keyDragDropSingle": "keyDragDropSingle", + "itemscroller.config.hotkeys.name.keyDragDropStacks": "keyDragDropStacks", + "itemscroller.config.hotkeys.name.keyDragMoveLeaveOne": "keyDragMoveLeaveOne", + "itemscroller.config.hotkeys.name.keyDragMoveMatching": "keyDragMoveMatching", + "itemscroller.config.hotkeys.name.keyDragMoveOne": "keyDragMoveOne", + "itemscroller.config.hotkeys.name.keyDragMoveStacks": "keyDragMoveStacks", + "itemscroller.config.hotkeys.name.keyMoveEverything": "keyMoveEverything", + "itemscroller.config.hotkeys.name.wsMoveDownLeaveOne": "wsMoveDownLeaveOne", + "itemscroller.config.hotkeys.name.wsMoveDownMatching": "wsMoveDownMatching", + "itemscroller.config.hotkeys.name.wsMoveDownSingle": "wsMoveDownSingle", + "itemscroller.config.hotkeys.name.wsMoveDownStacks": "wsMoveDownStacks", + "itemscroller.config.hotkeys.name.wsMoveUpLeaveOne": "wsMoveUpLeaveOne", + "itemscroller.config.hotkeys.name.wsMoveUpMatching": "wsMoveUpMatching", + "itemscroller.config.hotkeys.name.wsMoveUpSingle": "wsMoveUpSingle", + "itemscroller.config.hotkeys.name.wsMoveUpStacks": "wsMoveUpStacks", + "itemscroller.config.hotkeys.name.modifierMoveEverything": "modifierMoveEverything", + "itemscroller.config.hotkeys.name.modifierMoveMatching": "modifierMoveMatching", + "itemscroller.config.hotkeys.name.modifierMoveStack": "modifierMoveStack", + "itemscroller.config.hotkeys.name.modifierToggleVillagerGlobalFavorite": "modifierToggleVillagerGlobalFavorite", + "itemscroller.config.hotkeys.name.sortInventory": "sortInventory", + + "itemscroller.config.hotkeys.comment.openConfigGui": "Open the in-game config GUI", + "itemscroller.config.hotkeys.comment.craftEverything": "Craft everything possible once with the currently selected recipe", + "itemscroller.config.hotkeys.comment.dropAllMatching": "Drop all stacks identical to the hovered stack", + "itemscroller.config.hotkeys.comment.massCraft": "Mass craft and throw out the results with the\ncurrently selected recipe as long as this\nkeybind is held down", + "itemscroller.config.hotkeys.comment.moveCraftResults": "Move all of the currently selected recipe's\noutput items from the player inventory\nto the other inventory", + "itemscroller.config.hotkeys.comment.recipeView": "Show the Item Scroller recipe GUI", + "itemscroller.config.hotkeys.comment.slotDebug": "Print debug info for the hovered slot or GUI", + "itemscroller.config.hotkeys.comment.storeRecipe": "Store a recipe while hovering over a crafting output item", + "itemscroller.config.hotkeys.comment.throwCraftResults": "Throw all of the currently selected recipe's\noutput items to the ground from the player inventory", + "itemscroller.config.hotkeys.comment.toggleModOnOff": "Toggle all mod functionality ON/OFF", + "itemscroller.config.hotkeys.comment.villagerTradeFavorites": "Trade everything possible with all the favorited trades\nof the current villager", + "itemscroller.config.hotkeys.comment.keyDragDropLeaveOne": "Key to drop all but the last item from each stack dragged over", + "itemscroller.config.hotkeys.comment.keyDragDropSingle": "Key to drop one item from each stack dragged over", + "itemscroller.config.hotkeys.comment.keyDragDropStacks": "Key to drop the entire stacks dragged over", + "itemscroller.config.hotkeys.comment.keyDragMoveLeaveOne": "Key to move all but the last item from\nall the stacks dragged over", + "itemscroller.config.hotkeys.comment.keyDragMoveMatching": "Key to move all matching items dragged over", + "itemscroller.config.hotkeys.comment.keyDragMoveOne": "Key to move one item from each stack dragged over", + "itemscroller.config.hotkeys.comment.keyDragMoveStacks": "Key to move the entire stacks dragged over", + "itemscroller.config.hotkeys.comment.keyMoveEverything": "Key to move ALL items to the other\ninventory when clicking a stack", + "itemscroller.config.hotkeys.comment.wsMoveDownLeaveOne": "The key to move all but the last item from each stack\n\"down\" in the inventor", + "itemscroller.config.hotkeys.comment.wsMoveDownMatching": "The key to move all matching items \"down\" in the inventory", + "itemscroller.config.hotkeys.comment.wsMoveDownSingle": "The key to move single items \"down\" in the inventory", + "itemscroller.config.hotkeys.comment.wsMoveDownStacks": "The key to move stacks \"down\" in the inventory", + "itemscroller.config.hotkeys.comment.wsMoveUpLeaveOne": "The key to move all but the last item from each stack\n\"up\" in the inventory", + "itemscroller.config.hotkeys.comment.wsMoveUpMatching": "The key to move all matching items \"up\" in the inventory", + "itemscroller.config.hotkeys.comment.wsMoveUpSingle": "The key to move single items \"up\" in the inventory", + "itemscroller.config.hotkeys.comment.wsMoveUpStacks": "The key to move stacks \"up\" in the inventory", + "itemscroller.config.hotkeys.comment.modifierMoveEverything": "Modifier key to move ALL items to the other\ninventory when scrolling over a stack", + "itemscroller.config.hotkeys.comment.modifierMoveMatching": "Modifier key to move all matching items to the other\ninventory when scrolling over a stack", + "itemscroller.config.hotkeys.comment.modifierMoveStack": "Modifier key to move the entire stack to the other\ninventory when scrolling over it", + "itemscroller.config.hotkeys.comment.modifierToggleVillagerGlobalFavorite": "Modifier key to hold while middle clicking a trade,\nto toggle the global favorite state for that trade.\nGlobal favorites are used for villagers that don't\nhave any \"local\"/villager-specific favorites set.", + "itemscroller.config.hotkeys.comment.sortInventory": "Sort the inventory that the cursor is hovering over", + "itemscroller.gui.button.config_gui.generic": "Generic", "itemscroller.gui.button.config_gui.hotkeys": "Hotkeys", "itemscroller.gui.button.config_gui.toggles": "Toggles", @@ -13,4 +149,4 @@ "itemscroller.message.toggled_mod_off": "Toggled all Item Scroller functionality §cOFF", "itemscroller.message.toggled_mod_on": "Toggled all Item Scroller functionality §aON" -} \ No newline at end of file +} diff --git a/src/main/resources/assets/rocknroller/lang/es_es.json b/src/main/resources/assets/rocknroller/lang/es_es.json new file mode 100644 index 0000000..d6d2eda --- /dev/null +++ b/src/main/resources/assets/rocknroller/lang/es_es.json @@ -0,0 +1,150 @@ +{ + "itemscroller.config.generic.name.carpetCtrlQCraftingEnabledOnServer": "carpetCtrlQCraftingEnabledOnServer", + "itemscroller.config.generic.name.clientCraftingFixOn1_12": "clientCraftingFixOn1.12", + "itemscroller.config.generic.name.craftingRecipesSaveFileIsGlobal": "craftingRecipesSaveFileIsGlobal", + "itemscroller.config.generic.name.craftingRecipesSaveToFile": "craftingRecipesSaveToFile", + "itemscroller.config.generic.name.craftingRenderRecipeItems": "craftingRenderRecipeItems", + "itemscroller.config.generic.name.debugMessages": "debugMessages", + "itemscroller.config.generic.name.massCraftInhibitMidUpdates": "massCraftInhibitMidUpdates", + "itemscroller.config.generic.name.massCraftInterval": "massCraftInterval", + "itemscroller.config.generic.name.massCraftIterations": "massCraftIterations", + "itemscroller.config.generic.name.massCraftSwapsOnly": "massCraftSwapsOnly", + "itemscroller.config.generic.name.modMainToggle": "modMainToggle", + "itemscroller.config.generic.name.packetRateLimit": "packetRateLimit", + "itemscroller.config.generic.name.rateLimitClickPackets": "rateLimitClickPackets", + "itemscroller.config.generic.name.reverseScrollDirectionSingle": "reverseScrollDirectionSingle", + "itemscroller.config.generic.name.reverseScrollDirectionStacks": "reverseScrollDirectionStacks", + "itemscroller.config.generic.name.useRecipeCaching": "useRecipeCaching", + "itemscroller.config.generic.name.useSlotPositionAwareScrollDirection": "useSlotPositionAwareScrollDirection", + "itemscroller.config.generic.name.villagerTradeListRememberScrollPosition": "villagerTradeListRememberScrollPosition", + "itemscroller.config.generic.name.villagerTradeUseGlobalFavorites": "villagerTradeUseGlobalFavorites", + "itemscroller.config.generic.name.sortAssumeEmptyBoxStacks": "sortAssumeEmptyBoxStacks", + "itemscroller.config.generic.name.sortShulkerBoxesAtEnd": "sortShulkerBoxesAtEnd", + + "itemscroller.config.generic.comment.carpetCtrlQCraftingEnabledOnServer": "Activalo si el servidor tiene Carpet mod,\ny tienes activado el ctrlQCrafting .\nEsto solo cambia la forma en la forma en la que el mod de Item Scroller\nfunciona con la combiacion de teclas + Shift + Clik derecho en mesas de crafteo/inventario y demás.", + "itemscroller.config.generic.comment.clientCraftingFixOn1_12": "Arregla el problema del crafteo masivo en la 1.12.", + "itemscroller.config.generic.comment.craftingRecipesSaveFileIsGlobal": "Si es verdadero, el arvhivo de crafteo se usa de manera global en lugar de usarse solo en un mundo.", + "itemscroller.config.generic.comment.craftingRecipesSaveToFile": "Si esta activado, las funciones de crafteo seran guardadas\ndentro de minecraft/itemscroller/recipes_worldorservername.nbt.\nEsto permite que sean persistentes a pesar de los recinios del juego.", + "itemscroller.config.generic.comment.craftingRenderRecipeItems": "Si esta activo, los crafteos seran renderizados tambien \nen la vista previa de las recetas.", + "itemscroller.config.generic.comment.debugMessages": "Habilita algunos mensajes de depuración en la consola de juegos.", + "itemscroller.config.generic.comment.massCraftInhibitMidUpdates": "Previene las actualizaciones de la preview del item a crafear \nmientras se mueven los items en el crafteo, esto deberia reducir el uso de CPU\n al no estar el sistema consultando cada actualizacion necesaria.", + "itemscroller.config.generic.comment.massCraftInterval": "El intervalo en tick del juego mientras se relaiza el crafteo masivo", + "itemscroller.config.generic.comment.massCraftIterations": "Cuantas interacciones/intentos para el crafteo masivo relaizar por ejeccucion\nCon stacks de objetos, objetos no apilables,el inventario lleno o una receta pequeña\nEsto se usa para un crafteo masivo, ya que de lo contrario solo creara 1 o 2 crafteos por operacion.", + "itemscroller.config.generic.comment.massCraftSwapsOnly": "Usa el metodo mas reciente para llenar la grid de crafteo,\nutilizando solo intercambios de espacios.\n\nNota: Debido a que solo se utilizan paquetes de intercambio de los espacios,\nno son posibles los crafteos parciales\ntampoco se dividira ningun stack.", + "itemscroller.config.generic.comment.modMainToggle": "Desactiva todas las funcionalidades del mod.", + "itemscroller.config.generic.comment.packetRateLimit": "El límite de paquetes de clics en tragamonedas emulados enviados por tick de juego,\nsi 'rateLimitClickPackets' está habilitado", + "itemscroller.config.generic.comment.rateLimitClickPackets": "Esto esta destinado a la compatibilidad de los servidores que usand Spigot y similares\nque aplican limnites de volocidad de envio desde el cliente El limite para los game tick se puede cambiar en 'packetRateLimit´.", + "itemscroller.config.generic.comment.reverseScrollDirectionSingle": "Invertir la direccion del scrolling para el modo de un solo item.", + "itemscroller.config.generic.comment.reverseScrollDirectionStacks": "Invertir la direccion del scrolling para el modo stacks.", + "itemscroller.config.generic.comment.useRecipeCaching": "Permite almacenar en cache el ultimo crafteo\nEsto puede reducir bastante el uso de CPU al craftear masivamente.", + "itemscroller.config.generic.comment.useSlotPositionAwareScrollDirection": "Cuando esta activado, el movimiento de los items, depende de la posicion en las ranuras en la pantalla\n Esto puede tener un comportamiento inesperado con invetarios mas complejos\n¡Usalo con precaucion!", + "itemscroller.config.generic.comment.villagerTradeListRememberScrollPosition": "Recuerda y restaura la ultima posicion de scroll en\nla lista de tradeos al abrir la GUI", + "itemscroller.config.generic.comment.villagerTradeUseGlobalFavorites": "Activa los intercambios favoritos con aldenos que tenga guardados como Globales o Locales", + "itemscroller.config.generic.comment.sortAssumeEmptyBoxStacks": "Assume that empty boxes are stacking items\nwhen sorting the inventory.\nThis is useful if you installed mods to stack\nshulker boxes on remote server.\nThis will send an extra packet to ensure the\ninventory is synced.", + "itemscroller.config.generic.comment.sortShulkerBoxesAtEnd": "Sort shulker boxes at the end of the inventory\nwhen sorting the inventory.", + + "itemscroller.config.toggles.name.enableCraftingFeatures": "enableCraftingFeatures", + "itemscroller.config.toggles.name.enableDropkeyDropMatching": "enableDropkeyDropMatching", + "itemscroller.config.toggles.name.enableRightClickCraftingOneStack": "enableRightClickCraftingOneStack", + "itemscroller.config.toggles.name.enableScrollingEverything": "enableScrollingEverything", + "itemscroller.config.toggles.name.enableScrollingMatchingStacks": "enableScrollingMatchingStacks", + "itemscroller.config.toggles.name.enableScrollingSingle": "enableScrollingSingle", + "itemscroller.config.toggles.name.enableScrollingStacks": "enableScrollingStacks", + "itemscroller.config.toggles.name.enableScrollingStacksFallback": "enableScrollingStacksFallback", + "itemscroller.config.toggles.name.enableScrollingVillager": "enableScrollingVillager", + "itemscroller.config.toggles.name.enableShiftDropItems": "enableShiftDropItems", + "itemscroller.config.toggles.name.enableShiftPlaceItems": "enableShiftPlaceItems", + "itemscroller.config.toggles.name.enableVillagerTradeFeatures": "enableVillagerTradeFeatures", + + "itemscroller.config.toggles.comment.enableCraftingFeatures": "Activa el movimientos de ítems hacia y desde los cuadros de crafteo, con una memoria de recetas incorporada de 18 espacios.\n Mantén presionada la tecla de Receta para ver las recetas guardadas y cambiar la selección.\n Mientras mantienes presionada la tecla de Receta, puedes moverte o presionar una tecla numérica para cambiar la selección. \nUna receta se guarda en la \"ranura de receta\" actualmente seleccionada al hacer clic con la tecla de selección sobre una ranura de salida de crafteo configurada.\n Los cuadros de crafteo admitidos deben agregarse a la lista scrollableCraftingGrids", + "itemscroller.config.toggles.comment.enableDropkeyDropMatching": "Activa la funcion de soltar todos los items que coincidan desde el mismo invetario, con una hotkey configurada", + "itemscroller.config.toggles.comment.enableRightClickCraftingOneStack": "Activa la capacidad de craftear hasta un stack al hacer click derecho en una ranura que haya sido configurada como tanuda de salida en los crafteos.", + "itemscroller.config.toggles.comment.enableScrollingEverything": "Activa el movimiento de todos los items a la vez\nmientras se mantiene presionada la tecla para modifierMoveEverything", + "itemscroller.config.toggles.comment.enableScrollingMatchingStacks": "Activa el movimiento de todos los stacks que coincidan a la vez\nmientras se mantiene presionada la tecla para modifierMoveMatching", + "itemscroller.config.toggles.comment.enableScrollingSingle": "Activa el movimiento de ítems uno por uno al desplazarse sobre un stack.", + "itemscroller.config.toggles.comment.enableScrollingStacks": "Activa el movimiento de stacks completos al desplazarse sobre un stack.", + "itemscroller.config.toggles.comment.enableScrollingStacksFallback": "Activa un modo \"alternativo\" para desplazar stacks completos\n(por ejemplo, en una mesa de crafteo vanilla,\ndonde no funciona el Mayus+Shift).", + "itemscroller.config.toggles.comment.enableScrollingVillager": "Activa el movimiento especial en la GUI de los aldeanos.\n(Normlamente no puedea hacer click+Mayus en ellas.)\nManten presionada la tecla Mayus para moverte arriba/abajo sobre la ranura.", + "itemscroller.config.toggles.comment.enableShiftDropItems": "Activa soltar todos los items que coincidan a la vez, mientras tienes presioanda la tecla Mayus en un stack.", + "itemscroller.config.toggles.comment.enableShiftPlaceItems": "Activa mover todos los stacks a la ves mientras mantienes Mayus en una ranura vacia.", + "itemscroller.config.toggles.comment.enableVillagerTradeFeatures": "Avtiva la funcion de marcado de tradeos favoritos rapidos con aldenaos\nNota: El movimiento con Shift en la ranura de salida\n es una caracteristica afecta en esta opccion\nEsta opcion permite marcar los tradeos favoritos, haciendo click central\n y click derecho en la listra de tradeos para completar\n ese tradeo en concreto.", + + "itemscroller.config.hotkeys.name.craftEverything": "craftEverything", + "itemscroller.config.hotkeys.name.dropAllMatching": "dropAllMatching", + "itemscroller.config.hotkeys.name.keyDragDropLeaveOne": "keyDragDropLeaveOne", + "itemscroller.config.hotkeys.name.keyDragDropSingle": "keyDragDropSingle", + "itemscroller.config.hotkeys.name.keyDragDropStacks": "keyDragDropStacks", + "itemscroller.config.hotkeys.name.keyDragMoveLeaveOne": "keyDragMoveLeaveOne", + "itemscroller.config.hotkeys.name.keyDragMoveMatching": "keyDragMoveMatching", + "itemscroller.config.hotkeys.name.keyDragMoveOne": "keyDragMoveOne", + "itemscroller.config.hotkeys.name.keyDragMoveStacks": "keyDragMoveStacks", + "itemscroller.config.hotkeys.name.keyMoveEverything": "keyMoveEverything", + "itemscroller.config.hotkeys.name.massCraft": "massCraft", + "itemscroller.config.hotkeys.name.modifierMoveEverything": "modifierMoveEverything", + "itemscroller.config.hotkeys.name.modifierMoveMatching": "modifierMoveMatching", + "itemscroller.config.hotkeys.name.modifierMoveStack": "modifierMoveStack", + "itemscroller.config.hotkeys.name.modifierToggleVillagerGlobalFavorite": "modifierToggleVillagerGlobalFavorite", + "itemscroller.config.hotkeys.name.moveCraftResults": "moveCraftResults", + "itemscroller.config.hotkeys.name.openConfigGui": "openConfigGui", + "itemscroller.config.hotkeys.name.recipeView": "recipeView", + "itemscroller.config.hotkeys.name.slotDebug": "slotDebug", + "itemscroller.config.hotkeys.name.storeRecipe": "storeRecipe", + "itemscroller.config.hotkeys.name.throwCraftResults": "throwCraftResults", + "itemscroller.config.hotkeys.name.toggleModOnOff": "toggleModOnOff", + "itemscroller.config.hotkeys.name.villagerTradeFavorites": "villagerTradeFavorites", + "itemscroller.config.hotkeys.name.wsMoveDownLeaveOne": "wsMoveDownLeaveOne", + "itemscroller.config.hotkeys.name.wsMoveDownMatching": "wsMoveDownMatching", + "itemscroller.config.hotkeys.name.wsMoveDownSingle": "wsMoveDownSingle", + "itemscroller.config.hotkeys.name.wsMoveDownStacks": "wsMoveDownStacks", + "itemscroller.config.hotkeys.name.wsMoveUpLeaveOne": "wsMoveUpLeaveOne", + "itemscroller.config.hotkeys.name.wsMoveUpMatching": "wsMoveUpMatching", + "itemscroller.config.hotkeys.name.wsMoveUpSingle": "wsMoveUpSingle", + "itemscroller.config.hotkeys.name.wsMoveUpStacks": "wsMoveUpStacks", + "itemscroller.config.hotkeys.name.sortInventory": "sortInventory", + + "itemscroller.config.hotkeys.comment.craftEverything": "Craftea todo lo posible de una vez con la receta seleccionada actualmente.", + "itemscroller.config.hotkeys.comment.dropAllMatching": "Suelta todos los stacks iguales sobre otro stack mientras el cursos esta encima.", + "itemscroller.config.hotkeys.comment.keyDragDropLeaveOne": "Tecla para soltar todos los items del stack menos el ultimo.", + "itemscroller.config.hotkeys.comment.keyDragDropSingle": "Tecla para soltar solo un item de un stack.", + "itemscroller.config.hotkeys.comment.keyDragDropStacks": "Tecla para soltar todo el stack.", + "itemscroller.config.hotkeys.comment.keyDragMoveLeaveOne": "Tecla para mover todo el stack menos el ultimo item.", + "itemscroller.config.hotkeys.comment.keyDragMoveMatching": "Tecla para mover todos los items que sean iguales.", + "itemscroller.config.hotkeys.comment.keyDragMoveOne": "Tecla para mover un solo item del stack.", + "itemscroller.config.hotkeys.comment.keyDragMoveStacks": "Tecla para mover todos los stacks que se arrastren.", + "itemscroller.config.hotkeys.comment.keyMoveEverything": "Tecla para TODOS los items\na otro inventario al hacer clik.", + "itemscroller.config.hotkeys.comment.massCraft": "Crafteo masivo suelta lo crafteado con la receta que esta seleccionada actualmente\nsiempre que se mantega presionada la tecla asiganda.", + "itemscroller.config.hotkeys.comment.modifierMoveEverything": "Tecla para mover todos los items\na otro inventario mientras se usa la rueda del raton.", + "itemscroller.config.hotkeys.comment.modifierMoveMatching": "Tecla para mover los items iguales \na otro inventario mientras se usa la rueda del raton.", + "itemscroller.config.hotkeys.comment.modifierMoveStack": "Tecla para mover todos los stacks \na otro inventario mientras se usa la rueda del raton.", + "itemscroller.config.hotkeys.comment.modifierToggleVillagerGlobalFavorite": "Tecla para mantener presionada mientras se hace click en un tradeo\npara alternar el estado de favorito global en ese comercio\nLos tradeos fvoritos globales, se utilizan\npara que los aldenoas que no tienen ningun tradeo favorito asigando", + "itemscroller.config.hotkeys.comment.moveCraftResults": "Mueve todos los items crafteados, desde el inventario del jugador a otro.", + "itemscroller.config.hotkeys.comment.openConfigGui": "Abre la interfaz grafica in-game", + "itemscroller.config.hotkeys.comment.recipeView": "Muentra la interfaz de crafteo de Item Scroller.", + "itemscroller.config.hotkeys.comment.slotDebug": "Muentra la informacion de debug para el slot o interfaz grafica de usuario sobre la que esta colocado el cursor.", + "itemscroller.config.hotkeys.comment.storeRecipe": "Guarda el crafteo mientras tienes el cursor encima del item en la parte de salida de los crafteos", + "itemscroller.config.hotkeys.comment.throwCraftResults": "Lanzar todos los ítems de salida de la recet que\n actualmente esta seleccionada al suelo desde el inventario del jugador.", + "itemscroller.config.hotkeys.comment.toggleModOnOff": "Alternar todas las funcionalidades del mod ON/OFF", + "itemscroller.config.hotkeys.comment.villagerTradeFavorites": "Tradea todo lo posible con los comercios marcados como favoritos del aldeano actual.", + "itemscroller.config.hotkeys.comment.wsMoveDownLeaveOne": "Tecla para mover todo el stack, excepto el ultimo del stack hacia\n\"abajo\" en el inventario.", + "itemscroller.config.hotkeys.comment.wsMoveDownMatching": "Tecla para mover todos los objetos iguales hacia \"abajo\" en el inventario.", + "itemscroller.config.hotkeys.comment.wsMoveDownSingle": "Tecla para mover un solo item hacia \"abajo\" en el inventario.", + "itemscroller.config.hotkeys.comment.wsMoveDownStacks": "Tecla para mover stacks hacia \"abajo\" en el inventario", + "itemscroller.config.hotkeys.comment.wsMoveUpLeaveOne": "Tecla para mover todo el stack, excepto el ultimo del stack, hacia\n\"up\" en el inventario.", + "itemscroller.config.hotkeys.comment.wsMoveUpMatching": "Tecla para mover todos los objetos iguales haci \"arriba\" en el inventario.", + "itemscroller.config.hotkeys.comment.wsMoveUpSingle": "Tecla para mover un solo item hacia\"arriba\" en el inventario.", + "itemscroller.config.hotkeys.comment.wsMoveUpStacks": "Tecla para mover stacks hacias \"arriba\" en el inventario.", + "itemscroller.config.hotkeys.comment.sortInventory": "Sort the inventory that the cursor is hovering over", + + "itemscroller.gui.button.config_gui.generic": "Generico", + "itemscroller.gui.button.config_gui.hotkeys": "Combinacíon de teclas", + "itemscroller.gui.button.config_gui.toggles": "Toggles", + + "itemscroller.gui.label.recipe_page": "Página %d / %d", + "itemscroller.gui.label.trade_uses": "Uso de Tradeos: %d / %d", + "itemscroller.gui.label.trades": "Tradeos", + + "itemscroller.gui.title.configs": "%s Configuraciones - %s", + + "itemscroller.message.toggled_mod_off": "Activar todas las funionalidades de Item Scroller §cOFF", + "itemscroller.message.toggled_mod_on": "Activar todas las funionalidades de Item Scroller §aON" +} \ No newline at end of file diff --git a/src/main/resources/assets/rocknroller/lang/zh_cn.json b/src/main/resources/assets/rocknroller/lang/zh_cn.json index 87cfa60..1fab30b 100644 --- a/src/main/resources/assets/rocknroller/lang/zh_cn.json +++ b/src/main/resources/assets/rocknroller/lang/zh_cn.json @@ -1,158 +1,152 @@ { - "fml.menu.mods.info.description.rocknroller": "ItemScroller 非官方 (Neo)Forge 移植。\n通过滚动鼠标滚轮或在物品槽上拖动来移动库存图形用户界面中的物品。", + "fml.menu.mods.info.description.rocknroller": "ItemScroller 非官方 (Neo)Forge 移植。\n通过滚动鼠标滚轮或在物品槽上拖动来移动库存图形用户界面中的物品。", - "itemscroller.gui.button.config_gui.generic": "通用", + "itemscroller.config.generic.name.carpetCtrlQCraftingEnabledOnServer": "地毯端CtrlQ启用", + "itemscroller.config.generic.name.clientCraftingFixOn1_12": "1.12客户端修复", + "itemscroller.config.generic.name.craftingRenderRecipeItems": "配方显示", + "itemscroller.config.generic.name.debugMessages": "调试信息开关", + "itemscroller.config.generic.name.modMainToggle": "主开关", + "itemscroller.config.generic.name.massCraftInhibitMidUpdates": "批量合成刷新优化", + "itemscroller.config.generic.name.massCraftInterval": "批量合成速度", + "itemscroller.config.generic.name.massCraftIterations": "批量合成尝试", + "itemscroller.config.generic.name.massCraftSwapsOnly": "批量合成新方法", + "itemscroller.config.generic.name.packetRateLimit": "最大数据流", + "itemscroller.config.generic.name.craftingRecipesSaveToFile": "配方文件保存", + "itemscroller.config.generic.name.craftingRecipesSaveFileIsGlobal": "全局配方保存", + "itemscroller.config.generic.name.rateLimitClickPackets": "连点限制", + "itemscroller.config.generic.name.reverseScrollDirectionSingle": "反向单个移动", + "itemscroller.config.generic.name.reverseScrollDirectionStacks": "反向单组移动", + "itemscroller.config.generic.name.useRecipeCaching": "使用配方缓存", + "itemscroller.config.generic.name.useSlotPositionAwareScrollDirection": "栏位滚动方向", + "itemscroller.config.generic.name.villagerTradeUseGlobalFavorites": "置顶收藏交易", + "itemscroller.config.generic.name.villagerTradeListRememberScrollPosition": "交易书签", + "itemscroller.config.generic.name.sortAssumeEmptyBoxStacks": "sortAssumeEmptyBoxStacks", + "itemscroller.config.generic.name.sortShulkerBoxesAtEnd": "sortShulkerBoxesAtEnd", + + "itemscroller.config.generic.comment.carpetCtrlQCraftingEnabledOnServer": "如果服务器正在运行地毯端则建议开启\n这将改变物品滚轮整组丢弃的使用方式\n变为丢弃+Shift+右击丢弃整组。", + "itemscroller.config.generic.comment.clientCraftingFixOn1_12": "在客户端直接更新合成配方输出\n这修正了在1.12中快速/批量制造和右键点击制造所产生的不可使用的问题。", + "itemscroller.config.generic.comment.craftingRenderRecipeItems": "启用后,配方物品也将呈现于合成配方视图中。", + "itemscroller.config.generic.comment.debugMessages": "启用后,将会输出调试信息到游戏控制台中。", + "itemscroller.config.generic.comment.modMainToggle": "开启/关闭所有功能", + "itemscroller.config.generic.comment.massCraftInhibitMidUpdates": "禁止批量合成时配方输出槽在材料移动到合成GUI的过程中更新。\n这将会减少CPU的占用,因为游戏会在每次合成配方更改后\n不断地查询配方并显示产物。", + "itemscroller.config.generic.comment.massCraftInterval": "每tick中批量合成的次数。", + "itemscroller.config.generic.comment.massCraftIterations": "设置每次执行多少次批量合成的迭代或者尝试,\n适用于当玩家合成不可堆叠的物品或玩家背包已满这类情况,\n这将需要玩家拥有更大的背包空间,\n因为使用shift单击合成时,\n背包中可能只进行1或2次合成操作。", + "itemscroller.config.generic.comment.massCraftSwapsOnly": "使用新的方法填充配方GUI,\n即只使用slot swap packets(槽位交换包)\n注意:由于只使用槽位交换包,不可能有部分的合成!\n而且也不会发生整组物品拆开的现象。", + "itemscroller.config.generic.comment.packetRateLimit": "当 §6[连点限制]§f 开启后每个tick发送的最大模拟操作数据包的数量。", + "itemscroller.config.generic.comment.craftingRecipesSaveToFile": "启用后,合成配方将保存到文件\n\"minecraft/itemscroller/recipes_worldorservername.nbt\"\n中。这可以使得合成配方在游戏重启后能保持不变。", + "itemscroller.config.generic.comment.craftingRecipesSaveFileIsGlobal": "启用后,将会使配方文件全局化,而不是对每个世界或服务器单独保存。", + "itemscroller.config.generic.comment.rateLimitClickPackets": "为了与Spigot和类似服务器兼容,\n发送的数据包发送速率进行限制。\n这将模拟正常操作的数据包排队,\n并随着时间的推移以一定速率发送数据包。\n每个tick的限制可以在 §6[最大数据流]§f 中设置。", + "itemscroller.config.generic.comment.reverseScrollDirectionSingle": "反转滚动方向为单个物品移动模式。", + "itemscroller.config.generic.comment.reverseScrollDirectionStacks": "反转滚动方向为单组物品移动模式。", + "itemscroller.config.generic.comment.useRecipeCaching": "在合成配方操作获取输出项参数时,\n传递缓存中最后使用的配方参数。\n当大量合成物品时,这可以大大降低CPU使用率。", + "itemscroller.config.generic.comment.useSlotPositionAwareScrollDirection": "启用后,物品的移动方向将取决于屏幕上栏位的y轴位置。\n可能导致更复杂的背包,谨慎使用!", + "itemscroller.config.generic.comment.villagerTradeUseGlobalFavorites": "启用后,收藏的交易项目将会被置顶。", + "itemscroller.config.generic.comment.villagerTradeListRememberScrollPosition": "启用后,退出村民交易GUI将不会重置滚动条。", + "itemscroller.config.generic.comment.sortAssumeEmptyBoxStacks": "整理物品栏时假设空潜影盒可以堆叠。\n当你在远程服务器启用此特性时会很有用。\n这会多发送一个网络包来确保服务器同步", + "itemscroller.config.generic.comment.sortShulkerBoxesAtEnd": "整理物品栏时将潜影盒放在最后。", + + "itemscroller.config.toggles.name.enableCraftingFeatures": "启用配方视图", + "itemscroller.config.toggles.name.enableDropkeyDropMatching": "全部丢弃", + "itemscroller.config.toggles.name.enableRightClickCraftingOneStack": "右键合成", + "itemscroller.config.toggles.name.enableScrollingEverything": "滚动所有", + "itemscroller.config.toggles.name.enableScrollingMatchingStacks": "滚动相同", + "itemscroller.config.toggles.name.enableScrollingSingle": "滚动物品", + "itemscroller.config.toggles.name.enableScrollingStacks": "滚动一份", + "itemscroller.config.toggles.name.enableScrollingStacksFallback": "回放滚动模式", + "itemscroller.config.toggles.name.enableScrollingVillager": "滚动交易", + "itemscroller.config.toggles.name.enableShiftDropItems": "shift丢弃物品", + "itemscroller.config.toggles.name.enableShiftPlaceItems": "shift移动物品", + "itemscroller.config.toggles.name.enableVillagerTradeFeatures": "交易优化", + + "itemscroller.config.toggles.comment.enableCraftingFeatures": "开启内置共8页每页18种配方的存储,使得物品可以放置到合成表。\n按住 §6[配方视图]§f 查看配方列表,并可以通过滑动滚轮或数字键选择配方,点击配方可以在工作台完成合成。\n在放置配方达到待命状态(不取出合成产物)时,按下 §6[储存配方]§f 就可以在选定的位置进行配方储存(旧配方将被覆盖)。", + "itemscroller.config.toggles.comment.enableDropkeyDropMatching": "按下 §6[全部丢弃]§f 快捷键后从同一库存内丢弃所有匹配的物品。", + "itemscroller.config.toggles.comment.enableRightClickCraftingOneStack": "右键点击储存的配方后将直接合成一个物品。", + "itemscroller.config.toggles.comment.enableScrollingEverything": "按住 §6[滚动所有]§f 快捷键时,允许滑动滑轮来移动所有物品。", + "itemscroller.config.toggles.comment.enableScrollingMatchingStacks": "按住 §6[滚动相同]§f 快捷键时,允许滑动滑轮来移动所有匹配的物品。", + "itemscroller.config.toggles.comment.enableScrollingSingle": "在不按住任何快捷键时,允许滑动滑轮来移动单个物品。", + "itemscroller.config.toggles.comment.enableScrollingStacks": "按住 §6[滚动一份]§f 快捷键时,允许滑动滑动来移动整组物品。", + "itemscroller.config.toggles.comment.enableScrollingStacksFallback": "将启用\"回放\"的滚动模式。\n(在工作台等位置可能减少发包)", + "itemscroller.config.toggles.comment.enableScrollingVillager": "为交易GUI进行特殊处理,允许对输出位的物品进行滚动来进行快速交易。", + "itemscroller.config.toggles.comment.enableShiftDropItems": "允许通过按住 shift 键并单击物品时扔出所有匹配的物品。", + "itemscroller.config.toggles.comment.enableShiftPlaceItems": "允许通过按住 shift 键并将物品放置在空位时移动所有匹配的物品", + "itemscroller.config.toggles.comment.enableVillagerTradeFeatures": "为村民启用交易收藏和快速交易功能。 \n注意: §6[滚动交易]§f 是一个单独的功能,不受此选项的影响。 \n此选项允许通过单击鼠标中键来标记最喜欢的交易,\n并开启在交易列表上右键单击物品购空物品的功能。", + + "itemscroller.config.hotkeys.name.openConfigGui": "打开配置界面", + "itemscroller.config.hotkeys.name.craftEverything": "全部合成", + "itemscroller.config.hotkeys.name.dropAllMatching": "全部丢弃", + "itemscroller.config.hotkeys.name.massCraft": "全部合成并抛出", + "itemscroller.config.hotkeys.name.moveCraftResults": "工作台放置", + "itemscroller.config.hotkeys.name.recipeView": "配方视图", + "itemscroller.config.hotkeys.name.slotDebug": "调试栏", + "itemscroller.config.hotkeys.name.storeRecipe": "储存配方", + "itemscroller.config.hotkeys.name.throwCraftResults": "合成结果抛出", + "itemscroller.config.hotkeys.name.toggleModOnOff": "主开关", + "itemscroller.config.hotkeys.name.villagerTradeFavorites": "最优交易", + "itemscroller.config.hotkeys.name.keyDragDropLeaveOne": "丢到就剩一个", + "itemscroller.config.hotkeys.name.keyDragDropSingle": "就扔一个", + "itemscroller.config.hotkeys.name.keyDragDropStacks": "扔一份", + "itemscroller.config.hotkeys.name.keyDragMoveLeaveOne": "移到就剩一个", + "itemscroller.config.hotkeys.name.keyDragMoveMatching": "匹配的全部移动", + "itemscroller.config.hotkeys.name.keyDragMoveOne": "就移一个", + "itemscroller.config.hotkeys.name.keyDragMoveStacks": "移一份", + "itemscroller.config.hotkeys.name.keyMoveEverything": "全部移动", + "itemscroller.config.hotkeys.name.wsMoveDownLeaveOne": "就剩一个§4S", + "itemscroller.config.hotkeys.name.wsMoveDownMatching": "全部下移", + "itemscroller.config.hotkeys.name.wsMoveDownSingle": "就下移一个", + "itemscroller.config.hotkeys.name.wsMoveDownStacks": "下移一份", + "itemscroller.config.hotkeys.name.wsMoveUpLeaveOne": "就剩一个§4W", + "itemscroller.config.hotkeys.name.wsMoveUpMatching": "全部上移", + "itemscroller.config.hotkeys.name.wsMoveUpSingle": "就上移一个", + "itemscroller.config.hotkeys.name.wsMoveUpStacks": "上移一份", + "itemscroller.config.hotkeys.name.modifierMoveEverything": "滚动所有", + "itemscroller.config.hotkeys.name.modifierMoveMatching": "滚动相同", + "itemscroller.config.hotkeys.name.modifierMoveStack": "滚动一份", + "itemscroller.config.hotkeys.name.modifierToggleVillagerGlobalFavorite": "全局交易收藏", + "itemscroller.config.hotkeys.name.sortInventory": "sortInventory", + + "itemscroller.config.hotkeys.comment.openConfigGui": "打开游戏内配置界面。", + "itemscroller.config.hotkeys.comment.craftEverything": "用当前选定的配方消耗完所有的材料进行合成。", + "itemscroller.config.hotkeys.comment.dropAllMatching": "丢弃所有与鼠标指针指向的物品向匹配的物品", + "itemscroller.config.hotkeys.comment.massCraft": "批量合成当前选择的配方并将产物丢出,\n只要你按住快捷键。", + "itemscroller.config.hotkeys.comment.moveCraftResults": "将当前选择配方的所有材料全部放置于合成台上。", + "itemscroller.config.hotkeys.comment.recipeView": "显示配方GUI", + "itemscroller.config.hotkeys.comment.slotDebug": "打印鼠标悬停栏位或GUI的调试信息\n(译注:非调试时无需设置)", + "itemscroller.config.hotkeys.comment.storeRecipe": "当鼠标悬停在合成输出项目上时,存储当前的合成配方。", + "itemscroller.config.hotkeys.comment.throwCraftResults": "批量丢出当前选择配方中的输出物品。", + "itemscroller.config.hotkeys.comment.toggleModOnOff": "打开/关闭所有mod功能", + "itemscroller.config.hotkeys.comment.villagerTradeFavorites": "按下快捷键时将尝试一键买空所有收藏的交易内容。", + "itemscroller.config.hotkeys.comment.keyDragDropLeaveOne": "按住快捷键丢弃物品,被指到的物品仅保留一个。", + "itemscroller.config.hotkeys.comment.keyDragDropSingle": "按住快捷键丢弃物品,被指到的物品仅丢弃一个。", + "itemscroller.config.hotkeys.comment.keyDragDropStacks": "按住快捷键丢弃物品,被指到的格子全部丢弃。", + "itemscroller.config.hotkeys.comment.keyDragMoveLeaveOne": "按住快捷键移动物品,被指到的物品仅保留一个。", + "itemscroller.config.hotkeys.comment.keyDragMoveMatching": "按住快捷键移动所有相同物品。", + "itemscroller.config.hotkeys.comment.keyDragMoveOne": "按住快捷键移动物品,被指到的物品仅移动一个。", + "itemscroller.config.hotkeys.comment.keyDragMoveStacks": "按住快捷键移动物品,被指到的格子全部移动。", + "itemscroller.config.hotkeys.comment.keyMoveEverything": "点击物品时,将所有物品移到另一个容器内。", + "itemscroller.config.hotkeys.comment.wsMoveDownLeaveOne": "将库存中除最后一个物品之外的所有物品从每堆物品“向下”移动的键。", + "itemscroller.config.hotkeys.comment.wsMoveDownMatching": "将库存中所有匹配的物品“向下”移动的键。", + "itemscroller.config.hotkeys.comment.wsMoveDownSingle": "在库存中移动单个物品“向下”的键。", + "itemscroller.config.hotkeys.comment.wsMoveDownStacks": "在库存中移动一份物品“向下”的键。", + "itemscroller.config.hotkeys.comment.wsMoveUpLeaveOne": "将库存中除最后一个物品之外的所有物品从每堆物品“向上”移动的键。", + "itemscroller.config.hotkeys.comment.wsMoveUpMatching": "将库存中所有匹配的物品“向上”移动的键。", + "itemscroller.config.hotkeys.comment.wsMoveUpSingle": "在库存中移动单个物品“向上”的键。", + "itemscroller.config.hotkeys.comment.wsMoveUpStacks": "在库存中移动一份物品“向上”的键。", + "itemscroller.config.hotkeys.comment.modifierMoveEverything": "当在物品上滚动时,按下此键将会使所有物品移动到另一个库存\n(这个快捷键并没有实际功能,类似前缀)", + "itemscroller.config.hotkeys.comment.modifierMoveMatching": "当在物品上滚动时,按下此键将会使所有匹配的物品移动到另一个库存\n(这个快捷键并没有实际功能,类似前缀)", + "itemscroller.config.hotkeys.comment.modifierMoveStack": "当在堆栈上滚动时,修饰键将整个堆栈移动到另一个库存\n(这个快捷键并没有实际功能,类似前缀)", + "itemscroller.config.hotkeys.comment.modifierToggleVillagerGlobalFavorite": "按住该快捷键时收藏的交易将进行全局收藏\n全局收藏将会作用于所有村民。", + "itemscroller.config.hotkeys.comment.sortInventory": "对鼠标指针所在的物品栏进行整理。", + + "itemscroller.gui.button.config_gui.generic": "通用", "itemscroller.gui.button.config_gui.hotkeys": "快捷键", "itemscroller.gui.button.config_gui.toggles": "开关", "itemscroller.gui.label.recipe_page": "页 %d / %d", "itemscroller.gui.label.trades": "交易", "itemscroller.gui.label.trade_uses": "交易使用: %d / %", - - "itemscroller.message.toggled_mod_off": "Item Scroller功能调整为: §c关闭", - "itemscroller.message.toggled_mod_on": "Item Scroller功能调整为: §a开启", - - "enableCraftingFeatures":"Crafting | 制作特性", - "Enables scrolling items to and from crafting grids,\nwith a built-in 18 recipe memory.\nHold down the Recipe key to see the stored recipes and\nto change the selection. While holding the Recipe key,\nyou can either scroll or press a number key to change the selection.\nA recipe is stored to the currently selected \"recipe slot\"\n by clicking pick block over a configured crafting output slot.\nThe supported crafting grids must be added to the scrollableCraftingGrids list.":"开启内置共8页每页18种配方的存储,使得物品可以放置到合成表\n按住Recipe(配方)的快捷键查看配方列表,您可以滑动滚轮或使用数字键选择配方\n点击配方可以在工作台完成合成,在放置配方达到待命状态时(不取出合成产物)\n按下设定的storeRecipe(储存配方)快捷键就可以在选定的列表格内进行配方储存(自动覆写)。", - "enableDropkeyDropMatching":"Dropkey | 批量丢弃", - "Enables dropping all matching items from the same\ninventory with the hotkey":"使用快捷键从同一库存内丢弃所有匹配物品", - "enableRightClickCraftingOneStack":"RightClick | 右键制作", - "Enables crafting up to one full stack when right clicking on\na slot that has been configured as a crafting output slot.":"当右键点击储存的配方,可以直接制造一个物品", - "enableScrollingEverything":"Scrolling | 滚动所有", - "Enables scroll moving all items at once while\nholding the modifierMoveEverything keybind":"按住滚动所有快捷键时,允许滑动滑轮移动所有物品", - "enableScrollingMatchingStacks":"Scrolling | 滚动相同物品(全部)", - "Enables scroll moving all matching stacks at once\nwhile holding the modifierMoveMatching keybind":"按住滚动全部物品快捷键时,允许滑动滑轮移动所有相同物品", - "enableScrollingSingle":"Scrolling | 滚动物品", - "Enables moving items one item at a time by scrolling over a stack":"通过在物品上滑动滚轮,单个移动物品", - "enableScrollingStacks":"Scrolling | 滚动相同物品(一组)", - "Enables moving entire stacks at a time by scrolling over a stack":"按住滚动单组物品快捷键时,允许滑动滑轮移动一组相同物品", - "enableScrollingStacksFallback":"enableScrolling | 滚动合成", - "Enables a \"fallback\" mode for scrolling entire stacks\n(for example to a vanilla crafting table,\nwhere shift + click doesn't work).":"在工作台内配方表使用滚动合成\n比如工作台shift+点击不起作用时", - "enableScrollingVillager":"Scrolling | 交易滚动", - "Enables special handling for the Villager GUIs.\n(Normally you can't shift click items in them.)\nHold shift and scroll up/down over the trade output slot.":"为交易GUI进行特殊处理,可以对购买物品进行滚动\n(一滚马云流泪,两滚建林下跪,三滚化腾心碎,懂我意思吧QAQ)", - "enableShiftDropItems":"ShiftDrop | shift丢弃", - "Enables dropping all matching items at once by holding\nshift while clicking to drop a stack":"允许通过按住shift键同时丢出一组物品\n从而一次性丢出所有匹配的物品", - "enableShiftPlaceItems":"Shift | shift移动", - "Enables moving all matching stacks at once by holding\nshift while placing items to an empty slot":"在将物品放置到一个空槽时,通过按住shift,\n可以一次移动所有匹配的物品", - "enableVillagerTradeList":"Villager | 村民交易列表", - "Render a 1.14-style trade list in villager GUIs":"在村民gui中呈现一个1.14风格的交易列表\n(这不是1.16吗??????)", - - "carpetCtrlQCraftingEnabledOnServer":"carpetCtrlQCrafting | 地毯端CtrlQ启用", - "Set to true if the server is running the Carpet mod,\nand has the ctrlQCrafting option enabled.\nThis just changes which method Item Scroller uses\nfor the Drop key + Shift + Right click crafting.":"如果服务器正在运行地毯端则设置为开启,\n这将改变物品滚轮整组丢弃的使用方式\n变为丢弃+Shift+右击丢弃整组", - "clientCraftingFixOn1.12":"clientCrafting | 1.12客户端修复", - "Enable updating the crafting recipe output directly on the client side.\nThis fixes the quick/mass crafting and right-click-to-craft-a-stack\nfeatures othrwise being broken in 1.12.":"在客户端直接更新制作配方输出\n这修正了在1.12中快速/批量制造和右键点击制造所产生的不可使用的问题。", - "craftingRenderRecipeItems":"craftingRenderRecipeItems | 配方显示", - "If enabled, then the recipe items are also rendered\nin the crafting recipe view.":"如果启用,那么配方物品也会呈现在制作配方视图中。", - "craftingRecipesSaveToFile":"craftingRecipes | 配方文件保存", - "If enabled, then the crafting features recipes are saved to a file\ninside minecraft/itemscroller/recipes_worldorservername.nbt.\nThis makes the recipes persistent across game restarts.":"如果启用,那么制作配方将保存到\nminecraft/itemscroller/recipes_worldorservername.nbt\n内的一个文件中。这使得配方在游戏重启时能保持不变", - "craftingRecipesSaveFileIsGlobal":"craftingRecipesSave | 全局配方保存", - "If true, then the recipe file is global, instead\n of being saved per-world or server":"如果为真,则配方文件是全局的,而不是每个世界或每个服务器单独保存的", - "reverseScrollDirectionSingle":"reverseScrollDirection | 反向单个移动", - "Reverse the scrolling direction for single item mode.":"反转滚动方向为单个物品移动模式", - "reverseScrollDirectionStacks":"reverseScrollDirection | 反向单组移动", - "Reverse the scrolling direction for full stacks mode.":"反转滚动方向为单组物品移动模式", - "useSlotPositionAwareScrollDirection":"useSlotPositionAware | 栏位滚动方向", - "When enabled, the item movement direction depends\non the slots' y-position on screen. Might be derpy with more\ncomplex inventories, use with caution!":"当启用时,物品的移动方向取决于屏幕上栏位的y轴位置。使用谨慎!", - "villagerTradeListRememberPage":"villagerTradeList | 交易页面记忆", - "Remember and restore the last looked at page/trade when re-opening the GUI":"当重新打开GUI时,记住并恢复最后看到的页面/交易", - - "openConfigGui":"openConfigGui | 打开配置界面", - "Open the in-game config GUI":"打开游戏内配置界面", - "craftEverything":"craft | 全部制作", - "Craft everything possible once with the currently selected recipe":"用当前选定的配方消耗完所有的材料", - "dropAllMatching":"dropAll | 全部丢弃", - "Drop all stacks identical to the hovered stack":"丢弃所有鼠标指针指向的物品", - "mainToggle":"mainToggle | 主开关", - "Toggle all functionality ON/OFF":"开启/关闭所有功能,\n§4似乎是个摆设——ZMDF§r", - "massCraft":"massCraft | 全部合成抛出", - "Mass craft and throw out the results with the\ncurrently selected recipe as long as this\nkeybind is held down":"批量制作当前选择的配方物品并将它们丢出,\n只要你按住快捷键\n(§6做一个快乐的人体喷泉——ZMDF§r)", - "moveCraftResults":"moveCraft | 工作台放置", - "Move all of the currently selected recipe's\noutput items from the player inventory\nto the other inventory":"将当前选择的物品配方材料全部放置于合成台。", - "moveStackToOffhand":"moveStack | 手持物品", - "Swap the hovered stack with the offhand":"将鼠标指针指向的物品移到副手栏", - "recipeView":"recipeView | 配方视图", - "Show the Item Scroller recipe GUI":"显示配方的GUI", - "slotDebug":"slotDebug | 调试栏", - "Print debug info for the hovered slot or GUI":"打印鼠标悬停栏位或GUI的调试信息\n(§4然而并没有什么卵用——ZMDF§r)", - "storeRecipe":"storeRecipe | 储存配方", - "Store a recipe while hovering over a crafting output item":"将鼠标悬停在制作输出项目上时存储合成配方", - "throwCraftResults":"throwCraft | 全部抛出", - "Throw all of the currently selected recipe's\noutput items to the ground from the player inventory":"批量丢出当前选择的配方物品\n(§6人体喷泉+1——ZMDF§r)", - "villagerTradeFavorites":"villagerTrade | 最优交易", - "Trade everything possible with all the favorited trades\nof the current villager":"用当前村民的所有优惠交易进行所有可能的交易", - "keyDragMoveLeaveOne":"keyDragMove | 就剩一个", - "Key to move all but the last item from\nall the stacks dragged over":"按住快捷键移动物品,被指到的物品仅保留一个", - "keyDragMoveMatching":"keyDragMove | 全部移动", - "Key to move all matching items dragged over":"按住快捷键移动所有相同物品", - "keyDragMoveOne":"keyDrag | 就移一个", - "Key to move one item from each stack dragged over":"按住快捷键移动物品,被指到的物品仅移动一个", - "keyDragMoveStacks":"keyDragMove | 移一份", - "Key to move the entire stacks dragged over":"按住快捷键移动物品,被指到的格子全部移动", - "keyDragDropLeaveOne":"keyDragDrop | 丢到就剩一个", - "Key to drop all but the last item from each stack dragged over":"按住快捷键丢弃物品,被指到的物品仅保留一个", - "keyDragDropSingle":"keyDragDrop | 就扔一个", - "Key to drop one item from each stack dragged over":"按住快捷键丢弃物品,被指到的物品仅丢弃一个", - "keyDragDropStacks":"keyDragDropStacks | 扔一份", - "Key to drop the entire stacks dragged over":"按住快捷键丢弃物品,被指到的格子全部丢弃", - "keyMoveEverything":"keyMove | 移动所有", - "Key to move ALL items to the other\ninventory when clicking a stack":"点击物品时,将所有物品移到另一个容器内", - "wsMoveDownLeaveOne":"wsMoveDown | 就剩一个§4S", - "The key to move all but the last item from each stack\n\"down\" in the inventory":"将库存中除最后一个物品之外的所有物品从每堆物品“向下”移动的键", - "wsMoveDownMatching":"wsMoveDown | 全部下移", - "The key to move all matching items \"down\" in the inventory":"将库存中所有相同物品“向下”移动的键", - "wsMoveDownSingle":"wsMoveDown | 就下移一个", - "The key to move single items \"down\" in the inventory":"在库存中移动单个物品“向下”的键", - "wsMoveDownStacks":"wsMoveDown | 下移一份", - "The key to move stacks \"down\" in the inventory":"在库存中移动一份物品“向下”的键", - "wsMoveUpLeaveOne":"wsMoveUp | 就剩一个§4W", - "The key to move all but the last item from each stack\n\"up\" in the inventory":"将库存中除最后一个物品之外的所有物品从每堆物品“向上”移动的键", - "wsMoveUpMatching":"wsMoveUp | 全部上移", - "The key to move all matching items \"up\" in the inventory":"将库存中所有相同物品“向上”移动的键", - "wsMoveUpSingle":"wsMoveUp | 就上移一个", - "The key to move single items \"up\" in the inventory":"在库存中移动单个物品“向上”的键", - "wsMoveUpStacks":"wsMoveUp | 上移一份", - "The key to move stacks \"up\" in the inventory":"在库存中移动一份物品“向上”的键", - "modifierMoveEverything":"modifierMove | 移动所有", - "Modifier key to move ALL items to the other\ninventory when scrolling over a stack":"当在堆栈上滚动时,修饰键将所有项目移动到另一个库存\n(这个快捷键并没有实际功能,类似前缀)", - "modifierMoveMatching":"modifierMove | 移动相同", - "Modifier key to move all matching items to the other\ninventory when scrolling over a stack":"当在堆栈上滚动时,修饰键将所有匹配的项目移动到另一个库存\n(这个快捷键并没有实际功能,类似前缀)", - "modifierMoveStack":"modifierMove | 移动一份", - "Modifier key to move the entire stack to the other\ninventory when scrolling over it":"当在堆栈上滚动时,修饰键将整个堆栈移动到另一个库存\n(这个快捷键并没有实际功能,类似前缀)", - - "packetRateLimit":"packetRateLimit | 最大数据流", - "The limit of sent emulated slot click packets per game tick,\nif 'rateLimitClickPackets' is enabled":"当§6[连点限制]§f开启后限制每个tick发送的最大模拟操作数据包的数量", - "rateLimitClickPackets":"rateLimitClick | 连点限制", - "This is meant for compatibility with Spigot servers and similar,\nwhich apply rate limits to packets from the client.\nThis queues up the emulated slot click packets and sends\nthem rate limited over time. The limit per game tick can be set in 'packetRateLimit´.":"这是为了与Spigot服务器和类似服务器兼容,\n对来自客户端的数据包发送速率进行限制。\n这将模拟操作的数据包排队,\n并随着时间的推移向它们发送速率受限的数据包。\n每个tick的限制可以在§6[最大数据流]§f中设置", - "villagerTradeUseGlobalFavorites":"villagerTrade | 交易收藏", - "Whether or not global (per-item-type) villager trade\nfavorites should be used.":"该功能开启后,使用§6[交易优化]§f+鼠标中键\n标注的交易项目将会置顶", - "villagerTradeListRememberScrollPosition":"villagerTrade | 交易书签", - "Remember and restore the last scroll position in the\ntrade list when re-opening the GUI":"该功能开启后,退出村民交易GUI时将不会重置滚动条", - - "enableVillagerTradeFeatures":"VillagerTrade | 交易收藏", - "Enable trade favoriting and quick trade features for villagers.\nNote: The Shift + scrolling over the output slot is a separate feature\nand not affected by this option.\nThis option enables middle clicking to mark favorite trades,\nand right clicking on the trade list to fully trade that one trade.":"为村民启用交易收藏和快速交易功能。 \n注意:Shift+在输出槽上滚动是一个单独的功能,不受此选项的影响。 \n此选项允许通过§6[交易优化]§f+单击鼠标中键来标记最喜欢的交易,\n并开启在交易列表上右键单击物品购空物品的功能。", - - "villagerTradeFavorites":"villagerTrade | 交易优化", - "Trade everything possible with all the favorited trades\nof the current villager":"该功能为交易收藏功能的前置按键设置\n测试后发现该功能可以一键买空所有收藏的交易内容", - - "modifierToggleVillagerGlobalFavorite":"VillagerGlobal | 交易收藏", - "Modifier key to hold while middle clicking a trade,\nto toggle the global favorite state for that trade.\nGlobal favorites are used for villagers that don't have any specific favorites set.":"按住该快捷键单击鼠标中键对交易进行收藏\n全局收藏将会作用于没有特殊交易的村民", - "modMainToggle":"modMain | 主开关", - "Can disable all the functionality of the entire mod":"能否禁用整个mod的所有功能", - "toggleModOnOff":"ModOnOff | 主开关", - "Toggle all mod functionality ON/OFF":"打开/关闭所有mod功能", - "Modifier key to hold while middle clicking a trade,\nto toggle the global favorite state for that trade.\nGlobal favorites are used for villagers that don't\nhave any \"local\"/villager-specific favorites set.":"使用鼠标中键点击交易内容时按住快捷键\n切换该交易为全局最喜欢的状态(§d粉色星§f)\n全局的交易收藏夹只能用于没有任何\n“本地收藏夹(§e黄色星§f)”的村民", + "itemscroller.gui.title.configs": "%s 设置 - %s", - "massCraftInhibitMidUpdates":"massCraft | 批量合成刷新优化", - "Prevent recipe output slot updates in the middle of moving items\nto the crafting grid. This should reduce CPU usage\nbecause of not constantly querying the recipe after every grid change.":"禁止批量合成时配方输出槽在材料移动到合成GUI的过程中更新。\n这将会减少CPU的占用,因为游戏会在每次合成配方更改后\n不断地查询配方并显示产物。", - "massCraftInterval":"massCraft | 批量合成速度", - "The interval in game ticks the massCraft operation is repeated at":"每tick中批量合成的次数", - "massCraftIterations":"massCraft | 批量合成尝试", - "How many massCraft iterations/attempts to do per execution.\nWith unstackable items or a full inventory and \"small recipe\"\nthis will need to be larger, as a shift + click craft to the inventory\nmight only craft 1 or 2 items per operation.":"设置每次执行多少次批量合成的迭代或者尝试,\n当玩家合成不可堆叠的物品时或背包已经满了的时候这类情况,\n这将需要玩家拥有更大的背包空间,\n因为使用shift单击合成时,\n背包中可能只进行1或2次合成操作。", - "massCraftSwapsOnly":"massCraft | 批量合成新方法", - "Uses a newer method of filling the crafting grid,\nusing only swap slot packets.\n\nNote: Due to only using slot swap packets,\nno partial crafts are possible! And also no\nstack splitting will happen, at all.":"使用新的方法填充配方GUI,\n只使用slot swap packets(槽位交换包)\n注意:由于只使用槽位交换包,不可能有部分的合成!\n而且也不会发生整组物品拆开的现象。", - "useRecipeCaching":"massCraft | 使用配方缓存", - "Enables caching the last used recipe in the crafting\nrecipe output item fetching code. This can help a lot\nwith lowering CPU usage when mass crafting stuff.":"在合成配方操作获取输出项时的参数中,\n传递缓存中最后使用的配方参数。\n当大量制作物品时,这可以大大降低CPU使用率。", - - "itemscroller.gui.title.configs": "%s 配置 - %s" -} \ No newline at end of file + "itemscroller.message.toggled_mod_off": "Item Scroller 功能调整为:§c关闭", + "itemscroller.message.toggled_mod_on": "Item Scroller 功能调整为:§a开启" +} diff --git a/src/main/resources/rocknroller.mixins.json b/src/main/resources/rocknroller.mixins.json index 309bd27..7a108c4 100644 --- a/src/main/resources/rocknroller.mixins.json +++ b/src/main/resources/rocknroller.mixins.json @@ -10,11 +10,17 @@ "IMixinSlot", "MixinAbstractInventoryScreen", "MixinClientPlayerInteractionManager", + "MixinClientPlayNetworkHandler", "MixinCraftingScreenHandler", + "MixinItemStack", "MixinMerchantScreen", "MixinMerchantScreenHandler", + "MixinRecipeBookWidget", "MixinScreen" ], + "mixins": [ + "debug.MixinServerPlayNetworkHandler" + ], "injectors": { "defaultRequire": 1 }