// let inputs = [ // { // tag: "minecraft:planks", // proxies: [ // { // tag: "minecraft:stick", // rate: 0.5 // } // ] // } // ] // let stonecuttingMap = {} // function addStoneCutting(inputId, resultId, count) { // let o = stonecuttingMap[inputId] ?? (stonecuttingMap[inputId] = {}) // o[resultId] = count // } // function addFromCrafting(ingredients, result, count) { // let base // for(let ing of ingredients) { // if(base == null) { // base = inputs.find(inp => inp.tag == ing.tag || inp.item == ing.item ) // continue // } // } // if(base == null) { // return // } // } // ServerEvents.recipes(recipe => { // let materials = [] // let conversionRates = new Map() // let addMaterials = (ing) => { // materials = materials.concat(ing.itemIds) // } // // addMaterials(Ingredient.of('#minecraft:logs')) // addMaterials(Ingredient.of('#minecraft:planks')) // addMaterials(Ingredient.of('#forge:glass')) // const validRecipeTypes = [ // "minecraft:crafting_shaped", // "minecraft:stonecutting", // "minecraft:crafting_shapeless" // ] // for(let material of materials) { // let existingConversions = {} // let materialConversionRates = {} // let addConversionRate = (toItemId, rate) => { // if(materialConversionRates[toItemId] != null) { // if(materialConversionRates[toItemId] < rate) { // materialConversionRates[toItemId] = rate // } // } else { // materialConversionRates[toItemId] = rate // console.log(material, toItemId, rate) // exploreMaterial(toItemId) // } // } // let exploreMaterial = (materialItemId) => { // recipe.forEachRecipe({ // input: materialItemId // }, (recipe) => { // let type = recipe.getType() // if(validRecipeTypes.find(rl => type.equals(rl)) != null) { // return // } // let ings = recipe.getOriginalRecipeIngredients() // let cost = 0 // for(let ing of ings) { // let rate // if(ing.test(material)) { // rate = 1 // } else { // rate = Array.from(Object.keys(materialConversionRates)).find(subMaterial => ing.test(subMaterial)) // rate = materialConversionRates[rate] // if(rate == null || rate == undefined) { // return // } // } // cost += rate // } // let finalRate = Math.floor(recipe.getOriginalRecipeResult().getCount() / cost) // let toItemId = recipe.getOriginalRecipeResult().getId() // if(recipe.getType().equals("minecraft:stonecutting")) { // console.log(toItemId) // existingConversions[toItemId] = true // } // if(finalRate >= 1) { // addConversionRate(toItemId, finalRate) // } // }) // } // exploreMaterial(material) // for(let outputId in materialConversionRates) { // if(existingConversions[outputId]) { // continue // } // let rate = materialConversionRates[outputId] // recipe.stonecutting(Item.of(outputId, rate), material) // } // conversionRates.set(material, materialConversionRates) // } // // console.log(conversionRates.values()) // }) (() => { const abnormalSupports = [ 'chest', 'post', 'stripped_post', 'ladder', 'boards', 'cabinet' ] const abnormalsMods = [ 'environmental', 'upgrade_aquatic', 'atmospheric', 'autumnity' ] function botaniaWood(name) { return { "mod": "botania", "name": name, "blockTypes": { "stairs": `botania:${name}_planks_stairs`, "slab": `botania:${name}_planks_slab`, "wood": `botania:${name}`, "stripped_wood": `botania:stripped_${name}` }, noSupport: [ 'sign', 'hanging_sign', 'sign_post', 'door', 'trapdoor', 'boat', 'pressure_plate', 'button' ], supports: [ 'stripped_stairs', 'stripped_slab', 'log_stairs', 'log_slab', 'framed', 'chiseled_framed' ] } } const woodTypes = [ { "mod": "minecraft", "name": "oak", "blockTypes": { "ladder": 'minecraft:ladder' } }, { "mod": "minecraft", "name": "spruce", "blockTypes": {} }, { "mod": "minecraft", "name": "birch", "blockTypes": {} }, { "mod": "minecraft", "name": "dark_oak", "blockTypes": {} }, { "mod": "minecraft", "name": "acacia", "blockTypes": {} }, { "mod": "minecraft", "name": "mangrove", "blockTypes": {} }, { "mod": "minecraft", "name": "cherry", "blockTypes": {} }, { "mod": "minecraft", "name": "warped", "blockTypes": { "log": 'minecraft:warped_stem', "stripped_log": 'minecraft:stripped_warped_stem', wood: 'minecraft:warped_hyphae', stripped_wood: 'minecraft:stripped_warped_hyphae', // hollow_log: 'quark:hollow_warped_stem', // boat: 'boatload:warped_boat' }, noSupport: [ 'boat', ] }, { "mod": "enhanced_mushrooms", "name": "mushroom", "blockTypes": { "log": 'minecraft:mushroom_stem', "stripped_log": 'enhanced_mushrooms:stripped_mushroom_stem', wood: 'enhanced_mushrooms:mushroom_hyphae', stripped_wood: 'enhanced_mushrooms:stripped_mushroom_hyphae', short_door: 'dramaticdoors:short_red_mushroom_door', tall_door: 'dramaticdoors:tall_red_mushroom_door' // hollow_log: 'quark:hollow_warped_stem', // boat: 'boatload:warped_boat' } }, { "mod": "minecraft", "name": "crimson", "blockTypes": { "log": 'minecraft:crimson_stem', "stripped_log": 'minecraft:stripped_crimson_stem', wood: 'minecraft:crimson_hyphae', stripped_wood: 'minecraft:stripped_crimson_hyphae', // hollow_log: 'quark:hollow_crimson_stem', // boat: 'boatload:crimson_boat' }, noSupport: [ 'boat', ] }, { "mod": "minecraft", "name": "jungle", "blockTypes": {} }, { "mod": "traverse", "name": "fir", "blockTypes": {} }, { "mod": "alexscaves", "name": "pewen", "blockTypes": {} }, { "mod": "alexscaves", "name": "thornwood", "blockTypes": {} }, { "mod": "minecraft", "name": "bamboo", "blockTypes": { "log": 'minecraft:bamboo_block', "planks_bamboo": "minecraft:bamboo_planks", // "stairs": "quark:bamboo_planks_stairs", // "slab": "quark:bamboo_planks_slab", "stripped_log": "minecraft:stripped_bamboo_block", 'chest': 'quark:bamboo_chest', 'chiseled': 'minecraft:bamboo_mosaic', 'chiseled_stairs': 'minecraft:bamboo_mosaic_stairs', 'chiseled_slab': 'minecraft:bamboo_mosaic_stairs', 'spikes': 'supplementaries:bamboo_spikes', 'mat': 'quark:bamboo_mat', 'mat_carpet': 'quark:bamboo_mat_carpet' }, noSupport: [ 'planks', 'hollow_log', 'wood', 'stripped_wood', 'boat' ], supports: [ 'planks_bamboo', 'chiseled', 'spikes', 'mat', 'mat_carpet' ] }, { "mod": "quark", "name": "azalea", "blockTypes": { "stairs": "quark:azalea_planks_stairs", "slab": "quark:azalea_planks_slab" } }, { "mod": "quark", "name": "blossom", "blockTypes": { "stairs": "quark:blossom_planks_stairs", "slab": "quark:blossom_planks_slab" } }, { "mod": "quark", "name": "ancient", "blockTypes": { "stairs": "quark:ancient_planks_stairs", "slab": "quark:ancient_planks_slab" } }, { "mod": "hexcasting", "name": "edified", "blockTypes": {}, noSupport: [ 'sign', 'sign_post', 'hanging_sign', 'post', 'boat', 'stripped_post', 'boards' ] }, botaniaWood("livingwood"), botaniaWood("dreamwood") ] function getIdSupplementaries(woodType) { let name = [ this.name, woodType.name ] return woodType.mod === 'minecraft' ? createId(this.mod, name) : createId(this.mod, [ woodType.mod ], name) } const plankRecipes = [ // { // mod: 'decorative_blocks', // abbr: 'db', // name: 'support' // }, // { // mod: 'decorative_blocks', // abbr: 'db', // name: 'palisade' // }, // { // mod: 'decorative_blocks', // abbr: 'db', // name: 'seat' // }, { name: 'stairs', salvageable: true, generic: true }, { name: 'slab', count: 2, generic: true }, { name: 'pressure_plate', count: 1, generic: true, }, { name: 'button', count: 1, generic: true, salvageable: true }, // { // mod: 'architects_palette', // abbr: 'ap', // name: 'parquety', // getName(woodType) { // return [ woodType.name, 'boards' ] // } // }, // { // mod: 'architects_palette', // abbr: 'ap', // name: 'board_wall' // }, // { // mod: 'architects_palette', // abbr: 'ap', // name: 'board_stairs' // }, // { // mod: 'architects_palette', // abbr: 'ap', // name: 'board_slab' // }, // { // mod: 'architects_palette', // abbr: 'ap', // name: 'railing' // }, // { // mod: 'woodworks', // abbr: 'abnww', // name: 'boards' // }, { mod: 'supplementaries', name: 'sign_post', getId: getIdSupplementaries }, { mod: 'quark', abbr: 'q', name: 'ladder' }, { exclusive: true, mod: 'quark', abbr: 'q', name: 'mat' }, { exclusive: true, mod: 'quark', abbr: 'q', name: 'mat_carpet', count: 2 }, // { // mod: 'another_furniture', // abbr: 'af', // name: 'bench' // }, // { // mod: 'another_furniture', // abbr: 'af', // name: 'table' // }, // { // mod: 'another_furniture', // abbr: 'af', // count: 2, // name: 'shutter' // }, { generic: true, name: 'bowl', count: 2, getId(woodType) { return 'minecraft:bowl' } }, { generic: true, name: 'stick', count: 2, getId(woodType) { return 'minecraft:stick' } }, { exclusive: true, generic: true, name: 'chiseled', }, { generic: true, exclusive: true, name: 'framed', count: 1, getName(woodType) { return [ 'framed', woodType.name ] } }, { generic: true, exclusive: true, name: 'chiseled_framed', count: 1, getName(woodType) { return [ 'pattern_framed', woodType.name ] } }, { generic: true, exclusive: true, name: 'chiseled_framed', count: 1, getName(woodType) { return [ 'pattern_framed', woodType.name ] } } ] const strippedRecipes = [ { name: 'door', count: 2, generic: true }, { name: 'trapdoor', count: 1, salvageable: true, generic: true }, { name: 'fence', count: 1, generic: true }, { name: 'fence_gate', count: 1, generic: true }, { mod: 'dramaticdoors', name: 'tall_door', getName(woodType) { return [ 'tall', woodType.name, 'door' ] }, count: 1 }, { mod: 'dramaticdoors', name: 'short_door', getName(woodType) { return [ 'short', woodType.name, 'door' ] }, count: 2 }, { name: 'planks', generic: true, count: 4, crafts: plankRecipes }, { exclusive: true, name: 'planks_bamboo', generic: true, count: 2, crafts: plankRecipes }, // { // mod: 'quark', // abbr: 'q', // name: 'hollow_log', // count: 1, // getName(woodType) { // return [ 'hollow', woodType.name, 'log' ] // } // }, { name: 'boat', count: 1, generic: true }, // { // mod: 'quark', // abbr: 'q', // name: 'stripped_post', // count: 2, // getName(woodType) { // return [ 'stripped', woodType.name, 'post' ] // } // }, { name: 'sign', count: 2, generic: true }, { name: 'hanging_sign', count: 1, generic: true }, { mod: 'supplementaries', name: 'cross_brace', generic: true, getId(woodType) { return 'supplementaries:timber_cross_brace' }, count: 2 }, { mod: 'supplementaries', name: 'frame', generic: true, getId(woodType) { return 'supplementaries:timber_frame' }, count: 2 }, { mod: 'supplementaries', name: 'brace', generic: true, getId(woodType) { return 'supplementaries:timber_brace' }, count: 2 }, { exclusive: true, generic: true, name: 'spikes', count: 2 }, // { // mod: 'shelfmod', // name: 'shelf', // getName(woodType) { // return [ 'shelf_item', woodType.name ] // }, // count: 1 // }, // { // mod: 'shelfmod', // name: 'floor_shelf', // getName(woodType) { // return [ 'floor_shelf_item', woodType.name ] // }, // count: 1 // }, { generic: true, exclusive: true, name: 'stripped_slab', count: 1, getName(woodType) { return [ 'stripped', woodType.name, 'slab' ] } }, { generic: true, exclusive: true, name: 'stripped_stairs', count: 1, getName(woodType) { return [ 'stripped', woodType.name, 'stairs' ] } }, // { // mod: 'another_furniture', // count: 1, // abbr: 'af', // name: 'drawer' // }, // { // mod: 'farmersdelight', // count: 1, // abbr: 'fd', // name: 'cabinet', // getId(woodType) { // let name = [ woodType.name, 'cabinet' ] // if(abnormalsMods.includes(woodType.mod)) { // return createId('abnormals_delight', name) // } else { // return getIdFromName(this, woodType, name) // } // } // }, // { // mod: 'supplementaries', // count: 1, // name: 'hanging_sign', // getId: getIdSupplementaries // }, // { // mod: 'decorative_blocks', // abbr: 'db', // name: 'beam' // }, ] const logRecipes = [ { generic: true, name: 'wood', count: 1, crafts: strippedRecipes, }, { generic: true, name: 'stripped_log', count: 1, crafts: strippedRecipes, getName(woodType) { return [ 'stripped', woodType.name, 'log' ] } }, { generic: true, name: 'stripped_wood', count: 1, crafts: strippedRecipes, // proxyCraft: false, getName(woodType) { return [ 'stripped', woodType.name, 'wood' ] } }, // { // mod: 'quark', // abbr: 'q', // name: 'post', // count: 2, // }, { generic: true, exclusive: true, name: 'log_slab', count: 1, getName(woodType) { return [ woodType.name, 'slab' ] } }, { generic: true, exclusive: true, name: 'log_stairs', count: 1, getName(woodType) { return [ woodType.name, 'stairs' ] } }, ] // const rootRecipe = { // name: 'log', // generic: true, // crafts: rootRecipes // } const blockTypes = [ { name: 'log', generic: true, crafts: logRecipes } ] .concat(logRecipes) .concat(strippedRecipes) .concat(plankRecipes) // let recipesToAdd = [ // // { // // input: 'aether:golden_oak_wood', // // output: 'aether:golden_oak_log', // // count: 1 // // }, // // { // // input: 'aether:golden_oak_log', // // output: 'aether:golden_oak_wood', // // count: 1 // // } // ] let recipesToAdd = [] let tagsToAdd = { // "woodworks:materials/skyroot_log": [ // 'aether:golden_oak_log', // 'aether:golden_oak_wood' // ] } const inputForms = [ 'log', 'wood', 'stripped_log', 'stripped_wood', 'planks', 'planks_bamboo' ] const addRecipe = (input, output, count) => { // if(recipesToAdd[input] == null) { // recipesToAdd[input] = {} // } // recipesToAdd[input][output] = count recipesToAdd.push({ input: input, output: output, count: count }) } const createTag = (tag) => { if(tagsToAdd[tag] == null) tagsToAdd[tag] = [] } const addToTag = (tag, item) => { tagsToAdd[tag].push(item) } const createId = function(mod, parts) { return mod + ':' + Array.from(arguments).slice(1).map(p => p.join('_')).join('/') } const ifUnset = (value, fallback) => { if(value == null) { return fallback } else { return value } } const getIdFromName = (blockType, woodType, name) => { if(blockType.generic) { return createId(woodType.mod, name) } if(woodType.mod === 'minecraft' || woodType.mod === blockType.mod) { return createId(blockType.mod, name) } return createId('everycomp', [ blockType.abbr ], [ woodType.mod ], name) } const getId = (blockType, woodType) => { if(woodType.blockTypes[blockType.name]) { return woodType.blockTypes[blockType.name] } if(woodType.supports && woodType.supports.includes(blockType.name)) { blockType.mod = woodType.mod } if(blockType.getId) { return blockType.getId.call(blockType, woodType) } let name = blockType.getName ? blockType.getName.call(blockType, woodType) : [ woodType.name, blockType.name ] return getIdFromName(blockType, woodType, name) } const addRecipesForForms = (forms, resultBlockType, woodType) => { let blockTypeCount = ifUnset(resultBlockType.count, 1) let output = getId(resultBlockType, woodType) if(output == null) { console.error(`Null output for ${resultBlockType.name} of ${woodType}`) } if(resultBlockType.salvageable) { addToTag(forms[0].tag, output) addRecipe(output, getId(forms[0].blockType, woodType), 1) } let previousCount = 1 for(let { tag, count } of forms) { addRecipe('#' + tag, output, blockTypeCount * previousCount ) previousCount *= count } } const addForms = (forms, blockType, woodType) => { let blockFormTag = createId('woodworks', [ 'materials' ], [ woodType.mod ], [ woodType.name, blockType.name ]) createTag(blockFormTag) addToTag(blockFormTag, getId(blockType, woodType)) let newForms = [ { blockType: blockType, tag: blockFormTag, count: ifUnset(blockType.count, 1) } ].concat(forms) for(let resultBlockType of ifUnset(blockType.crafts, [])) { if(resultBlockType.exclusive) { if(woodType.supports == null || !woodType.supports.includes(resultBlockType.name)) continue } if(woodType.noSupport && woodType.noSupport.includes(resultBlockType.name)) continue addRecipesForForms(newForms, resultBlockType, woodType) if(resultBlockType.crafts && (resultBlockType.proxyCraft ?? true)) { addForms(newForms, resultBlockType, woodType) } } } // for(let woodType of woodTypes) { // addForms([], rootRecipe, woodType) // } for(let inputForm of inputForms) { let blockType = blockTypes.find(a => a.name == inputForm) if(blockType == null) { console.warn('Could not find block type: ' + blockType) continue } for(let woodType of woodTypes) { for(let resultBlockType of blockType.crafts ?? []) { if(resultBlockType.exclusive) { if(woodType.supports == null || !woodType.supports.includes(resultBlockType.name)) continue } if(woodType.noSupport && woodType.noSupport.includes(resultBlockType.name)) continue let count = ifUnset(resultBlockType.count, 1) let output = getId(resultBlockType, woodType) if(output == null) { console.error(`Null output for ${resultBlockType.name} of ${woodType}`) continue } addRecipe(getId(blockType, woodType), output, count) } // let blockFormTag = createId('woodworks', [ 'materials' ], [ woodType.mod ], [ woodType.name, blockType.name ]) // createTag(blockFormTag) // addToTag(blockFormTag, getId(blockType, woodType)) // let newForms = [ // { // blockType: blockType, // tag: blockFormTag, // count: ifUnset(blockType.count, 1) // } // ] // for(let resultBlockType of ifUnset(blockType.crafts, [])) { // if(resultBlockType.exclusive) { // if(woodType.supports == null || !woodType.supports.includes(resultBlockType.name)) // continue // } // if(woodType.noSupport && woodType.noSupport.includes(resultBlockType.name)) // continue // addRecipesForForms(newForms, resultBlockType, woodType) // } } } function proxify(input, output) { let count = recipesToAdd[input][output] if(recipesToAdd[output] != null) { for(let extraProxifiedOutput in recipesToAdd[output]) { if(input == extraProxifiedOutput) { continue } recipesToAdd[input][extraProxifiedOutput] = count * recipesToAdd[output][extraProxifiedOutput] proxify(input, extraProxifiedOutput) } } } ServerEvents.recipes(recipes => { recipes.remove({ type: 'sawmill:woodcutting' }) // for(let { input, output, count } of recipesToAdd) { // // console.log('Adding recipe for' + input + ' to ' + output) // if(Ingredient.of(input) == []) { // console.log('bad input', input) // } // recipes.custom({ // type: "sawmill:woodcutting", // count: count, // ingredient: Ingredient.of(input), // result: output // }) // .id((input + '_to_' + output).replace(/[^a-z0-9]/g, '_')) // } // recipes.forEachRecipe({ // type: "minecraft:stonecutting" // }, recipe => { // let inputs = recipe.getOriginalRecipeIngredients()[0].itemIds.toArray() // let count = recipe.getOriginalRecipeResult().getCount() // let output = recipe.getOriginalRecipeResult().getId() // // console.log(inputs, output) // // if(inputs.includes(output)) { // // inputs.splice(inputs.indexOf(output), 1) // // } // for(let input of inputs) { // addRecipe(input, output, count) // } // }) function proxify(input, output, count, outputs) { // if(outputs == null) { // outputs = recipesToAdd.filter(r => r.input == input).map(r => r.output) // } // console.log('Proxying for ' + input + ' to ' + output) recipesToAdd .filter(e => e.input == output) // .filter(e => e.input == output && !outputs.includes(e.output)) .forEach(e => { addRecipe(input, e.output, e.count * count, false) // outputs.push(e.output) proxify(input, e.output, e.count * count) }) } for(let { input, output, count } of recipesToAdd) { proxify(input, output, count) } let dict = {} for(let { input, output, count } of recipesToAdd) { dict[output] = dict[output] ?? {} dict[output][count] = dict[output][count] ?? [] dict[output][count].push(input) // if(count == 1) { // dict[input] = dict[input] ?? {} // dict[input][count] = dict[input][count] ?? [] // dict[input][count].push(output) // } } let recipeCount = 0 for(let output in dict) { for(let count in dict[output]) { recipes.custom({ type: "sawmill:woodcutting", count: count, ingredient: Ingredient.of(dict[output][count]), result: output }) } recipeCount++ } console.log('Added ' + recipeCount + ' sawmill recipes') recipes.forEachRecipe({ type: "minecraft:stonecutting" }, recipe => { let count = recipe.getOriginalRecipeResult().getCount() let output = recipe.getOriginalRecipeResult().getId() recipes.custom({ type: "sawmill:woodcutting", count: count, ingredient: Ingredient.of(recipe.getOriginalRecipeIngredients()[0]), result: output }) }) // for(let input in recipesToAdd) { // for(let output in recipesToAdd[input]) { // let count = recipesToAdd[input][output] // console.log('Adding recipe for ' + input + ' to ' + output) // if(Ingredient.of(input) == []) { // console.log('bad input', input) // } // recipes.custom({ // type: "sawmill:woodcutting", // count: count, // ingredient: Ingredient.of(input), // result: output // }) // // .id((input + '_to_' + output).replace(/[^a-z0-9._-]/g, '_')) // } // } }) ServerEvents.tags('item', tags => { console.log(tagsToAdd['woodworks:materials/quark/azalea_log']) for(let name in tagsToAdd) { tags.add(name, tagsToAdd[name]) } }) })()