artifact(法器)
文件位置:data/<namespace>/mxt/artifact/<path>.json
法器不是一种新物品,而是已有物品的一套规则:items 声明这份定义认领哪些物品(与六种绑定表、spirit_herb 完全同一套 ItemMatcher),匹配到的物品堆就是这件法器。它做什么由 abilities 逐条声明:每条写一个 mxt:ability 注册表条目的 id,或一个技能标签——技能本身永远只在 data/<命名空间>/mxt/ability/ 里定义一处(见技能 · 技能类型)。法器能力与技能是同一个概念,所以这里没有任何法器专属的技能类型。定义没有「器型」这类自由标签字段:它自己的注册表 id 就是这件法器的名字,要「把一族法器归到一起」就用物品标签(items 里的 #标签)或 id 的命名空间与路径来表达。定义里没有 quality 字段:法器按物品认领(items 就是那套 ItemMatcher),堆上不装定义身份组件,没有可以问的对象,所以这族物品的档写在注册表 default_quality 里,按物品 id 或 #标签 给。
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
items | 物品 id、#标签 或混合数组 | 必填 | 这份定义认领的物品:物品 id、#标签 或二者的混合数组,至少要匹配一件,见匹配器。 |
priority | Int | 0 | 多份同类定义匹配同一件物品时的先后:数值大者先(见 匹配器);相同则按注册表顺序。它同时决定这件法器的长按手势在长按池里的先后(功法阅读与灌注都是 0);同 priority 的两份定义还会被加载期报一条 problem。 |
spirit_capacity | 灵气 id 到数值的映射 | {} | 每种灵气的存储上限。键必须是具体灵气(不接受标签);空表表示这件法器不存灵气。求值时非有限按 0、向下取整;温养加成 × (1 + 0.5 × nourishment) 由管线乘上,公式里不要再乘一遍。 |
abilities | 技能 id 列表,条目可以是 #标签 | [] | 这件法器给持有者什么。每条是一个 mxt:ability 注册表条目的 id,或一个技能标签 #命名空间:路径(标签在授予时展开成它列出的每条技能,顺序即注册表顺序);单写一条或写成数组都行。一份定义可被多件法器共用,同一条技能也可以出现在技能书、命令、战利品里——被动还是主动由技能自己的 type 决定,法器不声明这件事。同名技能写两遍(直接写 + 经标签)会去重。见技能 · 技能类型。 |
curios_equipable | bool | false | 这类法器是否允许放进 Curios 槽位。腰带槽在「武器与灵宝」模式下接收匹配 weapon_binding 的物品,或声明了 true 的法器;四个 charm 槽位只收声明 true 的法器(curios:charm 物品标签仍可放别的东西)。 |
require_owner | bool | false | 是否必须先认主才能飞行与储物。false(默认)时未认主的法器谁都能用,一旦被认主就只认主人——认主是「绑定归属」而不是使用前提;true 时未认主一律拒绝。不影响 mxt:owned_by(它问的就是「归属是不是你」)与授予能力。 |
claim_action | ItemAction | {"type": "mxt:consume_health", "amount": 4} | 认主写归属时对持有者与物品执行的行为。认主的代价就在这条行为里:认主做的全部事情都归它一个字段管。不写就是这个默认值——每次认主扣 4 点生命(两格心)。免费认主必须显式写 {"type": "mxt:no_op"}:省略字段不等于免费。 可以写单条,也可以写数组(数组等于 mxt:sequence 简写,按顺序全跑一遍,与其它 ItemAction 字段是同一套简写);「既付代价又有效果」就写成数组——mxt:consume_health 后面接别的物品行为。 |
claim_condition | EntityCondition | 恒真 | 认主条件。只约束长按这条手势:不满足则 claim_action 不跑。mxt:set_artifact_owner 战利品函数与脚本写归属时仍无条件写。 |
pour_action | ItemAction | mxt:no_op | 长按注灵时,每一个真的收下了灵气的刻各跑一次(不是整个手势只跑一次)。 |
use_action | ItemAction | mxt:no_op | 这条长按手势走完整段之后跑一次。认主成功时跑,注灵结束时也跑;中途松手不跑。 |
hold_ticks | NumberProvider | 20 | 长按的 use 周期长度(刻),求值后夹在 0..72000。0 表示这份定义不接管长按,右键照旧由物品自己处理。声明级(无持有者)按空上下文求值,所以写公式时不要依赖持有者;有持有者的那一侧会在运行时再求一次。 |
element | 元素 id 列表,条目可以是 #标签 | [] | 这件法器是什么元素:条目是一个元素、# 标签是一组元素。这是「物品的元素」的第一顺位来源之一,完整口径见 weapon_binding。注意 spirit_capacity 里的灵气不参与这条读取:那说的是「能装什么」,不是「是什么」。 |
attachment_multiplier | Double | 1.0 | 这件法器作为护身物值多少:携带(双手与 Curios 槽)期间,打在携带者身上的打击留下的元素附着乘上它——0.5 只留一半、0 一点也不留,于是那条元素反应永远不会被这一击触发。多件法器相乘,不写就没有影响。这是「法宝抵消部分元素反应」的着力点:它压的是攒的速度,反应自身的效果不归它管。只有法器有这个字段(item_binding / weapon_binding 不提供),所以普通武器与物品不会意外变成护身物。 |
abilities 里每一条都是普通技能,type 取自所有技能共用的固有分派表 mxt:ability_type(内置十三种:empty、active、triggered、modifier、aura、interval、channelled、targeted、word、mount、flight_control、storage、upkeep)。类型、字段与写法全在技能 · 技能类型。
abilities 里的条目只能是 id 或 #标签。写一个对象进去(也就是把技能整个内联在这份文件里)不是合法条目,会让世界加载失败。
{
"items": "minecraft:diamond_sword",
"abilities": [
"mxt_test:artifact_guard",
"mxt_test:firebolt",
"mxt_test:bound_mount",
"#mxt_test:artifact_passive"
]
}- 前两条是各自的注册表条目:
mxt_test:artifact_guard是mxt:modifier(被动),mxt_test:firebolt是mxt:active(按一下)。被动还是主动由技能自己的type决定,法器定义不声明「我授予的是被动还是主动」。 - 第三条
mxt_test:bound_mount是一条mxt:mount(声明这件法器是飞行法器,不按键),第四条是一个技能标签,在授予时展开成它列出的那些技能——一包多件法器共用同一组被动时,改标签比逐件改定义省事;同名技能写两遍(直接写 + 经标签)会去重。 - 这几条技能自己的字段(飞行速度与每 tick 费用、储物格数、维持周期)都在技能自己那份文件里:
mxt:mount取speed/seats/sit/ 几何与技能的costs,mxt:storage取slots,mxt:upkeep取interval/on_fail/owner_only并同样用技能的costs。这些技能需要一件承载它的物品:被技能书之类没有物品的来源授予时语法合法,但使用时会被拒绝并报「没有承载物」。 - 除了定义里的
abilities,一堆具体的物品还能靠数据组件mxt:item_abilities({"abilities": ["example:foo"]})自带技能:运行时读的是定义声明的与组件写的并集,所以同一份定义认领的两堆物品可以带不一样的技能。组件里只存技能 id、不收标签;专用生产者是物品行为mxt:add_ability(通用补丁mxt:merge_components仍然可用)。
mxt:mount 是"这件法器是飞行法器"的声明,顺带回答它怎么画。 载具默认画的是它承载的那件物品的物品模型(展示框那套上下文:原始大小、没有位移的卡片),render 可以换成 mxt:geckolib 或内容模组注册的渲染器;display 可选,不写就用该渲染器自己的默认姿势。字段、默认值与七个姿态见载具渲染器类型。座位(脚底高度)不属于 display,那是 mxt:mount 自己的 seat_offsets。
灵气与温养
- 存量写在共用组件
mxt:spirit_storage(按灵气记数量,数值是浮点数,与灵石、符箓载体同一个形状),不是法器专属组件。 - 上限来自
spirit_capacity里那一种灵气的声明值;没有声明过的灵气灌不进去(上限按 0)。 - 存的是小数而不是整单位:长按注灵仍然一 tick 送进一个整单位,而御器飞行的每 tick 燃料就按这个精度扣(
0.1就是每刻 0.1),所以一件充好的法器能被精确烧到空。(灵石与符箓沿用同一个组件,它们只按整单位读写。) mxt:artifact_state组件只有归属(owner_uuid与显示用的owner_name)与nourishment(温养度0..1)。归属以owner_uuid为准(mxt:owned_by、飞行与储物都问它),owner_name是认主那一刻记下的显示名,只用于提示框。物品上没有这个名字时,客户端会问一次服务端(一次会话每个 id 只问一次)——服务端从在线玩家列表与持久化的名字缓存里回答,不查会话服务(那是网络请求),没见过这名玩家时就什么都不回、界面继续显示 UUID。每次真正收下灵气,温养度按收下的量 ÷ 本次该灵气的有效上限上涨并夹在0..1,只升不降;有效上限 =floor(声明上限 × (1 + 0.5 × nourishment)),养满即 1.5 倍,两端都夹取。想读温养度,用通用的mxt:component条件读mxt:artifact_state的nourishment。- 归属由
mxt:set_artifact_owner(战利品函数)、长按认主(见下)或任何写归属的脚本写入。飞行与储物按require_owner判权:false(默认)时未认主的谁都能用、认主后只认主人;true时未认主一律拒绝。mxt:owned_by与require_owner无关,它问的就是「归属是不是你」(未认主即 false);授予能力只看是否持有/装备。
长按
右键按住不放,潜行时不算。
| 持有者状态 | 长按会发生什么 |
|---|---|
| 没有主人 | 完成整段长按才认主:先判 claim_condition,通过才写归属,跑一次 claim_action(默认扣 4 点生命、不做任何预检),最后跑 use_action。条件不满足就整段不结算,claim_action 不跑。中途松手也什么都不结算。 |
| 主人是自己 | 按住期间把自己的灵气灌进法器:spirit_capacity 里写了几种灵气就灌几种,每种每刻 1 点,1:1 从持有者对应灵气池扣,直到灌满或松手;温养度照常按收下的量上涨。每一个真的收下了灵气的刻跑一次 pour_action,手势走完跑一次 use_action。 |
| 主人是别人 | 这次右键不接管:不播长按姿势,物品按自己的规则处理这次点击,只在动作栏说一句「此物已认主他人」。 |
| 主人是自己但已灌满 | 同上,不接管,提示「此物已充满灵气」。 |
- 长按时长由
hold_ticks决定(默认 20 刻 = 1 秒);hold_ticks: 0等于关掉这份定义的长按(工具提示也不会再报长按提示)。 - 与物品自带的用途不冲突:食物、药水这类自带
minecraft:consumable的物品若同时是法器,它自己的用途优先。 - 认主是绑定归属(写
owner_uuid),不是使用前提——要不要「必须先认主」仍然是require_owner说了算。 - 代价不做任何预检:长按只判
claim_condition,从不检查持有者付不付得起。生命不足也照扣,可能当场死亡。代价是用原版的秘法伤害扣的,因此抗性提升与保护附魔会照常减免;创造模式这类收不到伤害的持有者则是免费认主。 - 战利品函数与脚本写归属时,同样会跑
claim_action(代价也在里面),但那两条路不判claim_condition。见 战利品与判据。 - 想让「带在身上」持续付代价,不要往认主流程里塞——认主只发生一次。用
abilities里的mxt:upkeep:它按世界时间每interval刻结算一次costs,付不出来就跑on_fail。 - 注灵期间的反馈:动作栏按按住期间累计报「注入灵气 N 点」,一整段长按结束时报「本次共注入灵气 N 点」——原版按住不放会一个 use 周期接一个地重开,所以计数不在每个周期边界清零。某一门灵气付不出时报「自身灵气不足:灵气名」并点名是哪一门;法器在它声明的所有灵气上都已满时什么都不报。
一件法器只有「没主人」和「有主人」两种状态:
一个完整例子(两种灵气、被动+主动+飞行+储物+维持):
{
"items": ["#mxt:artifact/sword", "minecraft:netherite_sword"],
"spirit_capacity": {
"mxt:qi": 500,
"mxt:sword_intent": 50
},
"abilities": [
"mxt:sword_body",
"mxt:sword_rain",
"mxt:sword_flight",
"mxt:sword_storage",
"mxt:sword_upkeep"
],
"curios_equipable": true,
"hold_ticks": 30,
"claim_action": [
{ "type": "mxt:consume_health", "amount": "4 + realm_rank" },
{ "type": "mxt:damage_item", "amount": 1 }
],
"claim_condition": { "type": "mxt:has_ability", "ability": "mxt:sword_body" },
"pour_action": { "type": "mxt:charge_artifact", "aura": "mxt:qi", "amount": 1 },
"use_action": { "type": "mxt:consume_health", "amount": 1 }
}代价与效果同写一个字段就够:claim_action 是数组时按顺序全跑。想比默认更贵,就改里面那条 mxt:consume_health:
"claim_action": [
{ "type": "mxt:consume_health", "amount": "4 + realm_rank" },
{ "type": "mxt:damage_item", "amount": 1 }
]不想要代价就明确写免费认主——直接删掉 claim_action 不等于免费,那会退回默认的 4 点生命:
"claim_action": { "type": "mxt:no_op" }提示框
物品提示框会按这份定义逐行报出你写下的东西。法器名;每种灵气的「存量 / 有效上限」(含温养加成,按百分比着色);abilities 的每一条(一条一行:先写技能自己的名字,需要按键的用青色、纯被动的用蓝色,hidden: true 的那条不占行;然后 mxt:mount 再把「速度 · N 座 · 站/坐」与每刻消耗写在同一行,mxt:storage 报「已用 / 总格数」,mxt:upkeep 报一行「维持 · 每 N 刻消耗 X、Y」,多项代价用可翻译的分隔符连起来);以及认主状态——有主人时显示绿色 ✔ 已认主:主人名(名字在认主时写进物品,物品上没有这个名字时才退回 UUID),只有 require_owner: true 且还没认主时才显示红色 ✖ 未认主 · 需认主后才能飞行与储物,不需要认主的法器未认主时不占行。温养度大于 0 时另起一行。
最后一行是长按提示:未认主且从 claim_action 里读到正数时报「长按:以 N 点生命认主」,读到 0 时报「长按:认主(无需代价)」;自己是主人且还装得下灵气时报「长按:注入自身灵气」;hold_ticks: 0 的定义两行都不报。按住 F3+H 的高级提示还会多出定义 id,以及主人名显示出来时的那一行 UUID。curios_equipable 不在这里重复:物品能进哪些 Curios 槽位由 Curios 自己的提示列出。
需要按键的技能
判据只有一句:凡是要按键才发动的都算技能、都进轮盘。需要按键的有五个类型:mxt:active(按一下施放)、mxt:channelled(按一下进入引导,自己付款)、mxt:targeted(定向施放:按一下走一次完整施放,用 target_selector 圈出一批目标、对每个跑载荷技能的单目标那一半,见定向施放)、mxt:flight_control(开关:开=起剑、关=落剑)与 mxt:storage(一次性:打开储物箱,没有状态)。
- 一件法器可以给出好几条:轮盘的条目身份就是那条技能自己的注册表 id(如
mxt_test:bound_flight),所以同一把剑可以既有飞行又有储物;一本书授予的主动技和一件法器给的开关在轮盘上是同一类格子,也共用一个 id 空间(同一份mxt:ability)。布局校验问的是「这个 id 现在能不能解析出来」,编造的格子进不去。 - 它出现在声明它的那张从盘上(主手 / 副手 / Curios),也可以被玩家钉到主盘——两处都读「那件法器此刻在不在双手或 Curios 槽里」,什么也不存。能不能再钉一次看池子:配置界面右边那一池收的是学到的技能(功法 / 灵根 / 体质 / 境界授予)与 Curios 槽位上法器声明的技能;只由主手 / 副手物品声明的技能(手里的法器给的储物就是这样)不进池子,它只在「主手物品 / 副手物品」那两页上——手是随时会换的东西。已经钉在主盘上的格子不受影响:解析主盘走的是「谁授予的都算」的那一份池子,服务端照旧受理。
- 状态归技能自己管,不是数据包字段:
mxt:flight_control读的是驾驶者那份飞行状态(记着飞的是哪条术、哪辆车),mxt:storage没有状态(格子里就是「按一下打开」)。轮盘那一格只报告状态(开关底色绿=开、灰=关,一次性的是紫),按下去由服务端重新判一次再决定做什么,所以请求本身不携带「开到哪一侧」。 - 失败原因报得清楚:付不出资源时会带上是哪一门。轮盘按名字查
actionbar.mxt.ability.failure.*一份表,把原因报在动作栏与日志里——UNAVAILABLE只剩兜底,条件不满足 / 灵根不符 / 次数用完这些原因不会再说成「现在用不了」。NOT_OWNED/ALREADY_SET/UNAVAILABLE/NO_CARRIER/NO_VEHICLE/CANNOT_MOUNT六个是按压独有的,其余十二个与普通施放共有。这一格叫什么用的是技能自己按注册 id 生成的名字键(ability.mxt.<命名空间>.<路径>)。
精炼台仍未接入(写归属只有战利品函数、长按认主与脚本这三条路)。数据包里没有精炼配方类型,法器的产出走蓝图锻造。飞行与储物都已有玩家入口:轮盘上那两格(mxt:flight_control 那一格由功法授予,mxt:storage 由法器授予)。