Loot Tables
约 1883 字大约 6 分钟
2025-01-08
Loot Table Event
该事件允许我们直接修改战利品表,可以在其他模组将它们的战利品更改注入到原版战利品表之后触发。
Loot Tbales
getLootTableIds
- 返回一个数组,该数组包括所有可用的战利品表的ID。支持过滤。
- 语法:
getLootTableIds()getLootTableIds(filter: string | regex)
LootJS.lootTables(event => {
let ids = event.getLootTableIds()
})
LootJS.lootTables(event => {
let ids = event.getLootTableIds(/.*chests\/.*/)
})getLootTable
- 返回指定ID的战利品表,若没有对应的战利品表则返回
null。 - 语法:
getLootTable(id: string)
LootJS.lootTables(event => {
let table = event.getLootTable("minecraft:chests/simple_dungeon")
console.log(table)
// 实际测试中会直接报错(模组版本3.2.2)
})hasLootTable
- 返回一个
boolean值用于表示一个给定ID的战利品表是否存在。 - 语法:
hasLootTable(id: string)
LootJS.lootTables(event => {
let exists = event.hasLootTable("minecraft:chests/simple_dungeon")
console.log(exists)
// 若 exists 返回值为 true ,则该ID的战利品表存在
// 若返回值为 false ,则该ID的战利品表不存在
})clearLootTables
- 清空所有可以匹配给定过滤器的战利品表。
- 另外,我们可以直接对从
getLootTable方法获得的战利品表对象上调用.clear()方法。 - 语法:
clearLootTables(filter: string | regex)
LootJS.lootTables(event => {
event.getLootTable("minecraft:chests/bastion_treasure")
.clear()
.print()
// 日志中将会打印以下信息:
// Loot table: minecraft:chests/bastion_treasure
// % Pools [
// ]
})create
- 创建一个新的战利品表。
- 语法:
create(id: string, type?: LootType), 其中type未指定的情况下,默认为LootType.CHEST。
LootJS.lootTables(event => {
event.create("lootjs:table1", LootType.ENTITY).createPool(pool => {
// 编辑战利品池
})
})modifyLootTables
- 返回所有匹配给定过滤器的战利品表,并将它们作为一个集合返回。该集合允许您一次性修改所有匹配的战利品表。
- 另外,我们还可以通过使用战利品表类型来进行过滤。
- 语法:
modifyLootTables(filter: LootTableFilter | LootTableFilter[]),其中 一个LootTableFilter可以是一个字符串、正则表达式或者是一个LootType。
LootJS.lootTables(event => {
event.modifyLootTables(/.*chests\/.*/).createPool(pool => {
// 编辑战利品池
})
event.modifyLootTables(LootType.CHEST).createPool(pool => {
// 编辑战利品池
})
})
LootJS.lootTables(event => {
event.modifyLootTables(LootType.CHEST, "minecraft:gameplay/fishing").createPool(pool => {
// 编辑战利品池
})
event.modifyLootTables(LootType.CHEST, LootType.ENTITY).createPool(pool => {
// 编辑战利品池
})
})Block Loot Tables
getBlockTable
- 返回指定方块的战利品表,若没有对应的战利品表则返回
null。 - 语法:
getBlockTable(block: string | Block)
LootJS.lootTables(event => {
let table = event.getBlockTable("minecraft:diamond_ore")
})modifyBlockTables
- 返回所有匹配给定方块的战利品表,并将它们作为一个集合返回。该集合允许您一次性修改所有匹配的战利品表。
重要
由于 Minecraft 1.21 之后的加载顺序,战利品表会在标签存在之前加载。因此,无法使用 modifyBlockTables 方法通过标签进行修改。
如果需要通过标签进行修改,请考虑使用 loot modifier event。
- 语法:
modifyBlockTables(filter: string | string[] | Block | Block[])
LootJS.lootTables(event => {
event.modifyBlockTables("minecraft:diamond_ore")
.createPool(pool => {
// edit the pool
})
})LootJS.lootTables(event => {
event.modifyBlockTables("minecraft:diamond_ore", "minecraft:emerald_ore")
.createPool(pool => {
// edit the pool
})
})Entity Loot Tables
getEntityTable
- 返回指定方块的战利品表,若没有对应的战利品表则返回
null。 - 语法:
getEntityTable(entity: string | Block)
LootJS.lootTables(event => {
let table = event.getEntityTable("minecraft:sheep")
})modifyEntityTables
- 返回所有匹配给定实体的战利品表,并将它们作为一个集合返回。该集合允许您一次性修改所有匹配的战利品表。
重要
由于 Minecraft 1.21 之后的加载顺序,战利品表会在标签存在之前加载。因此,无法使用 modifyEntityTables 方法通过标签进行修改。
如果需要通过标签进行修改,请考虑使用 loot modifier event。
- 语法:
modifyEntityTables(filter: string | string[] | EntityType | EntityType[])
LootJS.lootTables(event => {
event.modifyEntityTables("minecraft:sheep")
.createPool(pool => {
// edit the pool
})
})LootJS.lootTables(event => {
event.modifyEntityTables("minecraft:sheep", "minecraft:pig")
.createPool(pool => {
// edit the pool
})
})修改你的第一个战利品表
让我们以铁矿石的战利品表为例子
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:alternatives",
"children": [
{
"type": "minecraft:item",
"conditions": [
{
"condition": "minecraft:match_tool",
"predicate": {
"predicates": {
"minecraft:enchantments": [
{
"enchantments": "minecraft:silk_touch",
"levels": {
"min": 1
}
}
]
}
}
}
],
"name": "minecraft:iron_ore"
},
{
"type": "minecraft:item",
"functions": [
{
"enchantment": "minecraft:fortune",
"formula": "minecraft:ore_drops",
"function": "minecraft:apply_bonus"
},
{
"function": "minecraft:explosion_decay"
}
],
"name": "minecraft:raw_iron"
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "minecraft:blocks/iron_ore"
}添加抽取项
假如我们想让玩家在挖掘铁矿石时可以额外掉落一个粗金,那其实有好几种方案可以实现这个目标,但是鉴于这篇笔记是 LootJS 的笔记,那我们就用 LootJS 为我们提供的方法来实现。
请注意这里我们使用的是 firstPool() 方法。我们将会大量使用该方法,以确保我们总是获取战利品表的第一个随机池。大多数原版战利品表只有一个随机池,该随机池会多次抽取。
LootJS.lootTables(event => {
event.getBlockTable("minecraft:iron_ore").print()
event.getBlockTable("minecraft:iron_ore")
.firstPool()
.addEntry("minecraft:raw_gold")
event.getBlockTable("minecraft:iron_ore").print()
})两次 print() 的输出如下
可以根据 LootJS 打印出来的信息,我们可以看到成功添加一个粗金到了铁矿石的战利品表。
Loot table: minecraft:blocks/iron_ore
% Pools [
{
% Rolls -> 1.0
% Bonus rolls -> 0.0
% Entries: [
{
minecraft:alternatives
% Entries: [
{
% Item: minecraft:iron_ore
% Conditions: [
minecraft:match_tool
]
% Item: minecraft:raw_iron
% Functions: [
minecraft:apply_bonus
minecraft:explosion_decay
]
}
]
}
]
}
]
Loot table: minecraft:blocks/iron_ore
% Pools [
{
% Rolls -> 1.0
% Bonus rolls -> 0.0
% Entries: [
{
minecraft:alternatives
% Entries: [
{
% Item: minecraft:iron_ore
% Conditions: [
minecraft:match_tool
]
% Item: minecraft:raw_iron
% Functions: [
minecraft:apply_bonus
minecraft:explosion_decay
]
}
]
% Item: minecraft:raw_gold
}
]
}
]带有权重
但是如果我们想要添加具有特定权重的物品呢?为此 LootJS 的 LootEntry API 为我们提供的 withWeight 函数。
关于 weight:
- 相较于其他项的此项的权重。
LootJS.lootTables(event => {
event.getBlockTable("minecraft:iron_ore")
.firstPool()
.addEntry(
LootEntry.of("minecraft:raw_gold")
.withWeight(20))
})设置数量
我们也可以使用 setCount 函数改变粗金每次掉落的数量
LootJS.lootTables(event => {
event.getBlockTable("minecraft:iron_ore").print()
event.getBlockTable("minecraft:iron_ore")
.firstPool()
.addEntry(
LootEntry.of("minecraft:raw_gold")
.withWeight(20)
.setCount([2,5]))
})修改抽取项
如果我们现在想要修改战利品表的一个现有抽取项,我们可以使用 modifyItem 方法。
LootJS.lootTables(event => {
event.getBlockTable("minecraft:iron_ore")
.firstPool()
.addEntry(
LootEntry.of("minecraft:raw_gold")
.withWeight(20).setCount([2,5]))
event.getBlockTable("minecraft:iron_ore")
.firstPool()
.modifyItemEntry(itemEntry => {
if (itemEntry.item.id === "minecraft:raw_gold") {
itemEntry.setWeight(10)
}
return itemEntry
})
})删除抽取项
如果我们还想将某一个抽取项从随机池中删除,我们可以使用 LootJS 为我们提供的方法 removeItem 方法。
LootJS.lootTables(event => {
// 目前 LootJS 3.2.2 有点问题
event.getBlockTable("minecraft:iron_ore")
.firstPool()
.removeItem("minecraft:raw_iron")
.removeItem("minecraft:iron_ore")
})创建你的第一个战利品表
我们可以使用 LootJS 来便捷的创建我们自己的战利品表。
创建战利品表
LootJS.lootTables(event => {
event.create("lootjs:rare_equipment")
.createPool(pool => {
})
})第一个随机池
第一个物品
{
"type": "minecraft:item",
"name": "minecraft:diamond_leggings",
"weight": 3,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20,
"max": 39
},
"options": "#minecraft:on_random_loot"
}
]
}
LootJS.lootTables(event => {
event.create("lootjs:rare_equipment")
.createPool(pool => {
// Per default it will always be `#minecraft:on_random_loot` for `enchantWithLevels`
pool.addEntry(
LootEntry.of("minecraft:diamond_leggings")
.withWeight(3)
.enchantWithLevels([20, 39])
)
})
})添加更多物品
我们也可以在第一随机池中添加更多的物品。
LootJS.lootTables(event => {
event.create("lootjs:rare_equipment").createPool(pool => {
pool.addEntry(
LootEntry.of("minecraft:diamond_leggings")
.withWeight(3)
.enchantWithLevels([20, 39])
)
pool.addEntry(
LootEntry.of("minecraft:iron_pickaxe")
.withWeight(10)
.enchantWithLevels([10, 19])
)
pool.addEntry(
LootEntry.of("minecraft:diamond_sword")
.withWeight(5)
.enchantWithLevels([30, 50])
.damage([0.3, 0.5])
)
pool.addEntry("minecraft:diamond_horse_armor")
pool.addEntry(
LootEntry.of("minecraft:diamond")
.setCount([2, 5])
)
})
})第二个随机池
我们可以在第二随机池中添加一把特殊而稀有的剑
LootJS.lootTables(event => {
event
.create("lootjs:rare_equipment")
.createPool(pool => {
// first pool
})
.createPool(pool => {
pool.addEntry(
LootEntry.of("minecraft:netherite_sword")
.enchant(builder => {
builder.withEnchantment("minecraft:sharpness", [4, 5])
builder.withEnchantment("minecraft:unbreaking", 3)
builder.withEnchantment("minecraft:knockback", 2)
builder.withEnchantment("minecraft:mending", 1)
})
)
// Vanilla often uses an empty entry with a weight instead of `randomChance`
// For this tutorial we will do the same.
pool.addEntry(
LootEntry.empty()
.withWeight(20))
})
})附加我们的战利品表
我们可以使用 reference 方法将我们的战利品表引用到其他战利品表上,同事可以使用 randomChance 方法使其抽取时更加稀有。
LootJS.lootTables(event => {
event.getLootTable("minecraft:gameplay/fishing")
.firstPool(pool => {
pool.addEntry(
LootEntry.reference("lootjs:rare_equipment")
.randomChance(0.1)
)
})
})