mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 19:35:00 -04:00
container revision fixes, item rendering: render material color quad
This commit is contained in:
parent
191c2e665e
commit
7e6fc7c933
@ -42,6 +42,7 @@ import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
|
||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.getAndRemove
|
||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast
|
||||
import java.util.*
|
||||
|
||||
class ItemStack(
|
||||
val item: Item,
|
||||
@ -54,7 +55,7 @@ class ItemStack(
|
||||
unbreakable: Boolean = false,
|
||||
durability: Int = 0,
|
||||
val nbt: MutableMap<String, Any> = synchronizedMapOf(),
|
||||
val container: Container? = null,
|
||||
container: Container? = null,
|
||||
hideFlags: Int = 0,
|
||||
) : TextFormattable {
|
||||
var count = count
|
||||
@ -105,6 +106,17 @@ class ItemStack(
|
||||
field = value
|
||||
apply()
|
||||
}
|
||||
var container = container
|
||||
set(value) {
|
||||
if (field != null && value != null) {
|
||||
throw IllegalStateException("Item already in a different container!")
|
||||
}
|
||||
if (field === value) {
|
||||
return
|
||||
}
|
||||
field = value
|
||||
apply()
|
||||
}
|
||||
|
||||
// ToDo: Apply if enchantments, lore or nbt changes
|
||||
|
||||
@ -319,6 +331,33 @@ class ItemStack(
|
||||
val damageable: Boolean
|
||||
get() = item.maxDamage > 0 || !unbreakable
|
||||
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return Objects.hash(item, count, durability, nbt)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) {
|
||||
return true
|
||||
}
|
||||
if (other !is ItemStack) {
|
||||
return false
|
||||
}
|
||||
if (hashCode() != other.hashCode()) {
|
||||
return false
|
||||
}
|
||||
return item == other.item
|
||||
&& count == other.count
|
||||
&& durability == other.durability
|
||||
&& enchantments == other.enchantments
|
||||
&& nbt == other.nbt
|
||||
&& lore == other.lore
|
||||
&& customDisplayName == other.customDisplayName
|
||||
&& repairCost == other.repairCost
|
||||
&& unbreakable == other.unbreakable
|
||||
&& hideFlags == other.hideFlags
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val HIDE_ENCHANTMENT_BIT = 0
|
||||
private const val HIDE_MODIFIERS_BIT = 1
|
||||
|
@ -41,6 +41,7 @@ open class Container(
|
||||
for ((slot, itemStack) in slots.toSynchronizedMap()) {
|
||||
if (itemStack.count <= 0 || itemStack.durability < 0) {
|
||||
slots.remove(slot)
|
||||
itemStack.container = null
|
||||
changes = true
|
||||
}
|
||||
}
|
||||
@ -53,13 +54,29 @@ open class Container(
|
||||
return slots[slotId]
|
||||
}
|
||||
|
||||
operator fun set(slotId: Int, itemStack: ItemStack?) {
|
||||
if (itemStack == null) {
|
||||
slots.remove(slotId) ?: return
|
||||
} else {
|
||||
slots[slotId] = itemStack // ToDo: Check for changes
|
||||
}
|
||||
fun remove(slotId: Int): ItemStack? {
|
||||
val itemStack = slots.remove(slotId) ?: return null
|
||||
itemStack.container = null
|
||||
revision++
|
||||
return itemStack
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The previous item
|
||||
*/
|
||||
operator fun set(slotId: Int, itemStack: ItemStack?): ItemStack? {
|
||||
if (itemStack == null) {
|
||||
return remove(slotId)
|
||||
}
|
||||
val previous = slots[slotId]
|
||||
if (previous == itemStack) {
|
||||
return previous
|
||||
}
|
||||
slots[slotId] = itemStack // ToDo: Check for changes
|
||||
itemStack.container = this
|
||||
|
||||
revision++
|
||||
return previous
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
|
@ -9,6 +9,7 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||
import glm_.vec2.Vec2i
|
||||
import java.lang.Integer.max
|
||||
|
||||
class ContainerItemsElement(
|
||||
hudRenderer: HUDRenderer,
|
||||
@ -24,17 +25,20 @@ class ContainerItemsElement(
|
||||
}
|
||||
|
||||
override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int {
|
||||
var maxZ = 0
|
||||
for ((_, data) in itemElements.toSynchronizedMap()) {
|
||||
data.element.render(offset + data.offset, z, consumer, options)
|
||||
maxZ = max(maxZ, data.element.render(offset + data.offset, z, consumer, options))
|
||||
}
|
||||
|
||||
return 2
|
||||
return maxZ
|
||||
}
|
||||
|
||||
override fun silentApply(): Boolean {
|
||||
if (this.revision == container.revision) {
|
||||
val revision = container.revision
|
||||
if (this.revision == revision) {
|
||||
return false
|
||||
}
|
||||
this.revision = revision
|
||||
|
||||
var changes = false
|
||||
for ((slot, binding) in slots) {
|
||||
@ -56,7 +60,7 @@ class ContainerItemsElement(
|
||||
changes = true
|
||||
} else {
|
||||
if (data.element.item == item) {
|
||||
if (data.element.poll()) {
|
||||
if (data.element.silentApply()) {
|
||||
changes = true
|
||||
}
|
||||
} else {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.elements.items
|
||||
|
||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
||||
import de.bixilon.minosoft.data.registries.items.block.BlockItem
|
||||
import de.bixilon.minosoft.data.text.ChatColors
|
||||
import de.bixilon.minosoft.data.text.TextComponent
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
@ -9,6 +10,7 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Compa
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
|
||||
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.primitive.ColorElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
@ -41,15 +43,22 @@ class ItemElement(
|
||||
}
|
||||
|
||||
override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int {
|
||||
if (item == null) {
|
||||
return 0
|
||||
}
|
||||
val item = item ?: return 0
|
||||
val size = size
|
||||
val countSize = countText.size
|
||||
countText.render(offset + Vec2i(HorizontalAlignments.RIGHT.getOffset(size.x, countSize.x), VerticalAlignments.BOTTOM.getOffset(size.y, countSize.y)), z + 1, consumer, options)
|
||||
|
||||
var color = ChatColors.WHITE
|
||||
if (item.item is BlockItem) {
|
||||
item.item.block?.defaultState?.material?.color?.let { color = it }
|
||||
}
|
||||
|
||||
val image = ColorElement(hudRenderer, _size, color)
|
||||
|
||||
image.render(offset, z + 1, consumer, options)
|
||||
|
||||
// ToDo: Render model
|
||||
return 2
|
||||
return TextElement.LAYERS + 1
|
||||
}
|
||||
|
||||
override fun poll(): Boolean {
|
||||
|
@ -46,14 +46,14 @@ class HotbarBaseElement(hudRenderer: HUDRenderer) : Element(hudRenderer), Pollab
|
||||
base.render(offset + HORIZONTAL_MARGIN, z, consumer, options)
|
||||
|
||||
baseAtlasElement.slots[selectedSlot + PlayerInventory.HOTBAR_OFFSET]?.let {
|
||||
frame.render(offset + it.start - HORIZONTAL_MARGIN + FRAME_OFFSET, z + 2, consumer, options)
|
||||
frame.render(offset + it.start - HORIZONTAL_MARGIN + FRAME_OFFSET, z + 1, consumer, options)
|
||||
}
|
||||
|
||||
inventoryElement.render(offset, z, consumer, options)
|
||||
val inventoryZ = inventoryElement.render(offset, z + 2, consumer, options)
|
||||
|
||||
// ToDo: Item rendering
|
||||
|
||||
return 2 // bar + frame
|
||||
return 2 + inventoryZ// bar + frame
|
||||
}
|
||||
|
||||
override fun poll(): Boolean {
|
||||
|
@ -216,11 +216,20 @@ class Camera(
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> { recalculateViewProjectionMatrix() })
|
||||
|
||||
fun dropItem(type: BlockBreakC2SP.BreakType) {
|
||||
fun dropItem(stack: Boolean) {
|
||||
val time = System.currentTimeMillis()
|
||||
if (time - lastDropPacketSent < ProtocolDefinition.TICK_TIME) {
|
||||
return
|
||||
}
|
||||
val type = if (stack) {
|
||||
connection.player.inventory.getHotbarSlot()?.count = 0
|
||||
BlockBreakC2SP.BreakType.DROP_ITEM_STACK
|
||||
} else {
|
||||
connection.player.inventory.getHotbarSlot()?.let {
|
||||
it.count--
|
||||
}
|
||||
BlockBreakC2SP.BreakType.DROP_ITEM
|
||||
}
|
||||
connection.sendPacket(BlockBreakC2SP(type, connection.player.positionInfo.blockPosition))
|
||||
lastDropPacketSent = time
|
||||
}
|
||||
@ -230,13 +239,13 @@ class Camera(
|
||||
mutableMapOf(
|
||||
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_Q),
|
||||
),
|
||||
)) { dropItem(BlockBreakC2SP.BreakType.DROP_ITEM) }
|
||||
)) { dropItem(false) }
|
||||
renderWindow.inputHandler.registerKeyCallback(DROP_ITEM_STACK_KEYBINDING, KeyBinding(
|
||||
mutableMapOf(
|
||||
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_Q),
|
||||
KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_LEFT_CONTROL)
|
||||
),
|
||||
)) { dropItem(BlockBreakC2SP.BreakType.DROP_ITEM_STACK) }
|
||||
)) { dropItem(true) }
|
||||
frustum.recalculate()
|
||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
||||
}
|
||||
|
@ -34,10 +34,11 @@ class ContainerItemSetS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
override fun handle(connection: PlayConnection) {
|
||||
connection.player.containers[containerId]?.set(slot, itemStack)
|
||||
|
||||
// ToDo: Check for changes
|
||||
connection.fireEvent(ContainerSlotChangeEvent(connection, this))
|
||||
}
|
||||
|
||||
override fun log() {
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Container item set (containerId=$containerId, slot=$slot, itemStack=$itemStack)" }
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Container item set (containerId=$containerId, revision=$revision, slot=$slot, itemStack=$itemStack)" }
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user