Support new any_of, all_of and sequence in loot tables

This commit is contained in:
Misode
2023-10-03 11:41:30 +02:00
parent 6074a15d61
commit fccbd72aeb

View File

@@ -266,7 +266,9 @@ function decorateFunctions(functions: any[], consumer: ItemConsumer, ctx: LootCo
function composeFunctions(functions: any[]): LootFunction {
return (item, ctx) => {
for (const fn of functions) {
if (composeConditions(fn.conditions ?? [])(ctx)) {
if (Array.isArray(fn)) {
composeFunctions(fn)
} else if (composeConditions(fn.conditions ?? [])(ctx)) {
const type = fn.function?.replace(/^minecraft:/, '');
(LootFunctions[type]?.(fn) ?? (i => i))(item, ctx)
}
@@ -328,6 +330,10 @@ const LootFunctions: Record<string, (params: any) => LootFunction> = {
const { min, max } = prepareIntRange(limit, ctx)
item.count = clamp(item.count, min, max )
},
sequence: ({ functions }) => (item, ctx) => {
if (!Array.isArray(functions)) return
composeFunctions(functions)(item, ctx)
},
set_count: ({ count, add }) => (item, ctx) => {
const oldCount = add ? (item.count) : 0
item.count = clamp(oldCount + computeInt(count, ctx), 0, 64)
@@ -391,12 +397,25 @@ function composeConditions(conditions: any[]): LootCondition {
}
function testCondition(condition: any, ctx: LootContext): boolean {
if (Array.isArray(condition)) {
return composeConditions(condition)(ctx)
}
const type = condition.condition?.replace(/^minecraft:/, '')
return (LootConditions[type]?.(condition) ?? (() => true))(ctx)
}
const LootConditions: Record<string, (params: any) => LootCondition> = {
alternative: ({ terms }) => (ctx) => {
alternative: params => LootConditions['any_of'](params),
all_of: ({ terms }) => (ctx) => {
if (!Array.isArray(terms) || terms.length === 0) return true
for (const term of terms) {
if (!testCondition(term, ctx)) {
return false
}
}
return true
},
any_of: ({ terms }) => (ctx) => {
if (!Array.isArray(terms) || terms.length === 0) return true
for (const term of terms) {
if (testCondition(term, ctx)) {