more container and gui fixes

This commit is contained in:
Bixilon 2022-02-26 17:28:27 +01:00
parent 63cdc8abf0
commit 44ffd1c41b
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
13 changed files with 104 additions and 85 deletions

View File

@ -166,17 +166,16 @@ open class Container(
}
}
fun clear() {
lock.lock()
val size = slots.size
if (size == 0) {
lock.unlock()
return
}
fun _clear() {
for (stack in slots.values) {
stack.holder?.container = null
}
slots.clear()
}
fun clear() {
lock.lock()
_clear()
lock.unlock()
revision++
}

View File

@ -57,12 +57,14 @@ class SimpleContainerAction(
return connection.sendPacket(ContainerClickC2SP(containerId, container.serverRevision, null, 0, count.ordinal, container.createAction(this), mapOf(), null))
}
val slotType = container.getSlotType(slot)
val matches = floatingItem.matches(target)
if (target != null && floatingItem.matches(target)) {
if (target != null && matches) {
if (slotType?.canPut(container, slot, floatingItem) == true) {
// merge
val subtract = if (count == ContainerCounts.ALL) minOf(target.item.item.maxStackSize - target.item._count, floatingItem.item._count) else 1
if (subtract == 0) {
// ToDo: Check stack size
if (subtract == 0 || target.item._count + subtract > target.item.item.maxStackSize) {
return
}
target.item._count += subtract
@ -88,7 +90,7 @@ class SimpleContainerAction(
return
}
// swap
if (count == ContainerCounts.ALL) {
if (count == ContainerCounts.ALL || !matches) {
container.floatingItem = target
container._set(slot, floatingItem)
} else {

View File

@ -42,7 +42,7 @@ class PlayerInventory(connection: PlayConnection) : Container(connection = conne
fun getHotbarSlot(hotbarSlot: Int = connection.player.selectedHotbarSlot): ItemStack? {
check(hotbarSlot in 0..HOTBAR_SLOTS) { "Hotbar slot out of bounds!" }
return slots[hotbarSlot + HOTBAR_OFFSET]
return this[hotbarSlot + HOTBAR_OFFSET]
}
operator fun get(slot: InventorySlots.EquipmentSlots): ItemStack? {
@ -54,10 +54,10 @@ class PlayerInventory(connection: PlayConnection) : Container(connection = conne
}
operator fun get(hand: Hands): ItemStack? {
return get(when (hand) {
return this[(when (hand) {
Hands.MAIN -> InventorySlots.EquipmentSlots.MAIN_HAND
Hands.OFF -> InventorySlots.EquipmentSlots.OFF_HAND
})
})]
}
@JvmName("setEquipment")
@ -68,7 +68,7 @@ class PlayerInventory(connection: PlayConnection) : Container(connection = conne
realSlots += Pair(slot.slot, itemStack)
}
super.set(*realSlots.toTypedArray())
set(*realSlots.toTypedArray())
}
override fun getSlotType(slotId: Int): SlotType? {

View File

@ -63,7 +63,7 @@ class GUIRenderer(
val shader = renderWindow.renderSystem.createShader("minosoft:hud".toResourceLocation())
val atlasManager = AtlasManager(renderWindow)
var currentCursorPosition: Vec2i by watched(Vec2i.EMPTY)
var currentMousePosition: Vec2i by watched(Vec2i.EMPTY)
private set
override fun init(latch: CountUpAndDownLatch) {
@ -114,7 +114,7 @@ class GUIRenderer(
override fun onMouseMove(position: Vec2i): Boolean {
val scaledPosition = position.scale()
currentCursorPosition = scaledPosition
currentMousePosition = scaledPosition
if (dragged.onMouseMove(scaledPosition)) {
return true
}

View File

@ -40,13 +40,13 @@ class ContainerItemsElement(
override var activeDragElement: ItemElement? = null
private var update = true
set(value) {
if (value) {
cacheUpToDate = false
}
if (field == value) {
return
}
field = value
if (value) {
cacheUpToDate = false
}
}
init {

View File

@ -50,10 +50,7 @@ class RawItemElement(
return
}
if (value != null) {
value::revision.observe(this) { forceSilentApply() }
}
if (field == value) {
return
value::revision.observe(this) { if (value === field) forceSilentApply() } // ToDo: check if watcher is still up-to-date
}
field = value
forceSilentApply()

View File

@ -231,7 +231,7 @@ class GUIManager(
}
elementOrder.add(0, element)
element.onOpen()
onMouseMove(guiRenderer.currentCursorPosition)
onMouseMove(guiRenderer.currentMousePosition)
}
@Deprecated("Only use for dynamic gui (e.g. dialogs, ...)")

View File

@ -110,9 +110,6 @@ open class GUIMeshElement<T : Element>(
}
override fun onCharPress(char: Int): Boolean {
if (lastPosition == null) {
return false
}
return element.onCharPress(char)
}
@ -122,8 +119,8 @@ open class GUIMeshElement<T : Element>(
}
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
val position = lastPosition ?: return false
val mouseButton = MouseButtons[key] ?: return element.onKey(key, type)
val position = lastPosition ?: return false
val mouseAction = MouseActions[type] ?: return false
return element.onMouseAction(position, mouseButton, mouseAction)
@ -144,8 +141,8 @@ open class GUIMeshElement<T : Element>(
}
override fun onDragKey(type: KeyChangeTypes, key: KeyCodes, dragged: Dragged): Element? {
val position = lastDragPosition ?: return null
val mouseButton = MouseButtons[key] ?: return element.onDragKey(key, type, dragged)
val position = lastDragPosition ?: return null
val mouseAction = MouseActions[type] ?: return null
return element.onDragMouseAction(position, mouseButton, mouseAction, dragged)
@ -156,9 +153,6 @@ open class GUIMeshElement<T : Element>(
}
override fun onDragChar(char: Int, dragged: Dragged): Element? {
if (lastDragPosition == null) {
return null
}
return element.onDragChar(char.toChar(), dragged)
}
@ -171,7 +165,7 @@ open class GUIMeshElement<T : Element>(
override fun onOpen() {
element.onOpen()
onMouseMove(guiRenderer.currentCursorPosition)
onMouseMove(guiRenderer.currentMousePosition)
}
override fun onHide() {

View File

@ -19,7 +19,7 @@ import glm_.vec2.Vec2i
class DraggedGUIElement<T : Dragged>(element: T) : GUIMeshElement<T>(element) {
override fun prepare() {
prepare(guiRenderer.currentCursorPosition - (element.size / 2))
prepare(guiRenderer.currentMousePosition - (element.size / 2))
}
override fun onMouseMove(position: Vec2i): Boolean {

View File

@ -35,13 +35,17 @@ class DraggedManager(
if (field == value || field?.element == value?.element) {
return
}
val position = guiRenderer.currentCursorPosition
val position = guiRenderer.currentMousePosition
val previous = field
previous?.element?.onDragEnd(position, guiRenderer.gui.onDragMove(Vec2i(-1, -1), previous.element))
field = value
guiRenderer.gui.onMouseMove(Vec2i(-1, -1)) // move mouse ot
value?.element?.onDragStart(position, guiRenderer.gui.onDragMove(position, value.element))
if (value == null) {
guiRenderer.gui.onMouseMove(position)
} else {
guiRenderer.gui.onMouseMove(Vec2i(-1, -1)) // move mouse out
value.element.onDragStart(position, guiRenderer.gui.onDragMove(position, value.element))
}
applyCursor()
}
override var lastTickTime: Long = -1L
@ -114,14 +118,14 @@ class DraggedManager(
}
val mouseAction = MouseActions[type] ?: return false
element.element.onDragMouseAction(guiRenderer.currentCursorPosition, mouseButton, mouseAction, target)
element.element.onDragMouseAction(guiRenderer.currentMousePosition, mouseButton, mouseAction, target)
return true
}
override fun onScroll(scrollOffset: Vec2d): Boolean {
val element = element ?: return false
val target = guiRenderer.gui.onDragScroll(scrollOffset, element.element)
element.element.onDragScroll(guiRenderer.currentCursorPosition, scrollOffset, target)
element.element.onDragScroll(guiRenderer.currentMousePosition, scrollOffset, target)
return true
}
}

View File

@ -46,7 +46,7 @@ class ChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRenderer) {
field = value
messages._active = value
messages.forceSilentApply()
historyIndex = -1
historyIndex = history.size + 1
forceApply()
}
override var skipDraw: Boolean

View File

@ -77,15 +77,7 @@ class InteractInteractionHandler(
}
// if out of world (border): return CONSUME
connection.sendPacket(BlockInteractC2SP(
position = target.blockPosition,
direction = target.direction,
cursorPosition = Vec3(target.hitPosition),
item = stack,
hand = hand,
insideBlock = false, // ToDo: insideBlock
))
try {
if (connection.player.gamemode == Gamemodes.SPECTATOR) {
return InteractionResults.SUCCESS
}
@ -103,6 +95,16 @@ class InteractInteractionHandler(
}
return stack.item.item.interactBlock(connection, target, hand, stack)
} finally {
connection.sendPacket(BlockInteractC2SP(
position = target.blockPosition,
direction = target.direction,
cursorPosition = Vec3(target.hitPosition),
item = stack,
hand = hand,
insideBlock = false, // ToDo: insideBlock
))
}
}
fun interactEntityAt(target: EntityTarget, hand: Hands): InteractionResults {
@ -119,7 +121,7 @@ class InteractInteractionHandler(
fun interactEntity(target: EntityTarget, hand: Hands): InteractionResults {
val player = connection.player
connection.sendPacket(EntityEmptyInteractC2SP(connection, target.entity, hand, player.isSneaking))
try {
if (player.gamemode == Gamemodes.SPECTATOR) {
return InteractionResults.PASS
@ -127,6 +129,9 @@ class InteractInteractionHandler(
// ToDo: return hit.entity.interact(hand) (e.g. equipping saddle)
return InteractionResults.PASS
} finally {
connection.sendPacket(EntityEmptyInteractC2SP(connection, target.entity, hand, player.isSneaking))
}
}
fun interactItem(item: ItemStack, hand: Hands): InteractionResults {
@ -136,8 +141,7 @@ class InteractInteractionHandler(
val player = connection.player
connection.sendPacket(PositionRotationC2SP(player.position, player.rotation, player.onGround))
// ToDo: Before 1.9
connection.sendPacket(UseItemC2SP(hand))
try {
if (interactionManager.isCoolingDown(item.item.item)) {
return InteractionResults.PASS
@ -145,6 +149,10 @@ class InteractInteractionHandler(
return item.item.item.interactItem(connection, hand, item)
} finally {
// ToDo: Before 1.9
connection.sendPacket(UseItemC2SP(hand))
}
}
fun useItem() {

View File

@ -14,6 +14,8 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.container
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
import de.bixilon.kutil.collections.map.SynchronizedMap
import de.bixilon.minosoft.data.container.Container
import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
@ -43,15 +45,9 @@ class ContainerItemsS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
null
}
override fun handle(connection: PlayConnection) {
val container = connection.player.containers[containerId]
val slots = if (container == null) {
synchronizedMapOf()
} else {
container.lock.lock()
container.slots.clear()
container.slots
}
private fun pushIncompleteContainer(connection: PlayConnection) {
val slots: SynchronizedMap<Int, ItemStack> = synchronizedMapOf()
for ((slotId, stack) in this.items.withIndex()) {
if (stack == null) {
@ -60,10 +56,29 @@ class ContainerItemsS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
slots[slotId] = stack
}
if (container == null) {
connection.player.incompleteContainers[containerId] = slots.unsafeCast()
} else {
}
private fun updateContainer(container: Container) {
container.lock.lock()
container._clear()
for ((slotId, stack) in this.items.withIndex()) {
if (stack == null) {
continue
}
container._set(slotId, stack)
}
container.lock.unlock()
container.revision++
}
override fun handle(connection: PlayConnection) {
val container = connection.player.containers[containerId]
if (container == null) {
pushIncompleteContainer(connection)
} else {
updateContainer(container)
}
}