Files
netease-modsdk-wiki/docs/wiki/items/tool-durability.md
2025-03-20 11:52:46 +08:00

266 lines
6.6 KiB
Markdown

---
title: 工具耐久度
category: 巧思案例
tags:
- 实验性
- 中级
- 脚本
mentions:
- MedicalJewel105
- TheDoctor15
- napstaa967
---
# 工具耐久度
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
## 简介
1.16.100+版本的物品耐久机制与1.10和1.16版本存在差异。现在需要明确定义物品何时会受到耐久损耗,并通过事件触发损耗行为。本教程将涵盖以下内容:
- 耐久度组件
- 更新耐久度的事件
- 实体伤害机制
- 方块破坏机制
- `repair_amount` 参数
- `on_tool_used` 事件
### 组件
::: code-group
```json [BP/items/my_item.json#components]
"minecraft:durability": {
"max_durability": 200
}
```
:::
`minecraft:durability`组件用于定义物品的最大耐久值
## 事件机制
### 物品事件
::: code-group
```json [BP/items/my_item.json#events]
"durability_update": {
"damage": {
"type": "none",
"amount": 1,
"target": "self"
}
}
```
:::
当该事件被触发时,物品(`self`目标)将承受耐久损耗。看似简单,不是吗?
### 脚本事件
对于脚本实现,我们将使用自定义函数处理耐久损耗
该函数支持物品的"耐久"附魔效果
::: code-group
```js [BP/scripts/main.js]
function damage_item(item) {
// 获取耐久度组件
const durabilityComponent = item.getComponent("durability")
var unbreaking = 0
// 获取耐久附魔等级
if (item.hasComponent("enchantments")) {
unbreaking = item.getComponent("enchantments").enchantments.getEnchantment("unbreaking")
if (!unbreaking) {
unbreaking = 0
} else {
unbreaking = unbreaking.level
}
}
// 应用损耗
if (durabilityComponent.damage == durabilityComponent.maxDurability) {
return
}
durabilityComponent.damage += Number(Math.round(Math.random() * 100) <= durabilityComponent.getDamageChance(unbreaking))
return item
}
```
:::
## 实体伤害
### 脚本实现
:::warning 实验性脚本
本脚本使用`@minecraft/server 1.9.0-beta`,该版本将在后续游戏更新中变更。
:::
对于1.20.40及更高格式版本,`on_hurt_entity`已失效。
以下脚本实现了武器耐久损耗机制:
::: code-group
```js [BP/scripts/main.js]
// 在此数组中添加你的物品ID
const my_items = ["wiki:silver_dagger"]
world.afterEvents.entityHurt.subscribe(event => {
// 无伤害来源实体则跳过
if (!event.damageSource.damagingEntity) return
// 获取装备的武器
const equipment = event.damageSource.damagingEntity.getComponent("minecraft:equippable")
if (!equipment) return
const weapon = equipment.getEquipment(EquipmentSlot.Mainhand)
// 无武器则跳过
if (!weapon) return
// 物品不在列表则跳过
if (!my_items.includes(weapon.typeId)) return
let newItem = damage_item(weapon)
equipment.setEquipment(EquipmentSlot.Mainhand, newItem)
if (!newItem) {
if (event.damageSource.damagingEntity instanceof Player) {
event.damageSource.damagingEntity.playSound("random.break")
}
}
})
```
:::
### on_hurt_entity事件
:::warning
`on_hurt_entity`在格式版本1.20.40后已移除
:::
在`minecraft:weapon`组件中定义`on_hurt_entity`,用于指定玩家使用该物品攻击实体时触发的事件
::: code-group
```json [BP/items/my_item.json#components]
"minecraft:weapon": {
"on_hurt_entity": {
"event": "durability_update"
}
}
```
:::
## 方块破坏
### 脚本实现
:::warning 实验性脚本
本脚本使用`@minecraft/server 1.9.0-beta`,该版本将在后续游戏更新中变更。
:::
对于1.20.20及更高格式版本,`on_dig`已失效。
以下脚本实现了工具耐久损耗机制:
::: code-group
```js [BP/scripts/main.js]
// 在此数组中添加你的物品ID
const my_items = ["wiki:obsidian_pickaxe"]
world.afterEvents.playerBreakBlock.subscribe(event => {
// 无物品则跳过
if (!event.itemStackAfterBreak) return
// 物品不在列表则跳过
if (!my_items.includes(event.itemStackAfterBreak.typeId)) return
// 创造模式玩家跳过
if (world.getPlayers({
gameMode: GameMode.creative
}).includes(event.player)) return
const newItem = damage_item(event.itemStackAfterBreak)
event.player.getComponent("minecraft:equippable").setEquipment(EquipmentSlot.Mainhand, newItem)
if (!newItem) {
event.player.playSound("random.break")
}
})
```
:::
### on_dig事件
:::warning
`on_dig`在格式版本1.20.20后已移除
:::
在`minecraft:digger`组件中定义`on_dig`,用于指定玩家使用该物品破坏方块时触发的事件
::: code-group
```json [BP/items/my_item.json#components]
"minecraft:digger": {
"use_efficiency": true,
"destroy_speeds": [
{
"block": {
"tags": "q.any_tag('wood')"
},
"speed": 8,
"on_dig": {
// 定义破坏带有wood标签的方块时触发的事件
"event": "durability_update"
}
}
],
"on_dig": {
// 定义破坏任意方块时触发的事件
"event": "durability_update"
}
}
```
:::
## repair_amount参数
在`minecraft:repairable`组件中定义`repair_amount`,用于指定物品修复时的耐久恢复量
::: code-group
```json [BP/items/my_item.json#components]
"minecraft:repairable": {
"repair_items": [
{
"repair_amount": "context.other->q.remaining_durability + 0.05 * context.other->q.max_durability",
"items": [
"bs:silver",
"bs:silver_axe"
]
}
]
}
```
:::
公式解析:
`"context.other->q.remaining_durability + 0.05 * context.other->q.max_durability"`
最终耐久 = 第一把斧的剩余耐久 + 第二把斧的剩余耐久 + 第二把斧最大耐久的5%
## on_tool_used事件
(当前可能不可用)
`on_tool_used`是通过标签系统触发的特殊事件。标签类似于实体的运行时标识符。已知标签:
| 标签 | 效果 | 触发方式 |
| -------------------- | ------------- | -------------------------------- |
| minecraft:is_axe | 剥离原木 | 与斧头可交互的方块互动时触发 |
| minecraft:is_hoe | 制作耕地 | 与锄头可交互的方块互动时触发 |
| minecraft:is_pickaxe | 未知 | 未知 |
| minecraft:is_sword | 未知 | 未知 |
可通过以下方式应用标签:
::: code-group
```json [BP/items/my_item.json#components]
"tag:minecraft:is_axe": {}
```
:::