Skip to content
This repository has been archived by the owner on May 27, 2024. It is now read-only.

Commit

Permalink
Bugfixes for non player instanced items
Browse files Browse the repository at this point in the history
  • Loading branch information
0ffz committed Aug 11, 2022
1 parent f236bb7 commit 6fda0bb
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 33 deletions.
39 changes: 16 additions & 23 deletions src/main/kotlin/com/mineinabyss/looty/LootyFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.mineinabyss.looty
import com.mineinabyss.geary.components.RegenerateUUIDOnClash
import com.mineinabyss.geary.datatypes.GearyEntity
import com.mineinabyss.geary.datatypes.GearyType
import com.mineinabyss.geary.helpers.NO_ENTITY
import com.mineinabyss.geary.helpers.addParent
import com.mineinabyss.geary.helpers.entity
import com.mineinabyss.geary.helpers.toGeary
Expand Down Expand Up @@ -43,26 +44,16 @@ object LootyFactory {
}
}

// fun addSlotTypeComponent(context: ItemLocation, entity: GearyEntity) = with(context) {
// entity.apply {
// remove<SlotType.Equipped>()
// remove<SlotType.Offhand>()
// remove<SlotType.Held>()
//
// when (slot) {
// in 36..39 -> add<SlotType.Equipped>()
// 40 -> add<SlotType.Offhand>()
// }
// if (slot == inventory.heldItemSlot) add<SlotType.Held>()
// }
// }

sealed class ItemState {
open val entity: GearyEntity? = null
abstract val entity: GearyEntity

class Loaded(override val entity: GearyEntity, val slot: Int, val pdc: PersistentDataContainer) : ItemState()
class Empty : ItemState()
class NotLoaded(val pdc: PersistentDataContainer) : ItemState()
class Empty : ItemState() {
override val entity: GearyEntity = NO_ENTITY
}
class NotLoaded(val slot: Int, val pdc: PersistentDataContainer) : ItemState() {
override val entity: GearyEntity = NO_ENTITY
}
}

private fun updateOldLootyItem(pdc: PersistentDataContainer, item: NMSItemStack) {
Expand All @@ -80,21 +71,23 @@ object LootyFactory {

//TODO maybe if the prefab has PlayerInstancedItem added to it, we should remove id?
fun getItemState(pdc: PersistentDataContainer?, slot: Int, item: NMSItemStack): ItemState {
if(pdc == null || item.item == Items.AIR) return ItemState.Empty()
if (pdc == null || item.item == Items.AIR) return ItemState.Empty()
if (LootyConfig.data.migrateByCustomModelData) {
updateOldLootyItem(pdc, item)
}
val prefabs = pdc.decodePrefabs()
if (prefabs.size == 1) {
val prefab = prefabs.first().toEntity()
return if (prefab.has<PlayerInstancedItem>()) {
if (prefab.has<PlayerInstancedItem>()) {
pdc.remove<UUID>()
ItemState.Loaded(prefab, slot, pdc)
} else ItemState.NotLoaded(pdc)
return ItemState.Loaded(prefab, slot, pdc)
} else if(pdc.decode<UUID>() == null) {
return ItemState.NotLoaded(slot, pdc)
}
}
val uuid = pdc.decode<UUID>()
if (uuid != null) {
val entity = globalContextMC.uuid2entity[uuid] ?: return ItemState.NotLoaded(pdc)
val entity = globalContextMC.uuid2entity[uuid] ?: return ItemState.NotLoaded(slot, pdc)
return ItemState.Loaded(entity, slot, pdc)
}
return ItemState.Empty()
Expand All @@ -109,7 +102,7 @@ object LootyFactory {
val prefabs = decoded.type.prefabs
if (prefabs.size == 1) {
val prefab = prefabs.first().toGeary()
return prefab
if (prefab.has<PlayerInstancedItem>()) return prefab
// cache.getInstance(prefab)?.let { return it }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mineinabyss.looty.ecs.components

import com.mineinabyss.geary.datatypes.GearyEntity
import com.mineinabyss.geary.helpers.NO_ENTITY
import com.mineinabyss.geary.helpers.toGeary
import com.mineinabyss.geary.prefabs.PrefabKey
import com.mineinabyss.idofront.nms.aliases.NMSItemStack
Expand All @@ -11,6 +12,7 @@ import org.bukkit.inventory.ItemStack
// TODO bad pattern, passing entity into component, move into event
class PlayerItemCache(parent: GearyEntity) {
private val entities = ULongArray(64)
private val cachedItems = Array<NMSItemStack?>(64) { null }
private val playerInstanced = PlayerInstancedItems(parent)

fun swap(firstSlot: Int, secondSlot: Int) {
Expand Down Expand Up @@ -47,6 +49,7 @@ class PlayerItemCache(parent: GearyEntity) {
val entity = entities[slot].toGeary()
if (entity.id == 0uL) return false
entities[slot] = 0uL
cachedItems[slot] = null
return if (entity.has<PlayerInstancedItem>())
playerInstanced.unsetSlot(entity, slot, removeEntity)
else if (removeEntity) {
Expand All @@ -65,10 +68,17 @@ class PlayerItemCache(parent: GearyEntity) {

fun getInstance(prefab: GearyEntity) = playerInstanced[prefab]

fun updateItem(entity: GearyEntity, item: NMSItemStack) {
fun updateItem(slot: Int, item: NMSItemStack) {
// Get the instance of the prefab if the entity is a prefab

cachedItems[slot] = item
val entity = entities[slot].toGeary()
if(entity == NO_ENTITY) return
val prefab = playerInstanced[entity]
(prefab ?: entity).set<ItemStack>(CraftItemStack.asCraftMirror(item))
}

fun getItem(slot: Int): NMSItemStack? {
return cachedItems[slot]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.mineinabyss.geary.annotations.Handler
import com.mineinabyss.geary.datatypes.forEachBit
import com.mineinabyss.geary.datatypes.pop1
import com.mineinabyss.geary.datatypes.setBit
import com.mineinabyss.geary.helpers.NO_ENTITY
import com.mineinabyss.geary.helpers.toGeary
import com.mineinabyss.geary.papermc.GearyMCContext
import com.mineinabyss.geary.papermc.GearyMCContextKoin
Expand Down Expand Up @@ -92,6 +91,7 @@ class ItemTrackerSystem : TickingSystem(interval = 1.ticks) {
// Set of new items looking for a possible old item to fill their heart :)
// val toMatch = mutableSetOf<Loaded>()
val toMatch = Array<Loaded?>(64) { null }
val toAdd = mutableSetOf<NotLoaded>()

fun attemptMove(loaded: Loaded): Boolean {
val id = loaded.entity.id.toLong()
Expand All @@ -111,22 +111,23 @@ class ItemTrackerSystem : TickingSystem(interval = 1.ticks) {
}

fun calculateForItem(item: NMSItemStack, slot: Int) {
// val currItem = cache.getItem(slot)
// if (currItem == item && item != ItemStack.EMPTY) return
val pdc = item.fastPDC
// Get uuid or prefab entity
val itemState = LootyFactory.getItemState(pdc, slot, item)
val currEntity = cache[slot]
// Based on them, check whether the item has changed
when (itemState) {
is Empty -> {}
is Loaded ->
if (currEntity != itemState.entity) toMatch[slot] = itemState
else cache.updateItem(slot, item) // Update ItemStack component to always lead to an up-to-date reference
is NotLoaded -> toAdd += itemState
}
if (currEntity != itemState.entity) {
when (itemState) {
is Empty -> if (currEntity == NO_ENTITY) return
is Loaded -> toMatch[slot] = itemState
is NotLoaded -> cache[slot] = LootyFactory.loadItem(player.toGeary(), itemState.pdc)
}
val currId = currEntity.id.toLong()
if (currId != 0L) toRemove[currId] = toRemove[currId].setBit(slot)
} else if (itemState is Loaded) {
// Update ItemStack component to always lead to an up-to-date reference
cache.updateItem(itemState.entity, item)
}
}

Expand All @@ -138,6 +139,7 @@ class ItemTrackerSystem : TickingSystem(interval = 1.ticks) {

// Consider cursor item as last slot
calculateForItem(player.toNMS().containerMenu.carried, 63)

// Try to match any changes with removed items, otherwise load them and update cache
for (loaded in toMatch) {
if (loaded == null) continue
Expand All @@ -154,7 +156,11 @@ class ItemTrackerSystem : TickingSystem(interval = 1.ticks) {
//TODO display entity name
debug("Removed $entity from ${player.name}")
}
}

// Add queued up items
toAdd.forEach {
cache[it.slot] = LootyFactory.loadItem(player.toGeary(), it.pdc)
}

// Set held item
Expand Down

0 comments on commit 6fda0bb

Please sign in to comment.