跳到主要内容

动作:流程控制

这一页的动作控制「什么时候做、做哪一段、记住什么」:等待、呼叫脚本组、提前结束、副本变量、任务组和触发组的开关。 每个动作的格式说明见 怎么看这几页动作说明,三种写法与 @对象 见 脚本写法。

delay 等待​

别名:wait

让这一串停下来,时间到了再执行下一行。

简写:delay 秒数

完整写法:$delay{time=2}

参数必填说明
第 1 个 / time(或 seconds、delay)否等多久。不写 = 1 秒

时间的写法:

写法意思
22 秒
1.51.5 秒(可以有小数)
10t10 tick(1 秒 = 20 tick)
500ms0.5 秒
1m、2m30s、1h、1d1 分钟、2 分 30 秒、1 小时、1 天(单位用 s m h d)
5分钟、1小时中文单位也可以(分钟、小时 或 时)
{v:等待秒数}用变量(代入后再换算)

对象:不看 @对象。

before.yml
script:
- "npc spawn 长老 长老 minecraft:villager &e古殿长老"
- "delay 2"
- "message &7长老:「霜烬守卫就在最深处……」"
- "delay 2"
- "message &7长老:「先打倒前厅的卫兵,大门才会打开。」"
monster.yml
霜烬守卫:
end:
- "message &6王座宝箱的寒冰融化了,结算时间内记得打开!"
- "delay 2"
- "clear"
script.yml
落石:
- "actionbar &c头顶传来碎裂声…… @alive"
- "delay 15t"
- "explosion 落石点 1"

注意:

  • delay 只暂停它所在的这一串。同时进行中的其他脚本(任务组、触发组、别的怪物组)照常运行。
  • 有些地方会等这一串跑完才继续,所以 delay 会把后面的事一起往后推:
    • before.yml 的 script 跑完才开始倒数;
    • 怪物组(或某一波)的 start 跑完才出怪;
    • 每一波的 end 跑完才进入下一波;
    • script 名称 会等脚本组跑完(包含里面的 delay)才执行下一行。
  • delay 0 也会等 1 tick。
  • 副本结束(通关、失败、强制结束)时,所有还在等的 delay 都会被取消,后面的行不会在副本外执行。
  • DungeonPlus 没有通用的等待脚本,所以它的 monstergroup、end 各自有 delay 参数;这两个参数在本插件里仍然有效, 而且不会卡住后面的行(见 monstergroup 和 end)。

script 呼叫脚本组​

别名:run

执行 script.yml 里的一个或多个脚本组。把重复用到的一段动作写成脚本组,到处都能呼叫。

简写:script 脚本组 [脚本组2 …]

DungeonPlus 写法:$script{script=脚本组1,脚本组2} @dungeon

参数必填说明
第 1 个起 / script(或 name、group)是script.yml 里的脚本组名称,不分大小写。多个用空格或英文逗号分开,按顺序接在一起执行

对象:

写法效果
不写、@dungeon、@self在这一行的位置直接执行,跑完(包括里面的 delay)才继续下一行。触发者沿用目前这一串的触发者
@player副本里的每个人各当一次触发者,各自执行一份,彼此同时进行;这一行不会等它们跑完,马上继续下一行
script.yml
狂暴:
- "title &4守卫狂暴了||&7小心它的攻击"
- "sound ENTITY_WITHER_AMBIENT 1 0.6"
- "glow 霜烬守卫"
- "mob minecraft:stray 王座 2"
- if: "{v:碎片} >= 3"
then:
- "message &b寒冰碎片发出光芒,全队恢复了生命!"
- "heal"
trigger.yml
守卫狂暴:
type: mob-health
mob: minecraft:wither_skeleton
below: 50
once: true
script:
- "script 狂暴"
script.yml
个人结算:
- "tell &7你这场击杀了 %clouddungeon_kills% 只怪物"
- "give EXPERIENCE_BOTTLE 4 @self"
end.yml
clear:
- "script 个人结算 @player"

script.yml 也可以写成 DungeonPlus 的样子,动作清单放在 action-script:(或 script:)底下:

script.yml
检查钥匙:
action-script:
- condition:
- "$data-condition{key=钥匙;type=value;value=>=3} @system"
true:
- "$obstacle{group=大门;operation=delete} @dungeon"
false:
- "$message{type=text;text=&c还差钥匙} @self"

注意:

  • 写错名称(script.yml 里没有这个脚本组)时,这一行会被跳过,控制台会提示。
  • 被呼叫的脚本组可以用呼叫它那一串的东西:触发组带进来的 {mob}、{count} 这类变量,以及所属的怪物组 (在怪物组里呼叫的脚本组用 mob 生成的怪,同样算这个怪物组的怪)。
  • 脚本组在里面写 stop 时只结束脚本组本身,呼叫它的那一串会接着执行下一行;写 clear、fail、end 会直接结束副本。
  • 脚本组可以呼叫别的脚本组,最多 32 层(防止 A 呼叫 B、B 又呼叫 A 无限循环)。
  • 用 @player 时 {self} 是那一份的玩家,适合「每个人各自结算」;没有 @player 时 {self} 是原本的触发者 (在任务组、怪物组里呼叫时没有触发者)。这点和 DungeonPlus 不同:DungeonPlus 的 @dungeon 一定没有触发者。

stop 结束这一串​

别名:return

到此为止,这一串后面的行都不执行。通常放在条件区块里,用来「不符合就不往下做」。

简写:stop

完整写法:$stop{}

没有参数。对象:不看 @对象。

trigger.yml
开启密门:
type: interact
point: 密门开关
script:
- if: "!item 霜之钥匙 @self"
then:
- "tell &c这扇门需要一把霜之钥匙。"
- "stop"
- "take 霜之钥匙 1 @self"
- "obstacle open 密门"
- "message &b{self} 打开了密门。"
script.yml
机关:
- "if {v:机关已启动} == 1 -> stop"
- "var set 机关已启动 1"
- "block remove 冰墙"

注意:

  • stop 写在条件区块里,结束的是整串,不只是那个区块。
  • stop 只停目前这一串:在 script 名称 呼叫的脚本组里 stop,脚本组结束、回到呼叫的那一串,那一串照常执行下一行。 想让呼叫的那一串也停下,在呼叫后面自己判断(例如脚本组里先 var set 中止 1,外面再 if {v:中止} == 1 -> stop)。
  • before.yml 里 stop 只是提前结束 before.yml,倒数和开始照常进行;要取消这一场请用 fail。
  • 怪物组的 start、end(以及每一波的)里 stop 只结束那一段脚本,怪物组照常往下走(出怪、进入下一波……)。
  • stop 不会停掉怪物组、任务组本身。要停它们用 monstergroup stop、task stop。

var 副本变量​

别名:data(DungeonPlus 的 $data)

改副本变量。变量是这一场副本共用的,可以当计数器、开关、阶段标记,用 {v:名称} 读出来,用 var 条件判断。

简写:var 操作 名称 [值]

DungeonPlus 写法:$data{key=名称;type=value;operation=add;value=1} @dungeon

参数必填说明
第 1 个 / operation是操作,见下表
第 2 个 / key(或 name)是变量名称,不分大小写,可以用中文
第 3 个起的整段 / value视操作值。里面的变量会先代入(%…% 对触发者代入)
type否只在完整写法里用:value(默认,一般变量)/ list(清单)。简写用 list- 开头的操作代替

一般变量的操作:

操作别名说明例子
set设成这个值(可以是文字)var set 阶段 2、var set 最后触发 {self}
add+加上var add 碎片 1
subtake、-减去var sub 护盾 25
mul*乘上var mul 伤害倍率 1.5
calc=把后面整段当算式算出来再存var calc 奖励 {v:碎片} * 10 + 5
resetdel、delete回到 config.yml 的 variables 设的初始值(没设 = 0)var reset 碎片

清单的操作(一个变量里放好几个值):

操作说明例子
list-add加一个值var list-add 已启动祭坛 东侧
list-remove(list-take、list-del)拿掉一个值var list-remove 已启动祭坛 东侧
list-clear(list-reset)清空var list-clear 已启动祭坛

完整写法的清单:$data{key=已启动祭坛;type=list;operation=add;value=东侧}(operation 用 add / take / reset)。

对象:不看 @对象,变量是整场副本共用的。

config.yml
variables:
碎片: 0
阶段: 1
trigger.yml
捡碎片:
type: mob-death
mob: minecraft:stray
script:
- "var add 碎片 1"
- "actionbar &b寒冰碎片 +1({v:碎片}/3)"
- "if {v:碎片} >= 3 -> trigger enable 启动祭坛"
trigger.yml
东侧祭坛:
type: interact
point: 东侧祭坛
once: true
script:
- "var list-add 已启动祭坛 东侧"
- "message &b东侧祭坛亮了(已启动:{list:已启动祭坛})"
- if: "$data-condition{key=已启动祭坛;type=list;value=西侧} @system"
then:
- "obstacle open 王座大门"

注意:

  • add、sub(take)省略值时等于 1:var add 碎片 就是加 1。mul 省略值等于乘 1(值不变)。
  • 没设过的变量读出来是 0。变量里放的是文字时,add 会把它当 0 来算。
  • 变量只存在这一场副本里,副本结束就清掉,下一场从 variables 的初始值重新开始。
  • calc 算不出数字时,会把整段文字原样存进去。算式写法见 条件判断。

task 任务组​

开始、停止、重来 task.yml 里的任务组(时间轴)。

简写:task 操作 任务名,或只写 task 任务名(= 开始)

DungeonPlus 写法:$task{name=毒雾;operation=start;mode=cycle} @dungeon

参数必填说明
第 1 个 / operation否start(默认)/ stop(或 end)/ restart
第 2 个 / name是task.yml 里的任务名称
mode否cycle(或 loop)= 时间轴跑完从头再来;timing = 只跑一遍。不写 = 照 task.yml 的 loop 设置

对象:不看 @对象。任务组没有触发者。

task.yml
毒雾:
auto-start: false
loop: true
timeline:
10:
- "message &2毒雾越来越浓了……"
- "effect POISON 3 1 @alive ~毒雾区"
monster.yml
沼泽巨蟒:
start:
- "task start 毒雾"
end:
- "task stop 毒雾"
- "message &a毒雾散去了。"
trigger.yml
重置倒计时:
type: interact
point: 计时石碑
script:
- "task restart 倒计时"
- "message &e{self} 重置了倒计时!"

注意:

  • 对正在跑的任务再 task start,效果和 restart 一样:从第 0 秒重新开始。
  • 时间轴第 0 秒的动作会在开始的当下立刻执行。
  • DungeonPlus 的 async 参数会被忽略(本插件的脚本一律在主线程按顺序执行,不需要选)。
  • 通关或失败时所有任务组都会停下。
  • 判断任务有没有在跑:条件 task 名称,变量 {task:名称}。

trigger 开关触发组​

别名:interact(DungeonPlus 的 $interact)

打开或关闭 trigger.yml 里的触发组。auto-start: false 的触发组要靠这个动作打开才会生效。

简写:trigger enable 触发名 / trigger disable 触发名,或只写 trigger 触发名(= 打开)

DungeonPlus 写法:$interact{type=BLOCK_INTERACT;name=启动祭坛;operation=start} @dungeon

参数必填说明
第 1 个 / operation否打开:enable / start / on(默认);关闭:disable / end / stop / off
第 2 个 / name是trigger.yml 里的触发组名称
type否DungeonPlus 的交互类型,本插件不需要,写了会忽略

对象:不看 @对象。

monster.yml
前厅卫兵:
end:
- "obstacle open 大门"
- "objective &f前往冰之祭坛(右键)"
- "hologram update 祭坛字 &b冰之祭坛||&e右键启动"
- "trigger enable 启动祭坛"
trigger.yml
启动祭坛:
type: interact
point: 祭坛
auto-start: false
once: true
script:
- "hologram remove 祭坛字"
- "monstergroup 霜烬守卫"
monster.yml
霜烬守卫:
start:
- "trigger disable 逃生通道"
end:
- "trigger enable 逃生通道"

注意:

  • 名称写错(trigger.yml 里没有)时控制台会提示。
  • 重新打开不会重置 once:已经触发过的 once: true 触发组打开后也不会再触发。
  • 「走进区域」这类触发组关掉再打开时,会重新计算谁在区域里;已经站在里面的人会被当成刚走进来,可能马上再触发一次。

log 写到控制台​

在服务器控制台写一行记录,排查脚本有没有执行到、变量是多少时很方便。玩家看不到。

简写:log 文字

完整写法:$log{text=文字}

参数必填说明
第 1 个起的整段 / text是要记录的文字,可以用变量

对象:不看 @对象。

控制台会显示成 [副本 example #3] 文字(副本 ID 和这一场的编号)。

trigger.yml
捡碎片:
type: mob-death
mob: minecraft:stray
script:
- "var add 碎片 1"
- "log {mob} 死了,碎片现在 {v:碎片},阶段 {v:阶段}"
monster.yml
霜烬守卫:
start:
- "log 霜烬守卫开始,在场 {players} 人,已用时 {elapsed}"

kether(不支持)​

DungeonPlus 的 $kether{group=…} 和 Kether 语句不支持。写了不会报错中断,但只会在控制台提示「本插件不支持 Kether」,什么都不做。

Kether 常见的用途都有对应的一般动作:

想做的事改用
等几秒再做delay
判断后分支if … -> 动作、if / then / else 区块,见 条件判断
给玩家发 actionbar、标题actionbar、title
执行指令command、console
计算数值var calc
不是 $ 开头的行

DungeonPlus 把「不是 $ 开头的行」当成 Kether 语句;本插件把它们当成简写动作。 从 DungeonPlus 搬过来的 Kether 行需要逐行改写成上面的动作。