mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 20:05:02 -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.compoundCast
|
||||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.getAndRemove
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.getAndRemove
|
||||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class ItemStack(
|
class ItemStack(
|
||||||
val item: Item,
|
val item: Item,
|
||||||
@ -54,7 +55,7 @@ class ItemStack(
|
|||||||
unbreakable: Boolean = false,
|
unbreakable: Boolean = false,
|
||||||
durability: Int = 0,
|
durability: Int = 0,
|
||||||
val nbt: MutableMap<String, Any> = synchronizedMapOf(),
|
val nbt: MutableMap<String, Any> = synchronizedMapOf(),
|
||||||
val container: Container? = null,
|
container: Container? = null,
|
||||||
hideFlags: Int = 0,
|
hideFlags: Int = 0,
|
||||||
) : TextFormattable {
|
) : TextFormattable {
|
||||||
var count = count
|
var count = count
|
||||||
@ -105,6 +106,17 @@ class ItemStack(
|
|||||||
field = value
|
field = value
|
||||||
apply()
|
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
|
// ToDo: Apply if enchantments, lore or nbt changes
|
||||||
|
|
||||||
@ -319,6 +331,33 @@ class ItemStack(
|
|||||||
val damageable: Boolean
|
val damageable: Boolean
|
||||||
get() = item.maxDamage > 0 || !unbreakable
|
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 {
|
companion object {
|
||||||
private const val HIDE_ENCHANTMENT_BIT = 0
|
private const val HIDE_ENCHANTMENT_BIT = 0
|
||||||
private const val HIDE_MODIFIERS_BIT = 1
|
private const val HIDE_MODIFIERS_BIT = 1
|
||||||
|
@ -41,6 +41,7 @@ open class Container(
|
|||||||
for ((slot, itemStack) in slots.toSynchronizedMap()) {
|
for ((slot, itemStack) in slots.toSynchronizedMap()) {
|
||||||
if (itemStack.count <= 0 || itemStack.durability < 0) {
|
if (itemStack.count <= 0 || itemStack.durability < 0) {
|
||||||
slots.remove(slot)
|
slots.remove(slot)
|
||||||
|
itemStack.container = null
|
||||||
changes = true
|
changes = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,13 +54,29 @@ open class Container(
|
|||||||
return slots[slotId]
|
return slots[slotId]
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun set(slotId: Int, itemStack: ItemStack?) {
|
fun remove(slotId: Int): ItemStack? {
|
||||||
if (itemStack == null) {
|
val itemStack = slots.remove(slotId) ?: return null
|
||||||
slots.remove(slotId) ?: return
|
itemStack.container = null
|
||||||
} else {
|
|
||||||
slots[slotId] = itemStack // ToDo: Check for changes
|
|
||||||
}
|
|
||||||
revision++
|
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() {
|
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.synchronizedMapOf
|
||||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
|
import java.lang.Integer.max
|
||||||
|
|
||||||
class ContainerItemsElement(
|
class ContainerItemsElement(
|
||||||
hudRenderer: HUDRenderer,
|
hudRenderer: HUDRenderer,
|
||||||
@ -24,17 +25,20 @@ class ContainerItemsElement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int {
|
override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int {
|
||||||
|
var maxZ = 0
|
||||||
for ((_, data) in itemElements.toSynchronizedMap()) {
|
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 {
|
override fun silentApply(): Boolean {
|
||||||
if (this.revision == container.revision) {
|
val revision = container.revision
|
||||||
|
if (this.revision == revision) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
this.revision = revision
|
||||||
|
|
||||||
var changes = false
|
var changes = false
|
||||||
for ((slot, binding) in slots) {
|
for ((slot, binding) in slots) {
|
||||||
@ -56,7 +60,7 @@ class ContainerItemsElement(
|
|||||||
changes = true
|
changes = true
|
||||||
} else {
|
} else {
|
||||||
if (data.element.item == item) {
|
if (data.element.item == item) {
|
||||||
if (data.element.poll()) {
|
if (data.element.silentApply()) {
|
||||||
changes = true
|
changes = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.gui.elements.items
|
package de.bixilon.minosoft.gui.rendering.gui.elements.items
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
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.ChatColors
|
||||||
import de.bixilon.minosoft.data.text.TextComponent
|
import de.bixilon.minosoft.data.text.TextComponent
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
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.Pollable
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments
|
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.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.elements.text.TextElement
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
|
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
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 {
|
override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int {
|
||||||
if (item == null) {
|
val item = item ?: return 0
|
||||||
return 0
|
|
||||||
}
|
|
||||||
val size = size
|
val size = size
|
||||||
val countSize = countText.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)
|
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
|
// ToDo: Render model
|
||||||
return 2
|
return TextElement.LAYERS + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun poll(): Boolean {
|
override fun poll(): Boolean {
|
||||||
|
@ -46,14 +46,14 @@ class HotbarBaseElement(hudRenderer: HUDRenderer) : Element(hudRenderer), Pollab
|
|||||||
base.render(offset + HORIZONTAL_MARGIN, z, consumer, options)
|
base.render(offset + HORIZONTAL_MARGIN, z, consumer, options)
|
||||||
|
|
||||||
baseAtlasElement.slots[selectedSlot + PlayerInventory.HOTBAR_OFFSET]?.let {
|
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
|
// ToDo: Item rendering
|
||||||
|
|
||||||
return 2 // bar + frame
|
return 2 + inventoryZ// bar + frame
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun poll(): Boolean {
|
override fun poll(): Boolean {
|
||||||
|
@ -216,11 +216,20 @@ class Camera(
|
|||||||
|
|
||||||
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> { recalculateViewProjectionMatrix() })
|
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> { recalculateViewProjectionMatrix() })
|
||||||
|
|
||||||
fun dropItem(type: BlockBreakC2SP.BreakType) {
|
fun dropItem(stack: Boolean) {
|
||||||
val time = System.currentTimeMillis()
|
val time = System.currentTimeMillis()
|
||||||
if (time - lastDropPacketSent < ProtocolDefinition.TICK_TIME) {
|
if (time - lastDropPacketSent < ProtocolDefinition.TICK_TIME) {
|
||||||
return
|
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))
|
connection.sendPacket(BlockBreakC2SP(type, connection.player.positionInfo.blockPosition))
|
||||||
lastDropPacketSent = time
|
lastDropPacketSent = time
|
||||||
}
|
}
|
||||||
@ -230,13 +239,13 @@ class Camera(
|
|||||||
mutableMapOf(
|
mutableMapOf(
|
||||||
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_Q),
|
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_Q),
|
||||||
),
|
),
|
||||||
)) { dropItem(BlockBreakC2SP.BreakType.DROP_ITEM) }
|
)) { dropItem(false) }
|
||||||
renderWindow.inputHandler.registerKeyCallback(DROP_ITEM_STACK_KEYBINDING, KeyBinding(
|
renderWindow.inputHandler.registerKeyCallback(DROP_ITEM_STACK_KEYBINDING, KeyBinding(
|
||||||
mutableMapOf(
|
mutableMapOf(
|
||||||
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_Q),
|
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_Q),
|
||||||
KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_LEFT_CONTROL)
|
KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_LEFT_CONTROL)
|
||||||
),
|
),
|
||||||
)) { dropItem(BlockBreakC2SP.BreakType.DROP_ITEM_STACK) }
|
)) { dropItem(true) }
|
||||||
frustum.recalculate()
|
frustum.recalculate()
|
||||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,11 @@ class ContainerItemSetS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
|||||||
override fun handle(connection: PlayConnection) {
|
override fun handle(connection: PlayConnection) {
|
||||||
connection.player.containers[containerId]?.set(slot, itemStack)
|
connection.player.containers[containerId]?.set(slot, itemStack)
|
||||||
|
|
||||||
|
// ToDo: Check for changes
|
||||||
connection.fireEvent(ContainerSlotChangeEvent(connection, this))
|
connection.fireEvent(ContainerSlotChangeEvent(connection, this))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun log() {
|
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