pca006132
本帖最后由 pca006132 于 2016-9-2 21:23 编辑

那么快就九月了, 我也开学两天了。
对未来的操练感到担忧, 然而也对CB界的技术传承比较担忧, 担心这些奇葩想法会自我这里失传, 所以就尽快写好这个教程了

execute教程是一直以来都想写的, 然而由于懒癌的关系一直动不了笔。这次还是昨天晚上睡不着想的架构, 或许简陋然而我也尽了最大努力了, 希望各位能理解我在写什么吧。
如果这帖子的格式鬼畜了的话也请勿怪...因为我这是在测试新写的markdown转bbcode, 看来效果还不错嘛:D
为什么要用markdown不用bbcode? 好写啊! 而且也不用烦配色, 红红红全红了多简单233333

如果各位不嫌弃的话, 可以来一起讨论execute的特殊用法, 也欢迎私聊/回复让我加上别的用法。


2021.12 数据,可能有更多内容
那么快就九月了, 我也开学两天了。
对未来的操练感到担忧, 然而也对CB界的技术传承比较担忧, 担心这些奇葩想法会自我这里失传, 所以就尽快写好这个教程了


execute教程是一直以来都想写的, 然而由于懒癌的关系一直动不了笔。这次还是昨天晚上睡不着想的架构, 或许简陋然而我也尽了最大努力了, 希望各位能理解我在写什么吧。
如果这帖子的格式鬼畜了的话也请勿怪...因为我这是在测试新写的markdown转bbcode, 看来效果还不错嘛:D
为什么要用markdown不用bbcode? 好写啊! 而且也不用烦配色, 红红红全红了多简单233333


如果各位不嫌弃的话, 可以来一起讨论execute的特殊用法, 也欢迎私聊/回复让我加上别的用法。



execute基础: 格式、运行方式
execute 格式大要

代码:

  1. execute <实体> <x> <y> <z> <命令>
让&lt;实体&gt;在指定位置(x、y、z坐标。如果是相对坐标则以实体位置为判定点)执行指定命令


代码:

  1. execute <实体> <x> <y> <z> detect <方块id> <方块数据值> <x2> <y2> <z2> <命令>
当实体在指定位置(x2、y2、z2坐标。如果是相对坐标则以执行位置为准。执行位置即x、y、z坐标的位置)检测到指定方块(id及数据值必须吻合。如果数据值为-1则代表所有数据值都吻合)时,则在执行位置执行命令(执行位置不是检测到方块的位置,而是先前x、y、z坐标的位置)


由于本教程主要是指出execute有什么主要用法, 而detect比较少用(起码我比较少用), 而且那用法一般也比较简单, 因此本教程不会探讨execute detect的特殊用法


注意
  • execute选择到的实体不需要有op权限也可以执行命令(虽然这应该是常识, 然而不知道为什么总会有人问这个问题)
  • execute里面可以嵌套execute(然而得注意, 这可能会让执行次数变得极高)。就好像叫别人去命令别人做事的样子。
例子:

代码:

  1. execute pca ~ ~ ~ setblock ~ ~ ~ command_block
如果pca的坐标是0 64 0, 则会在0 64 0的位置放置一个命令方块


代码:

  1. execute pca ~ ~5 ~ detect ~ ~-5 ~ air 0 setblock ~ ~ ~ command_block
如果pca的坐标是0 64 0, 如果0 64 0是空气,则会在0 69 0的位置放置一个命令方块


代码:

  1. execute @e ~ ~ ~ execute @e ~ ~ ~ say hi
如果有两个实体, 则会让该两个实体say hi(每个两次)


execute的运行方式
execute会让选择到的所有实体一个一个的逐个执行命令。
当那些实体全部执行完命令, 这execute命令才算是执行完成。
(所以大量execute嵌套很可能会导致game tick过长)


实体执行命令的次序就是选择器选择实体的顺序
选择器会优先选择在执行的世界的实体/玩家
(先选择最近的实体,当那些实体的距离一样时,它就会优先选择存在最久的)


execute命令的SuccessCount就是成功让多少实体执行命令。
至于AffectedEntities即使成功也只会是1(只是执行了很多次而已)


例子

代码:

  1. execute @e ~ ~ ~ say hi
假设实体的排列是ABCD, 命令方块放在最左边。


执行结果:


[A]hi
[B]hi
[C]hi
[D]hi

代码:

  1. execute @e ~ ~ ~ execute @e ~ ~ ~ say hi
假设实体的排列是AB, 命令方块放在最左边。


执行结果:


[A]hi
[B]hi
[B]hi
[A]hi

(原因和选择器的特性和执行坐标的改变有关, 你们猜猜为什么吧:D)



使用execute改变执行坐标
execute命令能够改变命令的执行坐标, 这对系统的可移植性作出了极大的贡献, 和选择器配合的好甚至能够做到一些原本需要多条命令才能做到的事情。


标记(marker)
为了系统的可移植性, 我们会避免用绝对坐标去标记不同的位置, 甚至连相对坐标也会避免使用。
然而, 有时候我们的命令还是需要知道某些位置才能工作的(比如是要关闭某个命令方块)


这个时候, 我们会把一个特定名字的实体(一般是AreaEffectCloud, 因为即使有大量的AreaEffectCloud对性能的影响是最微小的)放在指定的位置, 然后透过execute该实体去执行需要该坐标的命令(因为execute后执行坐标)


例子
(mark:(名字) 就是在下一个命令方块的位置放置一个指定名字的AreaEffectCloud)

代码:

  1. say hi
  2. execute @e[name=1] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}
  3. mark:1
  4. say 这不会执行
由于第二条命令(execute ... blockdata ...)先改变了执行坐标(改为第三条命令的命令方块位置), 再把原地的命令方块关掉。因此就能够关闭第三条命令的命令方块, 从而阻止其执行


特殊用法
有一些execute的特殊用法, 透过巧妙地更改执行坐标和使用选择器, 就能够做到一些原本要几条命令才能做好的事情


本部分由于本人难以说清如何想到此脑洞, 所以只能对用法进行解释, 希望能启发诸位想到更多新奇有趣的用法


生成一直线(之间有一定间隔)的实体
(本用法和其他章节的增加执行数量的用法配搭可有更佳的结果)
(本用法有一个限制: 命令的执行坐标必须在开始的那端, 否则可能会造成重叠的现象)

代码:

  1. execute @e[name=marker,c=-1] ~ ~ ~ summon ArmorStand ~(间隔) ~ ~ {CustomName:"marker"}
marker就是生成的那些实体的名字, 而间隔部分不一定是要x轴的, 放在任何地方也可以, 甚至三个轴上同时有间隔也并无不可


相信大家也看明白了, 本命令就是透过选择最远的那个marker去生成别的marker, 不停执行则可以生成一串的实体


调换执行
举个例子, 辗转相除法: 就是不停a %= b, b %= a...直至一方为0


按照一般的思路,这个做法得两条命令, 毕竟a %= b, b %= a是两个不同的东西吧。
然而问题来了, 这样子还怎么放在execute里1gt内完成啊?


所以, 就有了一个方法的诞生: execute @e[tag=num] ~ ~ ~ scoreboard players operation @e[c=1] scb %= @e[c=-1,tag=num] scb
这个方法其实就是这样的: 让a和b去分别把自己的分数%=最远的那个(就是另外一个)的分数


至于怎么做到大量执行次数就留待之后的环节继续讲解了



execute暴力增加执行次数
这些方法只适用于执行一条命令的时候


警告: 这些方法建议不要在高频系统里使用(尤其是服务器), 即使使用也请减少执行量, 否则后果严重


实体穷举
这方法适用于需要执行指定次数的命令


方法就是给大量实体一个索引值(1-n或是0-(n-1)), 然后减去需要执行的次数, 然后execute分数&lt;=-1/0的实体去执行命令


http://www.mcbbs.net/thread-629637-1-1.html 这帖子里的自我复制系统可以用别的方法做到以达到瞬间: 1000个实体, 分别有独立的索引值, 减去次数后execute分数&lt;=0的实体去execute @e[name=marker,c=-1] ~ ~ ~ summon ArmorStand ~(间隔) ~ ~ {CustomName:&quot;marker&quot;}, 然后execute所有marker去clone/放置stb并激活


execute嵌套(指数增加执行次数)
实体穷举的办法需要大量实体, 如果不愿意放置大量实体的话可以使用execute嵌套的办法去增加执行次数


execute 实体 ~ ~ ~*n出来的执行次数会是实体数^n那么多, 因此是增加执行次数的一个好办法


注意: 这办法没法确保执行多少次, 请加入一个execute去检查条件是否已经满足, 否则会让game tick时间大幅延长, 对服务器造成严重负担


暴力增加次数的特殊情况: CBer的execute问题
问题很简单:


execute @e ~ ~ ~ execute @e ~ ~ ~ execute @e ~ ~ ~ summon ArmorStand
初始实体为2个, 执行完了之后实体数会是多少? 并且为什么是那个数量

这个问题有很多人认为是8(2^3), 然而之后证实了是2048, 而且也找到一个合理解释了, 以下就来为大家解释一下


execute @e ~ ~ ~ execute @e ~ ~ ~ summon Armorstand
execute @e ~ ~ ~
[当前实体数为2, 于是下面会执行两次]
    execute @e ~ ~ ~
   [当前实体数为2, 于是下面会执行两次]
    summon Armorstand
    summon Armorstand
    execute @e ~ ~ ~
   [当前实体数为4, 于是下面会执行四次]
    summon Armorstand
    summon Armorstand
    summon Armorstand
    summon Armorstand

从此可以见到, execute的运作就是先选择实体,然后由选择了的实体去执行命令
选择器在选择好了实体之后就不会改变(比如execute @e ~ ~ ~ summon ArmorStand,初始实体数为2,那就只会执行2次),所以第一个execute的数目是不会无限增加下去的
不过,后面嵌套的那些execute会根据执行时存在的实体去选择,所以那个执行次数会变大的很快(因此就不是2^嵌套数那么多个实体)


所以如果要透过execute嵌套去生成实体, 请先小心计算之后会生成的实体量, 以免发生以外的情况



execute与stats
execute和stats配搭使用可以做到好像同时使用了一条命令和修改记分板分数的样子, 可以省却大量的穷举。


然而这也是有限制的, 首先: SuccessCount是整个命令执行完毕才改变分数的而不是一边执行一边增加分数。
其次, execute做成的SuccessCount是会被覆盖而不是继续增加的, 以下会说明嵌套execute时SuccessCount的变化

代码:

  1. 实体: A, B, C
  2. 命令: execute @e ~ ~ ~ execute @e ~ ~ ~ say hi

  3. 第一个execute:
  4. [执行者SuccessCount=0]
  5.     A: execute:
  6.   A: say hi
  7.   [A SuccessCount=1]
  8.   B: say hi
  9.   [B SuccessCount=1]
  10.   C: say hi
  11.   [C SuccessCount=1]
  12.     [A SuccessCount = 3]
  13.     B: execute:
  14.   B: say hi
  15.   [B SuccessCount=1]
  16.   A: say hi
  17.   [A SuccessCount=1]
  18.   C: say hi
  19.   [C SuccessCount=1]
  20.     [B SuccessCount = 3]
  21.     C: execute:
  22.   C: say hi
  23.   [C SuccessCount=1]
  24.   B: say hi
  25.   [B SuccessCount=1]
  26.   A: say hi
  27.   [A SuccessCount=1]
  28.     [C SuccessCount = 3]
  29. [执行者SuccessCount=3]

  30. 最后不同实体的分数:
  31. A = 1
  32. B = 1
  33. C = 3
  34. 执行者 = 3
例子: 1 game tick内给实体增加索引值
这道例子出自CBL新手群问答比赛


索引值可以是1-n, 也可以是0 - (1-n)


方法:

代码:

  1. //绑定stats部分(略...)

  2. execute @e[tag=markers] ~ ~ ~ testfor @e[score_SC=0]
解释: 当第一个实体执行testfor的时候, 自然所有实体的SC(SuccessCount分数)都是0了, 所以其索引值(也是SC记分板)为n。之后, 第二个实体执行的时候就有一个实体SC分数大于0, 于是其SC分数只有n-1了。如此类推, 到最后就只能选择到自己, 于是SC分数就是1了



结尾
我老了, 没法研究那么多, 也没时间研究那么多了, 只好把一些歪理论交给各位了, 希望大家能借鉴这里的一点脑洞去创造新的execute用法。
由于是赶着写的教程, 所以可能不太全面, 如有错漏敬请指正, 我会尽快修改/加上的了
如果有有趣的execute作品我会加到下面的列表里的了。如果阁下认为您的作品有比较有趣的脑洞(execute相关), 欢迎回复/私聊我, 如果我觉得有借鉴价值的话就会放在下面的了。


有趣的execute作品列表


botao123
顶,看标题感觉不错2333

ufof
前排支持pca,我也学学

乾.坤
真的很好,真的。
这就是老一代cber的精神,执着,与信仰。

SMARTMOORE
围观{:10_512:}

QQ1357288463
我已经全部放弃了,看这头疼

chyx
@FHC红石 你试试加贡献吧233

_DIM_
完全放弃。看着都头疼

爱心魔王FHC
总体看了下还可以吧,还不算放弃
当然对于新手来说= =我会推荐他们去看另一个教程的

execute与stats那里啊
最后不同实体的分数:
A和B不是应该都是3吗,为什么是1

还有索引值这个东西不是很懂啊,是什么??

Green_stone
嗯……虽然我写得比你早,不过看起来这个帖子更全面啊!

机器人WBW
之前的排序大法我还不理解,现在终于理解了√

Green_stone
chyx 发表于 2016-9-2 22:34
@FHC红石 你试试加贡献吧233

比不起没事啊,没有要攀比的意思。
做到自己最好就是了,MC没有最好的高手

langyo
拜倒exe神教

chyx
FHC红石 发表于 2016-9-3 10:20
总体看了下还可以吧,还不算放弃
当然对于新手来说= =我会推荐他们去看另一个教程的
execute与stats那里啊
最后不同实体的分数:
A和B不是应该都是3吗,为什么是1


你提出这个问题 证明你没有看懂。

索引值就是给他们编号而已 比如1 2 3 4..........

Jiang_xia
支持,学习了。

305822437
翻阅了各种教程,花了3个小时终于看通了这一篇教程,感动到痛哭流涕。

苍凉的少年
好具体的教程啊