命令方块吧 关注:6,130贴子:69,048
  • 18回复贴,共1

[CBL|玄素]这不是教程 §2命令本体

只看楼主收藏回复

原帖http://www.mcbbs.net/thread-631165-1-1.html
同步更新


IP属地:贵州1楼2016-09-11 22:01回复
    每条命令都可以看作由一定的成分组构而成。
    总能看到认为命令是确定的,我们只需要把它背下来就可以了的人。显然对命令有所了解之后,这样的认知就很容易被颠覆。mc中的命令并不像是某些游戏的作弊码,通过固定的东西来完成固定的效果……相对来说它要灵活很多。
    这一章就将会讲述我眼中命令的基本组成,或许不甚严谨,但是也许是一道新世界的大门(笑


    IP属地:贵州2楼2016-09-11 22:01
    回复
      命令分类
      分类永远有无数种方式,我比较习惯的方式倒是和wiki上相同:首先先分为服务器命令和非服务器限定的命令,非服务器类又按照命令的执行目标将命令分为四大类:玩家 实体 方块和世界。
      有些命令或许不会被单独一类所包括,比如/replaceitem就可以利用参数分别对实体和方块生效。这时候它被同时划分进两类。
      简单的列张表,结果将会是这个样子……
      http://minecraft.gamepedia.com/Commands#Summary_of_commands


      IP属地:贵州本楼含有高级字体3楼2016-09-11 22:02
      回复
        可选和必需
        参数一般分为两类,一类是必须填写的,一类是可以省略的。
        举个简单的例子,很多人最初接触到的命令是/gamemode,它的表现形式是这样的:
        /gamemode <模式> [玩家]
        其中gamemode是命令名,<模式>是必需参数,[玩家]是可选参数。
        很多时候我们都会直接/gamemode 1来结束这条命令。这并没有问题,因为最终写出的这条命令已经全部包含了所有的必需参数。指令的含义已经表达清楚,mc可以理解并执行。在这个例子里,我们让mc做的事情就是“将命令使用者的游戏模式切换为创造模式”。
        但有的时候我们并不仅仅想对自己进行模式的操作。我们可能会希望让所有的人都被切换为创造,于是我们写出了另一条命令:/gamemode 1 @a。
        在这条命令里,@a就是一个可选的参数。我们不需要加入这个参数也可以表达完整的意思,但是这个参数的加入使得我们表达的意思更加完整,或者说,给命令的效果增加了更多的限制条件。
        当一条必需参数缺失的命令被尝试执行时,mc会告诉你“你写的这是什么鬼玩意儿该给的东西都没给”,并且拒绝你的命令。如果必需参数完备,而有可选参数没有填写时,可选参数会按照默认值被补全进最终的执行。也就是说,实际上即使你缺省了参数,mc也不会无视它们——只是他们已经有一个可以代入执行的值了而已。


        IP属地:贵州本楼含有高级字体5楼2016-09-11 22:02
        回复
          我想偷懒!我要省参数!
          正如前文所述,当一个参数可以被缺省时,mc会用默认值替代它。
          没错,每一个被缺省的参数,都有一个默认值。
          显然有些参数是无法配给默认值的。比如summon的实体名——你不写清楚,mc怎么知道该给你生成些什么。
          而有些参数则是因为位置的原因无法配给默认值——例如setblock的坐标。
          你可能说“为什么不像summon一样将坐标放在生成目标之后呢?”
          因为setblock有一个更常被缺省的参数:方块数据值。
          能被缺省的参数一定放在命令的末尾,因为前面的必需参数之间出现了未可期的空位是不可接受的。
          有些命令看起来可以被省略的东西在指令的前段,但实际上,在mc的认知之中,这是两种不同的命令格式,查看help就可以知道这一点。
          依旧举个例子。execute命令可以跟一个detect参数,用于监测被execute的目标周围是否有满足要求的方块。非常实用的功能,但显然,未必需要。这时候这个功能往往被做成可选的,只是由于在detect之后并非空无一物——它之后会跟上其他的命令——所以在execute的help中,有无detect是两种命令格式,而不是单纯的参数可选与否。


          IP属地:贵州本楼含有高级字体6楼2016-09-11 22:03
          回复
            命令对象
            一条命令无论如何都会有自己的执行者和自己作用的目标。执行者不一定是玩家,甚至不一定是实体……比如cb表示“我是个方块”。目标也不一定是实体……比如有些世界操作命令,最后的目标就是level.dat(咦


            IP属地:贵州本楼含有高级字体7楼2016-09-11 22:03
            回复
              执行者转移
              通过一条名叫execute的命令我们可以转移执行者。
              这个转移是很完整的,基本可以看做被选中的实体执行了命令。无论是命令执行中的对象获取,还是指令返回值的挂靠,都将以被转移到的目标为准。
              举一个很简单的例子好了。
              1.10新增了命令/teleport,这条命令和/tp最大的不同就是修改了命令的坐标偏移获取方式:从相对于目标变成了相对于执行者。于是在聊天框执行这两条命令就会得到完全相异的结果:
              /tp @e ~ ~1 ~
              /teleport @e ~ ~1 ~
              前一个是将所有的目标,也就是所有实体,全部tp到比他们原先坐标y+1的位置;而后一条命令,将会将所有的实体,tp到指令执行者也就是你的头上一格……
              这并不是一对能够互换的命令,但是可以进行单方面的替换——
              /execute @e ~ ~ ~ teleport @e[c=1] ~ ~1 ~
              上面这条命令就和/tp @e ~ ~1 ~等价。原因很简单,因为在这条命令执行的时候,将会被视为全部的实体对自己执行了一次向上一格的teleport。执行者取代了目标成为坐标偏移的依据,而execute和选择器的配合让每一个执行者都成为了自身的目标。于是,效果就达到了。
              上面也提到了这个转移的完整性。execute @e[tag=a] ~ ~ ~ worldborder get是通过stats手段获得边界坐标的常用手法,但这时候这个queryresult的stats应该挂在tag为a的这个实体上,而不再是cb上——cb执行的只是execute,而不是worldborder get。一个execute链中,每一层都视作只执行它的那一层execute,除了最后一层执行最终跟随的命令。


              IP属地:贵州本楼含有高级字体9楼2016-09-11 22:04
              回复
                连续的执行者转移
                当一个实体在同一个命令中被多次execute时,按照执行解析的顺序来决定最后它会拥有怎么样的结果。例如,现在场上有两个tag为test的实体,在聊天框里执行此命令:
                execute @e[tag=test] ~ ~ ~ execute @e[tag=test,c=-1] ~ ~ ~ testfor @e[tag=test]
                首先被执行到的是execute @e[tag=test] ~ ~ ~这一层。你在这一层收获了2的SuccessCount和2的AffectEntity,执行者转移到两个带有tag的实体身上;
                第二步被执行的是execute @e[tag=test,c=-1] ~ ~ ~这一层。这两个实体在这一层收获了……且慢。
                mc对execute的执行规则很有意思。如果你看过pca那个execute*4炸电脑的帖子,应该理解难度会小上很多。
                为了方便描述,我们给这两个实体分别起个名字:按照选择到的顺序分别叫它们a和b。
                这条命令的实际执行逻辑是这样的:
                你选择了a和b;a选择了b;b执行了testfor;b选择了a;a执行了testfor。
                它就像一棵树,会在每一条链执行结束的时候退回到上一个分支点,然后跟着这一条分支继续执行,直到所有的分支尽数走完为止。
                这里附上pca那个帖子http://www.mcbbs.net/thread-630291-1-1.html,可以作为对execute和执行者转移带来影响的深一层思考。
                当execute链中任意一环选择不到目标的时候,这一条execute链就会中断。依旧是举例:
                execute @e[tag=a] ~ ~ ~ execute @e[tag=b,c=1,r=0] ~ ~ ~ ...
                一个在检测同一个实体多tag的时候常用到的小手段,实用性还是挺高的。这时候可能被加载的区块里面有不止一个拥有a这个tag的实体,但是由于第二个选择器的目标转移(c=1,r=0一般在不考虑tp的情况下仅会选择到自己),只有当自身拥有tag b的时候,后续的命令才会被执行;如果没有,那么基于这个拥有tag a的实体的execute就中断了,后续命令也就不会发生。但是这并不影响到其它拥有tag a的实体——试想前文树的比喻,你砍断了一根分支,其余的分支依旧健全。


                IP属地:贵州本楼含有高级字体10楼2016-09-11 22:04
                回复
                  命令返回值
                  同为命令三要素之一,命令会在执行完毕以后给予执行者一个(堆)返回值:这些值包括了命令成功次数(SuccessCount),影响实体数(AffectEntities),影响方块数(AffectBlocks),影响物品数(AffectItems)和查询结果(QueryResult)。显然并没有命令能同时对方块、实体和物品生效顺带还查询个值……所以一般来说,每条命令对我们有用的返回值只有1-2个,一个永远存在的返回SuccessCount和剩下四个中这条命令目标对应的值。
                  这个值被返回会有什么作用呢?应该从老时代过来的人都知道比较器可以检测cb是否执行成功,执行成功就会给出一个红石信号输出。实际上,这个输出信号的强度就是由返回值SuccessCount决定的。这个值在cb上被储存于一个nbt里,比较器检测这个nbt然后给出相应的输出。
                  当然,它远远不止能用做红石信号输出。作为一个值,我们想用它的话……对我相信大家已经想到怎么做了,记分板。


                  IP属地:贵州本楼含有高级字体11楼2016-09-11 22:05
                  回复
                    第二张搬运完毕。
                    这次换了个方式排版看着似乎舒服多了。


                    IP属地:贵州13楼2016-09-11 22:06
                    回复
                      高产


                      来自Android客户端15楼2016-09-12 01:06
                      收起回复
                        你是不是每一块文字都是粗体233


                        来自iPhone客户端16楼2016-09-15 09:42
                        收起回复
                          大赞,火钳


                          星座王
                          点亮12星座印记,去领取
                          活动截止:2100-01-01
                          去徽章馆》
                          IP属地:英国17楼2016-09-15 10:01
                          回复
                            顶起


                            来自Android客户端18楼2016-11-10 18:52
                            回复