fix some inventory actions, make ItemStack::copy is non locking

This commit is contained in:
Bixilon 2022-02-26 16:11:02 +01:00
parent 4917de4c00
commit 63cdc8abf0
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
8 changed files with 64 additions and 20 deletions

View File

@ -53,11 +53,12 @@ class FastMoveContainerAction(
}
}
val changes: Int2ObjectOpenHashMap<ItemStack> = Int2ObjectOpenHashMap()
for ((slot, content) in targets) {
for ((slot, content) in targets.toSortedMap()) {
if (content == null) {
changes[slot] = source
changes[this.slot] = null
container._set(slot, source)
container._set(this.slot, null)
break
}
val countToPut = source.item._count - (source.item.item.maxStackSize - content.item._count)
@ -73,6 +74,7 @@ class FastMoveContainerAction(
connection.sendPacket(ContainerClickC2SP(containerId, container.serverRevision, this.slot, 1, 0, container.createAction(this), changes, previous))
} finally {
container.commit()
container._validate()
}
}
}

View File

@ -36,7 +36,7 @@ class SimpleContainerAction(
floatingItem = item
} else {
// half
val stayCount = maxOf(item.item.count / 2, 1)
val stayCount = item.item.count / 2
item.item.count = stayCount
floatingItem = previous.copy(count = previous.item.count - stayCount)
}
@ -59,14 +59,24 @@ class SimpleContainerAction(
val slotType = container.getSlotType(slot)
if (target != null && floatingItem.matches(target)) {
if (slotType?.canPut(container, slot, floatingItem) != true) {
// is this check needed?
return
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) {
return
}
target.item._count += subtract
floatingItem.item._count -= subtract
} else if (slotType?.canRemove(container, slot, floatingItem) == true) {
// remove only (e.g. crafting result)
// ToDo: respect count
val subtract = minOf(floatingItem.item.item.maxStackSize - floatingItem.item._count, target.item._count)
if (subtract == 0) {
return
}
target.item._count -= subtract
floatingItem.item._count += subtract
}
// merge
val subtract = minOf(target.item.item.maxStackSize - target.item._count, floatingItem.item._count)
target.item._count += subtract
floatingItem.item._count -= subtract
connection.sendPacket(ContainerClickC2SP(containerId, container.serverRevision, slot, 0, count.ordinal, container.createAction(this), mapOf(slot to target), target))
return
@ -78,8 +88,13 @@ class SimpleContainerAction(
return
}
// swap
container.floatingItem = target
container._set(slot, floatingItem)
if (count == ContainerCounts.ALL) {
container.floatingItem = target
container._set(slot, floatingItem)
} else {
floatingItem.item._count--
container._set(slot, floatingItem.copy(count = 1))
}
connection.sendPacket(ContainerClickC2SP(containerId, container.serverRevision, slot, 0, count.ordinal, container.createAction(this), mapOf(slot to target), target))
} finally {
floatingItem.commit()

View File

@ -37,7 +37,7 @@ class DisplayProperty(
var _customDisplayName = customDisplayName
var customDisplayName by InventoryDelegate(stack, this::_customDisplayName)
var _dyeColor = dyedColor
var dyedColor by InventoryDelegate(stack, this::_dyeColor)
var dyeColor by InventoryDelegate(stack, this::_dyeColor)
init {
@ -80,8 +80,8 @@ class DisplayProperty(
fun copy(
stack: ItemStack,
lore: MutableList<ChatComponent> = this.lore.toMutableList(),
customDisplayName: ChatComponent? = this.customDisplayName,
dyedColor: RGBColor? = this.dyedColor,
customDisplayName: ChatComponent? = this._customDisplayName,
dyedColor: RGBColor? = this._dyeColor,
): DisplayProperty {
return DisplayProperty(stack, lore, customDisplayName, dyedColor)
}

View File

@ -81,8 +81,8 @@ class DurabilityProperty(
fun copy(
stack: ItemStack,
unbreakable: Boolean = this.unbreakable,
durability: Int = this.durability,
unbreakable: Boolean = this._unbreakable,
durability: Int = this._durability,
): DurabilityProperty {
return DurabilityProperty(stack, unbreakable, durability)
}

View File

@ -95,7 +95,7 @@ class EnchantingProperty(
fun copy(
stack: ItemStack,
enchantments: MutableMap<Enchantment, Int> = this.enchantments.toMutableMap(),
repairCost: Int = this.repairCost,
repairCost: Int = this._repairCost,
): EnchantingProperty {
return EnchantingProperty(stack, enchantments, repairCost)
}

View File

@ -90,7 +90,7 @@ class HideProperty(
fun copy(
stack: ItemStack,
hideFlags: Int = this.hideFlags,
hideFlags: Int = this._hideFlags,
): HideProperty {
return HideProperty(stack, hideFlags)
}

View File

@ -14,6 +14,8 @@
package de.bixilon.minosoft.data.container.types.generic
import de.bixilon.minosoft.data.container.Container
import de.bixilon.minosoft.data.container.slots.DefaultSlotType
import de.bixilon.minosoft.data.container.slots.SlotType
import de.bixilon.minosoft.data.registries.other.containers.ContainerType
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@ -23,4 +25,29 @@ abstract class GenericContainer(
connection: PlayConnection,
type: ContainerType,
title: ChatComponent?,
) : Container(connection, type, title)
) : Container(connection, type, title) {
override val sections: Array<IntRange> = arrayOf(0 until rows * SLOTS_PER_ROW, rows * SLOTS_PER_ROW until rows * SLOTS_PER_ROW + INVENTORY_SLOTS)
override fun getSlotType(slotId: Int): SlotType? {
if (slotId in 0 until rows * SLOTS_PER_ROW + INVENTORY_SLOTS) {
return DefaultSlotType
}
return null
}
override fun getSection(slotId: Int): Int? {
if (slotId in 0 until rows * SLOTS_PER_ROW) {
return 0
}
if (slotId in rows * SLOTS_PER_ROW until rows * SLOTS_PER_ROW + INVENTORY_SLOTS) {
return 1
}
return null
}
companion object {
const val SLOTS_PER_ROW = 9
const val INVENTORY_SLOTS = 4 * SLOTS_PER_ROW
}
}

View File

@ -332,7 +332,7 @@ abstract class Entity(
this is PlayerEntity -> {
val chestPlate = equipment[EquipmentSlots.CHEST]
if (chestPlate != null && chestPlate.item.item is DyeableArmorItem) {
chestPlate._display?.dyedColor?.let { return it }
chestPlate._display?.dyeColor?.let { return it }
}
val formattingCode = tabListItem.team?.formattingCode
if (formattingCode is RGBColor) {