第一百四十四章 弹射物共通标签

张三刚刚费尽千辛万苦打死了一个在水中拿三叉戟射他的溺尸,并获得了一把残三叉戟。他试了试这个三叉戟,发现按右键是可以丢出它的。于是张三尝试了一下,“听”的一声,三叉戟就丢了出去。“当”的一声,三叉戟掉了下来。

三叉戟可以右键扔出,像这样可以右键扔出的东西,在minecraft中还有雪球、鸡蛋。而箭这种需要用弓或弩射出的也是类似于这种东西。

这种可以射出、扔出、发射出的东西,我们给了他们一个总的称呼:弹射物。

既然都是弹射物,那肯定就有“弹射物共通标签”。

弹射物共通标签说白了就只有三个东西:两个布尔值一个int整形数组。

首先我们看看这两个布尔值,它们分别是:

hasbeenshot(byte字节型:1 或 0)

leftowner(byte字节型:1 或 0)

hasbeenshot这个标签在弹射物最开始射出时为0(false),当该弹射物实体存在超过1游戏刻时会改为1(true)。为什么要这样?因为这样,游戏才能确保让你只射出去了一次该弹射物(这是一个游戏事件:projectile_shoot)。如果没有这个标签会怎么样?

假设张三装了一个模组,该模组会在玩家每使用弹射物一次时,在玩家头顶20格处生成一个落地就会消失的铁砧,以增加游戏的挑战性。该模组是这样判断玩家使用弹射物的:

玩家右键射出弹射物时,会触发一个游戏事件:projectile_shoot。模组监测到该事件被触发,就立刻执行生成铁砧的指令,然后就完成了这个玩法。

如果没有hasbeenshot这个标签,当张三右键扔出刚才那个三叉戟时,游戏就会开始每一游戏刻都触发一遍projectile_shoot事件,模组每一游戏刻都监测到projectile_shoot被触发,最后导致张三只能走不能停,甚至需要躲进矿洞里才能避免被铁砧砸死。这就是没有这个标签的后果。

那leftowner呢?这个比hasbeenshot要好理解些。当弹射物刚刚被射出时,它此时的碰撞箱和射出者的碰撞箱是重复的。游戏总不可能刚开始检测到碰撞箱重复就认为是弹射物打中实体吧?所以,为了防止张三刚刚扔出三叉戟就被三叉戟给刺死,leftowner最开始的值被设定为0(false),直到完全射出去之后再改为1(true)。

那这个标签这样做会发生什么?这个标签的用途就是设定该弹射物是否会与其他实体碰撞(简而言之就是会不会打中其他实体)。所以游戏才会用这个标签来避免发生乌龙。

最后,这个int整形数组是:owner。它的作用很简单:储存丢出该弹射物的人。它不一定存在,比如箭的nbt内就(好像)没有这个(作者看箭的nbt里没有)。那它有什么用呢?

举个例子。java的死亡信息比基岩版的死亡信息要丰富(且搞笑)很多。比如张三用这个三叉戟杀死了李四,那么将会:

李四被张三刺穿了

为什么游戏知道这个三叉戟是张三射出的呢?答案就在于owner存储了张三的uuid。翻一下这个三叉戟的nbt,你会发现这么一条:

{owner:[i;,,-,]}

其中,[i;,,-,]就是张三的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;,,-,]到[i;-,-,-,-],会发生什么?

李四落地过猛

这就是owner的用法之一。

上一章目录+书架下一章