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) {
_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()
}

View File

@ -12,36 +12,6 @@ import ru.dbotthepony.mc.otm.network.ExoSuitMenuOpen
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
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 {
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
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 = {
_, old, new ->
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<ExoSuit
mainInventoryLine.dock = Dock.BOTTOM
for (slot in menu.hotbarSlots) {
for (slot in menu.playerHotbarSlots) {
val panel = SlotPanel(this, toolbeltLine, slot)
panel.dock = Dock.LEFT
}
@ -91,7 +61,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
offhand.dock = Dock.RIGHT
for (i in scrollPanel.scroll .. scrollPanel.scroll + 2) {
getSlotsRow(i).also {
getInventorySlotsRow(i).also {
it.parent = mainInventoryLine
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.vertex.PoseStack
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.Font
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 org.lwjgl.opengl.GL11
import org.lwjgl.opengl.GL13
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.menu.MatteryMenu
/**
@ -50,14 +51,106 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
val quickCraftingType get() = quickCraftingType
val isQuickCrafting get() = isQuickCrafting
private val inventorySlotsRows = Int2ObjectAVLTreeMap<EditablePanel>()
init {
if (menu.playerInventorySlots.isNotEmpty() && menu.autoCreateInventoryFrame) {
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<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() {
@ -354,10 +447,13 @@ abstract class MatteryScreen<T : MatteryMenu>(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

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 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 craftingSlots: List<MatterySlot>
@ -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
}

View File

@ -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<AbstractWidget> = Collections.unmodifiableList(_matteryWidgets)
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)
/**
* 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
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)
if (first) {
first = false
inventorySlotIndexStart = slot.index
}
}
}
var last: MatterySlot? = null
val mattery = ply.matteryPlayer
for (k in 0..8) {
last = InventorySlot(inventory, k, 8 + k * 18, 14 + 58)
if (mattery != null && mattery.hasExoSuit) {
for (i in 0 until mattery.exoSuitContainer.containerSize) {
val slot = InventorySlot(mattery.exoSuitContainer, i)
addSlot(last)
_playerInventorySlots.add(last)
_playerInventorySlots.add(slot)
_playerExoSuitSlots.add(slot)
_playerCombinedInventorySlots.add(slot)
addSlot(slot)
}
}
inventorySlotIndexEnd = last!!.index
for (i in 0..8) {
val slot = InventorySlot(inventory, i)
addSlot(slot)
_playerInventorySlots.add(slot)
_playerHotbarSlots.add(slot)
}
}
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(