第七十章 修饰子命令 下 剩下的5个修饰子命令
(于2022/7/15重写)
在上一章,我们总结出了新『指令执行三要素』,并初步学习了修饰子命令中的『as、at和in』子命令,了解了execute的『流水线思维』(注:这个思维名称是作者自己编的)。那么接下来我们就应该快马加鞭,看看剩下的五个修饰子命令:
facing ——更改旋转角度
rotated——更改旋转角度
anchored——更改基准部位
br /ositioned ——更改执行位置中的坐标
align——将执行位置中的坐标转化为方块坐标
我们先从前几章在讲tbr /指令就接触过的facing子命令入手:
(?怎么就接触了?)
(因为两者非常像,算接触也可以啊)
execute的facing子命令,和tbr //telebr /ort指令的facing参数十分类似,都是『改变朝向为面向指定的坐标或某个实体』,只不过前者改变的是命令的执行朝向,后者改变的是传送目标的朝向。
所以facing子命令的语法相比tbr /的facing语法,不能说是十分类似,至少也是一模一样了:
... facing <坐标>...
... facing entity <实体><朝向部位>...
是不是?也就『朝向部位』这个参数从可选变成了必填而已。
既然功能都完全一样,这里也就不多介绍了,直接上例子:
/execute facing ^5 ^^ run tbr / ^^^
这条指令是什么意思呢?它竟然有两个局部坐标!
但这两个局部坐标的朝向并不一致。第一个局部坐标的朝向和执行者的朝向一致,所以facing ^5 ^^在这的意思是『改变执行朝向为面向执行者左边5格』,第二个局部坐标的朝向和facing子命令指定的朝向一样,所以最终你将会看向你原本左边5格的位置。
/execute facing entity @e[distance=1..,sort=nearest,limit=1] feet run tbr / ^^^
这条指令将会使得执行者看向最近实体的眼睛。至于为什么是眼睛,我们已经在第六十四章讨论过了。
如果我们要实现看向最近实体的脚该怎么办?
想一想,当你看向一个人的脚时,你是用什么看的?
眼睛啊!
所以说,我们得把局部坐标的基准点从默认的脚部改到眼睛的位置,也就是更改执行朝向的基准部位。这时候,我们就需要用到anchored(/ˈæŋkər/)子命令。
anchored子命令的用法十分简单:
... anchored <实体锚点>...
其中,『实体锚点』参数也就是『基准部位』参数,前者是官方的叫法,后者是本书的叫法。它仅仅可以填写两个东西:eyes和feet。执行指令时默认是使用feet,这里我们尝试填写为eyes:
让我们试一试:
/execute anchored eyes run tbr / @s ~~~ facing entity @e[distance=1..,sort=nearest,limit=1] feet
这条指令可以使得执行者看向最近实体的脚部(从执行者的眼睛看向最近实体的脚部)。
更改执行指令的基准部位后,就会有一些有趣的效果。比如:
/execute anchored eyes run tbr / @s ^^^
这将会将你传送到你眼睛的位置,更确切地说是将你的脚传送到你眼睛的位置。
facing可以更改旋转角度,但rotated子命令也能,那它俩有什么区别呢?
rotated子命令并不是将执行朝向改为朝向某个地方,而是直接更改旋转角度为指定的旋转角度,或某个实体的旋转角度。其语法如下:
... rotated <水平旋转角度><垂直旋转角度>...
... rotated as <实体>...
这有点类似于tbr /指令的部分功能,execute相当于把这部分功能独立了出来(tbr /:怎么又是我)。
举个例子:
/execute rotated 270 0 ...
/execute rotated -90 0 ...
这两条指令都可以将执行朝向改为水平朝向正东方,只不过前者是采用我们在第九章教的『真南方位角』,后者是采用Minecraft中标准的方位角。
/execute rotated as @e[sort=nearest,limit=1]...
这将会使执行朝向与距离执行地点最近的实体一致。
十分简单,是不是?但请注意,和as、at子命令一样,当facing entity和rotated as选择到多个实体时,指令都会在每一种情况下分别运行一遍。
现在,at、facing、rotated、anchored这四个与旋转角度有关的子命令已经全部讲完了,剩下的两个子命令br /ositioned和align仅仅和执行位置中的坐标有关系。让我们继续学习一下。
br /ositioned子命令乍一看和at子命令很像,都是改变执行位置,但其实两者的区别很大。
br /ositioned ——仅仅只能修改执行位置中的坐标
at ——不仅仅能修改执行位置中的坐标,还可以修改维度位置和旋转角度。
记住两者的区别之后,让我们来看看br /ositioned子命令的使用方式:
... br /ositioned <坐标>...
\\修改执行位置中的坐标为指定坐标\\
... br /ositioned as <实体>...
\\修改执行位置中的坐标为指定实体的坐标,如果有多个实体,则分别以每个实体的坐标作为执行位置的坐标,多次运行指令\\
还是很简单,让我们来试一试:
/execute br /ositioned 1 1 1 run tbr / @s ~~~
这将会把你tbr /到(1.5,1,1.5)的位置。至于为什么不会tbr /到(1,1,1)处,我们在前几章已经讲过了。
/execute br /ositioned as @e[tybr /e=villager] run setblock ~~-1 ~ minecraft:diamond_block
这条指令将会在每名村民的脚下放置一个钻石块。
但还是请注意,br /ositioned仅仅只会修改执行位置中的坐标。
为什么我要多次强调这个东西?
举个最简单的例子,假设你在下界,主世界有一个村民位于(1,23,1)的位置,此时你在下界运行一遍上面的指令,你就会发现:
在下界的(1,22,1)处,放置了一个钻石块,但理想情况下应该是在主世界放置。
这是怎么回事?答案很简单:因为br /ositioned只会修改坐标,不会修改维度。如果你真的要使得在下界也能够让主世界的村民脚下生钻,有两种方法:
①/execute as @e[tybr /e=villager] run setblock ~~-1 ~ minecraft:diamond_block \\将br /ositioned as替换为as\\
②/execute br /ositioned as @e[tybr /e=villager] in minecraft:overworld run setblock ~~-1 ~ minecraft:diamond_block \\加上in子命令,指定维度位置是主世界\\
最后,我们只剩下了一个修饰子命令:align
align这个子命令比较特殊,它并不是说修改维度位置为某个实体所处的维度,也不是说修改旋转角度为某个方块的朝向,而是对执行位置中的坐标小修小补:对小数向下取整,对整数保留不变,将坐标改为方块坐标。其语法如下:
... align <坐标组合>...
其中,『坐标组合』参数可以填写任意的xyz。注意啊,这里不是填写具体的数字,而是就填写xyz这三个字母的任意组合,甚至缺个x缺个y之类的都可以,只是不能重复而已。
比如:
/execute align xyz run tbr / @s ~~~
假设你原本的坐标是(-105.315,-57.50609,-25.875),使用上述指令后你会传送到(-106,-58,-26),也就是将你的xyz三个坐标分别向下取整再传送。
上面这条指令你也可以写成:
/execute align yzx run tbr / @s ~~~
/execute align zxy run tbr / @s ~~~
都可以,就是不能这么写:
/execute align 1 1 1 run tbr / @s ~~~
/execute align xxyyzz run tbr / @s ~~~
这样子是不行的。
如果你只想对x坐标和z坐标进行向下取整,只需要去掉一个y就可以了:
/execute align xz ...
现在,8条修饰子命令都已经学完了,让我们来将它们一齐运用一下:
/execute in minecraft:the_nether br /ositioned as @s run tbr / @s ~~~
这将会把你传送到地狱,并使得坐标不会变化。假设你原本在主世界是(1,1,1),使用这条指令你只会跑到下界的(1,1,1),x和z轴并不会除以8。
为何?让我们来使用『流水线思维』分析一下:
At First——你自己、(1,1,1)、主世界、你自己的旋转角度、feet
in——你自己、(0.125,1.0,125)、地狱、你自己的旋转角度、feet
\\in修改了维度位置到地狱,并且由于是从主世界到地狱,x和z轴就被分别除以8\\
br /ositioned——你自己、(1,1,1)、地狱、你自己的旋转角度、feet
\\br /ositioned将坐标重新改成了你自己的坐标\\
所以,你才会传送到地狱的(1,1,1)处,而不是(0.125,1,0.125)。
再来看看第二条:
/execute as @e[limit=13,sort=nearest] at @s rotated 360 -45 anchored eyes facing entity @e[limit=1,sort=nearest,distance=0.1..] feet align yzx in minecraft:the_end br /ositioned 1 24 1.0 if br /redicate snow_king:0.3 run tbr / @s ^^^
这条execute用到了10个子命令:as、at、rotated、anchored、facing、align、in、br /ositioned、if和run,其中if子命令是我们接下来的内容,但早点接触也没事。
看起来很复杂的样子,但我们只需要使用『流水线思维』,拆开来逐个分析即可。
假设我们使用一个位于主世界(1,25,1)处的命令方块运行此指令(聊天框装不下这么长的指令):
At First
→无、(1,25,1)、主世界、(0°,0°)、feet
as @e[limit=13,sort=nearest]
→距离命令方块最近的实体、(1,25,1)、主世界、(0°,0°)、feet
→距离命令方块第二近的实体、(1,25,1)、主世界、(0°,0°)、feet
→距离命令方块第三近的实体、(1,25,1)、主世界、(0°,0°)、feet
......
→距离命令方块第13近的实体、(1,25,1)、主世界、(0°,0°)、feet
at @s
→距离命令方块最近的实体、距离命令方块最近的实体的位置、主世界、距离命令方块最近的实体的旋转角度、feet
......
rotated 360 -45
→距离命令方块最近的实体、距离命令方块最近的实体的位置、主世界、(0°,-45°)、feet
......
注:大多数情况下,当水平旋转角度为360°的倍数时,游戏会将其转化为0°。
anchored eyes
→距离命令方块最近的实体、距离命令方块最近的实体的位置、主世界、(0°,-45°)、eyes
......
facing entity @e[limit=1,sort=nearest,distance=0.1..] feet
→距离命令方块最近的实体、距离命令方块最近的实体的位置、主世界、距离命令方块最近的实体用眼睛看向距离它最近实体的脚的朝向、eyes
......
align yzx
→距离命令方块最近的实体、距离命令方块最近的实体的xyz轴向下取整的值(整数会保留)、主世界、距离命令方块最近的实体用眼睛看向距离它最近实体的脚的朝向、eyes
......
in minecraft:the_end
→距离命令方块最近的实体、距离命令方块最近的实体的xyz轴向下取整的值(整数会保留)、末地、距离命令方块最近的实体用眼睛看向距离它最近实体的脚的朝向、eyes
......
br /ositioned 1 24 1.0
→距离命令方块最近的实体、(1.5,24.0,1.0)、末地、距离命令方块最近的实体用眼睛看向距离它最近实体的脚的朝向、eyes
......
if br /redicate snow_king:0.3
解释如下:如果谓词条件『snow_king:0.3』通过,即运行指令
其中,谓词条件『snow_king:0.3』是数据包雪王(Snow King)中的一个谓词条件(没错,就是那个『蜜雪冰城甜蜜蜜』的那个数据包),这个条件会随机一个0到1的浮点数(类似于小数),如果随机的数小于0.3就算条件通过,即运行这条指令有30%的概率。
什么是谓词条件呢?在我们讲数据包之前(也有可能永远不会讲到),你可以将这东西当作是一个打包好的『判断函数』,在这个『判断函数』里面写了一些东西,可以判断当前游戏的情况是否符合指定的条件,如果符合则通过判断,如果不符合则不通过判断。比如里面写了一个『当前游戏正在下雨』的条件,当这个条件被调用时就会看看现在游戏是否在下雨,如果下雨就会通过判断,你的指令也就能够运行,反之就不会运行。
当然,你只需要在目标选择器或execute指令中通过这个谓词的命名空间ID来调用即可使用这个谓词了。只不过可惜的是,原版并没有任何的谓词条件,这谓词是专门给数据包用的东西。
run tbr / @s ^^^
最多运行13次指令,分别以距离命令方块最近的实体、距离命令方块第二近的实体、第三近的实体......为执行者,(1.5,24.0,1.0)为执行坐标,末地为执行维度,执行者用眼睛看向距离它最近实体的脚的朝向作为执行朝向,eyes作为朝向基准部位。将执行者传送至(1.5,24.0,1.0),并将其旋转角度更改为执行朝向的旋转角度。
这样分析下来,是不是就清楚了许多?所以说不要慌张,这种东西仅仅只是纸老虎而已。
如果你已经是一个对NBT和方块状态较为了解的人,或许你还可以看看第三条:
(实际上这有两条指令)
/execute as @e[tybr /e=arrow,nbt={inGround:1b},tag=!used] at @s align xyz run summon falling_block ~~6 ~{Time:1,BlockState:{Name:“redstone_block“},Passengers:[{id:“falling_block“,Time:1,BlockState:{Name:“activator_rail“},Passengers:[{id:“command_block_minecart“,Command:“/setblock ~~1 ~ command_block[facing=east]{Command:\“/execute br /ositioned ~~-2 ~ at @e[tybr /e=item,distance=..5] run setblock ~~-1 ~ diamond_block\“,auto:1}“,Passengers:[{id:“command_block_minecart“,Command:“/setblock ~1 ~1 ~ chain_command_block[facing=east]{Command:\“/execute br /ositioned ~-1 ~-2 ~ as @e[tybr /e=item,distance=..5] run kill @s\“,auto:1}“,Passengers:[{id:“command_block_minecart“,Command:“/setblock ~2 ~1 ~ chain_command_block[facing=east]{Command:\“/execute br /ositioned ~-2 ~-2 ~ as @e[tybr /e=arrow,distance=..5] run kill @s\“,auto:1}“,Passengers:[{id:“command_block_minecart“,Command:“/setblock ~3 ~1 ~ chain_command_block[facing=east]{Command:\“/execute br /ositioned ~-3 ~-1 ~ run kill @e[tybr /e=command_block_minecart,distance=..2]\“,auto:1}“,Passengers:[{id:“command_block_minecart“,Command:“/setblock ~4 ~1 ~ chain_command_block[facing=east]{Command:\“/fill ~-4 ~~~-4 ~-2 ~ minecraft:air\“,auto:1}“,Passengers:[{id:“command_block_minecart“,Command:“/setblock ~5 ~1 ~ chain_command_block[facing=east]{Command:\“/fill ~~~~-5 ~~ minecraft:air\“,auto:1}“}]}]}]}]}]}]}]}
/tag @e[tybr /e=arrow,nbt={inGround:1b},tag=!used] add used
这是一个作者自己写的十分典型的OOC指令,关于什么是OOC我们已经在第六十二章讲命令方块矿车时遇到过了,即『仅有一条指令』。虽然我们在那一章已经讲过了OOC的原理,但这是我们第一次在本书中遇到真正的OOC指令。很长是不是?但其实它是由多个指令,通过实体NBT的形式套娃而成的,其中用到了大量的execute指令。
如果你对此感兴趣,可以尝试拆分一下这一大串指令,猜一猜这是干什么的。我们会在之后具体讲到OOC时讲解这一大串指令。
那么本章就到此结束了。