mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
proper enchanting screen
This commit is contained in:
parent
899b838b2c
commit
56a6a3c821
@ -43,6 +43,7 @@ open class Container(
|
||||
@Deprecated("Should not be accessed directly")
|
||||
val slots: MutableMap<Int, ItemStack> by watchedMap(mutableMapOf())
|
||||
val lock = SimpleLock()
|
||||
var propertiesRevision by watched(0L)
|
||||
var revision by watched(0L)
|
||||
var serverRevision = 0
|
||||
private var lastActionId = 0
|
||||
|
@ -22,6 +22,7 @@ import de.bixilon.minosoft.data.container.slots.SlotType
|
||||
import de.bixilon.minosoft.data.container.stack.ItemStack
|
||||
import de.bixilon.minosoft.data.registries.MultiResourceLocationAble
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.enchantment.Enchantment
|
||||
import de.bixilon.minosoft.data.registries.items.DefaultItems
|
||||
import de.bixilon.minosoft.data.registries.other.containers.ContainerFactory
|
||||
import de.bixilon.minosoft.data.registries.other.containers.ContainerType
|
||||
@ -29,8 +30,13 @@ import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
|
||||
class EnchantingContainer(connection: PlayConnection, type: ContainerType, title: ChatComponent?) : InventorySynchronizedContainer(connection, type, title, (ENCHANTING_SLOTS + 1)..(ENCHANTING_SLOTS + PlayerInventory.MAIN_SLOTS)) {
|
||||
class EnchantingContainer(connection: PlayConnection, type: ContainerType, title: ChatComponent?) : InventorySynchronizedContainer(connection, type, title, ENCHANTING_SLOTS until (ENCHANTING_SLOTS + PlayerInventory.MAIN_SLOTS)) {
|
||||
override val sections: Array<IntRange> = arrayOf(0 until ENCHANTING_SLOTS, ENCHANTING_SLOTS until ENCHANTING_SLOTS + PlayerInventory.MAIN_SLOTS)
|
||||
val costs = IntArray(ENCHANTING_OPTIONS) { -1 }
|
||||
val enchantments: Array<Enchantment?> = arrayOfNulls(ENCHANTING_OPTIONS)
|
||||
var enchantmentLevels = IntArray(ENCHANTING_OPTIONS) { -1 }
|
||||
var seed = -1
|
||||
private set
|
||||
|
||||
override fun getSlotType(slotId: Int): SlotType? {
|
||||
return when (slotId) {
|
||||
@ -58,6 +64,15 @@ class EnchantingContainer(connection: PlayConnection, type: ContainerType, title
|
||||
return 1 + ENCHANTING_SLOTS + PlayerInventory.MAIN_SLOTS_PER_ROW * 3 + slot.ordinal
|
||||
}
|
||||
|
||||
override fun readProperty(property: Int, value: Int) {
|
||||
when (property) {
|
||||
0, 1, 2 -> costs[property] = value
|
||||
3 -> seed = value
|
||||
4, 5, 6 -> enchantments[property - 4] = connection.registries.enchantmentRegistry.getOrNull(value)
|
||||
7, 8, 9 -> enchantmentLevels[property - 7] = value
|
||||
}
|
||||
}
|
||||
|
||||
private object LapislazuliSlot : SlotType {
|
||||
override fun canPut(container: Container, slot: Int, stack: ItemStack): Boolean {
|
||||
return stack.item.item.resourceLocation == DefaultItems.LAPISLAZULI
|
||||
@ -68,7 +83,9 @@ class EnchantingContainer(connection: PlayConnection, type: ContainerType, title
|
||||
companion object : ContainerFactory<EnchantingContainer>, MultiResourceLocationAble {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:enchantment".toResourceLocation()
|
||||
override val ALIASES: Set<ResourceLocation> = setOf("minecraft:enchanting_table".toResourceLocation(), "EnchantTable".toResourceLocation())
|
||||
const val LAPISLAZULI_SLOT = 1
|
||||
const val ENCHANTING_SLOTS = 2
|
||||
const val ENCHANTING_OPTIONS = 3
|
||||
|
||||
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): EnchantingContainer {
|
||||
return EnchantingContainer(connection, type, title)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -54,6 +54,13 @@ open class ResourceLocation(
|
||||
return full
|
||||
}
|
||||
|
||||
fun toMinifiedString(): String {
|
||||
if (namespace == ProtocolDefinition.DEFAULT_NAMESPACE) {
|
||||
return path
|
||||
}
|
||||
return toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
val String.namespace: String
|
||||
get() {
|
||||
|
@ -37,7 +37,7 @@ abstract class AbstractButtonElement(
|
||||
text: Any,
|
||||
disabled: Boolean = false,
|
||||
) : Element(guiRenderer) {
|
||||
protected val textElement = TextElement(guiRenderer, text, background = false).apply { parent = this@AbstractButtonElement }
|
||||
protected val textElement = TextElement(guiRenderer, text, background = false, parent = this)
|
||||
protected abstract val disabledAtlas: AtlasElement?
|
||||
protected abstract val normalAtlas: AtlasElement?
|
||||
protected abstract val hoveredAtlas: AtlasElement?
|
||||
|
@ -14,6 +14,8 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.enchanting
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kutil.watcher.DataWatcher.Companion.observe
|
||||
import de.bixilon.minosoft.data.abilities.Gamemodes
|
||||
import de.bixilon.minosoft.data.container.types.EnchantingContainer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
@ -27,8 +29,14 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class EnchantingContainerScreen(guiRenderer: GUIRenderer, container: EnchantingContainer) : LabeledContainerScreen<EnchantingContainer>(guiRenderer, container, guiRenderer.atlasManager["minecraft:enchanting_container".toResourceLocation()]) {
|
||||
private val cards: Array<EnchantmentButtonElement> = Array(CARDS) { EnchantmentButtonElement(guiRenderer, this, guiRenderer.atlasManager["minecraft:level_requirement_${it}"], guiRenderer.atlasManager["minecraft:level_requirement_${it}_disabled"]) }
|
||||
private val cardAreas = arrayOf(atlasElement?.areas?.get("card_0"), atlasElement?.areas?.get("card_1"), atlasElement?.areas?.get("card_2"))
|
||||
private val cards: Array<EnchantmentButtonElement> = Array(EnchantingContainer.ENCHANTING_OPTIONS) { EnchantmentButtonElement(guiRenderer, this, guiRenderer.atlasManager["minecraft:level_requirement_${it}"], guiRenderer.atlasManager["minecraft:level_requirement_${it}_disabled"], it) }
|
||||
private val cardAreas = Array(EnchantingContainer.ENCHANTING_OPTIONS) { atlasElement?.areas?.get("card_$it") }
|
||||
|
||||
|
||||
init {
|
||||
container::propertiesRevision.observe(this) { forceApply() }
|
||||
container::revision.observe(this) { forceApply() }
|
||||
}
|
||||
|
||||
override fun forceRenderContainerScreen(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
|
||||
super.forceRenderContainerScreen(offset, consumer, options)
|
||||
@ -56,9 +64,21 @@ class EnchantingContainerScreen(guiRenderer: GUIRenderer, container: EnchantingC
|
||||
return super.getContainerAt(position)
|
||||
}
|
||||
|
||||
override fun forceSilentApply() {
|
||||
super.forceSilentApply()
|
||||
var lapisCount = container[EnchantingContainer.LAPISLAZULI_SLOT]?.item?._count ?: 0
|
||||
if (guiRenderer.connection.player.gamemode == Gamemodes.CREATIVE) {
|
||||
lapisCount = 64
|
||||
}
|
||||
|
||||
for (index in 0 until EnchantingContainer.ENCHANTING_OPTIONS) {
|
||||
val card = cards[index]
|
||||
card.update(lapisCount < index + 1, container.costs[index], container.enchantments[index], container.enchantmentLevels[index])
|
||||
}
|
||||
}
|
||||
|
||||
companion object : ContainerGUIFactory<EnchantingContainerScreen, EnchantingContainer> {
|
||||
override val clazz: KClass<EnchantingContainer> = EnchantingContainer::class
|
||||
const val CARDS = 3
|
||||
|
||||
override fun build(guiRenderer: GUIRenderer, container: EnchantingContainer): EnchantingContainerScreen {
|
||||
return EnchantingContainerScreen(guiRenderer, container)
|
||||
|
@ -14,31 +14,46 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.enchanting
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.registries.enchantment.Enchantment
|
||||
import de.bixilon.minosoft.data.text.ChatColors
|
||||
import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.data.text.TextComponent
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments.Companion.getOffset
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.input.button.AbstractButtonElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.play.container.ContainerButtonC2SP
|
||||
|
||||
class EnchantmentButtonElement(
|
||||
guiRenderer: GUIRenderer,
|
||||
val container: EnchantingContainerScreen,
|
||||
val levelAtlas: AtlasElement?,
|
||||
val disabledLevelAtlas: AtlasElement?,
|
||||
) : AbstractButtonElement(guiRenderer, "< text >", true) {
|
||||
val index: Int,
|
||||
) : AbstractButtonElement(guiRenderer, "", true) {
|
||||
override val disabledAtlas = guiRenderer.atlasManager["enchanting_table_card_disabled"]
|
||||
override val normalAtlas = guiRenderer.atlasManager["enchanting_table_card_normal"]
|
||||
override val hoveredAtlas = guiRenderer.atlasManager["enchanting_table_card_hovered"]
|
||||
private val levelText = TextElement(guiRenderer, ChatComponent.EMPTY, background = false)
|
||||
|
||||
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
|
||||
super.forceRender(offset, consumer, options)
|
||||
|
||||
val level = AtlasImageElement(guiRenderer, if (disabled) disabledLevelAtlas else levelAtlas)
|
||||
val size = size
|
||||
level.render(offset + Vec2i(5, HorizontalAlignments.CENTER.getOffset(size.y, level.size.y)), consumer, options)
|
||||
level.render(offset + Vec2i(5, VerticalAlignments.CENTER.getOffset(size.y, level.size.y)), consumer, options)
|
||||
|
||||
if (!_disabled) {
|
||||
levelText.render(offset + Vec2i(HorizontalAlignments.RIGHT.getOffset(size.x, levelText.size.x) - 3, VerticalAlignments.BOTTOM.getOffset(size.y, levelText.size.y) - 2), consumer, options)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
@ -48,6 +63,15 @@ class EnchantmentButtonElement(
|
||||
}
|
||||
|
||||
override fun submit() {
|
||||
TODO("Not yet implemented")
|
||||
container.container.id?.let { guiRenderer.connection.network.send(ContainerButtonC2SP(it, index)) }
|
||||
}
|
||||
|
||||
fun update(disabled: Boolean, cost: Int, enchantment: Enchantment?, level: Int) {
|
||||
_disabled = disabled || cost <= 0
|
||||
levelText.text = TextComponent(cost).color(RenderConstants.EXPERIENCE_BAR_LEVEL_COLOR)
|
||||
textElement._chatComponent = if (enchantment == null) ChatComponent.EMPTY else TextComponent(enchantment.resourceLocation.toMinifiedString() + " $level").color(ChatColors.BLUE)
|
||||
textElement.forceSilentApply()
|
||||
|
||||
forceSilentApply()
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
|
||||
@LoadPacket
|
||||
class ContainerButtonC2SP(
|
||||
private val containerId: Byte,
|
||||
private val buttonId: Byte, // up, middle, bottom (0, 1, 2); in later versions: lectern page, etc
|
||||
private val containerId: Int,
|
||||
private val buttonId: Int,
|
||||
) : PlayC2SPacket {
|
||||
|
||||
override fun write(buffer: PlayOutByteBuffer) {
|
||||
|
@ -20,14 +20,16 @@ import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
|
||||
@LoadPacket
|
||||
@LoadPacket(threadSafe = false)
|
||||
class ContainerPropertiesS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
|
||||
val containerId = buffer.readUnsignedByte()
|
||||
val property = buffer.readUnsignedShort()
|
||||
val value = buffer.readUnsignedShort()
|
||||
|
||||
override fun handle(connection: PlayConnection) {
|
||||
connection.player.containers[containerId]?.readProperty(property, value)
|
||||
val container = connection.player.containers[containerId] ?: return
|
||||
container.readProperty(property, value)
|
||||
container.propertiesRevision++
|
||||
}
|
||||
|
||||
override fun log(reducedLog: Boolean) {
|
||||
|
@ -29,7 +29,7 @@ import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
|
||||
@LoadPacket
|
||||
@LoadPacket(threadSafe = false)
|
||||
class OpenContainerS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
|
||||
val containerId = if (buffer.versionId <= V_1_14) { // ToDo: This is completely guessed, it has changed between 1.13 and 1.14, same as #L38
|
||||
buffer.readUnsignedByte()
|
||||
|
Loading…
x
Reference in New Issue
Block a user