diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index 67ead1708..f67f598c9 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -987,6 +987,16 @@ private fun androidFeatures(provider: MatteryLanguageProvider) { private fun gui(provider: MatteryLanguageProvider) { with(provider.english) { + gui("quickmove_from.restock", "Restock from storage") + gui("quickmove_from.restock_with_move", "Full restock from storage") + gui("quickmove_from.move", "Take all") + + gui("quickmove_to.restock", "Restock to storage") + gui("quickmove_to.restock_with_move", "Full restock to storage") + gui("quickmove_to.move", "Deposit all") + + gui("quickmove_hint", "Right click to show all variants") + gui("exopack.accept_wireless_charge", "Accept wireless charging") gui("exopack.dont_accept_wireless_charge", "Do not accept wireless charging") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt index cc3b3a7d4..3ca5d8e84 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt @@ -980,6 +980,16 @@ private fun androidFeatures(provider: MatteryLanguageProvider) { private fun gui(provider: MatteryLanguageProvider) { with(provider.russian) { + gui("quickmove_from.restock", "Быстрое пополнение из хранилища") + gui("quickmove_from.restock_with_move", "Быстрое перемещение из хранилища") + gui("quickmove_from.move", "Взять всё") + + gui("quickmove_to.restock", "Быстрое пополнение в хранилище") + gui("quickmove_to.restock_with_move", "Быстрое перемещение в хранилище") + gui("quickmove_to.move", "Переместить всё") + + gui("quickmove_hint", "Правый клик чтоб увидеть все варианты") + gui("exopack.accept_wireless_charge", "Принимать заряд от беспроводных зарядников") gui("exopack.dont_accept_wireless_charge", "Не принимать заряд от беспроводных зарядников") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/CargoCrateScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/CargoCrateScreen.kt index 974878362..1cae5b676 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/CargoCrateScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/CargoCrateScreen.kt @@ -7,6 +7,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.UserFilteredSlotPanel +import ru.dbotthepony.mc.otm.menu.QuickMoveInput import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu class CargoCrateScreen(menu: CargoCrateMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { @@ -23,9 +24,16 @@ class CargoCrateScreen(menu: CargoCrateMenu, inventory: Inventory, title: Compon UserFilteredSlotPanel(this, grid, slot) val controls = DeviceControls(this, frame) - controls.sortingButtons(menu.sort) + val leftControls = DeviceControls(this, frame) + leftControls.dockOnLeft = true + leftControls.quickMoveButtons(menu.quickMoveFromStorage, QuickMoveInput.Mode.RESTOCK, true) + + val leftInventoryControls = DeviceControls(this, inventoryFrame!!) + leftInventoryControls.dockOnLeft = true + leftInventoryControls.quickMoveButtons(menu.quickMoveToStorage, QuickMoveInput.Mode.RESTOCK_WITH_MOVE, false) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt index 9847cf848..08a000f1a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt @@ -36,6 +36,7 @@ import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.util.ItemStackSorter import ru.dbotthepony.mc.otm.core.util.getLevelFromXp import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot +import ru.dbotthepony.mc.otm.menu.QuickMoveInput import ru.dbotthepony.mc.otm.menu.SortInput import ru.dbotthepony.mc.otm.menu.UpgradeSlots import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback @@ -385,13 +386,17 @@ class DeviceControls>( } fun

> addButton(button: P): P { - buttons.add(button) - button.parent = this - alignButtons() + if (button !in buttons) { + buttons.add(button) + button.parent = this + alignButtons() + } + return button } fun

> addButton(button: P, after: EditablePanel<*>): P { + buttons.remove(button) val index = buttons.indexOf(after) if (index == -1) throw NoSuchElementException("Unknown panel to add button after: $after") buttons.add(index + 1, button) @@ -401,9 +406,12 @@ class DeviceControls>( } fun

> prependButton(button: P): P { - buttons.add(0, button) - button.parent = this - alignButtons() + if (button !in buttons) { + buttons.add(0, button) + button.parent = this + alignButtons() + } + return button } @@ -449,9 +457,75 @@ class DeviceControls>( return result } + private abstract inner class FoldableButtonPanel() : ButtonPanel(screen, this@DeviceControls, width = 18f, height = 18f) { + init { + addButton(this) + } + + private var buttons: List>? = null + + + fun makeButtons() { + if (buttons == null) { + buttons = doMakeButtons().also { + it.forEach { addButton(it, this) } + } + } + } + + fun removeButtons() { + if (buttons != null) { + buttons!!.forEach { it.remove() } + buttons = null + } + } + + override fun test(value: Int): Boolean { + return value == InputConstants.MOUSE_BUTTON_LEFT || hasExtraButtons && value == InputConstants.MOUSE_BUTTON_RIGHT + } + + fun switchButtons() { + if (buttons == null) + makeButtons() + else + removeButtons() + } + + protected abstract val hasExtraButtons: Boolean + protected abstract fun performAction() + protected abstract fun doMakeButtons(): List> + + final override fun onClick(mouseButton: Int) { + if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) { + performAction() + } else { + switchButtons() + } + } + } + fun sortingButtons(input: SortInput, unfoldableSettings: Boolean = true) { - object : ButtonPanel(screen, this@DeviceControls, width = 18f, height = 18f) { - var buttons: List>? = null + object : FoldableButtonPanel() { + override fun performAction() { + input.clientInput() + } + + override var isDisabled: Boolean + get() { return !input.input.test(minecraft.player ?: return false) } + set(value) {} + + override val hasExtraButtons: Boolean + get() = unfoldableSettings + + override fun doMakeButtons(): List> { + return sortingButtons(Delegate.Of(input.settings::isAscending), Delegate.Of(input.settings::sorting), ItemStackSorter.DEFAULT) { + for (v in ItemStackSorter.entries) { + add(v, v.icon, v.title) + } + + finish() + } + } init { tooltips.add(TranslatableComponent("otm.gui.sorting.sort_now")) @@ -459,50 +533,67 @@ class DeviceControls>( if (unfoldableSettings) { tooltips.add(TextComponent("")) tooltips.add(TranslatableComponent("otm.gui.sorting.sort_settings").withStyle(ChatFormatting.GRAY)) - } - addButton(this) - - if (!unfoldableSettings) { + } else { makeButtons() } } override val icon: IGUIRenderable get() = Widgets18.SORT_NOW + } + } - override fun test(value: Int): Boolean { - return value == InputConstants.MOUSE_BUTTON_LEFT || unfoldableSettings && value == InputConstants.MOUSE_BUTTON_RIGHT + fun quickMoveButtons(buttons: Map, mainMode: QuickMoveInput.Mode, isFromStorage: Boolean, unfoldableSettings: Boolean = true) { + object : FoldableButtonPanel() { + private val input = buttons[mainMode]!! + + override fun performAction() { + input.clientInput() } override var isDisabled: Boolean get() { return !input.input.test(minecraft.player ?: return false) } set(value) {} - private fun makeButtons() { - buttons = sortingButtons(Delegate.Of(input.settings::isAscending), Delegate.Of(input.settings::sorting), ItemStackSorter.DEFAULT) { - for (v in ItemStackSorter.entries) { - add(v, v.icon, v.title) + override val hasExtraButtons: Boolean + get() = unfoldableSettings + + override fun doMakeButtons(): List> { + return buttons.entries + .stream() + .filter { (m, _) -> m != input.mode } + .map { (m, b) -> + square18( + screen, + this, + icon = if (isFromStorage) m.iconFromStorage else m.iconToStorage, + onPress = { b.clientInput() } + ).also { + if (isFromStorage) + it.tooltips.add(m.textFromStorage) + else + it.tooltips.add(m.textToStorage) + } } - - finish() - } - - buttons!!.forEach { removeButton(it) } - buttons!!.forEach { addButton(it as EditablePanel, this) } + .toList() } - override fun onClick(mouseButton: Int) { - if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) { - input.clientInput() + init { + if (isFromStorage) + tooltips.add(input.mode.textFromStorage) + else + tooltips.add(input.mode.textToStorage) + + if (unfoldableSettings) { + tooltips.add(TextComponent("")) + tooltips.add(TranslatableComponent("otm.gui.quickmove_hint").withStyle(ChatFormatting.GRAY)) } else { - if (buttons == null) { - makeButtons() - } else { - buttons!!.forEach { it.remove() } - buttons = null - } + makeButtons() } } + + override val icon: IGUIRenderable + get() = if (isFromStorage) input.mode.iconFromStorage else input.mode.iconToStorage } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/AbstractVanillaChestMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/AbstractVanillaChestMenu.kt index 2281387e9..f7ccd1eb7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/AbstractVanillaChestMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/AbstractVanillaChestMenu.kt @@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.MenuType import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot +import ru.dbotthepony.mc.otm.menu.QuickMoveInput import ru.dbotthepony.mc.otm.menu.SortInput abstract class AbstractVanillaChestMenu( @@ -18,6 +19,8 @@ abstract class AbstractVanillaChestMenu( abstract val columns: Int abstract val containerSlots: List + abstract val quickMoveToStorage: Map + abstract val quickMoveFromStorage: Map val sort = SortInput(this, container, playerSortSettings) override fun stillValid(player: Player): Boolean { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt index 038854f22..b9f17a670 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt @@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Inventory import net.minecraft.world.inventory.MenuType import ru.dbotthepony.mc.otm.container.EnhancedContainer import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot +import ru.dbotthepony.mc.otm.menu.QuickMoveInput import ru.dbotthepony.mc.otm.menu.makeSlots class MatteryChestMenu( @@ -22,6 +23,9 @@ class MatteryChestMenu( addInventorySlots() } + override val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, containerSlots) + override val quickMoveFromStorage = QuickMoveInput.create(this, containerSlots, playerInventorySlots) + companion object { @JvmStatic @JvmOverloads diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryShulkerBoxMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryShulkerBoxMenu.kt index 9ebc6d65e..e987c22b6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryShulkerBoxMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryShulkerBoxMenu.kt @@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.container.EnhancedContainer import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot +import ru.dbotthepony.mc.otm.menu.QuickMoveInput import ru.dbotthepony.mc.otm.menu.makeSlots class MatteryShulkerBoxMenu( @@ -24,6 +25,9 @@ class MatteryShulkerBoxMenu( addInventorySlots() } + override val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, containerSlots) + override val quickMoveFromStorage = QuickMoveInput.create(this, containerSlots, playerInventorySlots) + class Slot(container: Container, slot: Int) : MatteryMenuSlot(container, slot) { override fun mayPlace(stack: ItemStack): Boolean { return super.mayPlace(stack) && stack.item.canFitInsideContainerItems() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/VanillaChestScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/VanillaChestScreen.kt index eaa1f0976..5a990200d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/VanillaChestScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/VanillaChestScreen.kt @@ -10,6 +10,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel +import ru.dbotthepony.mc.otm.menu.QuickMoveInput class VanillaChestScreen(menu: AbstractVanillaChestMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { override fun makeMainFrame(): FramePanel> { @@ -28,6 +29,14 @@ class VanillaChestScreen(menu: AbstractVanillaChestMenu, inventory: Inventory, t val controls = DeviceControls(this, frame) controls.sortingButtons(menu.sort) + val leftControls = DeviceControls(this, frame) + leftControls.dockOnLeft = true + leftControls.quickMoveButtons(menu.quickMoveFromStorage, QuickMoveInput.Mode.RESTOCK, true) + + val leftInventoryControls = DeviceControls(this, inventoryFrame!!) + leftInventoryControls.dockOnLeft = true + leftInventoryControls.quickMoveButtons(menu.quickMoveToStorage, QuickMoveInput.Mode.RESTOCK_WITH_MOVE, false) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/QuickMoveInput.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/QuickMoveInput.kt index e3d3bf1b1..f57aaa260 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/QuickMoveInput.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/QuickMoveInput.kt @@ -1,19 +1,26 @@ package ru.dbotthepony.mc.otm.menu +import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.Slot import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items +import ru.dbotthepony.mc.otm.client.render.Widgets18 +import ru.dbotthepony.mc.otm.client.render.sprites.AbstractMatterySprite import ru.dbotthepony.mc.otm.container.IFilteredContainerSlot import ru.dbotthepony.mc.otm.container.util.containerSlotOrNull +import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.util.ItemStackKey import ru.dbotthepony.mc.otm.core.util.asKey import ru.dbotthepony.mc.otm.core.util.asKeyOrNull class QuickMoveInput(private val menu: MatteryMenu, val from: Collection, val to: Collection, val mode: Mode) { - enum class Mode { - RESTOCK { + enum class Mode(val iconFromStorage: AbstractMatterySprite, val iconToStorage: AbstractMatterySprite) { + RESTOCK( + Widgets18.RESTOCK_FROM_STORAGE, + Widgets18.RESTOCK_TO_STORAGE + ) { override fun move(from: Collection, to: Collection, player: Player) { val (_, itemsFrom) = computeSlotLists(from, true) val (_, itemsTo) = computeSlotLists(to, false) @@ -27,7 +34,10 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection, } }, - RESTOCK_WITH_MOVE { + RESTOCK_WITH_MOVE( + Widgets18.RESTOCK_WITH_MOVE_FROM_STORAGE, + Widgets18.RESTOCK_WITH_MOVE_TO_STORAGE + ) { override fun move(from: Collection, to: Collection, player: Player) { val (_, itemsFrom) = computeSlotLists(from, true) val (emptyTo, itemsTo) = computeSlotLists(to, false) @@ -45,7 +55,10 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection, } }, - MOVE { + MOVE( + Widgets18.MOVE_EVERYTHING_FROM_STORAGE, + Widgets18.MOVE_EVERYTHING_TO_STORAGE + ) { override fun move(from: Collection, to: Collection, player: Player) { val toSorted = prioritySortSlots(to) @@ -59,11 +72,19 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection, }; abstract fun move(from: Collection, to: Collection, player: Player) + + val textFromStorage: Component get() { + return TranslatableComponent("otm.gui.quickmove_from.${name.lowercase()}") + } + + val textToStorage: Component get() { + return TranslatableComponent("otm.gui.quickmove_to.${name.lowercase()}") + } } - private val input = menu.oneWayInput(handler = ::handle) + val input = menu.oneWayInput(handler = ::handle) - fun trigger() { + fun clientInput() { input.accept(null) } @@ -72,6 +93,10 @@ class QuickMoveInput(private val menu: MatteryMenu, val from: Collection, } companion object { + fun create(menu: MatteryMenu, from: Collection, to: Collection): Map { + return Mode.entries.associateWith { QuickMoveInput(menu, from, to, it) } + } + private fun computeSlotLists(slots: Collection, skipFilteredSlots: Boolean): Pair, MutableMap>> { val emptySlots = ArrayList() val filledSlots = HashMap>() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/CargoCrateMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/CargoCrateMenu.kt index 90272457d..5f46a3188 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/CargoCrateMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/CargoCrateMenu.kt @@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Player import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.menu.MatteryMenu +import ru.dbotthepony.mc.otm.menu.QuickMoveInput import ru.dbotthepony.mc.otm.menu.SortInput import ru.dbotthepony.mc.otm.menu.UserFilteredMenuSlot import ru.dbotthepony.mc.otm.menu.makeSlots @@ -20,6 +21,8 @@ class CargoCrateMenu( private val trackedPlayerOpen = !inventory.player.isSpectator val sort = SortInput(this, actualContainer, playerSortSettings) + val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, storageSlots) + val quickMoveFromStorage = QuickMoveInput.create(this, storageSlots, playerInventorySlots) init { if (trackedPlayerOpen) {