动态操作语句(Dynamic Operation Statement,简称DOS) 是萌芽引擎中的一项特色机制,专为服务器管理员设计。通过对多种DOS进行组合,用户可实现以往通常依赖附属插件才能完成的功能。该机制是萌芽引擎UI系统的核心功能之一,显著提升了界面配置的灵活性与能力
DOS主要适用于较为简单的图形化配置界面的构建与逻辑设计,如您是一名插件开发者,通常无需直接使用DOS
对于复杂的UI操作,当前版本我们更推荐直接使用客户端脚本(Script)进行处理
DOS需要写在对应组件的有效位置才能触发,目前有效的触发位置有以下几处
%下面是GUI的options内的DOS填写位置
#打开该GUI时执行DOS
openDos:
- "openChild<->default3"
#关闭该GUI时执行DOS
closeDos:
- "message<->thisGui界面被关闭了"
#当玩家在此GUI内按下按键时触发
keyDos:
keyDown_22:
- "message<->按下了 U 键"
keyUp_22:
- "message<->松开了 U 键"
keyDown@U:
- "message<->按下了 U 键"
keyUp@U:
- "message<->松开了 U 键"
%下面是任意组件的DOS填写位置
#当界面打开的时候 该组件第一次加载时触发该DOS
initDos:
- "message<->我是界面 thisGui 的组件 thisPart"
%下面是按钮组件的DOS填写位置
#鼠标左键按钮时执行DOS
clickDos:
- "open<->default2"
#鼠标右键按钮时执行DOS
rightDos:
- "open<->null"
#鼠标悬浮按钮时执行DOS
hoverDos:
- "open<->null"
#鼠标悬浮离开按钮后执行DOS
leaveDos:
- "open<->null"
%下面是复选框组件的DOS填写位置
#复选框被选中时触发的DOS
checkedDos:
- 'message<->你选择上了'
#复选框被取消选中时触发的DOS
cancelledDos:
- 'message<->你取消了选择'
#复选框被鼠标左键时触发的DOS
clickDos:
- "open<->default2"
#复选框被鼠标右键时触发的DOS
rightDos:
- "open<->null"
#鼠标悬浮在复选框时触发的DOS
hoverDos:
- "open<->null"
#鼠标悬浮离开复选框时触发的DOS
leaveDos:
- "open<->null"
%下面是输入框组件的DOS填写位置
#在输入槽内按下回车后执行DOS
enterDos:
- "opcmd<->say &a亲爱的 &e%player_name% &a想说 %input%"
DOS都是以 标记<->参数 的形式书写 不同的标记拥有不同的功能
在书写时,支持**多行字符串与列表**两种格式,下面以openDos为例来展示两种书写格式
#多行字符串
openDos: |
message<->开了界面thisGui
delay<->3000
playSound<->opengui
#列表
openDos:
- "message<->开了界面thisGui"
- "delay<->3000"
- "playSound<->opengui"
Tips:更推荐上面的多行字符串的这种写法,可以利用缩进格式增加可读性
# 在 DOS 中 有以下几种特殊占位符
# thisGui 会被替换为发出该DOS的界面名字 thisPart 会被替换为发出该DOS的组件名字
# 例如 update<->thisGui@thisPart 就会更新发出该DOS的组件
# parentPart 会被替换为发出该DOS的父组件的名字
# preChild 会被替换为发出该DOS的界面的上一层子界面的名字 nextChild 会被替换为发出该DOS的界面的下一层子界面的名字
# firstChild 会被替换为发出该DOS的界面的第一层子界面的名字 lastChild 会被替换为发出该DOS的界面的最后一层子界面的名字
# 如果要更新滚动框中的组件(slider,scrollableParts)时组件索引名要设置为 滚动框组件索引名$滚动框内组件的索引名
# 如果要更新画布中的组件(relativeParts)时组件索引名要设置为 画布组件索引名$画布内组件的索引名
#关闭当前界面 同时打开另一个界面
- "open<->default2"
#关闭当前界面
- "open<->null"
#跳转到此处的第六行dos
- "goto<->6"
#跳转到此处第一行的dos
- "goto<->1"
#运行到第十行dos就结束运行(包括第十行)
- "limit<->10"
#标记该行dos为mark1 可以标记为任何字符 例如 mark<->萌芽引擎
- "mark<->mark1"
#运行到mark1就结束
- "limit<->mark1"
#跳转至mark1继续运行
- "goto<->mark1"
#延迟3000毫秒后才会往下面运行dos
- "delay<->3000"
# 运行新的名为dosName的dos 用;隔开
- "run<->dosName@mesaage<->萌芽引擎1;message<->萌芽引擎2"
# 运行新的名为dosName的dos 用;隔开 与run的区别是 他是立刻执行的 没有延迟 但是不支持 goto进行循环
- "exe<->dosName@mesaage<->萌芽引擎1;message<->萌芽引擎2"
- "stop<->dosName" # 停止名为dosName的dos的运行
#播放声音
- "playSound<->opengui"
#停止播放的声音@淡出tick(默认为0)
- "stopSound<->opengui@fadeOut"
#以子界面(二级界面)模式打开一个gui
- "openChild<->default3"
#关闭最后一个子界面
- "openChild<->null"
#关闭名为default3的子界面
- "closeChild<->default3"
#关闭所有子界面
- "closeChild<->all"
#################################################################
% 出于对安全的考虑,在Config.yml中注册过的的指令,
% 才允许被萌芽GUI的指令型DOS中的servercmd、opcmd运行。
% 禁止运行敏感指令 例如 op、gamemode等,如需使用 强烈建议使用其他插件处理
#################################################################
#点击的人以玩家的身份执行命令(支持PAPI变量)
- "cmd<->say %player_name%打开了"
#点击的人以OP的身份执行命令(支持PAPI变量)(不推荐使用)
- "opcmd<->gamemode %player_name% 1"
#点击的人让后台执行一条命令(支持PAPI变量)(不推荐使用)
- "servercmd<->say %player_name%"
#将消息输出到玩家聊天框 \n 换行
- "message<->&a萌芽引擎\n&b棒棒棒!"
#让玩家说出这句话,其他玩家也会收到 \n 换行
- "chat<->&a萌芽引擎\n&b棒棒棒!"
#在不询问玩家是否同意的情况下 直接打开指定网页
- "openWeb<->http://wiki.germengine.com/"
#代表一个置顶的HUD提示消息,会永远显示在屏幕最顶端,目前支持 left1,center1,anchor
- "hudMessage<->left1@我是提示内容\n会换行"
#注意 索引名是在Config 配置的名字
- "hudMessage<->anchor@索引名@内容"
#禁止所有可互动操作(例如按钮的点击 悬浮改图片 播放声音)
- "invalid<->all"
#禁止default界面里所有可互动操作(例如按钮的点击 悬浮图片 播放声音)
- "invalid<->default@all"
#禁止button(这里填的是yml的索引名)的可互动操作(例如点击 悬浮图片 播放声音)
- "invalid<->button"
#禁止default界面里button(button是索引名)的可互动操作(例如点击 悬浮图片 播放声音)
- "invalid<->default@button"
#开启所有已打开界面的部件中可互动操作(例如点击 悬浮图片 播放声音)
- "valid<->all"
#开启已打开界面default所有的可互动操作(例如点击 悬浮图片 播放声音)
- "valid<->default@all"
#开启已打开界面中所有索引名为button的可互动操作(例如点击 悬浮图片 播放声音)
- "valid<->button"
#开启已打开界面default中索引名为button的可互动操作(例如点击 悬浮图片 播放声音)
- "valid<->default@button"
#########################################
%注意:使用执行动画型DOS的前提是目标组件支持动画
#########################################
#使得已开启界面default中索引名为button的部件播放动画default_rotate与default_fade(更新列表时用$或者\n隔开)
- "playAnimation<->default@button@default_rotate$default_fade"
#使得已开启界面default中所有部件播放动画default_rotate与default_fade(更新列表时用$或者\n隔开)
- "playAnimation<->default@all@default_rotate$default_fade"
#指定一个组件播放模型动作 该组件需要支持实体类型(type等于entity) 在各子界面无重复组件indexName时 界面名可省略
- "playModelAnimation<->界面名@组件名@动画名"
#指定一个组件停止播放模型动作 该组件需要支持实体类型(type等于entity) 在各子界面无重复组件indexName时 界面名可省略
- "stopModelAnimation<->界面名@组件名@动画名"
############################################
%注意:使用变量化槽位型DOS的前提是目标槽位加载了物品
############################################
# 将槽位id为germplugin_test的物品转化为变量
# 变量 %identity_slot_germplugin_test_tip0% 代表名字
# 变量 %identity_slot_germplugin_test_tip1-100% 分别代表物品描述的1-100行
- "placeholderItem<->identity@germplugin_test"
#在label组件 %某变量%的行后面插入 萌芽萌芽
- "insertLabel<->thisGui@某个label部件索引位置@%某变量%@萌芽萌芽"
#在label组件的最后面插入 萌芽萌芽
- "addLabel<->thisGui@canvasChannel1$MessageList@萌芽萌芽"
#删除label的第一百行
- "removeLabel<->thisGui@canvasChannel1$MessageList@100"
#删除label的第一行
- "removeLabel<->thisGui@canvasChannel1$MessageList@first"
#删除label的最后一行
- "removeLabel<->thisGui@canvasChannel1$MessageList@last"
# 模拟左键点击一个指定identity的槽位 最后的true代表强制性的 无视slot的invalid和interact是否开启
- "interactSlot<->ClickSlot@identity@true"
# 模拟Shift+左键点击一个指定identity的槽位 最后的true代表强制性的 无视slot的invalid和interact是否开启
- "interactSlot<->ShiftClickSlot@identity@true"
# 模拟右键点击一个指定identity的槽位 最后的true代表强制性的 无视slot的invalid和interact是否开启
- "interactSlot<->RightSlot@identity@true"
# 模拟Shift+右键点击一个指定identity的槽位 最后的true代表强制性的 无视slot的invalid和interact是否开启
- "interactSlot<->ShiftRightSlot@identity@true"
#指定一个entity组件播放模型动作 在各子界面无重复组件indexName时 界面名可省略
- "playModelAnimation<->界面名@组件名@动画名"
#指定一个entity组件停止播放模型动作 在各子界面无重复组件indexName时 界面名可省略
- "stopModelAnimation<->界面名@组件名@动画名"
#########################################################
% 如果要更新滚动框中的组件(slider,scrollableParts)时
% 组件索引名要设置为 部件索引名$滚动框内部件的索引名
% 如果要更新画布中的组件(relativeParts)时
% 组件索引名要设置为 组件索引名$画布内组件的索引名
#########################################################
#重新载入所有组件 动画、坐标、大小之类的组件属性都将被重新计算再载入
- "update<->all"
# 重新载入所有已打开界面中索引名为button的组件 动画、坐标、大小之类的组件属性都将被重新计算再载入
- "update<->button"
#重新载入已打开的界面中default里的所有组件
- "update<->default@all"
#重新载入已打开的界面中default里的索引名为button的组件
- "update<->default@button"
#更新所有已打开界面中索引名为 button 组件中 width 属性 为 w*10
- "update<->button@width@w*10"
#更新所有已打开界面中所有组件 width 属性 为 w*10
- "update<->all@width@w*10"
#重新载入已打开的界面中default里的索引名为button的组件 更新组件中 width 属性 为 w*10
- "update<->default@button@width@w*10"
#重新载入已打开的界面中default的所有组件中 width 属性 为 w*10
- "update<->default@all@width@w*10"
#更新已打开的界面中索引名为 button 组件中 animations 属性 为 default_fade 和 default_rotate (更新列表时用$或者\n隔开)
- "update<->texture@animations@default_fade$default_rotate"
# 可修改界面的options选项
- "updateOption<->界面名@字段名@值"
#删除已打开的界面中所有索引名为 button 的部件
- "remove<->button"
#删除已打开的default界面中索引名为 button 的部件
- "remove<->default@button"
#将组件排序 例如 gui(名字是test1)内有个canvas(test_canvas1)内有组件p1,p2,p3
#现在我想让让他按照 p3,p1,p2的顺序排列 那么就可以使用
#这个dos test1$test_canvas1@p3,p1,p2
- "sort<->gui$partRealName@indexName1,indexName2,indexName3"
# 操作其他组件 slot也可以操作 相当于可以替代interactSlotDos 不过上面的可以用identity
- "interact<->GuiName@PartName@Click@true"
- "interact<->GuiName@PartName@ShiftClick@true"
- "interact<->GuiName@PartName@Right@true"
- "interact<->GuiName@PartName@ShiftRight@true"
#运行新的名为dosName的DOS 用;隔开将要执行的多个DOS
- "run<->dosName@mesaage<->萌芽引擎1;message<->萌芽引擎2"
# 运行新的名为dosName的dos 用;隔开 与run的区别是 他是立刻执行的 没有延迟 但是不支持 goto进行循环
- "exe<->dosName@mesaage<->萌芽引擎1;message<->萌芽引擎2"
#停止名为dosName的dos的运行
- "stop<->dosName"
#例如 aaaa@10 这样变量库就会新添加一个变量 %aaaa%=10
- "putPlaceholder<->变量名@值"
#例如 aaaa@random[10,20] 这样变量库就会新添加一个变量 %aaaa%将会取值为在10~20之间的某个数(包含10和20)
- "putPlaceholder<->变量名@random[10,20]"
#注意!如果第二个@后面跟了一个true 那么代表这个变量不会过期,否则在这里放入的变量将会在60秒内未使用的情况下过期
- "putPlaceholder<->变量名@值@true"
# 使用putPlaceholder时 例如 "putPlaceholder<->aa@20+7" 那么%aa%的得到的结果还是 20+7
# 使用 "calPlaceholder<->aa@20+7" 那么%aa%的得到的结果还是 27
# 例如 "calPlaceholder<->aaa@100*99" 这样后变量库会存在一个变量为 %aaa%=9900
- "calPlaceholder<->变量名@100 * %变量%"
#注意!如果第二个@后面跟了一个true 那么代表这个变量不会过期,否则在这里放入的变量将会在60秒内未使用的情况下过期
- "calPlaceholder<->变量名@100 * %变量%@true"
#刷新该变量的值 不写为1秒自动刷新一次 如需更快刷新可以使用此dos 注意 请省略原papi变量的百分号%
- "refreshPlaceholder<->vault_eco_balance"
#删除此变量 写all时会删除全部变量(当变量库不存在某个变量时会向服务器重新获取) 注意 请省略原papi变量的百分号%
- "removePlaceholder<->vault_eco_balance"
- "wait<->%vault_eco_balance%>100" #等待变量值通过才会继续向下执行
#判断玩家权限等于true时 才会继续向下面运行
- "placeholder<->%player_has_permission_germ_gui%@true"
#玩家的金钱变量等于1000时 才会继续向下面运行
- "placeholder<->[%vault_eco_balance%]@[1000]"
#客户端内有此变量才会接着往下运行 注意 请省略原papi变量的百分号%
- "havePlaceholder<->vault_eco_balance"
#玩家的金钱变量等于1000时运行 第5~10行的dos 否则运行 第10~15行的dos
- "placeholder<->[%vault_eco_balance%]@[1000]@[5,10]@[10,15]"
#玩家的金钱变量等于1000时运行 第5行~最后一行的dos 否则运行 第10行~最后一行的dos
- "placeholder<->[%vault_eco_balance%]@[1000]@[5]@[10]"
#这里的 mark 只为示范,为了说明这里的跳转位置也可以使用 mark标记的位置
- "placeholder<->[%vault_eco_balance%]@[1000]@[mark1,mark2]@[mark3,mark4]"
#玩家的金钱变量大于或等于1000时 才会继续向下面运行
- "placeholder<->%vault_eco_balance%@1000"
#玩家的金钱变量小于或等于1000时 才会继续向下面运行
- "placeholder<->1000@%vault_eco_balance%"
# 此Dos的格式 条件@达成条件@条件未达,条件由各种运算符组成,达成条件、条件未达与placeholder的用法一致不过多解释
# 所有运算的量都可以用变量表示 例如 %player_health% >= 100 (PS:所有比较运算符如果比较成功返回1)
# 写法一: 玩家的金币数量大于100 才会向下执行
- "condition<->%vault_eco_balance%>100"
# 写法二: 条件@[gotoDos]@[gotoDos] 此处代表玩家的金币大于100时 跳转到mark1标记处(也可以使用行号代表) 未达时跳转到mark2
- "condition<->%vault_eco_balance%>100@[mark1]@[mark2]"
# 写法三: 条件并条件@[gotoDos,limitDos]@[gotoDos,limitDos]
- "condition<->%vault_eco_balance%>100 && %vault_eco_balance%<500@[mark1,mark2]@[mark3,mark4]"
# 写法四: 条件@{条件成立运行的dos}@{条件失败运行的dos} 意为:当玩家的金币大于100时夸两句(其实是执行了多条dos,每条用;隔开,看起来像这样 条件@{dos1;dos2;dos...}@{dos1,dos2,dos...})
- "condition<->%vault_eco_balance%>100@{message<->你的金币真多;message<->可以分我一些么}@{message<->你真穷;message<->我可以送你些金币}"
# 实现望远镜效果 本DOS格式为: 修改相机的类型@过渡时间@持续时间@目标值@是否从头开始 fov可以使用变量 %setting_fov% 来获取玩家客户端设置的fov
- "camera<->fov@1000@2000@20@false"
# 反复修改y加delay可以实现镜头地震的效果 支持修改的相机类型有 fov offset_x offset_y offset_z pitch yaw roll camera_pitch camera_yaw camera_roll
- "camera<->offset_y@100@100@rnd(2)@false"
# 将相机脱离出玩家本体,可以实现类似于第三人称的效果
- "remoteCamera<->switch@true/false"
# 将脱离出来的相机沿着x轴移动5格 本dos格式为: 移动类型@过渡时间@x@y@z@yaw@pitch 移动类型有: move(根据相机当前位置移动) move_to(移动到某个坐标) move_relative_self(根据玩家本体的位置移动)
- "remoteCamera<->move@1000@5@0@0@0@0"
#更新玩家客户端Bend开关
- "updateClient<->bends@enable@true/false"
#更新玩家客户端的标题为 标题名可以修改标题
- "updateClient<->title@Minecraft [1.12.2] Powered by GermEngine"
# 第一人称时关闭或者显示绑定在自己身上的effect特效
- "updateClient<->effect@skin@showSelf@true/false"
# 开启或者关闭渲染HUD
- "updateClient<->gui@showHUD@true/false"
#开启或者关闭渲染除了topper以外的所有HUD
- "updateClient<->gui@showHUD2@true/false"
# 开启或者关闭渲染时装
- "updateClient<->skin@showHUD@true/false"
# 开启或者关闭真实第一人称
- "updateClient<->rfp2@enable@true/false"
# 第一人称时关闭或者显示绑定在自己身上的effect特效
- "updateClient<->effect@showFirstView@true/false"
# 第一人称开关显示自己的时装(包括基岩盔甲)
- "updateClient<->skin@showFirstView@true/false"
# 动态开关所有客户端germmod.cfg的配置节点
- "updateClient<->engineConfig@配置节点@true/false"
#重置玩家的自定义视口(类似调整第三人称准星位置)
- "updateClient<->viewport@reset"
#将viewportX的值设置为4,viewportX是左右,viewportY是上下,viewportZ是前后
- "updateClient<->viewport@viewportX@4"
#是否开启类似时装工坊中的时装武器覆盖在原版钻石剑中的逻辑
- "updateClient<->skin@itemSkinOverride@true/false"
#使某个坐标发光 设置为0就是取消发光
- "block<->light@x@y@z@0-100"
#实现望远镜效果 本DOS格式为:修改相机的类型@过渡时间@持续时间@目标值@是否从头开始
- "camera<->fov@1000@2000@20@false"
#反复修改y加delay可以达到镜头地震的效果
- "camera<->offset_y@100@100@rnd(0,2)@false"
#目前支持的相机类型:fov offset_x offset_y offset_z pitch yaw roll camera_pitch camera_yaw camera_roll
#将相机脱离出玩家本体
- "remoteCamera<->switch@true/false"
#将脱离出的相机沿x轴移动5格
- "remoteCamera<->move@1000@5@0@0@0"#本DOS格式为:移动类型@过渡时间@x@y@z@yaw@pitch 移动类型暂且只有move
- "camera<->turnlook@1000" # 让玩家头和身体朝着一个方向
# 实现望远镜效果 本dos格式为: 修改相机的类型@过渡时间@持续时间@目标值@是否从头开始 fov可以使用变量 %setting_fov% 来获取玩家客户端设置的fov
- "camera<->fov@1000@2000@20@false"
# 反复修改y加delay可以实现镜头地震的效果
# 支持修改的相机类型有 fov offset_x offset_y offset_z pitch yaw roll camera_pitch camera_yaw camera_roll
- "camera<->offset_y@100@100@rnd(2)@false"
- "camera<->lockmove@-1"
- "camera<->lockview@1@-1"
- "camera<->unlockview"
- "camera<->unlockmove"
- "camera<->reset" # 重置相机取消所有移动
- "remoteCamera<->switch@true/false" # 将相机脱离出玩家本体,可以实现类似于第三人称的效果
# 将脱离出来的相机沿着x轴移动5格 本dos格式为: 移动类型@过渡时间@x@y@z@yaw@pitch
# 移动类型有: move(根据相机当前位置移动) move_to(移动到某个坐标) move_relative_self(根据玩家本体的位置移动)
# 使用例子
# /gp camera setview 名字 2 变为第三人称
# 镜头离开玩家向前移动
# /gp hud dos 名字 remoteCamera<->switch@true<br>remoteCamera<->move@1000@20@0@0@0@0<br>delay<->2000<br>remoteCamera<->switch@false
- "remoteCamera<->move@1000@5@0@0@0@0"