进度
进度(Advancements)是Minecraft在1.12加入的新系统,替代了旧有的成就(Achievement)系统。
进度除了能引导玩家进行游戏外,有以下特别的地方:
- 能够自定义。玩家能够自定义进度,只需要根据下文指出的架构编写JSON文件并将JSON文件放于
(地图)/data/advancements/(命名空间)/路径
里,这方式和命令函数类似。自定义的功能也非常强大,详见下方的介绍。 - 更为精美的界面。进度有一个独立的界面,里面有不同的选项卡(Tab),显示进度树(Tree),每个进度都有图标、标题、描述,选项卡的背景也能自定义。
- 完成奖励。能够定义完成进度时获得的奖励。
进度虽然是以树(Tree)形式显示的,大部分进度也有其父进度,然而不需要先达成父进度也能达成之后的子进度。换句话说,玩家能以任何次序获得进度。
每个玩家的每个进度只能获得一次,除非被人使用命令删除了该玩家的该进度。
进度的判据(Criteria)不在乎完成时间,只要完成的判据符合要求(Requirements),就可以完成该进度。
如果把进度放在命名空间为minecraft
,路径和原版相同名称的进度一样的地方,则会覆盖该原版进度。
地图制作中,我们除了利用进度引导玩家游戏以外,我们也会使用进度当作检测方法,检测玩家行为。
警告!
本章节部分图片可能会令密集恐惧症患者及强迫症患者感到不适。
如果读者患有以上两种疾病,请点击本框,关掉相关图片。
常见类型
本章节的JSON格式将会以列表方式列出,类型会在描述里说明(compound除外)。
温馨提示:别直接使用浮点数检查数值,如果那是一个浮点数,请使用其范围(浮点数)版本。
范围
key name
(标签名称)max
: 最大数值,类型为(类型)。min
: 最小数值,类型为(类型)。
(类型)代表了视乎引用时怎么写。比如类型为 范围(整数)
,则类型为整数;类型为 范围(浮点数)
,则类型为浮点数。
实体格式(Entity)
- Entity
distance
absolute
: 绝对距离,即距离^2 = x^2 + y^2 + z^2
,其中^
代表次方,x y z 代表相应轴上的距离。类型为 范围(整数)。horizontal
: 平面距离,即距离^2 = x^2 + z^2
。类型为 范围(整数)。x
: x轴上的距离。类型为 范围(整数)。y
: y轴上的距离。类型为 范围(整数)。z
: z轴上的距离。类型为 范围(整数)。
effects
<minecraft:效果名称>
,一个效果,以其效果名称为标签名称。(需要minecraft:
前缀)amplifier
: 效果倍率,整数int。(如果需要检测范围请使用下一个标签)amplifier
: 效果倍率。类型为 范围(整数)。duration
: 时间(秒数),整数int。duration
: 时间(秒数)。类型为 范围(整数)。
location
: 检测实体位置相关信息。类型为 位置。nbt
: 检测实体NBT,类型为字串。(NBT的格式就是命令里的检测格式,Base tag为 entity ,如"{CustomName:\"test\"}"
)type
: 实体ID,需要minecraft:
前缀,类型为字串。
物品格式(Item)
- Item
count
: 物品数量。整数int。count
: 物品数量。范围(整数)。data
: 物品数据值。整数int。durability
: 物品耐久度。整数int。durability
: 物品耐久度。范围(整数)。enchantments
: 附魔列表。子标签为compound。- (一个附魔)
enchantment
: 附魔id(需要加上minecraft:
前缀)。字串。level
: 附魔等级。整数int。level
: 附魔等级。范围(整数)。
- (一个附魔)
item
: 物品ID。(需要加上minecraft:
前缀)。字串。nbt
: 物品NBT。Base tag为tag
,如"{display:{Name:\"distilled water\"}"}
。字串。potion
: 药水ID。参见https://minecraft.gamepedia.com/Potion#Item_data。字串。
位置格式(Location)
- location
biome
: 实体在于的生态群系ID。类型为字串。dimension
: 实体在于的世界。类型为字串。
只接受overworld
,the_end
及the_nether。
feature
: 实体在于的结构。类型为字串。
只接受EndCity
,Fortress
,Mansion
,Mineshaft
,Monument
,Stronghold
,Temple
及Village。
position
x
: 实体的x坐标。类型为浮点数。x
: 实体的x坐标。类型为 范围(浮点数)。y
: 实体的y坐标。类型为浮点数。y
: 实体的y坐标。类型为 范围(浮点数)。z
: 实体的z坐标。类型为浮点数。z
: 实体的z坐标。类型为 范围(浮点数)。
伤害类型(Damage type)
- damage type
bypasses_armor
: 伤害是否不能被阻挡。类型为布尔值(True/False)。
伤害来源包括: 火焰,窒息(方块及世界边界),实体挤压(范围内太多实体),溺水,饥饿,掉落,撞墙(飞行时),虚空(掉落虚空及/kill命令),重新计算血量(比如超出了上限),魔法伤害,凋零伤害。bypasses_invulnerability
: 伤害是否能伤害无敌的玩家(创造模式)。类型为布尔值。
伤害来源只有虚空伤害(包括掉落虚空及kill
命令)。bypasses_magic
: 伤害是否来自饥饿。类型为布尔值。direct_entity
: 直接伤害来源(实体,如 箭、火球等,不在乎是谁射出的)。类型为 实体。is_explosion
: 检查伤害是否来自爆炸。类型为布尔值。
伤害来源包括: 爬行者,TNT,矿车TNT,地狱幽灵火球,床(在地狱睡时会爆炸),凋灵,凋灵之首。is_fire
: 检查伤害是否来自火焰。类型为布尔值。 伤害来源包括: 站在火焰方块里,整个人着火,在熔岩里,在岩浆块上,恶魂火球,烈焰人火球。is_magic
: 检查伤害是否来自魔法。类型为布尔值。
伤害来源包括: 闪电,瞬间伤害,中毒,守卫者的部分射线伤害(部分算作生物伤害),唤魔者的尖牙攻击,无主的凋灵之首(unowned wither skulls, 通过summon
命令生成的, 因为凋灵发射的凋灵之首算作生物伤害)is_projectile
: 检查伤害是否来自投射物。类型为布尔值。
投射物包括: 烈焰人火球 ,末影龙火球,恶魂火球,羊驼的口水,箭(所有),射出的火焰弹,丢出的蛋,丢出的雪球,凋灵之首。source_entity
: 伤害来源(实体)。类型为 实体。
如果是投射物的伤害,则需要视乎该投射物有没有"主人",也就是射出此投射物的实体。如果有,则算作该主人造成的伤害,否则则算作该投射物的伤害。 如果是中毒这类伤害,则不会被算作是实体造成的伤害(即使是由女巫扔出的药水)。
伤害(Damage)
- damage
blocked
: 检查伤害有没有被成功阻挡。类型为布尔值。dealt
: 检查原始伤害数值(不计算伤害减免)。类型为浮点数。dealt
: 检查原始伤害数值(不计算伤害减免)。类型为范围(浮点数)。direct_entity
: 直接伤害来源(实体,如 箭、火球等,不在乎是谁射出的)。类型为 实体。source_entity
: 伤害来源(实体)。类型为 实体。
如果是投射物的伤害,则需要视乎该投射物有没有"主人",也就是射出此投射物的实体。如果有,则算作该主人造成的伤害,否则则算作该投射物的伤害。
如果是中毒这类伤害,则不会被算作是实体造成的伤害(即使是由女巫扔出的药水)。taken
: 检查实际受到的伤害(计算伤害减免后)。类型为浮点数。taken
: 检查实际受到的伤害(计算伤害减免后)。类型为范围(浮点数)。type
: 检查伤害的类型。类型为 伤害类型。
criteria及requirements
Advancement 里也使用criteria及trigger,翻译也和记分板变量里的一样,然而这些并不是记分板的元素。
criteria格式
criteria(判据)格式:
- (Advancement根标签)
criteria
: 一堆判据,类型为compound。<criteria name>
: 一个判据。标签名称为自定义判据名称(命令里及requirements可能需要使用,建议使用有意义的名称),类型为compound。trigger
: 判据的触发器,指定这判据会检查什么。类型为字串conditions
: 判据的详细条件。不同触发器会有不同条件,此处就不详细列出。类型为compound。
不一定存在。比如minecraft:impossible
这个trigger并没有conditions。
触发器及其详细条件可以在 https://minecraft.gamepedia.com/Advancements#List_of_triggers 找到。
Conditions里可能使用上述常见格式,如Damage tags
代表伤害,Tags common to all items
代表物品格式等。
阅读wiki的JSON架构和阅读NBT类似,标签左边都会有个图标表示标签类型,如果分不清则可以把鼠标悬浮在该图标上,这样会显示该标签类型。
我们以以下两个触发器为例子:
比方说第一个我们希望检查吃了一个名字为毒苹果
的苹果。
我们会这样写(假设判据名称为ate_poison_apple
):
{
"criteria": {
"ate_poison_apple": {
"trigger": "minecraft:consume_item",
"conditions": {
"item": "minecraft:apple",
"nbt": "{display:{Name:\"毒苹果\"}}"
}
}
}
}
然后如果我们只想让命令能够给予这进度,我们会使用minecraft:impossible
这触发器。
{
"criteria": {
"impossible": {
"trigger": "minecraft:impossible"
}
}
}
requirements
如果我们想做复杂一些的判断,比如说有多个选项,每个选项需要达成一堆条件,那么我们应该怎么做呢?
方法就是使用requirements。(不过如果是全部判据都需要达成的话就不需要写requirements)。
- (Advancement根标签)
requirements
: (所有 子列表都要符合要求才算完成)- (一个列表)。(任何 一个子标签符合就算整个列表符合要求)
- 一个判据名称,字串。
- (一个列表)。(任何 一个子标签符合就算整个列表符合要求)
其实requirements是一个 合取范式,也就是一堆or的and。
比如说
(a or b) and (c or d or e)
这就是一个合取范式了。
写成requirements就是
{
"requirements": [
["a", "b"],
["c", "d", "e"]
]
}
这样,我们只需要达成a或b其中一个判据,以及c或d或e其中一个判据,就能获得该进度。
如我们达成了a和c就能获得该进度。然而获得a和b就无法获得该进度。
注意,我们写a and (b or c)
这种式子的时候,a是得放进独立的一个列表里的,即使式子里并没有任何括号
{
"requirements": [
["a"],
["b", "c"]
]
}
理论上所有逻辑式子都能写成合取范式,然而我们有两个主要限制:
- Advancements没有not
- 写出来的合取范式多长就不知道了
所以建议如果那逻辑比较复杂,发现很难写成合取范式甚至里面就有not的运算,那么就可以试试使用命令检查条件然后手动添加进度。
显示相关
显示格式
- (advancement根标签)
display
(可选,不存在则该进度不会以任何方式显示)
注意,如果填写了display,里面的标签除非有默认数值或特别指明可选,否则都必须填写。icon
: 进度的图标,在弹出提示及进度界面里显示。(其实就是个物品贴图)item
: 物品ID,需要有minecraft:
前缀。字串。data
: 物品数据值。整数。
title
: 进度的标题。字串。(如果需要使用样式请使用下一个类型)title
: 进度的标题。Compound(JSON文本)。
可以使用样式及点击事件。(点击事件只会在聊天栏公布玩家获得进度时点击生效)description
: 进度的描述。字串。(如果需要使用样式请使用下一个类型)description
: 进度的描述。Compound(JSON文本)。
可以使用样式,但不能使用点击事件。frame
: 进度图标的外框,默认为task
。外框将会在下文详细列出。background
: 指定此进度选项卡背景的路径。只对根进度有效(即无parent标签)。将会在下文讲解。字串。show_toast
: 是否在完成此进度后在屏幕右上方显示提示信息。默认为显示(True)。布尔值。announce_to_chat
: 是否在完成此进度后在聊天栏广播信息。默认为显示(True)。布尔值。hidden
: 是否在进度选项卡里隐藏此进度及之后的子进度(直至完成此进度才会被显示)。对根进度无效。默认为False。布尔值。
parent
: 指定进度的父进度名称(只对显示有作用)。字串。可选。
进度提示信息
获得进度时,如果show_toast
为true
,则会在窗口右上方显示一条信息,很快便会消失。
而如果announce_to_chat
为true
,则会在聊天栏显示信息。有颜色的部分为进度的标题,颜色因frame
的不同而改变,把鼠标悬浮在进度标题上能显示进度描述,点击能触发title
的clickEvent
。
进度界面
这是进度的界面。最大的部分展示的是选择了的进度选项卡(Tab)。
每个根进度都会有其独立选项卡。
选项卡界面上方有一个个按钮,其图标就是该选项卡根进度的图标,悬浮会显示其标题,点击即能切换选项卡。选项卡名称为根进度的title
。
背景
选项卡的背景能够被根进度自定义,会使用指定路径的图片把背景重复填满整个背景。
路径为:namespace:path
,如果无指定namespace则默认minecraft
。
Namespace,即命名空间,为资源包assets
下的文件夹名称,一般情况下为minecraft
。不过其实是可以加入别的命名空间的。
而path即资源包assets/(namespace)/
后的路径,包括文件扩展名(如.png
等)。
如果我们不指定命名空间,或使用minecraft
命名空间,我们可以使用游戏原有资源作为背景图片,如物品材质。
如background为test:1.png
,而地图文件里有一个resources.zip
的内容为
+ resources.zip
+ pack.mcmeta
+ assets
+ test
+ 1.png
假设1.png
为黑人问号,我们会有以下结果:
图片在进度背景里会被缩小并且重复填满整个背景,所以请小心使用,建议使用一些简单点的背景。
图标外框
图标 | 名称 |
---|---|
task | |
goal | |
challenge |
未完成则灰色,完成则咖啡色
父进度
进度可以指定父进度。
父进度在进度选项卡里会放在子进度的左边,并以线连着子进度。
多个子进度可以有同一父进度,换句话说就是一个父进度可以有很多个子进度。
不过一个子进度不可以有很多个父进度。
当我们说一个进度前的进度,我们是说该进度的父进度。当我们说前的所有进度,我们是说该进度的父进度、父进度的父进度,如此类推,但不包括前方进度的其他子进度。简单点来说就是前方一条直线直至根进度(没有父进度的进度)。
从钻石剑图示的进度开始,其所有前方的进度。可见是不会有分支的。
而我们说之后的所有进度,就代表从此进度出发,此进度的子进度、子进度的子进度,如此类推。当中是包括分支的。而之后第n层进度就代表我们看多少次子进度。比如说之后的两层进度,就包括此进度的子进度,以及子进度的子进度。
从铁锭图示开始,之后的所有进度。假如是之后的两层进度,则只包括6个进度(到了图示为盾牌、黑曜石及钻石的进度即停止)。
当一个父进度被完成时,进度面板中就会显示该父进度前的所有进度(除了hidden
的)及后两层的进度。
如果父进度设置了hidden:true
,自己以及之后所有子进度都会从界面中隐藏,直至父进度被完成,或子进度被完成(会显示前方没hidden
的进度以及出现一条线跨越父进度的位置,只有父进度仍然会被隐藏)。假如一个父进度没有display
标签,表现则和hidden
类似,只是父进度永远也不可能被显示。
没有父进度的进度就是根进度。会自己拥有一个选项卡。
选项卡只有当玩家拥有根进度的时候才会被显示,不论是否hidden
。
如果根进度没有display
标签,则整个选项卡都不会被显示,换句话说就是我们不能看到其子进度在进度的面板出现。
rewards
进度奖励格式
- (进度根标签)
rewards
recipes
: 一列表的合成配方名称。类型为字串列表。
即为玩家解锁指定列表的所有合成配方。loot
: 一列表的loot table名称。类型为字串列表。
即执行loot table,抽取奖励。experience
: 给予玩家一定数量(固定不是随机)的经验。类型为整数。function
: 命令函数名称。字串。
即以获得进度的玩家为执行者,在当前坐标执行命令函数。
除了可以用作给予奖励,还可以当作事件使用。
命令
advancement <grant|revoke> <玩家> <only|until|from|through> <进度名称> [判据]
<grant|revoke>
grant
就是给予进度/判据。revoke
就是移除进度/判据。
<玩家>
: 需要给予/移除进度/判据的玩家。<only|until|from|through>
only
: 只给予相应的进度/判据。until
: 给予指定进度及之前的所有进度,也就是所有左边连着此进度的进度。
顺序为: 进度的父进度,进度的父进度的父进度...根进度,此进度。from
: 给予指定进度及之后的所有进度。
顺序为: 指定进度,进度的子进度,进度的子进度的子进度...
然而由于一个进度可以有多个子进度,而子进度间的顺序在不同作业系统所有不同,所以顺序不能被确定。through
: 给予制定进度之前及之后的所有进度。类似分别执行until
及from
。次序为先执行until
,然后执行from
。
<进度名称>
: 指定的进度(用途看上方参数)。
和命令函数的命名方法类似,(命名空间):(路径)
,路径不需要写上文件扩展名。如minecraft:adventure/adventuring_time
。[判据]
: 可选。如果指定则只给予/移除指定进度的指定判据。否则则直接给予/移除指定进度。
advancement <grant|revoke> <玩家> everything
这个就不用多说了,给予或移除指定玩家的所有进度,不论命名空间。
advancement test <玩家> <进度名称> [判据]
检测指定玩家有没有获得指定进度。如果指定了判据则只检测玩家有没有达成指定判据(如果获得了进度则肯定达成了指定判据)。
当玩家获得了指定进度/判据时成功,没有则失败。