【命令】命令判定条件的基本项目列表
本帖最后由 惯宣-CGX_ 于 2024-5-20 02:24 编辑命令判定条件的基本项目列表
献给 YanRan233
『绪论』
【定义】
- 一条完整的命令链在执行命令之前,有时需要一些条件加以限制,或是说只有在达成条件的时候,才可以继续执行后面的命令。这就是通俗意义的「判定条件」。故而本文在此选取使用命令判定条件的,一些较为基本的项目,将其罗列出来,以供所需之处随时查阅。
- 需要明白,判定条件只是判定条件是否通过,条件通过后并不意味着命令链会立即触发,触发命令只能使用对应的「触发器」。命令方块里面有基本的红石激活和保持开启,但是仍然有“断链”和“克隆”这样另类的触发方式。更不用说动画控制器的Qurey Function以及利用实体事件来判定了,毕竟行为包里连触发器都要重新搭建。
- 关于触发器可以查阅《常见命令方块条件链式汇总及各功能偏向的比较》。如果使用没有三色命令方块的旧版本或是已经习惯在命令链当中穿插红石结构,可以查阅《〈红石理论〉| Part I 红石·理论基础》,以解决红石结构运作中出现的问题。
【基本逻辑】
- 而搭建命令架构,是由「技术决定效果」。步骤上是根据目标效果,选取所需要的技术,但是在此过程中起决定性作用的是所选取的技术。整个机制最终呈现什么样的效果,最开始都是依据所选取的技术展开构建的。
- 一般来说,要检测一个东西,最好就是能够直接检测,True就是True、False就是False。但是由于命令本身存在着极大的局限性和缺陷,多数情况下还是更常用到「等效代替法」,也就是间接判定。例如:检测玩家是否受到攻击,会使用耐久值为0的盔甲判定是否受到攻击。这是因为在BE中,仅依靠纯命令是无法直接检测玩家是否受到攻击的,所以使用一旦受到攻击就会损坏并消失的盔甲进行代替判定。
- 那么有些时候,还会碰到命令不能直接检测“无”的情况。这个时候就需要「反选」机制了,既然能检测“有”,这样只要把输出改变为相反的结果就好了。所以存在三种办法反选:一、利用比较器检测命令执行状态,然后用红石的非门结构改变结果;二、使用断链法改变命令接续状态;三、将输出结果转化为方块,再检测方块类型决定结果,同时这个也是选择的做法。
- 无论想要实现什么机制,都是无法离开其应用的技术基础的。必须要存在一个能检测的条件,这样才有可以检测的前提,必须尊重客观规律:不存在的事物就是不存在。至于一时之间超脱当前技术水平的局限,几乎是不可能的,因而剩下的只有「穷举」这一条路。所以,如果一个判定机制在穷举之后仍旧做不到,请放弃。
- 受限于篇幅与所识,本文在此仅列出可以直接检测的项目列表,也就是标题所写的「基本项目」。在此之外,如果对本文所记述的命令产生了任何疑问,可以查询官方中文wiki以获取该命令的更多相关信息。
『列表』
条件检测千千万,亿舍Q特占一半。
【目标选择器】
- 目标选择器是最常用于过滤目标的条件。
目标选择器类型
@a全部玩家
@p最近的玩家
@s自己
@r随机玩家。可用type选择非玩家。
@e实体
目标选择器参数
name实体名称
family族
m游戏模式
haspermission权限
c数量
hasitem拥有物品
type实体类型
l、lm经验等级,lm为最小等级
scores计分项分数
tag标签
x,y,z执行位置
dx,dy,dz执行位置范围
r、rm距离内、外
rx、rxm垂直旋转角度
ry、rym水平旋转角度,m为最小旋转角度
【检测死亡玩家】
/tag @a add "死亡"
/tag @e remove "死亡"
这里以标签标记为例:@a包括已死亡的玩家,而@e选择的是实体,此时玩家的实体仍未重生,无法被选择到。
【检测有无实体】
/testfor @a
/execute if entity @a
/execute unless entity @a
/execute @a ~~~ scoreboard players add 实体数量 实体数量 1
testfor是最基本的检测有无实体,没有实体则运行失败。因为没有目标实体时是运行失败,所以用testfor检测没有目标实体,需要用到反选才可以检测运行失败的状态。有点小麻烦。
新版本的execute则没有这个问题。作为代替办法,使用execute让目标实体执行scoreboard,给记分板加分也是可行的方案,这样可以直接检测出目标实体的数量。
【选择特定位置上的实体】
修改执行坐标:
/.. @e ..
x、y、z分别是经度、高度、纬度,取决于地图内的实地坐标。使用“~”则是根据实体当前所在的位置进行偏移。但是这样只是改变目标选择器的执行位置,如:@p会选择距离该坐标最近的玩家,而@a依旧会选择全部玩家。如果要选择特定区域内的实体,需要用到dx、dy、dz限制范围。
dx、dy、dz的正方向与坐标方向一致,都朝向东南。x、y、z和dx、dy、dz、两类配合,共同形成一个值域,并选择在坐标上存在于该值域的目标。这个值域随着参数输入的数量而改变维度,呈现为线、平方、立体的过渡,选择适合的来用就好。
利用实体:
/execute at @e as @p at @s run ..
/execute @e ~~~ execute @p ~~~ ..
使用execute可以在目标实体处执行命令,配合目标选择器的rm、m可以选择该实体一定范围内的目标。这个范围呈现球形。
利用方块:
/execute as @e at @s if block ~~~ stone
/execute @e ~~~ detect ~~~ stone 0 ..
使用execute还可以检测目标实体的相应位置是否为选定方块,即选择相应位置有选定方块存在的目标。
【检测方块】
检测方块通常使用如下命令:
/testforblock ~~~ stone
/testforblocks ~~~ ~~~ ~~~ all
/execute @e ~~~ detect ~~~ stone 0 ..
/execute if block ~~~ stone run ..
/execute if blocks ~~~ ~~~ ~~~ all run ..
testforblock用于检测单个方块可以完全被execute代替。而testforblocks则用于检测两个区域的方块是否一致,新execute还包括if blocks可以代替testforblocks。
不使用新execute检测不为某个方块都是需要反选的,所以不到非必要的时候,尽可能地还是写要检测什么方块。一个常见的误区就是:应该要去检测某个位置是否为空气(air),而不是去检测是否不为某个方块。
【非定点检测方块】
/execute as @e at @s if block ~~~ stone
/execute @e ~~~ detect ~~~ stone 0 ..
使用execute可以利用实体,将检测的位置修改为变动的坐标。
【检测槽位】
容器:
o/replaceitem block ~~~ slot.container 0 keep air
v> /..
使用replaceitem的keep模式替换物品,只有在槽位为空时命令才会执行成功,失败则不会替换,也就是检测有无物品。
可惜的是,仅凭replaceitem还无法检测容器内的物品,比较常见的做法是破坏容器,利用目标选择器选择物品。当然,使用testforblocks(即execute if blocks)也是一种办法。
实体:
o /replaceitem entity @a slot.weapon.mainhand 0 keep bedrock
v /.. @a ..
v /clear @a bedrock
命令选择所有目标判定,即使有部分目标执行失败,只要有目标执行成功仍会算作命令执行成功,下一个有条件的命令方块可以激活,导致误判。所以建议使用游戏过程中不会出现的物品,配合目标选择器的hasitem参数判定。
hasitem的补充:
/.. @e ..
/.. @e ..
使用hasitem检测没有某样物品时可以使用参数quantity=0。但是要注意air的数量永远等于0,即不能用item=air来判定某个槽位是否为空。
【读取记分板】
o/scoreboard players test 实体数量 * 0
v> /..
o /scoreboard players operation @e 记分项 = 目标 记分项
v /execute @e ~~~ ..
o /execute if score 目标 记分项 matches 0..
伪玩家记分不可以使用目标选择器检测,因而要使用记分板的test语法检测,这样就依赖有条件的命令方块了。因此也有故意将一个实体充作闪存,然后在需要时覆写记分,并交由目标选择器进行选择。这类做法主要是应用于函数内,当然有新execute那当然用新execute是最好的。
【选择没有分数的目标】
/scoreboard players add @a 记分项 0
/execute as @a at @s unless score 目标 记分项 matches 0..
使用记分板的add可以给目标添加0分,使目标变为有分数,然后可以使用目标选择器进行选择。在新execute中可以使用unless score子条件,选出真正没有分数的目标。
【选择变动分数】
/execute as @a at @s if score @s 记分项 = 目标 记分项
减法:
o /scoreboard players operation @a 记分项 -= 目标 记分项
v /.. @a ..
要选择变动分数的目标最好就是用新execute,不然在旧版本就只有减法一个办法。因为不知道变动的分数是多少,所以让目标选择器归零,将所有目标的分数减去变动的分数,这样选出分数为0的目标,就是和变动的分数一致的目标。
【循环检测中仅激活一次】
标签:
o /tag @a[条件] add "符合条件"
v /execute @a ~~~ ..
v /tag @a add "已执行"
v /tag @a[条件] remove "符合条件"
v /tag @a[不符合条件] remove "已执行"
用标签循环检测就是不停地给予标签到符合条件的目标,然后以标签为标记执行命令,最后移除标签。那么仅激活一次的做法就是:在激活后给予标签以识别出已执行的目标,直至目标不符合条件、可以再次激活时才去除第二重标签,允许再次激活。
记分板:
o /scoreboard players set @a[不符合条件] 记分项 0
v /scoreboard players add @a[条件,scores={记分项=0..1}] 记分项 1
v /execute @a ~~~
记分板中用add可以给符合条件的目标加分,那么只选择分数为预定值的目标执行命令就可以了。然后在可以再次执行命令的时候归零,重新进行这个循环。
请注意,testfor是检测过就会触发(也就是说那个物品已经被检测过一次就不会反复触发)而execute是检测到就算触发(如果那个物品一直被检测,则会一直触发指令) 黑夜小祥 发表于 2024-3-1 17:13
请注意,testfor是检测过就会触发(也就是说那个物品已经被检测过一次就不会反复触发)而execute是检测到就 ...
所以开头就要搞明白,“判定条件”和“触发”是两回事。
你使用比较器检测那当然会在失败之前一直保持激活,使用命令方块的有条件则不会。其呈现效果和execute基本一致。
归根到底,这不是testfor的问题,而是你没有选好触发器。
页: [1]