本帖最后由 tdiant 于 2023-3-31 10:35 编辑
PlayerDropItemEvent只能获取到丢出的物品,如何获取它是从物品栏里哪个槽位被丢出的呢。
PlayerDropItemEvent只能获取到丢出的物品,如何获取它是从物品栏里哪个槽位被丢出的呢。
本帖最后由 结冰的离季 于 2023-3-30 15:00 编辑
我能想到的就是 每tick 获取玩家背包的快照(每个位置对应哪个itemstack)
然后与上一tick的快照比较,就能知道背包的改动,但还得判断发生改动的物品是否是丢出的物品,所以还得配合
PlayerDropItemEvent,那么你还得知道是 快照先备份还是玩家先触发 PlayerDropItemEvent
如果是唯一的物品倒是可以 直接 Inventory::first(ItemStack) 去查
我能想到的就是 每tick 获取玩家背包的快照(每个位置对应哪个itemstack)
然后与上一tick的快照比较,就能知道背包的改动,但还得判断发生改动的物品是否是丢出的物品,所以还得配合
PlayerDropItemEvent,那么你还得知道是 快照先备份还是玩家先触发 PlayerDropItemEvent
如果是唯一的物品倒是可以 直接 Inventory::first(ItemStack) 去查
在这个时候获取玩家背包,玩家背包里的物品尚未被丢出,值得注意的是,它不一定需要把这个物品拿在手中才能丢弃。
结冰的离季 发表于 2023-3-30 14:54
我能想到的就是 每tick 获取玩家背包的快照(每个位置对应哪个itemstack)
然后与上一tick的快照比较,就能 ...
equals的话不用担心唯一的物品的问题吧,只有完全相同的itemstack才会equals
如果是打开物品栏,鼠标放在物品上按的Q,监听InventoryClickEvent事件,自然知道按的是哪个格子
对于没有打开物品栏按的Q,监听客户端发来的这个包PacketType.Play.Client.BLOCK_DIGhttps://wiki.vg/Protocol#Player_Action,在收到包的时机,玩家背包的getHeldItemSlot()就是要扔的格子了
对于没有打开物品栏按的Q,监听客户端发来的这个包PacketType.Play.Client.BLOCK_DIGhttps://wiki.vg/Protocol#Player_Action,在收到包的时机,玩家背包的getHeldItemSlot()就是要扔的格子了
青蛙的名单 发表于 2023-3-30 15:37
equals的话不用担心唯一的物品的问题吧,只有完全相同的itemstack才会equals
最近才讨论了这么一件事
耗子 发表于 2023-3-20 14:31
任何你从Bukkit API获取到的ItemStack,都是调用CraftItemStack.asCraftMirror创建了新的CraftItemStack对象。也就是说,就算游戏内物品是同一个,但由于Bukkit包装了一层的缘故,你永远获取到的是完全不同identityHashCode
无敌三脚猫 发表于 2023-3-30 15:49
如果是打开物品栏,鼠标放在物品上按的Q,监听InventoryClickEvent事件,自然知道按的是哪个格子
对于没有 ...
不一定是按下Q才能丢出,可能是在物品栏里点击了物品,把物品放到光标上,然后再点击物品栏界面外区域,将其丢掉。这种情况下就比较复杂了,比如说可以右键物品堆选中物品堆的一半,然后丢掉。在这种情况下,题主的这个问题实际上变成了追踪光标上的物品堆是从何而来的。
青蛙的名单 发表于 2023-3-30 15:37
equals的话不用担心唯一的物品的问题吧,只有完全相同的itemstack才会equals
ItemStack 的 equals 是 getAmount() == stack.getAmount() && isSimilar(stack)
所以两组 石头 是equals 的
我的个人建议是监听
Click Container
数据包,因为它真的会告诉很详尽的操作方式
Click Container
数据包,因为它真的会告诉很详尽的操作方式