【1.13】新版本execute嵌套的改变

我们先来看看一个例子再解释发生了什么
比如说现在有两个盔甲架,下面简称AMS(为什么不是AS?因为1.13有个execute as的子命令,避免混淆)

这是F3 debug界面,高亮部分显示的是 渲染实体数(不含玩家)/  含玩家总实体数
然后我们执行这个exe嵌套命令

  1. /execute @e[type=armor_stand] ~ ~ ~ execute @e[type=armor_stand] ~ ~ ~ summon armor_stand

复制代码

执行结果如下


一共8个AMS


然而在1.13版本(其实是快照啦)下,相同的两个AMS,运行

  1. /execute as @e[type=armor_stand] run execute as @e[type=armor_stand] run summon minecraft:armor_stand

复制代码

(我知道理论上要完全等价于1.12命令的话还要加上at @s,不过在这个例子里面影响不大就算了)
结果会是

一共6个AMS


为什么是这样呢在1.12的情况下
嵌套狂魔pca的教程已经解释过了,嵌套exe时,最外层的exe一开始已经决定了执行次数,是不变的

但是后面的exe会根据实体的实时数量,增加其执行次数,流程图如下:

  • 首先,最外面的exe选中了两个AMS,让它们轮流执行后面的exe
  • 然后第一个被选择的AMS,选中了一共两个AMS(自己和对方)执行summon命令,于是总数变为2+2=4个
  • 第二个被选择的AMS,选中了2个原本的AMS+2个新summon的AMS,于是总数变为4+4=8个

更多层数嵌套的exe也是一样道理的,不过其逻辑复杂无比,我的脑内逻辑回路连同我的电脑内存一起过载烧掉了,所以就不举例了(警告,3层exe就足够召唤2048个AMS出来,切勿轻易尝试)


然而在1.13的版本里面,嵌套exe的逻辑有所改变,其流程如下:

  • 首先,最外面的exe选中了两个AMS,让它们轮流执行后面的exe
  • 然后被选中的两个AMS再检测符合条件的实体,每人选中两个AMS(自己和对方)
  • 最后执行summon命令,每人召唤2个AMS,加上原本两个AMS,一共6个

由此可见,1.13嵌套exe和之前版本最大的区别在于,exe选中的实体数量不会随着后面执行的部分即时更新
而变成了在执行命令前一次过检测,确定所有符合要求的对象后,再执行命令


追加一个例子进一步说明这个情况
还是两个AMS,现在它们都有一个叫test的分数,初始为0

然后我们执行

  1. /execute @e[score_test=0] ~ ~ ~ execute @e[score_test=0] ~ ~ ~ scoreboard players add @e[type=armor_stand] test 1

复制代码

结果会是

为什么会是2呢?
因为被最外层exe选中的第一个AMS,会exe自己和另一个AMS,共两个AMS执行了score add的命令,这时候两个AMS的分数从0增加到2
第二个AMS判定的时候,由于两个AMS的分数都不为0,所以不会再执行加分


那么在1.13的情况呢?

执行命令

  1. /execute as @e[scores={test=0}] run execute as @e[scores={test=0}] run scoreboard players add @e[type=armor_stand] test 1

复制代码


结果是4
其道理和summon的例子类似
这个命令会先根据目标选择器确定所有需要执行命令的实体
两个AMS分别选中对方,整个命令总共选中了4个实体(每个AMS分别选中2次)
然后最后根据这个实体列表执行最后的score add命令,所以总共会加4分
中间AMS的分数即使已经改变,但由于被选中的实体已经是确定的,所以不会影响这个过程


题外话,在1.13中,一条execute命令中有两个as/at,效果等同于as run as
例如

  1. /execute as @e[scores={test=0}] as @e[scores={test=0}] run scoreboard players add @e[type=armor_stand] test 1

复制代码

  1. /execute as @e[scores={test=0}] run execute as @e[scores={test=0}] run scoreboard players add @e[type=armor_stand] test 1

复制代码

是一样效果的


那么如果想在1.13中达成以前的嵌套效果那是不是就不成了呢?
不是,有一个麻烦一点的方法可以做到,那就是使用func
比方说现在我们有个func
名为test:summon,命令为

  1. execute as @e[type=armor_stand] run summon minecraft:armor_stand

复制代码

然后我们执行

  1. execute as @e[type=armor_stand] run function test:summon

复制代码

即不直接嵌套两个execute,通过放到function中嵌套
效果会等于1.12前的execute嵌套,为什么呢?其逻辑为

  • execute在执行run内的命令前确定好目标实体,分别为两个AMS
  • 两个AMS轮流执行function
  • 执行function的时候里面的execute检查执行对象
  • 第一个func选中了两个AMS(本身和对方),召唤了2个AMS
  • 第二个func选中了共4个AMS,再召唤4个AMS,共8个AMS

 


我想说的废话到此为止了,泡也冒完了,组长跑路了现在出来卖教程赚工资卖完了,可以回去摸鱼了好像是

发表评论

您必须 登录 才能发表留言!