container: slot types, sections

This commit is contained in:
Bixilon 2022-02-25 13:05:48 +01:00
parent c8068a6867
commit d69fae0627
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
19 changed files with 352 additions and 112 deletions

View File

@ -45,12 +45,6 @@
}, },
"end": { "end": {
"$ref": "#/definitions/vec2i" "$ref": "#/definitions/vec2i"
},
"section": {
"type": "integer"
},
"type": {
"enum": ["default", "main_hand", "off_hand", "feet", "legs", "chest", "head", "read_only"]
} }
}, },
"required": [ "required": [

View File

@ -21,8 +21,11 @@ import de.bixilon.kutil.watcher.DataWatcher.Companion.observe
import de.bixilon.kutil.watcher.DataWatcher.Companion.watched import de.bixilon.kutil.watcher.DataWatcher.Companion.watched
import de.bixilon.kutil.watcher.map.MapDataWatcher.Companion.watchedMap import de.bixilon.kutil.watcher.map.MapDataWatcher.Companion.watchedMap
import de.bixilon.minosoft.data.inventory.click.ContainerAction import de.bixilon.minosoft.data.inventory.click.ContainerAction
import de.bixilon.minosoft.data.inventory.click.SlotSwapContainerAction
import de.bixilon.minosoft.data.inventory.stack.ItemStack import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.inventory.stack.property.HolderProperty import de.bixilon.minosoft.data.inventory.stack.property.HolderProperty
import de.bixilon.minosoft.data.registries.other.containers.slots.DefaultSlotType
import de.bixilon.minosoft.data.registries.other.containers.slots.SlotType
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.c2s.play.container.CloseContainerC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.container.CloseContainerC2SP
@ -75,6 +78,10 @@ open class Container(
lock.unlock() lock.unlock()
} }
open fun getSlotType(slotId: Int): SlotType? = DefaultSlotType
open fun getSlotSwap(slot: SlotSwapContainerAction.SwapTargets): Int? = null
open fun getSection(slotId: Int): Int? = null
operator fun get(slotId: Int): ItemStack? { operator fun get(slotId: Int): ItemStack? {
try { try {
lock.acquire() lock.acquire()

View File

@ -16,8 +16,16 @@ package de.bixilon.minosoft.data.registries.other.containers
import de.bixilon.kutil.collections.CollectionUtil.lockMapOf import de.bixilon.kutil.collections.CollectionUtil.lockMapOf
import de.bixilon.kutil.collections.map.LockMap import de.bixilon.kutil.collections.map.LockMap
import de.bixilon.minosoft.data.inventory.InventorySlots import de.bixilon.minosoft.data.inventory.InventorySlots
import de.bixilon.minosoft.data.inventory.click.SlotSwapContainerAction
import de.bixilon.minosoft.data.inventory.stack.ItemStack import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.player.Hands import de.bixilon.minosoft.data.player.Hands
import de.bixilon.minosoft.data.registries.other.containers.slots.DefaultSlotType
import de.bixilon.minosoft.data.registries.other.containers.slots.RemoveOnlySlotType
import de.bixilon.minosoft.data.registries.other.containers.slots.SlotType
import de.bixilon.minosoft.data.registries.other.containers.slots.equipment.ChestSlotType
import de.bixilon.minosoft.data.registries.other.containers.slots.equipment.FeetSlotType
import de.bixilon.minosoft.data.registries.other.containers.slots.equipment.HeadSlotType
import de.bixilon.minosoft.data.registries.other.containers.slots.equipment.LegsSlotType
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.bixilon.minosoft.util.KUtil.toResourceLocation
@ -62,6 +70,45 @@ class PlayerInventory(connection: PlayConnection) : Container(
super.set(*realSlots.toTypedArray()) super.set(*realSlots.toTypedArray())
} }
override fun getSlotType(slotId: Int): SlotType? {
return when (slotId) {
0 -> RemoveOnlySlotType // crafting result
in 1..4 -> DefaultSlotType // crafting
ARMOR_OFFSET + 0 -> HeadSlotType
ARMOR_OFFSET + 1 -> ChestSlotType
ARMOR_OFFSET + 2 -> LegsSlotType
ARMOR_OFFSET + 3 -> FeetSlotType
in ARMOR_OFFSET + 3..HOTBAR_OFFSET + HOTBAR_SLOTS + 1 -> DefaultSlotType // all slots, including offhand
else -> null
}
}
override fun getSlotSwap(slot: SlotSwapContainerAction.SwapTargets): Int {
return when (slot) {
SlotSwapContainerAction.SwapTargets.HOTBAR_1 -> HOTBAR_OFFSET + 0
SlotSwapContainerAction.SwapTargets.HOTBAR_2 -> HOTBAR_OFFSET + 1
SlotSwapContainerAction.SwapTargets.HOTBAR_3 -> HOTBAR_OFFSET + 2
SlotSwapContainerAction.SwapTargets.HOTBAR_4 -> HOTBAR_OFFSET + 3
SlotSwapContainerAction.SwapTargets.HOTBAR_5 -> HOTBAR_OFFSET + 4
SlotSwapContainerAction.SwapTargets.HOTBAR_6 -> HOTBAR_OFFSET + 5
SlotSwapContainerAction.SwapTargets.HOTBAR_7 -> HOTBAR_OFFSET + 6
SlotSwapContainerAction.SwapTargets.HOTBAR_8 -> HOTBAR_OFFSET + 7
SlotSwapContainerAction.SwapTargets.HOTBAR_9 -> HOTBAR_OFFSET + 8
SlotSwapContainerAction.SwapTargets.OFFHAND -> 45
}
}
override fun getSection(slotId: Int): Int? {
return when (slotId) {
in 0..4 -> null // crafting
in ARMOR_OFFSET..ARMOR_OFFSET + 4 -> 0 // armor
in ARMOR_OFFSET + 5 until HOTBAR_OFFSET -> 1 // inventory
in HOTBAR_OFFSET..HOTBAR_OFFSET + HOTBAR_SLOTS -> 2 // hotbar
else -> null // offhand, else
}
}
val InventorySlots.EquipmentSlots.slot: Int val InventorySlots.EquipmentSlots.slot: Int
get() { get() {
return when (this) { return when (this) {

View File

@ -0,0 +1,16 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots
object DefaultSlotType : SlotType

View File

@ -0,0 +1,24 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots
import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.registries.other.containers.Container
object ReadOnlySlotType : SlotType {
override fun canRemove(container: Container, slot: Int, stack: ItemStack): Boolean = false
override fun canModify(container: Container, slot: Int, stack: ItemStack): Boolean = false
override fun canPut(container: Container, slot: Int, stack: ItemStack): Boolean = false
}

View File

@ -0,0 +1,24 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots
import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.registries.other.containers.Container
object RemoveOnlySlotType : SlotType {
override fun canRemove(container: Container, slot: Int, stack: ItemStack): Boolean = true
override fun canModify(container: Container, slot: Int, stack: ItemStack): Boolean = true
override fun canPut(container: Container, slot: Int, stack: ItemStack): Boolean = true
}

View File

@ -0,0 +1,24 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots
import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.registries.other.containers.Container
interface SlotType {
fun canRemove(container: Container, slot: Int, stack: ItemStack) = true
fun canModify(container: Container, slot: Int, stack: ItemStack) = true
fun canPut(container: Container, slot: Int, stack: ItemStack) = true
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots.equipment
import de.bixilon.minosoft.data.inventory.InventorySlots
import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.registries.items.armor.ArmorItem
import de.bixilon.minosoft.data.registries.other.containers.Container
object ChestSlotType : EquipmentSlotType {
override fun canPut(container: Container, slot: Int, stack: ItemStack): Boolean {
val item = stack.item.item
if (item !is ArmorItem) {
return false
}
return item.equipmentSlot == InventorySlots.EquipmentSlots.CHEST
}
}

View File

@ -0,0 +1,16 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots.equipment
interface EquipmentSlotType : SingleItemSlotType

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots.equipment
import de.bixilon.minosoft.data.inventory.InventorySlots
import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.registries.items.armor.ArmorItem
import de.bixilon.minosoft.data.registries.other.containers.Container
object FeetSlotType : EquipmentSlotType {
override fun canPut(container: Container, slot: Int, stack: ItemStack): Boolean {
val item = stack.item.item
if (item !is ArmorItem) {
return false
}
return item.equipmentSlot == InventorySlots.EquipmentSlots.FEET
}
}

View File

@ -0,0 +1,31 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots.equipment
import de.bixilon.minosoft.data.inventory.InventorySlots
import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.registries.items.armor.ArmorItem
import de.bixilon.minosoft.data.registries.other.containers.Container
object HeadSlotType : EquipmentSlotType {
override fun canPut(container: Container, slot: Int, stack: ItemStack): Boolean {
val item = stack.item.item
// ToDo: Carved pumpkin
if (item !is ArmorItem) {
return false
}
return item.equipmentSlot == InventorySlots.EquipmentSlots.HEAD
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots.equipment
import de.bixilon.minosoft.data.inventory.InventorySlots
import de.bixilon.minosoft.data.inventory.stack.ItemStack
import de.bixilon.minosoft.data.registries.items.armor.ArmorItem
import de.bixilon.minosoft.data.registries.other.containers.Container
object LegsSlotType : EquipmentSlotType {
override fun canPut(container: Container, slot: Int, stack: ItemStack): Boolean {
val item = stack.item.item
if (item !is ArmorItem) {
return false
}
return item.equipmentSlot == InventorySlots.EquipmentSlots.LEGS
}
}

View File

@ -0,0 +1,18 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.other.containers.slots.equipment
import de.bixilon.minosoft.data.registries.other.containers.slots.SlotType
interface SingleItemSlotType : SlotType

View File

@ -22,7 +22,7 @@ class AtlasElement(
override val texture: AbstractTexture, override val texture: AbstractTexture,
val start: Vec2i, val start: Vec2i,
val end: Vec2i, val end: Vec2i,
val slots: Int2ObjectOpenHashMap<Vec2iBinding>, // ToDo: Use an array? val slots: Int2ObjectOpenHashMap<AtlasSlot>,
) : TextureLike { ) : TextureLike {
override val size: Vec2i = end - start override val size: Vec2i = end - start
override lateinit var uvStart: Vec2 override lateinit var uvStart: Vec2

View File

@ -60,17 +60,18 @@ class AtlasManager(private val renderWindow: RenderWindow) {
val texture = renderWindow.textureManager.staticTextures.createTexture(versionData["texture"].toResourceLocation(), mipmaps = false) val texture = renderWindow.textureManager.staticTextures.createTexture(versionData["texture"].toResourceLocation(), mipmaps = false)
val start = versionData["start"].toVec2i() val start = versionData["start"].toVec2i()
val end = versionData["end"].toVec2i() val end = versionData["end"].toVec2i()
val slots: Int2ObjectOpenHashMap<Vec2iBinding> = Int2ObjectOpenHashMap() val slots: Int2ObjectOpenHashMap<AtlasSlot> = Int2ObjectOpenHashMap()
versionData["slots"].toJsonObject()?.let { versionData["slots"].toJsonObject()?.let {
for ((slotId, slotData) in it) { for ((slotId, slotData) in it) {
val slot = slotData.asJsonObject() val slot = slotData.asJsonObject()
slots[slotId.toInt()] = Vec2iBinding( slots[slotId.toInt()] = AtlasSlot(
start = slot["start"].toVec2i(), start = slot["start"].toVec2i(),
end = slot["end"].toVec2i(), end = slot["end"].toVec2i(),
) )
} }
} }
// ToDo: special
val atlasElement = AtlasElement( val atlasElement = AtlasElement(
texture = texture, texture = texture,

View File

@ -15,7 +15,7 @@ package de.bixilon.minosoft.gui.rendering.gui.atlas
import glm_.vec2.Vec2i import glm_.vec2.Vec2i
data class Vec2iBinding( data class AtlasSlot(
val start: Vec2i, val start: Vec2i,
val end: Vec2i, val end: Vec2i,
) { ) {

View File

@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.gui.elements.items
import de.bixilon.kutil.watcher.map.MapDataWatcher.Companion.observeMap import de.bixilon.kutil.watcher.map.MapDataWatcher.Companion.observeMap
import de.bixilon.minosoft.data.registries.other.containers.Container import de.bixilon.minosoft.data.registries.other.containers.Container
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Vec2iBinding import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasSlot
import de.bixilon.minosoft.gui.rendering.gui.elements.Element import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.gui.AbstractLayout import de.bixilon.minosoft.gui.rendering.gui.gui.AbstractLayout
import de.bixilon.minosoft.gui.rendering.gui.gui.dragged.elements.item.FloatingItem import de.bixilon.minosoft.gui.rendering.gui.gui.dragged.elements.item.FloatingItem
@ -32,7 +32,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
class ContainerItemsElement( class ContainerItemsElement(
guiRenderer: GUIRenderer, guiRenderer: GUIRenderer,
val container: Container, val container: Container,
val slots: Int2ObjectOpenHashMap<Vec2iBinding>, // ToDo: Use an array? val slots: Int2ObjectOpenHashMap<AtlasSlot>, // ToDo: Use an array?
) : Element(guiRenderer), AbstractLayout<ItemElement> { ) : Element(guiRenderer), AbstractLayout<ItemElement> {
private val itemElements: Int2ObjectOpenHashMap<ItemElementData> = Int2ObjectOpenHashMap() private val itemElements: Int2ObjectOpenHashMap<ItemElementData> = Int2ObjectOpenHashMap()
private var floatingItem: FloatingItem? = null private var floatingItem: FloatingItem? = null

View File

@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container
import de.bixilon.minosoft.data.registries.other.containers.Container import de.bixilon.minosoft.data.registries.other.containers.Container
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.atlas.Vec2iBinding import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasSlot
import de.bixilon.minosoft.gui.rendering.gui.elements.Element import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.items.ContainerItemsElement import de.bixilon.minosoft.gui.rendering.gui.elements.items.ContainerItemsElement
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
@ -33,7 +33,7 @@ abstract class ContainerScreen(
guiRenderer: GUIRenderer, guiRenderer: GUIRenderer,
val container: Container, val container: Container,
background: AtlasElement, background: AtlasElement,
items: Int2ObjectOpenHashMap<Vec2iBinding> = background.slots, items: Int2ObjectOpenHashMap<AtlasSlot> = background.slots,
) : Screen(guiRenderer), AbstractLayout<Element> { ) : Screen(guiRenderer), AbstractLayout<Element> {
private val containerBackground = AtlasImageElement(guiRenderer, background) private val containerBackground = AtlasImageElement(guiRenderer, background)
protected val containerElement = ContainerItemsElement(guiRenderer, container, items).apply { parent = this@ContainerScreen } protected val containerElement = ContainerItemsElement(guiRenderer, container, items).apply { parent = this@ContainerScreen }

View File

@ -715,239 +715,187 @@
"slots": { "slots": {
"0": { "0": {
"start": [154, 28], "start": [154, 28],
"end": [171, 45], "end": [171, 45]
"type": "read_only",
"section": -1
}, },
"1": { "1": {
"start": [98, 18], "start": [98, 18],
"end": [115, 35], "end": [115, 35]
"section": -1
}, },
"2": { "2": {
"start": [116, 18], "start": [116, 18],
"end": [133, 35], "end": [133, 35]
"section": -1
}, },
"3": { "3": {
"start": [98, 36], "start": [98, 36],
"end": [115, 53], "end": [115, 53]
"section": -1
}, },
"4": { "4": {
"start": [116, 36], "start": [116, 36],
"end": [133, 53], "end": [133, 53]
"section": -1
}, },
"5": { "5": {
"start": [8, 8], "start": [8, 8],
"end": [25, 25], "end": [25, 25]
"section": 0,
"type": "head"
}, },
"6": { "6": {
"start": [8, 26], "start": [8, 26],
"end": [25, 43], "end": [25, 43]
"section": 0,
"type": "chest"
}, },
"7": { "7": {
"start": [8, 44], "start": [8, 44],
"end": [25, 61], "end": [25, 61]
"section": 0,
"type": "legs"
}, },
"8": { "8": {
"start": [8, 62], "start": [8, 62],
"end": [25, 79], "end": [25, 79]
"section": 0,
"type": "feet"
}, },
"9": { "9": {
"start": [8, 84], "start": [8, 84],
"end": [25, 101], "end": [25, 101]
"section": 1
}, },
"10": { "10": {
"start": [26, 84], "start": [26, 84],
"end": [43, 101], "end": [43, 101]
"section": 1
}, },
"11": { "11": {
"start": [44, 84], "start": [44, 84],
"end": [61, 101], "end": [61, 101]
"section": 1
}, },
"12": { "12": {
"start": [62, 84], "start": [62, 84],
"end": [79, 101], "end": [79, 101]
"section": 1
}, },
"13": { "13": {
"start": [80, 84], "start": [80, 84],
"end": [97, 101], "end": [97, 101]
"section": 1
}, },
"14": { "14": {
"start": [98, 84], "start": [98, 84],
"end": [115, 101], "end": [115, 101]
"section": 1
}, },
"15": { "15": {
"start": [116, 84], "start": [116, 84],
"end": [133, 101], "end": [133, 101]
"section": 1
}, },
"16": { "16": {
"start": [134, 84], "start": [134, 84],
"end": [151, 101], "end": [151, 101]
"section": 1
}, },
"17": { "17": {
"start": [152, 84], "start": [152, 84],
"end": [169, 101], "end": [169, 101]
"section": 1
}, },
"18": { "18": {
"start": [8, 102], "start": [8, 102],
"end": [25, 119], "end": [25, 119]
"section": 1
}, },
"19": { "19": {
"start": [26, 102], "start": [26, 102],
"end": [43, 119], "end": [43, 119]
"section": 1
}, },
"20": { "20": {
"start": [44, 102], "start": [44, 102],
"end": [61, 119], "end": [61, 119]
"section": 1
}, },
"21": { "21": {
"start": [62, 102], "start": [62, 102],
"end": [79, 119], "end": [79, 119]
"section": 1
}, },
"22": { "22": {
"start": [80, 102], "start": [80, 102],
"end": [97, 119], "end": [97, 119]
"section": 1
}, },
"23": { "23": {
"start": [98, 102], "start": [98, 102],
"end": [115, 119], "end": [115, 119]
"section": 1
}, },
"24": { "24": {
"start": [116, 102], "start": [116, 102],
"end": [133, 119], "end": [133, 119]
"section": 1
}, },
"25": { "25": {
"start": [134, 102], "start": [134, 102],
"end": [151, 119], "end": [151, 119]
"section": 1
}, },
"26": { "26": {
"start": [152, 102], "start": [152, 102],
"end": [169, 119], "end": [169, 119]
"section": 1
}, },
"27": { "27": {
"start": [8, 120], "start": [8, 120],
"end": [25, 137], "end": [25, 137]
"section": 1
}, },
"28": { "28": {
"start": [26, 120], "start": [26, 120],
"end": [43, 137], "end": [43, 137]
"section": 1
}, },
"29": { "29": {
"start": [44, 120], "start": [44, 120],
"end": [61, 137], "end": [61, 137]
"section": 1
}, },
"30": { "30": {
"start": [62, 120], "start": [62, 120],
"end": [79, 137], "end": [79, 137]
"section": 1
}, },
"31": { "31": {
"start": [80, 120], "start": [80, 120],
"end": [97, 137], "end": [97, 137]
"section": 1
}, },
"32": { "32": {
"start": [98, 120], "start": [98, 120],
"end": [115, 137], "end": [115, 137]
"section": 1
}, },
"33": { "33": {
"start": [116, 120], "start": [116, 120],
"end": [133, 137], "end": [133, 137]
"section": 1
}, },
"34": { "34": {
"start": [134, 120], "start": [134, 120],
"end": [151, 137], "end": [151, 137]
"section": 1
}, },
"35": { "35": {
"start": [152, 120], "start": [152, 120],
"end": [169, 137], "end": [169, 137]
"section": 1
}, },
"36": { "36": {
"start": [8, 142], "start": [8, 142],
"end": [25, 159], "end": [25, 159]
"section": 2
}, },
"37": { "37": {
"start": [26, 142], "start": [26, 142],
"end": [43, 159], "end": [43, 159]
"section": 2
}, },
"38": { "38": {
"start": [44, 142], "start": [44, 142],
"end": [61, 159], "end": [61, 159]
"section": 2
}, },
"39": { "39": {
"start": [62, 142], "start": [62, 142],
"end": [79, 159], "end": [79, 159]
"section": 2
}, },
"40": { "40": {
"start": [80, 142], "start": [80, 142],
"end": [97, 159], "end": [97, 159]
"section": 2
}, },
"41": { "41": {
"start": [98, 142], "start": [98, 142],
"end": [115, 159], "end": [115, 159]
"section": 2
}, },
"42": { "42": {
"start": [116, 142], "start": [116, 142],
"end": [133, 159], "end": [133, 159]
"section": 2
}, },
"43": { "43": {
"start": [134, 142], "start": [134, 142],
"end": [151, 159], "end": [151, 159]
"section": 2
}, },
"44": { "44": {
"start": [152, 142], "start": [152, 142],
"end": [169, 159], "end": [169, 159]
"section": 2
}, },
"45": { "45": {
"start": [77, 62], "start": [77, 62],
"end": [94, 79], "end": [94, 79]
"type": "off_hand",
"section": -1
} }
}, },
"areas": { "areas": {