PCC 语法

命令语法

注释

会被编译器忽略。
注意: 这些注释不能与命令方块在同一行

//单行注释
/*
   多行注释
*/

模块

帮助组织命令。代表模块的开始,之后的命令需要多一层缩排。用户也能只编译指定模块的命令。
一般模块不会被编译,除非被调用(看下方PCC命令)或特殊模块名称。
语法: #module (模块名称)

#module example
    /say this is the first command
    /say this is the second
/say this is not the command of module 'example'

特殊模块名称


标签

标签接下来的命令方块,之后可以透过JavaScript/自带函数取得该命令方块的坐标等信息。
语法: @label (标签名称)

注意不能有多于一个命令方块拥有同一个标签
如果真的需要那样做,请使用标记实体(Marker)

@label test
/say test

/say the coordinate of test is: ${GetCoordinateFromLabel('test')}

命令

默认: auto ccb
一行命令后的连续行数,如果都有多一层缩排,则会被连接起来,没有任何空白字符会被加入,那些行最后的空格也不会被移除。
命令写不写/其实也没啥分别

//注意'.'字符后有一个空格
icb:say this is a long example. 
    Really long.

//等于
icb:say this is a long example. Really long.

可以放置’空置’命令方块,写法就是: /,比如

say start
//下面这个就是空置的
/
say end

命令前缀

可以同时使用,一个接着一个。注意后面那个会覆盖掉前面那个的属性。

//An auto, impulse command block
icb:1:say test

//An not auto, impulse command block
1:icb:say test2

0:r:say ${1}
//等于
0:say $${1}

一行纯前缀后的连续行数,如果都有多一层缩排,就会被视为继承前面该行纯前缀。

?:
    /say this is a conditional command block
    /say this is also a conditional command block

自带的PCC命令

新链

开启新链
语法: @chain (x y z) (方向) [wrap-(回绕(wrap)命令方块数)-(回绕方向)]
方向可以是+/- x/y/z, 比如+x, -y
xyz坐标可以使用~,代表上一个链的开始坐标(如果是第一个链则代表默认链的开始坐标)。

回绕命令方块数就是过了多少个命令方块就会回绕新一行(并且翻转方向)。
回绕方向就是回绕的时候向着哪个方向回绕。

@chain ~1 ~ ~ +x wrap-10-+z

标记实体(Marker)

在下一个命令方块的位置生成标记实体。会使用不可见、长时间的AEC作为标记实体
语法: @mark (名称) [tag1] [tag2]...

@mark test tag1 tag2 tag3 tag4

Stats

绑定下一个命令方块的stats到指定实体/玩家名的分数。(会自动设置分数)
语法: @stat <stat to bind> <entity/fake player name> <objective>

@stat SuccessCount @e[name=test,c=1] dummy

Sign

使用一个牌子标记下一个命令方块的位置。NBT的部分只需要填写需要修改的行,其他行默认会为TextN:"{\"text\":\"\"}"
语法: @sign (NBT)

@sign {Text1:"{\"text\":\"test\"}"}

调用模块

通过结构方块调用模块。

需要导出NBT文件并且放进地图内。
该链的方向与回绕(wrap)长度视乎默认设置,所以别搞太高难度的姿势…插到自己的模块就不好了
语法: @call (模块名称)@cond_call (模块名称)
cond_call就是当前面的命令成功执行时执行。

放置模块

就是你上面写好了模块,然后你下面需要用到那堆命令,又不需要在执行时实时放置模块,就可以用这个。
基本上和直接写模组里面的命令没分别
语法: @static (模块名称)

停止执行后方命令

把后面setblock air掉…所以记住要有重置的命令。
语法: @break

建议在模块里使用(可以一次过reset),或者后方的CB这样写:

@mark empty
/

并且在模块开始时执行命令,请自行把(direction)替换为链的方向:

execute @e[name=empty] ~ ~ ~ setblock ~ ~ ~ chain_command_block facing=(direction) {auto:1b}

如果会回绕(wrap),则需要不同朝向的分别处理,获取该命令方块的方向。


缩排

缩排对PCC非常重要,因为PCC有一些地方需要使用缩排表示内容,比如#module及多行命令。比如说以下的输入

#module test
    /say test 1
    /say test 2
    /say test 3
        4
        5
/say 1

里面的test模块的命令是:

然而如果这样写:

#module test
    /say test 1
    /say test 2
    /say test 3
    4
    5
/say 1

则会变为

缩排可以让差不多的输入变得完全不同,因此请注意缩排。

非常重要!
缩排必须使用统一缩排规则: 比如4个空格,1个tab等,而且不能混用
因为PCC是透过空白字符(空格及tab)数决定缩排等级的,空格和tab混用会导致错误
PCC会以第一个缩排决定一层缩排的字符数。


JavaScript

用户可以在生成时使用脚本的函数、变量。
所以用户可以把资料和命令分离,增加可读性以及可以方便修改生成出来的命令。

大约处理顺序:

  1. 记录行数, 移除注释,移除空行,记录缩排及提取JavaScript(#include, #script, #run)
  2. 加载JavaScript脚本
  3. 运行#run命令,记录行数(x.i, x为原先那#run的行数)及缩排
  4. 组成模块(根据缩排)
  5. 逐行处理label,执行PCC命令或记录命令到命令方块
  6. 逐个命令方块处理里面的命令,及检查有没有错误
  7. 生成OOC

加载JavaScript脚本

可以声明变量、函数,以及加入自定义的PCC命令。

从URL中获取

会首先执行,先于文件内的脚本
语法: #include <(URL)>

#include <www.example.com/script.js>

文件内的脚本

开始: #script
完结: #end script

注意: 这个只应该出现一次

#script
/*
   JS脚本(声明变量、函数,以及加入自定义的PCC命令。)
*/

const TEST = 1;
#end script

调用JavaScript

JavaScript的函数以及变量可以在生成时调用。PCC提供了三种方法供调用脚本,视乎你需要修改什么:

生成一连串的命令

和预处理类似,函数会在脚本完成加载后执行,而结果就会自动放进文件里(不会修改原本的文件)。生成后的命令可以有PCC命令、前缀等等。调用函数时不会有任何命令方块的资料可供使用,因为调用的时候还没开始处理命令。

语法: #run (表达式)

例子:

#script
function f(x) {
    let results = [];
    for (let i = 0; i < x; i++)
        results.push('/say ' + i.toString());
    return results.join('\n');
}
#end script

#run f(3)

生成的命令:

/say 0
/say 1
/say 2

取代命令中的一部分

如果需要取代命令的一部分,无论是调用函数或是常量,请使用${表达式}。在$字符前加上$就可以转义这个字符。表达式的结果会替换掉命令的那一部分(非字串的会调用toString())。如果你需要经常使用$符号又不想出现过多的转义,可以使用原始命令的前缀(参见上方命令前缀部分)。

这类表达式一般会在生成OOC前执行(几乎是最后的),除非是在PCC命令里使用。
因此正常来说所有命令方块的位置都是可知的。
然而,如果在PCC命令里使用,请确保需要得知的资料在先前已经被处理,否则可能会出错。
比如@chain需要放在一个指定命令方块旁边,那么请保证该命令方块的的位置在@chain命令前,否则会出现错误(因为在调用该坐标的时候不知道该命令方块的位置)。

例子:

#script
function f() {
    //return something like "x y z"
    return CurrentCommandBlock.coordinate.join(' ');
}
#end script

/say This is at ${f()}

比如命令方块的位置在1, 2, 3,生成的命令会是:

/say this is at 1 2 3

PCC命令

PCC命令会在读取命令时执行。PCC命令可以开启新链、增加命令方块、在导入时执行命令等。然而因为它在读取命令时执行,它只能取得前面的命令的数据,而不能取得后面的命令的数据。

语法: @(函数名称) (之后的字串会为参数1)

注意参数1会先被处理,比如会处理掉那些 $$${}

例子:

#script
function doNothing(x) {
    console.log(x);
}
#end script

@doNothing say test

输出(console):

'say test'