第一百四十四章 弹射物共通标签
张三刚刚费尽千辛万苦打死了一个在水中拿三叉戟射他的溺尸,并获得了一把残三叉戟。他试了试这个三叉戟,发现按右键是可以丢出它的。于是张三尝试了一下,“听”的一声,三叉戟就丢了出去。“当”的一声,三叉戟掉了下来。
三叉戟可以右键扔出,像这样可以右键扔出的东西,在Minecraft中还有雪球、鸡蛋。而箭这种需要用弓或弩射出的也是类似于这种东西。
这种可以射出、扔出、发射出的东西,我们给了他们一个总的称呼:弹射物。
既然都是弹射物,那肯定就有“弹射物共通标签”。
弹射物共通标签说白了就只有三个东西:两个布尔值一个Int整形数组。
首先我们看看这两个布尔值,它们分别是:
HasBeenShot(Byte字节型:1 或 0)
LeftOwner(Byte字节型:1 或 0)
HasBeenShot这个标签在弹射物最开始射出时为0(false),当该弹射物实体存在超过1游戏刻时会改为1(true)。为什么要这样?因为这样,游戏才能确保让你只射出去了一次该弹射物(这是一个游戏事件:br /rojectile_shoot)。如果没有这个标签会怎么样?
假设张三装了一个模组,该模组会在玩家每使用弹射物一次时,在玩家头顶20格处生成一个落地就会消失的铁砧,以增加游戏的挑战性。该模组是这样判断玩家使用弹射物的:
玩家右键射出弹射物时,会触发一个游戏事件:br /rojectile_shoot。模组监测到该事件被触发,就立刻执行生成铁砧的指令,然后就完成了这个玩法。
如果没有HasBeenShot这个标签,当张三右键扔出刚才那个三叉戟时,游戏就会开始每一游戏刻都触发一遍br /rojectile_shoot事件,模组每一游戏刻都监测到br /rojectile_shoot被触发,最后导致张三只能走不能停,甚至需要躲进矿洞里才能避免被铁砧砸死。这就是没有这个标签的后果。
那LeftOwner呢?这个比HasBeenShot要好理解些。当弹射物刚刚被射出时,它此时的碰撞箱和射出者的碰撞箱是重复的。游戏总不可能刚开始检测到碰撞箱重复就认为是弹射物打中实体吧?所以,为了防止张三刚刚扔出三叉戟就被三叉戟给刺死,LeftOwner最开始的值被设定为0(false),直到完全射出去之后再改为1(true)。
那这个标签这样做会发生什么?这个标签的用途就是设定该弹射物是否会与其他实体碰撞(简而言之就是会不会打中其他实体)。所以游戏才会用这个标签来避免发生乌龙。
最后,这个Int整形数组是:Owner。它的作用很简单:储存丢出该弹射物的人。它不一定存在,比如箭的NBT内就(好像)没有这个(作者看箭的NBT里没有)。那它有什么用呢?
举个例子。JAVA的死亡信息比基岩版的死亡信息要丰富(且搞笑)很多。比如张三用这个三叉戟杀死了李四,那么将会:
李四被张三刺穿了
为什么游戏知道这个三叉戟是张三射出的呢?答案就在于Owner存储了张三的UUID。翻一下这个三叉戟的NBT,你会发现这么一条:
{Owner:[I;604943943,800279987,-1589083251,1188657888]}
其中,[I;604943943,800279987,-1589083251,1188657888]就是张三的UUID。
但别忘了一件事情。1.16版本是把UUID高位和低位合并成了一个新的整形数组UUID。那在1.16版本以前,Owner是什么呢?难不成是{Owner:{UUIDMost:XXX,UUIDLeast:XXX}}?
都不对。实际上这比你们想的要简单许多。假设张三刚刚不是在1.16版本刺穿李四的,而是在1.13版本,那么你将会发现Owner变成了:
{ownerName:“张三“}
其中,“张三”是张三的游戏ID。没错,你没看错,是游戏ID!
好啊你个Mojang,这么偷懒,连UUID都不用了,直接上玩家名啊。
吐槽归吐槽,我们还是要研究一下Owner能搞出什么效果。
末影珍珠可以传送玩家。但当发射器射出末影珍珠时,反而传送不了发射器。这最主要的原因就是末影珍珠触碰到方块确定要传送的实体时是看Owner里存储的实体UUID的,而发射器不是实体所以没有UUID。如果在末影珍珠还在飞行的时候更改Owner存储的值从[I;604943943,800279987,-1589083251,1188657888]到[I;-1208925302,-1027194075,-1929403206,-1285938804],会发生什么?
李四落地过猛
这就是Owner的用法之一。