ah yes, enslaved bonus slots in all menus

This commit is contained in:
DBotThePony 2022-09-02 11:21:02 +07:00
parent da3ae55d38
commit 915f3821db
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 182 additions and 117 deletions

View File

@ -78,6 +78,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
private set(value) { private set(value) {
_exoSuitMenu = null _exoSuitMenu = null
if (ply.containerMenu.slots.any { it.container == field }) {
ply.closeContainer()
}
for (i in 0 until value.containerSize.coerceAtMost(field.containerSize)) { for (i in 0 until value.containerSize.coerceAtMost(field.containerSize)) {
if (!field[i].isEmpty) { if (!field[i].isEmpty) {
value[i] = field[i] value[i] = field[i]
@ -626,7 +630,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
shouldSendIteration = false shouldSendIteration = false
} }
if (hasExoSuit && ply.containerMenu != exoSuitMenu) { if (hasExoSuit && ply.containerMenu == ply.inventoryMenu) {
exoSuitMenu.broadcastChanges() exoSuitMenu.broadcastChanges()
} }

View File

@ -12,36 +12,6 @@ import ru.dbotthepony.mc.otm.network.ExoSuitMenuOpen
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuitInventoryMenu>(menu, TranslatableComponent("otm.gui.exosuit")) { class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuitInventoryMenu>(menu, TranslatableComponent("otm.gui.exosuit")) {
private val slotRows = Int2ObjectAVLTreeMap<EditablePanel>()
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<Slot>(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 { override fun makeMainFrame(): FramePanel {
val frame = FramePanel(this, width = 200f, height = 180f, title = this.title) val frame = FramePanel(this, width = 200f, height = 180f, title = this.title)
@ -52,16 +22,16 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
var mainInventoryLine: EditablePanel? = null var mainInventoryLine: EditablePanel? = null
val scrollPanel = DiscreteScrollBarPanel(this, null, maxScroll = { ((menu.combinedInventorySlots.size - 27) + 8) / 9 }, val scrollPanel = DiscreteScrollBarPanel(this, null, maxScroll = { ((menu.playerCombinedInventorySlots.size - 27) + 8) / 9 },
scrollCallback = { scrollCallback = {
_, old, new -> _, old, new ->
for (i in old .. old + 2) { for (i in old .. old + 2) {
getSlotsRow(i).visible = false getInventorySlotsRow(i).visible = false
} }
for (i in new .. new + 2) { for (i in new .. new + 2) {
val row = getSlotsRow(i) val row = getInventorySlotsRow(i)
row.visible = true row.visible = true
row.y = (i - new) * AbstractSlotPanel.SIZE row.y = (i - new) * AbstractSlotPanel.SIZE
row.parent = mainInventoryLine row.parent = mainInventoryLine
@ -82,7 +52,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
mainInventoryLine.dock = Dock.BOTTOM mainInventoryLine.dock = Dock.BOTTOM
for (slot in menu.hotbarSlots) { for (slot in menu.playerHotbarSlots) {
val panel = SlotPanel(this, toolbeltLine, slot) val panel = SlotPanel(this, toolbeltLine, slot)
panel.dock = Dock.LEFT panel.dock = Dock.LEFT
} }
@ -91,7 +61,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
offhand.dock = Dock.RIGHT offhand.dock = Dock.RIGHT
for (i in scrollPanel.scroll .. scrollPanel.scroll + 2) { for (i in scrollPanel.scroll .. scrollPanel.scroll + 2) {
getSlotsRow(i).also { getInventorySlotsRow(i).also {
it.parent = mainInventoryLine it.parent = mainInventoryLine
it.y = AbstractSlotPanel.SIZE * (i - scrollPanel.scroll) it.y = AbstractSlotPanel.SIZE * (i - scrollPanel.scroll)
} }

View File

@ -2,6 +2,8 @@ package ru.dbotthepony.mc.otm.client.screen
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack import com.mojang.blaze3d.vertex.PoseStack
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
import net.minecraft.ChatFormatting import net.minecraft.ChatFormatting
import net.minecraft.client.gui.Font import net.minecraft.client.gui.Font
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
@ -14,9 +16,8 @@ import net.minecraftforge.client.event.ContainerScreenEvent.Render.Foreground
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL11
import org.lwjgl.opengl.GL13 import org.lwjgl.opengl.GL13
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
/** /**
@ -50,16 +51,108 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
val quickCraftingType get() = quickCraftingType val quickCraftingType get() = quickCraftingType
val isQuickCrafting get() = isQuickCrafting val isQuickCrafting get() = isQuickCrafting
private val inventorySlotsRows = Int2ObjectAVLTreeMap<EditablePanel>()
init { init {
if (menu.playerInventorySlots.isNotEmpty() && menu.autoCreateInventoryFrame) { 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) { val hotbarStrip = EditablePanel(this, inventoryFrame, height = AbstractSlotPanel.SIZE)
SlotPanel(this, inventoryFrame, slot, slot.x.toFloat(), slot.y.toFloat()) 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<Slot>(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() { override fun init() {
super.init() super.init()
@ -354,10 +447,13 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
} }
companion object { 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 DEFAULT_FRAME_HEIGHT = 100f
const val INVENTORY_FRAME_WIDTH = DEFAULT_FRAME_WIDTH 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_WITH_SLOT = 17f
const val GAUGE_TOP_WITHOUT_SLOT = 26f const val GAUGE_TOP_WITHOUT_SLOT = 26f
const val SLOT_TOP_UNDER_GAUGE = 70f const val SLOT_TOP_UNDER_GAUGE = 70f

View File

@ -25,29 +25,6 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen
} }
} }
val hotbarSlots: List<InventorySlot>
val mainInventorySlots: List<InventorySlot>
init {
val builder = ImmutableList.builder<InventorySlot>()
for (i in 0 .. 8) {
builder.add(InventorySlot(capability.ply.inventory, i))
}
hotbarSlots = builder.build()
}
init {
val builder = ImmutableList.builder<InventorySlot>()
for (i in 9 .. 35) {
builder.add(InventorySlot(capability.ply.inventory, i))
}
mainInventorySlots = builder.build()
}
val armorSlots: List<EquipmentSlot> = makeArmorSlots() val armorSlots: List<EquipmentSlot> = makeArmorSlots()
val offhandSlot = object : InventorySlot(capability.ply.inventory, 40) { val offhandSlot = object : InventorySlot(capability.ply.inventory, 40) {
@ -56,26 +33,6 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen
} }
} }
val exoSuitSlots: List<MatterySlot>
val combinedInventorySlots: List<MatterySlot>
init {
val builder = ImmutableList.builder<MatterySlot>()
for (i in 0 until capability.exoSuitContainer.containerSize) {
builder.add(MatterySlot(capability.exoSuitContainer, i))
}
exoSuitSlots = builder.build()
}
init {
val builder = ImmutableList.builder<MatterySlot>()
builder.addAll(mainInventorySlots)
builder.addAll(exoSuitSlots)
combinedInventorySlots = builder.build()
}
val craftingGrid: CraftingContainer val craftingGrid: CraftingContainer
val craftingSlots: List<MatterySlot> val craftingSlots: List<MatterySlot>
@ -94,11 +51,10 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen
craftingSlots = builder.build() craftingSlots = builder.build()
exoSuitSlots.forEach(this::addSlot) addInventorySlots(autoFrame = false)
craftingSlots.forEach(this::addSlot) craftingSlots.forEach(this::addSlot)
addSlot(offhandSlot) addSlot(offhandSlot)
hotbarSlots.forEach(this::addSlot)
mainInventorySlots.forEach(this::addSlot)
armorSlots.forEach(this::addSlot) armorSlots.forEach(this::addSlot)
} }
@ -152,26 +108,26 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen
if (slotIndex == craftingResultSlot.index) { if (slotIndex == craftingResultSlot.index) {
val item = craftingResultSlot.item val item = craftingResultSlot.item
val leftover = moveItemStackToSlots(item, combinedInventorySlots, simulate = true) val leftover = moveItemStackToSlots(item, playerCombinedInventorySlots, simulate = true)
if (leftover.isEmpty) { if (leftover.isEmpty) {
val copy = item.copy() val copy = item.copy()
moveItemStackToSlots(item, combinedInventorySlots, simulate = false) moveItemStackToSlots(item, playerCombinedInventorySlots, simulate = false)
item.count = 0 item.count = 0
craftingResultSlot.onTake(ply, copy) craftingResultSlot.onTake(ply, copy)
return copy return copy
} }
return ItemStack.EMPTY return ItemStack.EMPTY
} else if (combinedInventorySlots.any { it.index == slotIndex }) { } else if (playerCombinedInventorySlots.any { it.index == slotIndex }) {
val item = slots[slotIndex].item val item = slots[slotIndex].item
val copy = item.copy() val copy = item.copy()
moveItemStackTo(item, hotbarSlots) moveItemStackTo(item, playerHotbarSlots)
return copy 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 item = slots[slotIndex].item
val copy = item.copy() val copy = item.copy()
moveItemStackTo(item, combinedInventorySlots) moveItemStackTo(item, playerCombinedInventorySlots)
return copy return copy
} }

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.menu
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.mojang.datafixers.util.Pair import com.mojang.datafixers.util.Pair
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.Container 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.item.enchantment.EnchantmentHelper.hasBindingCurse
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraftforge.network.PacketDistributor 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.ItemFilter
import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot
import ru.dbotthepony.mc.otm.menu.widget.AbstractWidget import ru.dbotthepony.mc.otm.menu.widget.AbstractWidget
@ -33,8 +39,36 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
val matteryWidgets: List<AbstractWidget> = Collections.unmodifiableList(_matteryWidgets) val matteryWidgets: List<AbstractWidget> = Collections.unmodifiableList(_matteryWidgets)
private val _playerInventorySlots = ArrayList<MatterySlot>() private val _playerInventorySlots = ArrayList<MatterySlot>()
private val _playerHotbarSlots = ArrayList<MatterySlot>()
private val _playerMainSlots = ArrayList<MatterySlot>()
private val _playerExoSuitSlots = ArrayList<MatterySlot>()
private val _playerCombinedInventorySlots = ArrayList<MatterySlot>()
/**
* inventory + exosuit + hotbar (in this order)
*/
val playerInventorySlots: List<MatterySlot> = Collections.unmodifiableList(_playerInventorySlots) val playerInventorySlots: List<MatterySlot> = Collections.unmodifiableList(_playerInventorySlots)
/**
* hotbar only
*/
val playerHotbarSlots: List<MatterySlot> = Collections.unmodifiableList(_playerHotbarSlots)
/**
* inventory only
*/
val playerMainSlots: List<MatterySlot> = Collections.unmodifiableList(_playerMainSlots)
/**
* exosuit only
*/
val playerExoSuitSlots: List<MatterySlot> = Collections.unmodifiableList(_playerExoSuitSlots)
/**
* inventory + exosuit (in this order)
*/
val playerCombinedInventorySlots: List<MatterySlot> = Collections.unmodifiableList(_playerCombinedInventorySlots)
var autoCreateInventoryFrame = true var autoCreateInventoryFrame = true
private set private set
@ -121,33 +155,38 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
} }
protected fun addInventorySlots(autoFrame: Boolean = true) { protected fun addInventorySlots(autoFrame: Boolean = true) {
check(_playerInventorySlots.isEmpty()) { "Already created inventory slots" }
autoCreateInventoryFrame = autoFrame autoCreateInventoryFrame = autoFrame
var first = true
for (row in 0..2) { for (i in 9 .. 35) {
for (column in 0..8) { val slot = InventorySlot(inventory, i)
val slot = InventorySlot(inventory, column + row * 9 + 9, 8 + column * 18, 14 + row * 18)
_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) _playerInventorySlots.add(slot)
_playerExoSuitSlots.add(slot)
_playerCombinedInventorySlots.add(slot)
addSlot(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) { addSlot(slot)
last = InventorySlot(inventory, k, 8 + k * 18, 14 + 58) _playerInventorySlots.add(slot)
_playerHotbarSlots.add(slot)
addSlot(last)
_playerInventorySlots.add(last)
} }
inventorySlotIndexEnd = last!!.index
} }
override fun broadcastChanges() { override fun broadcastChanges() {
@ -226,7 +265,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
moveToPlayer = true moveToPlayer = true
} }
if (moveToPlayer == null && playerInventorySlots.any { it.index == slotIndex }) { if (moveToPlayer == null && _playerInventorySlots.any { it.index == slotIndex }) {
moveToPlayer = false moveToPlayer = false
} }
@ -246,7 +285,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
moved = initialItem.copy() moved = initialItem.copy()
if (moveToPlayer) { if (moveToPlayer) {
if (!moveItemStackTo(initialItem, playerInventorySlots)) { if (!moveItemStackTo(initialItem, _playerInventorySlots)) {
return ItemStack.EMPTY return ItemStack.EMPTY
} }
} else { } else {
@ -266,11 +305,11 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
} }
fun quickMoveToInventory(stack: ItemStack, simulate: Boolean): ItemStack { fun quickMoveToInventory(stack: ItemStack, simulate: Boolean): ItemStack {
if (inventorySlotIndexStart == 0 && inventorySlotIndexEnd == 0) { if (_playerInventorySlots.isEmpty()) {
return stack return stack
} }
return moveItemStackToSlots(stack, inventorySlotIndexStart, inventorySlotIndexEnd, simulate = simulate) return moveItemStackToSlots(stack, _playerInventorySlots, simulate = simulate)
} }
override fun moveItemStackTo( override fun moveItemStackTo(