diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt index d2d8912b8..3d13c0e1e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt @@ -78,6 +78,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn private set(value) { _exoSuitMenu = null + if (ply.containerMenu.slots.any { it.container == field }) { + ply.closeContainer() + } + for (i in 0 until value.containerSize.coerceAtMost(field.containerSize)) { if (!field[i].isEmpty) { value[i] = field[i] @@ -626,7 +630,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn shouldSendIteration = false } - if (hasExoSuit && ply.containerMenu != exoSuitMenu) { + if (hasExoSuit && ply.containerMenu == ply.inventoryMenu) { exoSuitMenu.broadcastChanges() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExoSuitInventoryScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExoSuitInventoryScreen.kt index 30f142f04..1b027f2fc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExoSuitInventoryScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExoSuitInventoryScreen.kt @@ -12,36 +12,6 @@ import ru.dbotthepony.mc.otm.network.ExoSuitMenuOpen import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen(menu, TranslatableComponent("otm.gui.exosuit")) { - private val slotRows = Int2ObjectAVLTreeMap() - - private fun getSlotsRow(index: Int): EditablePanel { - return slotRows.computeIfAbsent(index, Int2ObjectFunction { - val canvas = object : EditablePanel(this@ExoSuitInventoryScreen, null, width = AbstractSlotPanel.SIZE * 9f, height = AbstractSlotPanel.SIZE) { - override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean { - return false - } - } - - val offset = it * 9 - - if (menu.combinedInventorySlots.size <= offset) { - return@Int2ObjectFunction canvas - } - - for (i in 0 .. (8).coerceAtMost(menu.combinedInventorySlots.size - offset - 1)) { - val slot = object : SlotPanel(this@ExoSuitInventoryScreen, canvas, menu.combinedInventorySlots[offset + i]) { - override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean { - return false - } - } - - slot.dock = Dock.LEFT - } - - return@Int2ObjectFunction canvas - }) - } - override fun makeMainFrame(): FramePanel { val frame = FramePanel(this, width = 200f, height = 180f, title = this.title) @@ -52,16 +22,16 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen for (i in old .. old + 2) { - getSlotsRow(i).visible = false + getInventorySlotsRow(i).visible = false } for (i in new .. new + 2) { - val row = getSlotsRow(i) + val row = getInventorySlotsRow(i) row.visible = true row.y = (i - new) * AbstractSlotPanel.SIZE row.parent = mainInventoryLine @@ -82,7 +52,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen(menu: T, inventory: Inventory, tit val quickCraftingType get() = quickCraftingType val isQuickCrafting get() = isQuickCrafting + private val inventorySlotsRows = Int2ObjectAVLTreeMap() + init { if (menu.playerInventorySlots.isNotEmpty() && menu.autoCreateInventoryFrame) { - inventoryFrame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH, INVENTORY_FRAME_HEIGHT, inventory.displayName).also(this::addPanel) + if (menu.playerExoSuitSlots.isEmpty()) { + inventoryFrame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH, INVENTORY_FRAME_HEIGHT, inventory.displayName).also(this::addPanel) - for (slot in menu.playerInventorySlots) { - SlotPanel(this, inventoryFrame, slot, slot.x.toFloat(), slot.y.toFloat()) + val hotbarStrip = EditablePanel(this, inventoryFrame, height = AbstractSlotPanel.SIZE) + hotbarStrip.dock = Dock.BOTTOM + + for (slot in menu.playerHotbarSlots) { + SlotPanel(this, hotbarStrip, slot).also { it.dock = Dock.LEFT } + } + + for (i in 0 .. 2) { + getInventorySlotsRow(i).also { + it.parent = inventoryFrame + it.y = i * AbstractSlotPanel.SIZE + } + } + } else { + inventoryFrame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH_EXTENDED, INVENTORY_FRAME_HEIGHT, inventory.displayName).also(this::addPanel) + + var slotListCanvas: EditablePanel? = null + + val scrollbar = DiscreteScrollBarPanel(this, inventoryFrame, { ((menu.playerCombinedInventorySlots.size - 27) + 8) / 9 }, { + _, old, new -> + + for (i in old .. old + 2) { + getInventorySlotsRow(i).visible = false + } + + for (i in new .. new + 2) { + getInventorySlotsRow(i).also { + it.visible = true + it.parent = slotListCanvas + it.y = (i - new) * AbstractSlotPanel.SIZE + } + } + + menu.ply.matteryPlayer?.exoSuitMenu?.lastScroll = new + }) + + slotListCanvas = object : EditablePanel(this@MatteryScreen, inventoryFrame, height = AbstractSlotPanel.SIZE * 3f) { + override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean { + scrollbar.mouseScrolledInner(x, y, scroll) + return true + } + } + + slotListCanvas.dock = Dock.TOP + + val hotbarStrip = EditablePanel(this, inventoryFrame, height = AbstractSlotPanel.SIZE) + hotbarStrip.dock = Dock.BOTTOM + + for (slot in menu.playerHotbarSlots) { + SlotPanel(this, hotbarStrip, slot).also { it.dock = Dock.LEFT } + } + + scrollbar.parent = slotListCanvas + scrollbar.dock = Dock.RIGHT + + scrollbar.scroll = menu.ply.matteryPlayer?.exoSuitMenu?.lastScroll ?: 0 + + for (i in scrollbar.scroll .. scrollbar.scroll + 2) { + getInventorySlotsRow(i).also { + it.parent = slotListCanvas + it.y = (i - scrollbar.scroll) * AbstractSlotPanel.SIZE + } + } } } } + protected fun getInventorySlotsRow(index: Int): EditablePanel { + return inventorySlotsRows.computeIfAbsent(index, Int2ObjectFunction { + val canvas = object : EditablePanel(this@MatteryScreen, null, width = AbstractSlotPanel.SIZE * 9f, height = AbstractSlotPanel.SIZE) { + override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean { + return false + } + } + + val offset = it * 9 + + if (menu.playerCombinedInventorySlots.size <= offset) { + return@Int2ObjectFunction canvas + } + + for (i in 0 .. (8).coerceAtMost(menu.playerCombinedInventorySlots.size - offset - 1)) { + val slot = object : SlotPanel(this@MatteryScreen, canvas, menu.playerCombinedInventorySlots[offset + i]) { + override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean { + return false + } + } + + slot.dock = Dock.LEFT + } + + return@Int2ObjectFunction canvas + }) + } + override fun init() { super.init() @@ -354,10 +447,13 @@ abstract class MatteryScreen(menu: T, inventory: Inventory, tit } companion object { - const val DEFAULT_FRAME_WIDTH = 18f * 9f + 16f + const val DEFAULT_FRAME_WIDTH = AbstractSlotPanel.SIZE * 9f + 16f const val DEFAULT_FRAME_HEIGHT = 100f + const val INVENTORY_FRAME_WIDTH = DEFAULT_FRAME_WIDTH - const val INVENTORY_FRAME_HEIGHT = 3f * 18f + 18f + 24f + const val INVENTORY_FRAME_WIDTH_EXTENDED = DEFAULT_FRAME_WIDTH + ScrollBarConstants.WIDTH + 2f + const val INVENTORY_FRAME_HEIGHT = 3f * AbstractSlotPanel.SIZE + AbstractSlotPanel.SIZE + 24f + const val GAUGE_TOP_WITH_SLOT = 17f const val GAUGE_TOP_WITHOUT_SLOT = 26f const val SLOT_TOP_UNDER_GAUGE = 70f diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ExoSuitInventoryMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ExoSuitInventoryMenu.kt index 68fb22471..f9e19ed83 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ExoSuitInventoryMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ExoSuitInventoryMenu.kt @@ -25,29 +25,6 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen } } - val hotbarSlots: List - val mainInventorySlots: List - - init { - val builder = ImmutableList.builder() - - for (i in 0 .. 8) { - builder.add(InventorySlot(capability.ply.inventory, i)) - } - - hotbarSlots = builder.build() - } - - init { - val builder = ImmutableList.builder() - - for (i in 9 .. 35) { - builder.add(InventorySlot(capability.ply.inventory, i)) - } - - mainInventorySlots = builder.build() - } - val armorSlots: List = makeArmorSlots() val offhandSlot = object : InventorySlot(capability.ply.inventory, 40) { @@ -56,26 +33,6 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen } } - val exoSuitSlots: List - val combinedInventorySlots: List - - init { - val builder = ImmutableList.builder() - - for (i in 0 until capability.exoSuitContainer.containerSize) { - builder.add(MatterySlot(capability.exoSuitContainer, i)) - } - - exoSuitSlots = builder.build() - } - - init { - val builder = ImmutableList.builder() - builder.addAll(mainInventorySlots) - builder.addAll(exoSuitSlots) - combinedInventorySlots = builder.build() - } - val craftingGrid: CraftingContainer val craftingSlots: List @@ -94,11 +51,10 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen craftingSlots = builder.build() - exoSuitSlots.forEach(this::addSlot) + addInventorySlots(autoFrame = false) + craftingSlots.forEach(this::addSlot) addSlot(offhandSlot) - hotbarSlots.forEach(this::addSlot) - mainInventorySlots.forEach(this::addSlot) armorSlots.forEach(this::addSlot) } @@ -152,26 +108,26 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen if (slotIndex == craftingResultSlot.index) { val item = craftingResultSlot.item - val leftover = moveItemStackToSlots(item, combinedInventorySlots, simulate = true) + val leftover = moveItemStackToSlots(item, playerCombinedInventorySlots, simulate = true) if (leftover.isEmpty) { val copy = item.copy() - moveItemStackToSlots(item, combinedInventorySlots, simulate = false) + moveItemStackToSlots(item, playerCombinedInventorySlots, simulate = false) item.count = 0 craftingResultSlot.onTake(ply, copy) return copy } return ItemStack.EMPTY - } else if (combinedInventorySlots.any { it.index == slotIndex }) { + } else if (playerCombinedInventorySlots.any { it.index == slotIndex }) { val item = slots[slotIndex].item val copy = item.copy() - moveItemStackTo(item, hotbarSlots) + moveItemStackTo(item, playerHotbarSlots) return copy - } else if (hotbarSlots.any { it.index == slotIndex } || craftingSlots.any { it.index == slotIndex }) { + } else if (playerHotbarSlots.any { it.index == slotIndex } || craftingSlots.any { it.index == slotIndex }) { val item = slots[slotIndex].item val copy = item.copy() - moveItemStackTo(item, combinedInventorySlots) + moveItemStackTo(item, playerCombinedInventorySlots) return copy } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt index 849e690ff..d9135285f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.menu import com.google.common.collect.ImmutableList import com.mojang.datafixers.util.Pair +import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer import net.minecraft.world.Container @@ -12,6 +13,11 @@ import net.minecraft.world.item.ItemStack import net.minecraft.world.item.enchantment.EnchantmentHelper.hasBindingCurse import net.minecraft.world.level.block.entity.BlockEntity import net.minecraftforge.network.PacketDistributor +import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.client.screen.panels.AbstractSlotPanel +import ru.dbotthepony.mc.otm.client.screen.panels.Dock +import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot import ru.dbotthepony.mc.otm.menu.widget.AbstractWidget @@ -33,8 +39,36 @@ abstract class MatteryMenu @JvmOverloads protected constructor( val matteryWidgets: List = Collections.unmodifiableList(_matteryWidgets) private val _playerInventorySlots = ArrayList() + private val _playerHotbarSlots = ArrayList() + private val _playerMainSlots = ArrayList() + private val _playerExoSuitSlots = ArrayList() + private val _playerCombinedInventorySlots = ArrayList() + + /** + * inventory + exosuit + hotbar (in this order) + */ val playerInventorySlots: List = Collections.unmodifiableList(_playerInventorySlots) + /** + * hotbar only + */ + val playerHotbarSlots: List = Collections.unmodifiableList(_playerHotbarSlots) + + /** + * inventory only + */ + val playerMainSlots: List = Collections.unmodifiableList(_playerMainSlots) + + /** + * exosuit only + */ + val playerExoSuitSlots: List = Collections.unmodifiableList(_playerExoSuitSlots) + + /** + * inventory + exosuit (in this order) + */ + val playerCombinedInventorySlots: List = Collections.unmodifiableList(_playerCombinedInventorySlots) + var autoCreateInventoryFrame = true private set @@ -121,33 +155,38 @@ abstract class MatteryMenu @JvmOverloads protected constructor( } protected fun addInventorySlots(autoFrame: Boolean = true) { + check(_playerInventorySlots.isEmpty()) { "Already created inventory slots" } autoCreateInventoryFrame = autoFrame - var first = true - for (row in 0..2) { - for (column in 0..8) { - val slot = InventorySlot(inventory, column + row * 9 + 9, 8 + column * 18, 14 + row * 18) + for (i in 9 .. 35) { + val slot = InventorySlot(inventory, i) + + _playerInventorySlots.add(slot) + _playerMainSlots.add(slot) + _playerCombinedInventorySlots.add(slot) + addSlot(slot) + } + + val mattery = ply.matteryPlayer + + if (mattery != null && mattery.hasExoSuit) { + for (i in 0 until mattery.exoSuitContainer.containerSize) { + val slot = InventorySlot(mattery.exoSuitContainer, i) _playerInventorySlots.add(slot) + _playerExoSuitSlots.add(slot) + _playerCombinedInventorySlots.add(slot) addSlot(slot) - - if (first) { - first = false - inventorySlotIndexStart = slot.index - } } } - var last: MatterySlot? = null + for (i in 0..8) { + val slot = InventorySlot(inventory, i) - for (k in 0..8) { - last = InventorySlot(inventory, k, 8 + k * 18, 14 + 58) - - addSlot(last) - _playerInventorySlots.add(last) + addSlot(slot) + _playerInventorySlots.add(slot) + _playerHotbarSlots.add(slot) } - - inventorySlotIndexEnd = last!!.index } override fun broadcastChanges() { @@ -226,7 +265,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor( moveToPlayer = true } - if (moveToPlayer == null && playerInventorySlots.any { it.index == slotIndex }) { + if (moveToPlayer == null && _playerInventorySlots.any { it.index == slotIndex }) { moveToPlayer = false } @@ -246,7 +285,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor( moved = initialItem.copy() if (moveToPlayer) { - if (!moveItemStackTo(initialItem, playerInventorySlots)) { + if (!moveItemStackTo(initialItem, _playerInventorySlots)) { return ItemStack.EMPTY } } else { @@ -266,11 +305,11 @@ abstract class MatteryMenu @JvmOverloads protected constructor( } fun quickMoveToInventory(stack: ItemStack, simulate: Boolean): ItemStack { - if (inventorySlotIndexStart == 0 && inventorySlotIndexEnd == 0) { + if (_playerInventorySlots.isEmpty()) { return stack } - return moveItemStackToSlots(stack, inventorySlotIndexStart, inventorySlotIndexEnd, simulate = simulate) + return moveItemStackToSlots(stack, _playerInventorySlots, simulate = simulate) } override fun moveItemStackTo(