本帖最后由 pca006132 于 2015-11-6 23:34 编辑

大家好,我是pca。今天来和大家说说1.9的chain CB(下称CCB)如何做到else/else if及嵌套
首先让我来介绍一下if、else、if else嵌套的概念(如果早就知道的话就可以跳过~)


if、else、else if

什么是if呢?相信大家都知道,if就是如果
比如说,如果地图上有盔甲架,就say 地图上有盔甲架
常见的表达方法:



至于else呢,就是当前面的if的条件没有达成,就执行下面的东西(否则就不执行)。也就是否则
比如说,如果地图上有盔甲架,就say 地图上有盔甲架;否则就say 地图上没有盔甲架



else if则是else 和 if一起使用,如果前面的if的条件没有达成,就执行另外一个if
例子: 如果有玩家叫a,就say 这里有个玩家叫a;否则如果有玩家叫b,就say这里有个玩家叫b;否则如果有玩家叫c,就say这里有个玩家叫b;否则就say这里没有任何叫a/b/c的玩家


从这个例子上可以看到,if、else、else if是可以配搭一起用的



嵌套

比如说,我们要在地图上有盔甲架并且有叫a的玩家的时候就say地图上有盔甲架和a玩家我们可以怎么办呢?我们可以用and,然而这需要scb,然而这并不符合本文的中心,而且也会很麻烦(如果要有盔甲架但是不能有叫a的玩家呢?或者是有盔甲架并且有叫b的玩家呢?难道写多几次?)
所以我们需要一个叫嵌套的东西
嵌套就是在if 里弄多一个if之类的东西,以下是一个例子
if (地图上有盔甲架)
{
    if (地图上有叫a的玩家)
    {
        say .......
    }
}
里面的东西和一般的基本上是一样的。无论是if、else、还是else if也能够嵌套别的if



1.9 CCB的特性

在了解如何做到if那些控制之前,你需要明白CCB的一些特性,不然的话是不能够明白那个系统的原理的。

首先,CCB是会把之前指着它的CB的信号延续下去无论它有没有被激活/conditional的条件是否满足
只要对着它的ICB(普通CB),RCB(自带高频的CB)有被激活(有没有成功执行命令是完全没关系的),或者对着它的CCB有信号传过来,它就会传递信号

第二,CCB在激活了(有红石信号激活/auto)并且满足条件(见下)的情况下就会执行命令

第三,CCB在以下情况下被称之为"条件满足"
  • 不是conditional模式
  • conditional模式下,前一个CB箭头对着它的箭头尾端,并且前一个CB在传递信号的时候成功执行命令
(比如??(第一个箭头为前一个命令方块及其方向,后一个箭头为conditional模式的CCB及其方向),如果前一个成功执行,后面那个就会为满足条件)
(比如
??(第一个箭头为前一个命令方块及其方向,后一个箭头为conditional模式的CCB及其方向),即使前一个成功执行,后面那个还是不满足条件,因为不是对着其箭头尾部)

接下来会使用的特殊简写(除了第一个CB是普通CB之外,所有都是CCB)
cond:命令
该CCB是在conditional模式的
mark:名字
以指定名字的盔甲架来标记下一个命令方块的位置


CCB的if、else、else if
首先,这个我经常使用blockdata来更改CCB的auto,因为auto为0的时候,它不会执行命令,但是会传递信号。而且,blockdata几乎是没有延迟的(执行后会马上看到结果),起码没有1gt的延迟,在CCB这种每个命令执行时间少于1gt的情况下(微观延迟)是极度有用的。

——if——
if就相当简单,后面的命令加上cond就可以了。
比如
testfor @e[type=ArmorStand]
cond:say there are armorstands
cond:say 第二个命令
如此类推,用我上面的表达方法就是
if (有盔甲架)
{
say there are armorstands
say 第二个命令
}
因为如果第一个条件不符合,后面的第一个CB就不能够执行,第二个也因为第一个不能执行而无法执行,如此类推,一串的cond命令方块就无法执行了
——————————————

——else——
else呢,就稍微难一点了,我们需要用到blockdata
比如
  1. testfor @e[type=Item]
  2. cond:say 这里有物品
  3. cond:execute @e[type=ArmorStand,name=1] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}
  4. mark:1
  5. say 这里没有物品
  6. execute @e[type=ArmorStand,name=1] ~ ~ ~ blockdata ~ ~ ~ {auto:1b}
复制代码
整个事情就好像是,当检测到有物品,就说有物品,并且令名字为1的盔甲架所在的命令方块无法执行命令,只能传递信息。最后把所有命令方块重置(令其能够执行命令)
如果没有物品,名字为1的盔甲架所在的命令方块就不会被blockdata,因此能够执行命令。

————————————

——else if——
else if其实和else差不多,都是利用那个auto的原理,然而这个稍微比较复杂点。例子:
  1. testfor @e[type=Item]
  2. cond:say 这里有物品
  3. cond:execute @e[type=ArmorStand,name=1] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}


  4. mark:1
  5. testfor @e[type=Creeper]
复制代码
其实,就是在else里增加一个if那样子而已。

相信大家也看到那个say 2、say 1和say end了。到底我弄那些看起来什么也表达不了的东西来干啥呢?
其实就是想告诉大家,有cond:和没有cond:是很大差别的。有cond:,就是当前面的成功执行才可以执行这个命令,所以就是在{}里面
如果没有cond:,就是在{}外面



嵌套!
warning!警告!
前方可能会让人头疼,如果不熟习上方的概念的话切勿看下方。(:D其实看看也无妨,然而我不确保解释的好)

好了,说了那么多,嵌套怎么做呢?
其实很简单的,大家看到我写的那个mark:1吗?1是什么意思呢?其实我就是把它当做为第一层那么看的。
嵌套的话,就是不同名字的盔甲架,1、2、3、4.....
第一层的在一开始的是auto:1b的,其他则是auto:0b(这里是简化了的)
如果符合某条件,它就把所有和它同一层次的CB变成auto:0b,并且把所有的下一层次CB变为auto:1b。
到了另外一个部分(比如if {} else {}就是两个部分),就把它需要用到的层次重置(以减少需要重置的次数)

相信大家也看到不明所以了,以下是一个例子,希望能够让大家更容易明白这个概念。
  1. execute @e[type=ArmorStand,name=1] ~ ~ ~ blockdata ~ ~ ~ {auto:1b}
  2. execute @e[type=ArmorStand,name=2] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}
  3. execute @e[type=ArmorStand,name=3] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}

  4. testfor @e[type=Arrow]
  5. cond:execute @e[type=ArmorStand,name=1] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}
  6. cond:execute @e[type=ArmorStand,name=2] ~ ~ ~ blockdata ~ ~ ~ {auto:1b}

  7.     mark:2
  8.     cond:testfor @e[type=Item]
  9.     cond:execute @e[type=ArmorStand,name=3] ~ ~ ~ blockdata ~ ~ ~ {auto:1b}
  10.     cond:execute @e[type=ArmorStand,name=2] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}

  11.         mark:3
  12.         cond:testfor @a
  13.         cond:say there are arrows,items and players
  14.         cond:execute @e[type=ArmorStand,name=3] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}

  15.         mark:3
  16.         say there are arrows and items

  17.     mark:2
  18.     testfor @a
  19.     cond:say there're arrows and players
  20.     cond:execute @e[type=ArmorStand,name=2] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}

  21.     mark:2
  22.     say there are arrows


  23. execute @e[type=ArmorStand,name=2] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}
  24. mark:1
  25. testfor @e[type=Item]
  26. cond:execute @e[type=ArmorStand,name=1] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}
  27. cond:execute @e[type=ArmorStand,name=2] ~ ~ ~ blockdata ~ ~ ~ {auto:1b}

  28.     mark:2
  29.     cond:testfor @a
  30.     cond:say there are items and players
  31.     cond:execute @e[type=ArmorStand,name=2] ~ ~ ~ blockdata ~ ~ ~ {auto:0b}

  32.     mark:2
  33.     say there are items

  34. mark:1
  35. testfor @a
  36. cond:say there are players
复制代码
首先就是把所有的第一层次CB变为auto:1b,并且把所有其他层次的CB变为auto:0b
然后如果检测到箭,就把第二层次的变为auto:1b(进入第二层次),并把第一层次的变为auto:0b(把后面的命令忽略掉)
    如果检测到物品,就把第三层次变为auto:1b(进入第三层次),并把第二层次的变为auto:0b(把之后的忽略掉)
        如果检测到玩家,就say检测到箭、物品和玩家。然后把第三层次的变为auto:0b(忽略掉后方的)
        否则,就say 检测到箭和物品。
    否则,如果检测到玩家,就say 检测到箭和玩家。并且把第二层次的变为auto:0b
    否则,就say 检测到箭。
把所有第二层次的CB重置为auto:0b(不用重置第三层次是因为这里用不到第三层次)
否则,如果检测到物品,就把第二层次的变为auto:1b(进入第二层次),并把第一层次的变为auto:0b(把后面的命令忽略掉)
    如果检测到玩家,就say 检测到物品和玩家。并且把第二层次的变为auto:0b
    否则,就say 检测到物品
否则,如果检测到玩家
就say检测到玩家。



很简单吧= ̄ω ̄=,就是不停的把不同层次disable/enable。

深夜码字哦,各位客官来捧个场吧QAQ
{:10_521:}

[groupid=546]Command Block Logic[/groupid]