进度

进度(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_endthe_nether。
    • feature: 实体在于的结构。类型为字串。
      只接受EndCity, Fortress, Mansion, Mineshaft, Monument, Stronghold, TempleVillage。
    • 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: 进度的标题。CompoundJSON文本)。
        可以使用样式及点击事件。(点击事件只会在聊天栏公布玩家获得进度时点击生效)
      • description: 进度的描述。字串。(如果需要使用样式请使用下一个类型)
      • description: 进度的描述。CompoundJSON文本)。
        可以使用样式,但不能使用点击事件。
      • frame: 进度图标的外框,默认为task。外框将会在下文详细列出。
      • background: 指定此进度选项卡背景的路径。只对根进度有效(即无parent标签)。将会在下文讲解。字串。
      • show_toast: 是否在完成此进度后在屏幕右上方显示提示信息。默认为显示(True)。布尔值。
      • announce_to_chat: 是否在完成此进度后在聊天栏广播信息。默认为显示(True)。布尔值。
      • hidden: 是否在进度选项卡里隐藏此进度及之后的子进度(直至完成此进度才会被显示)。对根进度无效。默认为False。布尔值。
    • parent: 指定进度的父进度名称(只对显示有作用)。字串。可选。

进度提示信息

获得进度时,如果show_toasttrue,则会在窗口右上方显示一条信息,很快便会消失。


而如果announce_to_chattrue,则会在聊天栏显示信息。有颜色的部分为进度的标题,颜色因frame的不同而改变,把鼠标悬浮在进度标题上能显示进度描述,点击能触发titleclickEvent

进度界面


这是进度的界面。最大的部分展示的是选择了的进度选项卡(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: 给予制定进度之前及之后的所有进度。类似分别执行untilfrom。次序为先执行until,然后执行from
  • <进度名称>: 指定的进度(用途看上方参数)。
    和命令函数的命名方法类似,(命名空间):(路径),路径不需要写上文件扩展名。如minecraft:adventure/adventuring_time
  • [判据]: 可选。如果指定则只给予/移除指定进度的指定判据。否则则直接给予/移除指定进度。

advancement <grant|revoke> <玩家> everything

这个就不用多说了,给予或移除指定玩家的所有进度,不论命名空间。


advancement test <玩家> <进度名称> [判据]

检测指定玩家有没有获得指定进度。如果指定了判据则只检测玩家有没有达成指定判据(如果获得了进度则肯定达成了指定判据)。
当玩家获得了指定进度/判据时成功,没有则失败。

results matching ""

    No results matching ""