From fccbd72aeb62943c74ae47a94c314426278a5f1a Mon Sep 17 00:00:00 2001 From: Misode Date: Tue, 3 Oct 2023 11:41:30 +0200 Subject: [PATCH] Support new any_of, all_of and sequence in loot tables --- src/app/components/previews/LootTable.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/app/components/previews/LootTable.ts b/src/app/components/previews/LootTable.ts index e7946c67..36e0eac4 100644 --- a/src/app/components/previews/LootTable.ts +++ b/src/app/components/previews/LootTable.ts @@ -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 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 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)) {