From c75e27860e6275fd1ded0c71848c6ff08af731b1 Mon Sep 17 00:00:00 2001 From: Niklas Widmann Date: Sun, 15 Oct 2023 23:52:22 +0200 Subject: [PATCH] correct recipe exports & several bug fixes --- package.json | 33 +++++++++++++--- src/common/ingredient.ts | 10 +++-- src/common/result.ts | 25 +++--------- src/emit/recipe.ts | 15 +++++++- src/index.ts | 2 +- src/parser/adAstra.ts | 20 ++++++++++ src/parser/botania.ts | 51 ++++++++++++++++++++----- src/parser/lootTable.ts | 4 +- src/parser/recipe/botania/orechid.ts | 10 ++--- src/parser/recipe/thermal/ingredient.ts | 4 +- src/parser/roots.ts | 10 +++++ src/parser/thermal.ts | 5 +++ src/rule/recipe.ts | 5 ++- test/recipe.test.ts | 12 ++++++ 14 files changed, 154 insertions(+), 52 deletions(-) create mode 100644 src/parser/adAstra.ts create mode 100644 src/parser/roots.ts diff --git a/package.json b/package.json index 16603de..0f97da8 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,34 @@ "description": "Data Modifier", "main": "dist/index.js", "exports": { - ".": "./dist/index.js", - "./parser": "./dist/parser/index.js", - "./parser/create": "./dist/parser/create.js", - "./parser/thermal": "./dist/parser/thermal.js", - "./parser/farmersdelight": "./dist/parser/farmersdelight.js" + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./parser": { + "types": "./dist/parser/index.d.ts", + "default": "./dist/parser/index.js" + }, + "./parser/create": { + "types": "./dist/parser/create.d.ts", + "default": "./dist/parser/create.js" + }, + "./parser/thermal": { + "types": "./dist/parser/thermal.d.ts", + "default": "./dist/parser/thermal.js" + }, + "./parser/farmersdelight": { + "types": "./dist/parser/farmersdelight.d.ts", + "default": "./dist/parser/farmersdelight.js" + }, + "./parser/adAstra": { + "types": "./dist/parser/adAstra.d.ts", + "default": "./dist/parser/adAstra.js" + }, + "./parser/roots": { + "types": "./dist/parser/roots.d.ts", + "default": "./dist/parser/roots.js" + } }, "types": "./dist/index.d.ts", "files": [ diff --git a/src/common/ingredient.ts b/src/common/ingredient.ts index c3a5c24..6364856 100644 --- a/src/common/ingredient.ts +++ b/src/common/ingredient.ts @@ -2,19 +2,21 @@ import { TagRegistry, TagRegistryHolder } from '../loader/tags.js' import { createId, encodeId, Id, NormalizedId } from './id.js' import { Logger } from '../logger.js' import { resolveCommonTest } from './predicates.js' -import { Block, BlockSchema, Fluid, FluidSchema, Item, ItemSchema } from './result.js' +import { Block, BlockSchema, FluidStack, FluidStackSchema, ItemStack, ItemStackSchema } from './result.js' import zod from 'zod' import { exists } from '@pssbletrngle/pack-resolver' import { IllegalShapeError, tryCatching } from '../error.js' export const ItemTagSchema = zod.object({ tag: zod.string(), + count: zod.number().optional(), }) export type ItemTag = zod.infer export const FluidTagSchema = zod.object({ fluidTag: zod.string(), + amount: zod.number().optional(), }) export type FluidTag = zod.infer @@ -26,7 +28,7 @@ export const BlockTagSchema = zod.object({ export type BlockTag = zod.infer -export type Ingredient = Item | ItemTag | Fluid | FluidTag | Block | BlockTag | IngredientInput[] +export type Ingredient = ItemStack | ItemTag | FluidStack | FluidTag | Block | BlockTag | IngredientInput[] export type IngredientInput = Ingredient | string export function createIngredient(input: unknown): Ingredient { @@ -42,8 +44,8 @@ export function createIngredient(input: unknown): Ingredient { } if (typeof input === 'object') { - if ('item' in input) return ItemSchema.parse(input) - if ('fluid' in input) return FluidSchema.parse(input) + if ('item' in input) return ItemStackSchema.parse(input) + if ('fluid' in input) return FluidStackSchema.parse(input) if ('block' in input) return BlockSchema.parse(input) if ('tag' in input) return ItemTagSchema.parse(input) diff --git a/src/common/result.ts b/src/common/result.ts index 3ae595b..d1d2a20 100644 --- a/src/common/result.ts +++ b/src/common/result.ts @@ -1,37 +1,24 @@ import zod from 'zod' import { IllegalShapeError } from '../error.js' -export const ItemSchema = zod.object({ +export const ItemStackSchema = zod.object({ item: zod.string(), + count: zod.number().optional(), + chance: zod.number().optional(), }) -export type Item = zod.infer - -export const FluidSchema = zod.object({ +export const FluidStackSchema = zod.object({ fluid: zod.string(), + amount: zod.number().optional(), + chance: zod.number().optional(), }) -export type Fluid = zod.infer - -export const ItemStackSchema = ItemSchema.and( - zod.object({ - count: zod.number().optional(), - }) -) - export type ItemStack = zod.infer -export const FluidStackSchema = FluidSchema.and( - zod.object({ - amount: zod.number().optional(), - }) -) - export type FluidStack = zod.infer export const BlockSchema = zod.object({ block: zod.string(), - weight: zod.number().optional(), }) export type Block = zod.infer diff --git a/src/emit/recipe.ts b/src/emit/recipe.ts index d545cd5..979684f 100644 --- a/src/emit/recipe.ts +++ b/src/emit/recipe.ts @@ -21,6 +21,7 @@ import { Acceptor } from '@pssbletrngle/pack-resolver' type RecipeTest = Readonly<{ id?: CommonTest + type?: CommonTest namespace?: string output?: IngredientTest input?: IngredientTest @@ -88,15 +89,17 @@ export default class RecipeEmitter implements RecipeRules { private resolveRecipeTest(test: RecipeTest) { const id: Predicate[] = [] + const type: Predicate[] = [] const ingredient: Predicate[] = [] const result: Predicate[] = [] if (test.id) id.push(resolveIDTest(test.id)) + if (test.type) type.push(resolveIDTest(test.type)) if (test.namespace) id.push(id => id.namespace === test.namespace) if (test.output) result.push(this.resolveIngredientTest(test.output)) if (test.input) ingredient.push(this.resolveIngredientTest(test.input)) - return { id, ingredient, result } + return { id, type, ingredient, result } } addRecipe>( @@ -110,7 +113,13 @@ export default class RecipeEmitter implements RecipeRules { removeRecipe(test: RecipeTest) { const recipePredicates = this.resolveRecipeTest(test) this.ruled.addRule( - new RecipeRule(recipePredicates.id, recipePredicates.ingredient, recipePredicates.result, () => null) + new RecipeRule( + recipePredicates.id, + recipePredicates.type, + recipePredicates.ingredient, + recipePredicates.result, + () => null + ) ) } @@ -121,6 +130,7 @@ export default class RecipeEmitter implements RecipeRules { this.ruled.addRule( new RecipeRule( recipePredicates.id, + recipePredicates.type, recipePredicates.ingredient, [predicate, ...recipePredicates.result], recipe => recipe.replaceResult(replacer) @@ -135,6 +145,7 @@ export default class RecipeEmitter implements RecipeRules { this.ruled.addRule( new RecipeRule( recipePredicates.id, + recipePredicates.type, [predicate, ...recipePredicates.ingredient], recipePredicates.result, recipe => recipe.replaceIngredient(replacer) diff --git a/src/index.ts b/src/index.ts index 167bf48..1385a70 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,7 +19,7 @@ export { } from './common/ingredient.js' export { TagInput, Id, IdInput, NormalizedId, encodeId, createId } from './common/id.js' export { default as Registry } from './common/registry.js' -export { Item, Block, ItemStack, Fluid, FluidStack, createResult, ResultInput, Result } from './common/result.js' +export { Block, ItemStack, FluidStack, createResult, ResultInput, Result } from './common/result.js' export { default as createLogger, Logger, createSilentLogger, wrapLogMethods } from './logger.js' export { RecipeDefinition, FabricCondition, ForgeCondition } from './schema/recipe.js' export { TagEntry, TagDefinition } from './schema/tag.js' diff --git a/src/parser/adAstra.ts b/src/parser/adAstra.ts new file mode 100644 index 0000000..f2735e1 --- /dev/null +++ b/src/parser/adAstra.ts @@ -0,0 +1,20 @@ +export { + HammeringRecipe, + HammeringRecipeDefinition, + default as HammeringRecipeParser, +} from './recipe/adAstra/hammering.js' +export { + InputOutputRecipe, + InputOutputRecipeDefinition, + default as InputOutputRecipeRecipeParser, +} from './recipe/adAstra/inputOutput.js' +export { + NasaWorkbenchRecipe, + NasaWorkbenchRecipeDefinition, + default as NasaWorkbenchRecipeParser, +} from './recipe/adAstra/nasaWorkbench.js' +export { + SpaceStationRecipe, + SpaceStationRecipeDefinition, + default as SpaceStationRecipeParser, +} from './recipe/adAstra/spaceStation.js' diff --git a/src/parser/botania.ts b/src/parser/botania.ts index f2e1154..1f9aa67 100644 --- a/src/parser/botania.ts +++ b/src/parser/botania.ts @@ -1,9 +1,42 @@ -export { ApothecaryRecipeDefinition, ApothecaryRecipe, default as ApothecaryRecipeParser } from './recipe/botania/apothecary.js' -export { NbtWrapperRecipeDefinition, NbtWrapperRecipe, default as NbtWrapperRecipeParser } from './recipe/botania/nbtWrapper.js' -export { ElvenTradeRecipeDefinition, ElvenTradeRecipe, default as ElvenTradeRecipeParser } from './recipe/botania/elvenTrade.js' -export { GogWrapperRecipeDefinition, GogWrapperRecipe, default as GogWrapperRecipeParser } from './recipe/botania/gogWrapper.js' -export { ManaInfusionRecipeDefinition, ManaInfusionRecipe, default as ManaInfusionRecipeParser } from './recipe/botania/manaInfusion.js' -export { OrechidRecipeDefinition, OrechidRecipe , default as OrechidRecipeParser } from './recipe/botania/orechid.js' -export { PureDaisyRecipeDefinition, PureDaisyRecipe, default as PureDaisyRecipeParser } from './recipe/botania/pureDaisy.js' -export { TerraPlateRecipeDefinition, TerraPlateRecipe, default as TerraPlateRecipeParser } from './recipe/botania/terraPlate.js' -export { RunicAltarRecipeDefinition, RunicAltarRecipe, default as RunicAltarRecipeParser } from './recipe/botania/runicAltar.js' \ No newline at end of file +export { + ApothecaryRecipeDefinition, + ApothecaryRecipe, + default as ApothecaryRecipeParser, +} from './recipe/botania/apothecary.js' +export { BrewRecipeDefinition, BrewRecipe, default as BrewRecipeParser } from './recipe/botania/brew.js' +export { + ElvenTradeRecipeDefinition, + ElvenTradeRecipe, + default as ElvenTradeRecipeParser, +} from './recipe/botania/elvenTrade.js' +export { + GogWrapperRecipeDefinition, + GogWrapperRecipe, + default as GogWrapperRecipeParser, +} from './recipe/botania/gogWrapper.js' +export { + ManaInfusionRecipeDefinition, + ManaInfusionRecipe, + default as ManaInfusionRecipeParser, +} from './recipe/botania/manaInfusion.js' +export { + NbtWrapperRecipeDefinition, + NbtWrapperRecipe, + default as NbtWrapperRecipeParser, +} from './recipe/botania/nbtWrapper.js' +export { OrechidRecipeDefinition, OrechidRecipe, default as OrechidRecipeParser } from './recipe/botania/orechid.js' +export { + PureDaisyRecipeDefinition, + PureDaisyRecipe, + default as PureDaisyRecipeParser, +} from './recipe/botania/pureDaisy.js' +export { + RunicAltarRecipeDefinition, + RunicAltarRecipe, + default as RunicAltarRecipeParser, +} from './recipe/botania/runicAltar.js' +export { + TerraPlateRecipeDefinition, + TerraPlateRecipe, + default as TerraPlateRecipeParser, +} from './recipe/botania/terraPlate.js' diff --git a/src/parser/lootTable.ts b/src/parser/lootTable.ts index ec1e815..c407370 100644 --- a/src/parser/lootTable.ts +++ b/src/parser/lootTable.ts @@ -1,9 +1,9 @@ import { extendLootEntry, LootEntry, LootEntryBase, LootEntrySchema, LootTable } from '../schema/loot.js' import { IllegalShapeError } from '../error.js' import { IngredientInput, ItemTag, Predicate } from '../common/ingredient.js' -import { Item } from '../common/result.js' +import { ItemStack } from '../common/result.js' -export type LootItemInput = Item | ItemTag | LootEntry +export type LootItemInput = ItemStack | ItemTag | LootEntry export function createLootEntry(input: LootItemInput): LootEntry { if (input && typeof input === 'object') { diff --git a/src/parser/recipe/botania/orechid.ts b/src/parser/recipe/botania/orechid.ts index 8721d05..44fc01b 100644 --- a/src/parser/recipe/botania/orechid.ts +++ b/src/parser/recipe/botania/orechid.ts @@ -15,19 +15,19 @@ export type BlockInput = | Readonly<{ type: 'block' block: string - weight?: number }> | Readonly<{ type: 'tag' tag: string - weight?: number }> export type OrechidRecipeDefinition = RecipeDefinition & Readonly<{ input: BlockInput output: BlockInput - result: ResultInput + biome_bonus?: number + biome_bonus_tag?: string + weight?: number }> export function createBlockInput(input: IngredientInput): BlockInput | null { @@ -37,14 +37,12 @@ export function createBlockInput(input: IngredientInput): BlockInput | null { return { type: 'block', block: ingredient.block, - weight: ingredient.weight, } if ('blockTag' in ingredient) return { type: 'tag', tag: ingredient.blockTag, - weight: ingredient.weight, } return null @@ -65,12 +63,10 @@ export function fromBlockInput(input: BlockInput): Block | BlockTag { case 'block': return { block: encodeId(input.block), - weight: input.weight, } case 'tag': return { blockTag: encodeId(input.tag), - weight: input.weight, } default: throw new IllegalShapeError(`Unknown block input type`, input) diff --git a/src/parser/recipe/thermal/ingredient.ts b/src/parser/recipe/thermal/ingredient.ts index 84f9836..30883f4 100644 --- a/src/parser/recipe/thermal/ingredient.ts +++ b/src/parser/recipe/thermal/ingredient.ts @@ -1,6 +1,6 @@ import { FluidTag, IngredientInput, ItemTagSchema } from '../../../common/ingredient.js' import zod from 'zod' -import { ItemSchema } from '../../../common/result.js' +import { ItemStackSchema } from '../../../common/result.js' import { omit } from 'lodash-es' import { IllegalShapeError } from '../../../error.js' @@ -21,7 +21,7 @@ export type ThermalIngredientInput = Exclude | Therma function fromThermalList(input: ThermalItemList): IngredientInput { return input.value.map(it => { if (it && typeof it === 'object') { - if ('item' in it) return { ...ItemSchema.parse(it), count: input.count } + if ('item' in it) return { ...ItemStackSchema.parse(it), count: input.count } if ('tag' in it) return { ...ItemTagSchema.parse(it), count: input.count } } throw new IllegalShapeError('thermal array ingredients may only be of type item/itemtag', it) diff --git a/src/parser/roots.ts b/src/parser/roots.ts new file mode 100644 index 0000000..d2098ae --- /dev/null +++ b/src/parser/roots.ts @@ -0,0 +1,10 @@ +export { + RootRitualRecipe, + RootRitualRecipeDefinition, + default as RootRitualRecipeParser, +} from './recipe/roots/ritual.js' +export { + RootComponentRecipe, + RootComponentRecipeDefinition, + default as RootComponentRecipeParser, +} from './recipe/roots/component.js' diff --git a/src/parser/thermal.ts b/src/parser/thermal.ts index 23b8199..9b08901 100644 --- a/src/parser/thermal.ts +++ b/src/parser/thermal.ts @@ -1,4 +1,9 @@ export { ThermalRecipeDefinition, ThermalRecipe, default as ThermalRecipeParser } from './recipe/thermal/index.js' +export { + TreeExtractionRecipe, + TreeExtractionRecipeDefinition, + default as TreeExtractionRecipeParser, +} from './recipe/thermal/treeExtraction.js' export { ThermalCatalystRecipeDefinition, ThermalCatalystRecipe, diff --git a/src/rule/recipe.ts b/src/rule/recipe.ts index 551b3cb..66b2422 100644 --- a/src/rule/recipe.ts +++ b/src/rule/recipe.ts @@ -1,12 +1,13 @@ import { IngredientInput, Predicate } from '../common/ingredient.js' import { Recipe } from '../parser/recipe/index.js' -import { encodeId, Id } from '../common/id.js' +import { createId, encodeId, Id } from '../common/id.js' import { Logger } from '../logger.js' import Rule, { Modifier } from './index.js' export default class RecipeRule extends Rule { constructor( private readonly idsTests: Predicate[], + private readonly typeTests: Predicate[], private readonly ingredientTests: Predicate[], private readonly resultTests: Predicate[], modifier: Modifier @@ -16,8 +17,10 @@ export default class RecipeRule extends Rule { matches(id: Id, recipe: Recipe, logger: Logger): boolean { const prefixed = logger.group(encodeId(id)) + const type = createId(recipe.toJSON().type) return ( this.idsTests.every(test => test(id, prefixed)) && + this.typeTests.every(test => test(type, prefixed)) && this.ingredientTests.every(test => recipe.getIngredients().some(it => test(it, prefixed))) && this.resultTests.every(test => recipe.getResults().some(it => test(it, prefixed))) ) diff --git a/test/recipe.test.ts b/test/recipe.test.ts index 46631a2..c32fcea 100644 --- a/test/recipe.test.ts +++ b/test/recipe.test.ts @@ -94,6 +94,18 @@ describe('recipe removal', () => { expect(acceptor.jsonAt('data/minecraft/recipe/sticky_piston.json')).toMatchObject(EMPTY_RECIPE) }) + it('removes recipes with type filter', async () => { + const acceptor = createTestAcceptor() + + loader.recipes.removeRecipe({ + type: 'minecraft:smelting', + }) + + await loader.emit(acceptor) + + expect(acceptor.paths().length).toBe(118) + }) + it('removes recipes with result filter', async () => { const acceptor = createTestAcceptor()