mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-19 04:15:14 -04:00
more container and gui fixes
This commit is contained in:
parent
63cdc8abf0
commit
44ffd1c41b
@ -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++
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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? {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
|
@ -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, ...)")
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user