diff --git a/examples/postInit/pyrotech.groovy b/examples/postInit/pyrotech.groovy index bccda9577..a7e6a58bf 100644 --- a/examples/postInit/pyrotech.groovy +++ b/examples/postInit/pyrotech.groovy @@ -5,40 +5,42 @@ log.info 'mod \'pyrotech\' detected, running script' // Anvil: -// When using hammer or pickaxe it can convert items. +// Converts an item to a new item by hitting it with a hammer or pickaxe. -mods.pyrotech.anvil.removeByOutput(item('minecraft:stone_slab', 3)) +mods.pyrotech.anvil.removeByInput(item('pyrotech:material:37')) +mods.pyrotech.anvil.removeByOutput(item('minecraft:stone_slab:3') * 2) // mods.pyrotech.anvil.removeAll() mods.pyrotech.anvil.recipeBuilder() - .input(item('minecraft:diamond') * 4) + .input(item('minecraft:diamond')) .output(item('minecraft:emerald') * 2) - .hits(5) + .hits(8) .typeHammer() .tierGranite() .name('diamond_to_emerald_granite_anvil') .register() mods.pyrotech.anvil.recipeBuilder() - .input(item('minecraft:diamond') * 8) + .input(item('minecraft:bedrock')) .output(item('minecraft:nether_star') * 1) .hits(10) .typePickaxe() .tierIronclad() - .name('diamond_to_nether_star_ironclad_anvil') + .inherit(true) + .name('bedrock_to_nether_star') .register() mods.pyrotech.anvil.recipeBuilder() - .input(item('minecraft:diamond') * 4) + .input(item('minecraft:gold_block')) .output(item('minecraft:gold_ingot') * 16) .hits(5) .typePickaxe() .tierObsidian() - .name('diamond_to_gold_obsidian_anvil') + .name('gold_block_to_gold_obsidian_anvil') .register() -mods.pyrotech.anvil.add('iron_to_clay', ore('ingotIron'), item('minecraft:clay_ball'), 9, 'granite', 'hammer') +mods.pyrotech.anvil.add('flint_from_gravel', ore('gravel'), item('minecraft:flint'), 5, 'granite', 'pickaxe', true) // Barrel: // Over time converts a fluid with four items into a new fluid. @@ -57,43 +59,152 @@ mods.pyrotech.barrel.recipeBuilder() mods.pyrotech.barrel.add('iron_dirt_water_to_lava', ore('ingotIron'), ore('ingotIron'), item('minecraft:dirt'), item('minecraft:dirt'), fluid('water'), fluid('lava'), 1000) +// Bloomery: +// Converts item to a new item or a 'bloom' which are items that needs to be hit with hammer on anvil to get the output +// with varying amounts. + +mods.pyrotech.bloomery.removeByInput(item('minecraft:gold_ore')) +// mods.pyrotech.bloomery.removeByOutput(item('minecraft:iron_nugget')) +// mods.pyrotech.bloomery.removeAll() + +mods.pyrotech.bloomery.recipeBuilder() + .input(item('minecraft:iron_block')) + .bloom(item('minecraft:apple')) + .failureChance(0.0F) + .slag(item('minecraft:carrot')) + .inherit(true) + .name('metal_vegetation') + .register() + +mods.pyrotech.bloomery.recipeBuilder() + .input(item('minecraft:noteblock')) + .output(item('minecraft:record_13')) + .experience(0.25F) + .tierIronclad() + .bloomYield(1, 1) + .burnTime(2000) + .failureChance(0.5F) + .failureOutput(item('minecraft:record_11'), 1) + .inherit(true) + .name('recipe_for_soundphiles') + .register() + +mods.pyrotech.bloomery.recipeBuilder() + .input(item('minecraft:sponge')) + .output(item('minecraft:sponge')) + .bloomYield(2, 5) + .typePickaxe() + .langKey(item('minecraft:stick').getTranslationKey()) + .inherit(true) + .name('sponge_duplication') + .register() + +mods.pyrotech.bloomery.recipeBuilder() + .input(item('minecraft:birch_boat')) + .bloom(item('minecraft:dark_oak_boat')) + .tierObsidian() + .failureChance(0.1) + .failureOutput(item('minecraft:spruce_boat'), 5) + .failureOutput(item('minecraft:jungle_boat'), 2) + .failureOutput(item('minecraft:boat'), 1) + .name('boat_smelting') + .register() + +mods.pyrotech.bloomery.recipeBuilder() + .input(item('minecraft:sand')) + .output(item('minecraft:glass')) + .bloomYield(3, 5) + .experience(0.1F) + .burnTime(4000) + .tierGranite() + .tierObsidian() + .anvilHit(2) + .typePickaxe() + .failureChance(0.05) + .failureOutput(item('minecraft:nether_star'), 1) + .failureOutput(item('minecraft:gold_ingot'), 10) + .name('glasswork') + .register() + + +mods.pyrotech.bloomery.add('loreming_the_ipsum', item('minecraft:redstone'), item('minecraft:lava_bucket'), false) +mods.pyrotech.bloomery.add('cooking_a_story', item('minecraft:written_book'), item('minecraft:book'), 200, true) +mods.pyrotech.bloomery.addBloom('cyanide', item('minecraft:poisonous_potato'), item('minecraft:potato'), true) + +// Refractory Crucible: +// Converts item into a liquid. + +mods.pyrotech.brick_crucible.removeByInput(item('minecraft:gravel')) +mods.pyrotech.brick_crucible.removeByOutput(fluid('water') * 125) +// mods.pyrotech.brick_crucible.removeAll() + +mods.pyrotech.brick_crucible.recipeBuilder() + .input(item('minecraft:vine')) + .fluidOutput(fluid('water') * 250) + .burnTime(60) + .name('water_from_vine') + .register() + + +mods.pyrotech.brick_crucible.add('lava_from_obsidian', ore('obsidian'), fluid('lava') * 1000, 2000) + // Refractory Kiln: -// Converts an item into a new one by burning it. Has a chance to fail. +// Converts an item into a new item or one of the failure outputs if the recipe fails. +mods.pyrotech.brick_kiln.removeByInput(item('minecraft:cobblestone')) mods.pyrotech.brick_kiln.removeByOutput(item('pyrotech:bucket_clay')) // mods.pyrotech.brick_kiln.removeAll() mods.pyrotech.brick_kiln.recipeBuilder() - .input(item('minecraft:iron_ingot')) - .output(item('minecraft:gold_ingot')) - .burnTime(400) - .failureChance(1f) - .failureOutput(item('minecraft:wheat'), item('minecraft:carrot'), item('minecraft:sponge')) - .name('iron_to_gold_kiln_with_failure_items_brick') + .input(item('minecraft:fish')) + .output(item('minecraft:cooked_fish')) + .burnTime(200000) + .failureChance(0.99f) + .failureOutput(item('minecraft:dragon_egg'), item('minecraft:dragon_breath')) + .name('meaning_of_life') .register() -mods.pyrotech.brick_kiln.add('clay_to_iron_brick', item('minecraft:clay_ball') * 5, item('minecraft:iron_ingot'), 1200, 0.5f, item('minecraft:dirt'), item('minecraft:cobblestone')) +mods.pyrotech.brick_kiln.add('beetroot_soup', item('minecraft:beetroot'), item('minecraft:beetroot_soup'), 1200, 0.1f, item('minecraft:beetroot_seeds')) // Refractory Oven: -// When powered by burning fuel can convert items. +// Converts item into a new item. mods.pyrotech.brick_oven.removeByInput(item('minecraft:porkchop')) mods.pyrotech.brick_oven.removeByOutput(item('minecraft:cooked_porkchop')) // mods.pyrotech.brick_oven.removeAll() mods.pyrotech.brick_oven.recipeBuilder() - .input(item('minecraft:diamond')) - .output(item('minecraft:emerald')) - .duration(400) - .name('diamond_campfire_to_emerald_brick') + .input(item('minecraft:chorus_fruit')) + .output(item('minecraft:chorus_fruit_popped')) + .duration(800) + .name('chorus_fruit_whats_popping') .register() -mods.pyrotech.brick_oven.add('apple_to_dirt_brick', item('minecraft:apple'), item('minecraft:dirt'), 1000) +mods.pyrotech.brick_oven.add('lead_poisoning', item('minecraft:slime_ball'), item('minecraft:lead') * 16, 1000) + +// Refractory Sawmill: +// Converts an item into a new item with an item with durability and drops wood chips on given amount of time. + +mods.pyrotech.brick_sawmill.removeByInput(item('minecraft:planks:1')) +mods.pyrotech.brick_sawmill.removeByOutput(item('pyrotech:material:23')) +// mods.pyrotech.brick_sawmill.removeAll() + +mods.pyrotech.brick_sawmill.recipeBuilder() + .input(item('minecraft:golden_helmet')) + .output(item('minecraft:gold_ingot') * 2) + .duration(1500) + .woodChips(5) + .name('golden_helmet_recycling') + .register() + + +mods.pyrotech.brick_sawmill.add('glowstone_to_dust', item('minecraft:glowstone'), item('pyrotech:sawmill_blade_stone'), item('minecraft:glowstone_dust'), 200, 0) +mods.pyrotech.brick_sawmill.add('bed_to_wool', item('minecraft:bed'), item('minecraft:wool') * 3, 500, 3) // Campfire: -// When powered by burning logs can convert items. +// Converts item into a new item on given amount of time. mods.pyrotech.campfire.removeByInput(item('minecraft:porkchop')) mods.pyrotech.campfire.removeByOutput(item('minecraft:cooked_porkchop')) @@ -126,6 +237,13 @@ mods.pyrotech.chopping_block.recipeBuilder() .name('diamond_to_emerald_chopping_block') .register() +mods.pyrotech.chopping_block.recipeBuilder() + .input(item('minecraft:iron_ingot')) + .output(item('minecraft:gold_ingot')) + .inherit(true) + .name('iron_to_gold_chopping_block') + .register() + // Compacting Bin: // When using a shovel it can convert items. @@ -137,17 +255,25 @@ mods.pyrotech.compacting_bin.removeByOutput(item('minecraft:bone_block')) mods.pyrotech.compacting_bin.recipeBuilder() .input(item('minecraft:diamond')) .output(item('minecraft:emerald')) - .toolUses(5) - .name('diamond_to_emerald_compacting_bin') + .hits(5, 4, 3, 2) + .inherit(true) + .name('diamond_to_emerald') .register() +mods.pyrotech.compacting_bin.recipeBuilder() + .input(item('minecraft:slime_ball') * 9) + .output(item('minecraft:slime')) + .name('slime_compacting') + .register() -mods.pyrotech.compacting_bin.add('iron_to_clay', ore('ingotIron') * 5, item('minecraft:clay_ball') * 20, 9) + +mods.pyrotech.compacting_bin.add('iron_to_clay', ore('ingotIron') * 5, item('minecraft:clay_ball') * 20, false, 9, 7, 6, 6) // Compost Bin: // Can convert multiple items into a new one when its full. mods.pyrotech.compost_bin.removeByInput(item('minecraft:golden_carrot')) +// mods.pyrotech.compost_bin.removeByOutput(item('pyrotech:mulch') * 4) // mods.pyrotech.compost_bin.removeAll() mods.pyrotech.compost_bin.recipeBuilder() @@ -158,12 +284,13 @@ mods.pyrotech.compost_bin.recipeBuilder() .register() -mods.pyrotech.compost_bin.add('iron_to_clay2', ore('ingotIron') * 5, item('minecraft:clay_ball') * 20, 2) +mods.pyrotech.compost_bin.add('iron_to_clay2', ore('ingotIron'), item('minecraft:clay_ball') * 20, 2) // Crude Drying Rack: // Converts an item over time into a new one. mods.pyrotech.crude_drying_rack.removeByInput(item('minecraft:wheat')) +mods.pyrotech.crude_drying_rack.removeByOutput(item('minecraft:paper')) // mods.pyrotech.crude_drying_rack.removeAll() mods.pyrotech.crude_drying_rack.recipeBuilder() @@ -173,13 +300,22 @@ mods.pyrotech.crude_drying_rack.recipeBuilder() .name('diamond_to_emerald_crude_drying_rack') .register() +mods.pyrotech.crude_drying_rack.recipeBuilder() + .input(item('minecraft:glowstone_dust')) + .output(item('minecraft:redstone')) + .dryTime(1000) + .inherit(true) + .name('glowstone_to_redstone') + .register() + -mods.pyrotech.crude_drying_rack.add('apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200) +mods.pyrotech.crude_drying_rack.add('apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200, true) // Drying Rack: // Converts an item over time into a new one. mods.pyrotech.drying_rack.removeByInput(item('minecraft:wheat')) +mods.pyrotech.drying_rack.removeByOutput(item('minecraft:sponge')) // mods.pyrotech.drying_rack.removeAll() mods.pyrotech.drying_rack.recipeBuilder() @@ -189,12 +325,91 @@ mods.pyrotech.drying_rack.recipeBuilder() .name('iron_to_gold_drying_rack') .register() +mods.pyrotech.drying_rack.recipeBuilder() + .input(item('minecraft:ender_eye')) + .output(item('minecraft:ender_pearl')) + .dryTime(500) + .inherit(true) + .name('ender_eye_to_ender_pearl') + .register() + + +mods.pyrotech.drying_rack.add('apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200, true) + +// Mechanical Compacting Bin: +// Converts given amount of item into new item. + +mods.pyrotech.mechanical_compacting_bin.removeByInput(item('minecraft:snowball')) +mods.pyrotech.mechanical_compacting_bin.removeByOutput(item('minecraft:bone_block')) +// mods.pyrotech.mechanical_compacting_bin.removeAll() + +mods.pyrotech.mechanical_compacting_bin.recipeBuilder() + .hits(2, 2, 1, 1) + .input(item('minecraft:melon') * 8) + .output(item('minecraft:melon_block')) + .name('melon_compacting') + .register() + + +mods.pyrotech.mechanical_compacting_bin.add('wheat_to_hay_block', ore('cropWheat') * 9, item('minecraft:hay_block')) +mods.pyrotech.mechanical_compacting_bin.add('gold_to_wheat', ore('ingotGold') * 4, item('minecraft:wheat') * 64, 4, 4, 3, 2) + +// Pit Burning: +// Converts a block in world to an item and fluid by burning. + +mods.pyrotech.pit_burn.removeByInput(item('minecraft:coal_block')) +mods.pyrotech.pit_burn.removeByOutput(item('minecraft:coal', 1) * 10) +// mods.pyrotech.pit_burn.removeAll() + +mods.pyrotech.pit_burn.recipeBuilder() + .input(item('minecraft:cauldron')) + .output(item('minecraft:cobblestone')) + .fluidOutput(fluid('water') * 50) + .burnStages(6) + .burnTime(1200) + .name('water_from_cauldron') + .register() + +mods.pyrotech.pit_burn.recipeBuilder() + .input(item('minecraft:soul_sand')) + .output(item('minecraft:sand')) + .fluidOutput(fluid('lava') * 200) + .requiresRefractoryBlocks(true) + .burnStages(2) + .burnTime(600) + .failureChance(0.25F) + .failureOutput(item('minecraft:gravel') * 2) + .failureOutput(item('minecraft:dirt') * 3) + .name('lava_to_sand') + .register() + +mods.pyrotech.pit_burn.recipeBuilder() + .input(blockstate('minecraft:sponge', + 'wet=true')) + .output(item('minecraft:sponge')) + .fluidOutput(fluid('water') * 25) + .fluidLevelAffectsFailureChance(true) + .burnStages(10) + .burnTime(500) + .name('sponge_dehydrating') + .register() + +mods.pyrotech.pit_burn.recipeBuilder() + .input(item('minecraft:chest')) + .output(item('minecraft:ender_chest')) + .fluidOutput(fluid('lava') * 125) + .fluidLevelAffectsFailureChance(true) + .requiresRefractoryBlocks(true) + .burnStages(4) + .burnTime(2000) + .name('chest_burning') + .register() -mods.pyrotech.drying_rack.add('apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200) // Pit Kiln: // Converts an item into a new one by burning it. Has a chance to fail. +mods.pyrotech.pit_kiln.removeByInput(item('pyrotech:bucket_refractory_unfired')) mods.pyrotech.pit_kiln.removeByOutput(item('pyrotech:bucket_clay')) // mods.pyrotech.pit_kiln.removeAll() @@ -207,12 +422,22 @@ mods.pyrotech.pit_kiln.recipeBuilder() .name('iron_to_gold_kiln_with_failure_items') .register() +mods.pyrotech.pit_kiln.recipeBuilder() + .input(item('minecraft:record_11')) + .output(item('minecraft:record_13')) + .burnTime(200) + .failureChance(0f) + .inherit(true) + .name('record_11_to_record_13') + .register() + -mods.pyrotech.pit_kiln.add('clay_to_iron', item('minecraft:clay_ball') * 5, item('minecraft:iron_ingot'), 1200, 0.5f, [item('minecraft:dirt'), item('minecraft:cobblestone')]) +mods.pyrotech.pit_kiln.add('brick_to_iron', item('minecraft:brick'), item('minecraft:iron_ingot'), 1200, true, 0.5f, item('minecraft:dirt'), item('minecraft:cobblestone')) // Soaking Pot: -// Converts an item into a new one by soaking it in a liquid. Can require a campfire. +// Converts an item and liquid into a new item. Can require a campfire below. +mods.pyrotech.soaking_pot.removeByInput(item('pyrotech:hide_washed')) mods.pyrotech.soaking_pot.removeByOutput(item('pyrotech:material', 54)) // mods.pyrotech.soaking_pot.removeAll() @@ -228,23 +453,51 @@ mods.pyrotech.soaking_pot.recipeBuilder() mods.pyrotech.soaking_pot.add('dirt_to_apple', item('minecraft:dirt'), fluid('water'), item('minecraft:apple'), 1200) +// Stone Crucible: +// Converts an item into a liquid. + +mods.pyrotech.stone_crucible.removeByInput(item('minecraft:ice')) +mods.pyrotech.stone_crucible.removeByOutput(fluid('water') * 500) +// mods.pyrotech.stone_crucible.removeAll() + +mods.pyrotech.stone_crucible.recipeBuilder() + .input(ore('sugarcane')) + .fluidOutput(fluid('water') * 500) + .burnTime(1000) + .inherit(true) + .name('water_from_sugarcane') + + + +mods.pyrotech.stone_crucible.add('water_from_cactus', ore('blockCactus'), fluid('water') * 1000, 600, true) + // Stone Kiln: // Converts an item into a new one by burning it. Has a chance to fail. +mods.pyrotech.stone_kiln.removeByInput(item('minecraft:sand')) mods.pyrotech.stone_kiln.removeByOutput(item('pyrotech:bucket_clay')) // mods.pyrotech.stone_kiln.removeAll() mods.pyrotech.stone_kiln.recipeBuilder() - .input(item('minecraft:iron_ingot')) - .output(item('minecraft:gold_ingot')) - .burnTime(400) - .failureChance(1f) - .failureOutput(item('minecraft:wheat'), item('minecraft:carrot'), item('minecraft:sponge')) - .name('iron_to_gold_kiln_with_failure_items_stone') + .input(item('minecraft:diamond')) + .output(item('minecraft:emerald')) + .burnTime(800) + .failureChance(0.6f) + .failureOutput(item('minecraft:egg'), item('minecraft:fish')) + .name('diamond_to_emerald_with_failure_outputs') + .register() + +mods.pyrotech.stone_kiln.recipeBuilder() + .input(item('minecraft:compass')) + .output(item('minecraft:clock')) + .burnTime(1200) + .failureChance(0f) + .inherit(true) + .name('compass_to_clock') .register() -mods.pyrotech.stone_kiln.add('clay_to_iron_stone', item('minecraft:clay_ball') * 5, item('minecraft:iron_ingot'), 1200, 0.5f, item('minecraft:dirt'), item('minecraft:cobblestone')) +mods.pyrotech.stone_kiln.add('clay_to_iron_stone', item('minecraft:clay_ball'), item('minecraft:iron_ingot'), 1200, true, 0.5f, item('minecraft:dirt'), item('minecraft:cobblestone')) // Stone Oven: // When powered by burning fuel can convert items. @@ -257,16 +510,45 @@ mods.pyrotech.stone_oven.recipeBuilder() .input(item('minecraft:diamond')) .output(item('minecraft:emerald')) .duration(400) + .inherit(true) .name('diamond_campfire_to_emerald_stone') .register() -mods.pyrotech.stone_oven.add('apple_to_dirt_stone', item('minecraft:apple'), item('minecraft:dirt'), 1000) +mods.pyrotech.stone_oven.add('sand_to_dirt', item('minecraft:sand'), item('minecraft:dirt'), 1000, true) + +// Stone Sawmill: +// Converts an item into a new item with an item with durability and drops wood chips on given amount of time. + +mods.pyrotech.stone_sawmill.removeByInput(item('minecraft:planks:1')) +mods.pyrotech.stone_sawmill.removeByOutput(item('pyrotech:material:23')) +// mods.pyrotech.stone_sawmill.removeAll() + +mods.pyrotech.stone_sawmill.recipeBuilder() + .input(item('minecraft:sign')) + .output(item('minecraft:planks:0') * 2) + .duration(200) + .woodChips(5) + .inherit(true) + .name('wood_from_sign') + .register() + +mods.pyrotech.stone_sawmill.recipeBuilder() + .input(item('minecraft:stone_pickaxe'), item('pyrotech:sawmill_blade_bone')) + .output(item('minecraft:iron_pickaxe')) + .duration(5000) + .name('stone_pickaxe_upgrade') + .register() + + +mods.pyrotech.stone_sawmill.add('apple_to_gapple_with_golden_blade', item('minecraft:apple'), item('pyrotech:sawmill_blade_bone'), item('minecraft:golden_apple'), 2000, 0, false) +mods.pyrotech.stone_sawmill.add('stone_to_cobblestone', ore('stone'), item('minecraft:cobblestone'), 500, 0, true) // Tanning Rack: // Converts an item over time into a new one. mods.pyrotech.tanning_rack.removeByInput(item('minecraft:wheat')) +mods.pyrotech.tanning_rack.removeByOutput(item('minecraft:leather')) // mods.pyrotech.tanning_rack.removeAll() mods.pyrotech.tanning_rack.recipeBuilder() @@ -279,3 +561,201 @@ mods.pyrotech.tanning_rack.recipeBuilder() mods.pyrotech.tanning_rack.add('apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200, item('minecraft:clay_ball')) +// Wither Forge: +// Converts item to a new item or a 'bloom' which are items that needs to be hit with hammer on anvil to get the output +// with varying amounts. + +mods.pyrotech.wither_forge.removeByInput(item('minecraft:gold_ore')) +// mods.pyrotech.wither_forge.removeByOutput(item('minecraft:iron_nugget')) +// mods.pyrotech.wither_forge.removeAll() + +mods.pyrotech.wither_forge.recipeBuilder() + .input(item('minecraft:minecart')) + .output(item('minecraft:furnace_minecart')) + .slag(item('minecraft:iron_ingot')) + .experience(0.8F) + .bloomYield(1, 1) + .burnTime(2000) + .failureChance(0.5F) + .failureOutput(item('minecraft:tnt_minecart'), 1) + .name('minecart_smelting') + .register() + +mods.pyrotech.wither_forge.recipeBuilder() + .input(item('minecraft:fishing_rod') | item('minecraft:carrot_on_a_stick')) + .output(item('minecraft:cooked_fish')) + .bloomYield(5, 8) + .langKey(item('minecraft:fishing_rod').getTranslationKey()) + .name('fishing') + .register() + +mods.pyrotech.wither_forge.recipeBuilder() + .input(item('minecraft:paper')) + .bloom(item('minecraft:book')) + .tierGranite() + .tierObsidian() + .failureChance(0.1F) + .failureOutput(item('minecraft:milk_bucket'), 5) + .failureOutput(item('minecraft:bone'), 2) + .name('knowledge') + .register() + +mods.pyrotech.wither_forge.recipeBuilder() + .input(item('minecraft:comparator')) + .output(item('minecraft:redstone')) + .bloomYield(12, 15) + .experience(0.6F) + .burnTime(4000) + .tierGranite() + .tierIronclad() + .anvilHit(5) + .typePickaxe() + .failureChance(0.15F) + .failureOutput(item('minecraft:glowstone_dust'), 5) + .failureOutput(item('minecraft:sugar'), 4) + .name('comparator_melting') + .register() + + +mods.pyrotech.wither_forge.add('flower_pot', item('minecraft:flower_pot'), item('minecraft:clay_ball')) +mods.pyrotech.wither_forge.add('hoopify', item('minecraft:hopper') * 4, item('minecraft:chest'), 60) +mods.pyrotech.wither_forge.addBloom('quartz_recipe', item('minecraft:quartz') * 3, ore('oreQuartz')) +mods.pyrotech.wither_forge.addBloom('feathery', item('minecraft:feather'), 10, 15, item('minecraft:chicken'), 200, 0.1F, 0.25F, item('minecraft:cooked_chicken')) + +// Worktable: +// Crafting table which asks you to hit it with a tool to craft stuff. + +mods.pyrotech.worktable.removeByOutput(item('pyrotech:iron_hunters_knife')) +// mods.pyrotech.worktable.removeAll() + +mods.pyrotech.worktable.shapedBuilder() + .name('irons_to_dirts') + .output(item('minecraft:dirt') * 8) + .shape([[item('minecraft:iron_ingot'),item('minecraft:iron_ingot'),item('minecraft:iron_ingot')], + [item('minecraft:iron_ingot'),null,item('minecraft:iron_ingot')], + [item('minecraft:iron_ingot'),item('minecraft:iron_ingot'),item('minecraft:iron_ingot')]]) + .replaceByName() + .register() + +mods.pyrotech.worktable.shapedBuilder() + .name(resource('minecraft:sea_lantern')) + .output(item('minecraft:clay')) + .shape([[ore('blockRedstone')], + [ore('blockRedstone')], + [ore('blockRedstone')]]) + .replaceByName() + .register() + +mods.pyrotech.worktable.shapedBuilder() + .output(item('minecraft:nether_star')) + .row('TXT') + .row('X X') + .row('!X!') + .key('T', item('minecraft:gravel')) + .key('X', item('minecraft:clay').reuse()) + .key('!', item('minecraft:gunpowder').transform({ _ -> item('minecraft:diamond') })) + .tool(item('minecraft:diamond_sword'), 5) + .register() + +mods.pyrotech.worktable.shapedBuilder() + .output(item('minecraft:clay_ball') * 3) + .shape('S S', + ' G ', + 'SWS') + .key([S: ore('ingotIron').reuse(), G: ore('gemDiamond'), W: fluid('water') * 1000]) + .tool(item('minecraft:diamond_axe'), 3) + .register() + +mods.pyrotech.worktable.shapedBuilder() + .name('gold_duplication_with_tnt') + .output(item('minecraft:gold_block')) + .row('!!!') + .row('!S!') + .row('!!!') + .key([S: ore('blockGold').reuse(), '!': item('minecraft:tnt').transform(item('minecraft:diamond'))]) + .tool(item('minecraft:iron_shovel'), 2) + .register() + +mods.pyrotech.worktable.shapedBuilder() + .output(item('minecraft:clay')) + .row(' B') + .key('B', item('minecraft:glass_bottle')) + .tool(item('minecraft:stone_sword'), 3) + .register() + +mods.pyrotech.worktable.shapedBuilder() + .output(item('minecraft:clay')) + .row(' 1 ') + .row(' 0 ') + .row(' 1 ') + .key('1', item('minecraft:iron_sword')) + .key('0', item('minecraft:diamond_sword').withNbt([display:[Name:'Sword with Specific NBT data']])) + .tool(item('minecraft:iron_axe'), 4) + .register() + +mods.pyrotech.worktable.shapelessBuilder() + .output(item('minecraft:string')) + .input([item('minecraft:cobblestone'),item('minecraft:feather'),item('minecraft:gold_ingot')]) + .register() + +mods.pyrotech.worktable.shapelessBuilder() + .name('precious_to_clay') + .output(item('minecraft:clay')) + .input([item('minecraft:emerald'),item('minecraft:iron_ore'),item('minecraft:gold_ingot')]) + .register() + +mods.pyrotech.worktable.shapelessBuilder() + .name(resource('example:resource_location2')) + .output(item('minecraft:stone')) + .input([item('minecraft:gold_ore'), item('minecraft:gold_ingot')]) + .register() + +mods.pyrotech.worktable.shapelessBuilder() + .output(item('minecraft:ender_eye')) + .input([item('minecraft:ender_pearl'),item('minecraft:bowl')]) + .replace() + .tool(item('minecraft:iron_sword'), 4) + .register() + +mods.pyrotech.worktable.shapelessBuilder() + .name('minecraft:pink_dye_from_pink_tulp') + .output(item('minecraft:clay')) + .input([item('minecraft:stick')]) + .replaceByName() + .tool(item('minecraft:iron_pickaxe'), 2) + .register() + +mods.pyrotech.worktable.shapelessBuilder() + .name(resource('minecraft:pink_dye_from_peony')) + .output(item('minecraft:coal')) + .input([item('minecraft:stone'), item('minecraft:iron_ingot')]) + .replaceByName() + .tool(item('minecraft:stone_axe'), 2) + .register() + + +// mods.pyrotech.worktable.addShaped(item('minecraft:gold_block'), item('minecraft:diamond_pickaxe'), 2, [[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')],[null, null, null],[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]]) +// mods.pyrotech.worktable.addShaped(item('minecraft:gold_block'), [[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')],[null, null, null],[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]]) +// mods.pyrotech.worktable.addShaped(resource('example:resource_location'), item('minecraft:clay'), item('minecraft:iron_shovel'), 2, [[item('minecraft:cobblestone')],[item('minecraft:nether_star')],[item('minecraft:cobblestone')]]) +// mods.pyrotech.worktable.addShaped(resource('example:resource_location'), item('minecraft:clay'), [[item('minecraft:cobblestone')],[item('minecraft:nether_star')],[item('minecraft:cobblestone')]]) +// mods.pyrotech.worktable.addShaped('gold_v_to_clay', item('minecraft:clay'), item('minecraft:iron_pickaxe'), 3, [[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[null,item('minecraft:gold_ingot'),null]]) +// mods.pyrotech.worktable.addShaped('gold_v_to_clay', item('minecraft:clay'), [[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[null,item('minecraft:gold_ingot'),null]]) +// mods.pyrotech.worktable.addShapeless(item('minecraft:clay'), item('minecraft:stone_shovel'), 3, [item('minecraft:cobblestone'),item('minecraft:nether_star'),item('minecraft:gold_ingot')]) +// mods.pyrotech.worktable.addShapeless(item('minecraft:clay'), [item('minecraft:cobblestone'),item('minecraft:nether_star'),item('minecraft:gold_ingot')]) +// mods.pyrotech.worktable.addShapeless(resource('example:resource_location2'), item('minecraft:clay'), item('minecraft:stone_shovel'), 3, [item('minecraft:cobblestone'), item('minecraft:gold_ingot')]) +// mods.pyrotech.worktable.addShapeless(resource('example:resource_location2'), item('minecraft:clay'), [item('minecraft:cobblestone'), item('minecraft:gold_ingot')]) +// mods.pyrotech.worktable.addShapeless('precious_to_clay', item('minecraft:clay'), item('minecraft:iron_shovel'), 2, [item('minecraft:diamond'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]) +// mods.pyrotech.worktable.addShapeless('precious_to_clay', item('minecraft:clay'), [item('minecraft:diamond'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]) +// mods.pyrotech.worktable.replaceShaped(item('minecraft:chest'), item('minecraft:iron_axe') | item('minecraft:stone_axe'), 3, [[ore('logWood'),ore('logWood'),ore('logWood')],[ore('logWood'),null,ore('logWood')],[ore('logWood'),ore('logWood'),ore('logWood')]]) +// mods.pyrotech.worktable.replaceShaped(item('minecraft:chest'), [[ore('logWood'),ore('logWood'),ore('logWood')],[ore('logWood'),null,ore('logWood')],[ore('logWood'),ore('logWood'),ore('logWood')]]) +// mods.pyrotech.worktable.replaceShaped(resource('minecraft:sea_lantern'), item('minecraft:diamond_pickaxe'), 3, item('minecraft:clay'), [[item('minecraft:glowstone')],[item('minecraft:glowstone')],[item('minecraft:glowstone')]]) +// mods.pyrotech.worktable.replaceShaped(resource('minecraft:sea_lantern'), item('minecraft:clay'), [[item('minecraft:glowstone')],[item('minecraft:glowstone')],[item('minecraft:glowstone')]]) +// mods.pyrotech.worktable.replaceShaped('gold_to_diamonds', item('minecraft:diamond') * 8, item('minecraft:diamond_pickaxe'), 4, [[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]]) +// mods.pyrotech.worktable.replaceShaped('gold_to_diamonds', item('minecraft:diamond') * 8, [[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]]) +// mods.pyrotech.worktable.replaceShapeless(item('minecraft:ender_eye'), item('minecraft:shears'), 3, [item('minecraft:ender_pearl'),item('minecraft:nether_star')]) +// mods.pyrotech.worktable.replaceShapeless(item('minecraft:ender_eye'), [item('minecraft:ender_pearl'),item('minecraft:nether_star')]) +// mods.pyrotech.worktable.replaceShapeless(resource('minecraft:pink_dye_from_peony'), item('minecraft:clay'), item('minecraft:stone_axe'), 2, [item('minecraft:cobblestone'), item('minecraft:gold_ingot')]) +// mods.pyrotech.worktable.replaceShapeless(resource('minecraft:pink_dye_from_peony'), item('minecraft:clay'), [item('minecraft:cobblestone'), item('minecraft:gold_ingot')]) +// mods.pyrotech.worktable.replaceShapeless('minecraft:pink_dye_from_pink_tulp', item('minecraft:iron_axe'), 2, item('minecraft:clay'), [item('minecraft:nether_star')]) +// mods.pyrotech.worktable.replaceShapeless('minecraft:pink_dye_from_pink_tulp', item('minecraft:clay'), [item('minecraft:nether_star')]) + diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Anvil.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Anvil.java index c495e06d0..f7ca753c1 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Anvil.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Anvil.java @@ -3,16 +3,22 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.EnumHelper; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; +import com.codetaylor.mc.pyrotech.modules.tech.basic.init.recipe.AnvilIroncladRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.basic.init.recipe.AnvilObsidianRecipesAdd; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.AnvilRecipe; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import org.jetbrains.annotations.Nullable; import java.util.Arrays; +import java.util.Locale; @RegistryDescription public class Anvil extends ForgeRegistryWrapper { @@ -21,17 +27,27 @@ public Anvil() { super(ModuleTechBasic.Registries.ANVIL_RECIPE); } + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + @RecipeBuilderDescription(example = { - @Example(".input(item('minecraft:diamond') * 4).output(item('minecraft:emerald') * 2).hits(5).typeHammer().tierGranite().name('diamond_to_emerald_granite_anvil')"), - @Example(".input(item('minecraft:diamond') * 8).output(item('minecraft:nether_star') * 1).hits(10).typePickaxe().tierIronclad().name('diamond_to_nether_star_ironclad_anvil')"), - @Example(".input(item('minecraft:diamond') * 4).output(item('minecraft:gold_ingot') * 16).hits(5).typePickaxe().tierObsidian().name('diamond_to_gold_obsidian_anvil')") + @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald') * 2).hits(8).typeHammer().tierGranite().name('diamond_to_emerald_granite_anvil')"), + @Example(".input(item('minecraft:bedrock')).output(item('minecraft:nether_star') * 1).hits(10).typePickaxe().tierIronclad().inherit(true).name('bedrock_to_nether_star')"), + @Example(".input(item('minecraft:gold_block')).output(item('minecraft:gold_ingot') * 16).hits(5).typePickaxe().tierObsidian().name('gold_block_to_gold_obsidian_anvil')") }) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'iron_to_clay', ore('ingotIron'), item('minecraft:clay_ball'), 9, 'granite', 'hammer'")) + @MethodDescription(type = MethodDescription.Type.ADDITION) public AnvilRecipe add(String name, IIngredient input, ItemStack output, int hits, String tier, String type) { + return add(name, input, output, hits, tier, type, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.anvil.add.inherit", example = @Example("'flint_from_gravel', ore('gravel'), item('minecraft:flint'), 5, 'granite', 'pickaxe', true")) + public AnvilRecipe add(String name, IIngredient input, ItemStack output, int hits, String tier, String type, boolean inherit) { AnvilRecipe.EnumTier enumTier = EnumHelper.valueOfNullable(AnvilRecipe.EnumTier.class, tier, false); AnvilRecipe.EnumType enumType = EnumHelper.valueOfNullable(AnvilRecipe.EnumType.class, type, false); if (enumTier == null || enumType == null) { @@ -46,14 +62,30 @@ public AnvilRecipe add(String name, IIngredient input, ItemStack output, int hit .hits(hits) .tier(enumTier) .type(enumType) + .inherit(inherit) .name(name) .input(input) .output(output) .register(); } - @MethodDescription(example = @Example("item('minecraft:stone_slab', 3)")) - public void removeByOutput(ItemStack output) { + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('pyrotech:material:37')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing pyrotech anvil recipe") + .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (AnvilRecipe recipe : getRegistry()) { + if (recipe.getInput().test(input)) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:stone_slab:3') * 2")) + public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing pyrotech anvil recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") .error() @@ -61,7 +93,7 @@ public void removeByOutput(ItemStack output) { return; } for (AnvilRecipe recipe : getRegistry()) { - if (recipe.getOutput().isItemEqual(output)) { + if (output.test(recipe.getOutput())) { remove(recipe); } } @@ -74,13 +106,12 @@ public static class RecipeBuilder extends AbstractRecipeBuilder { @Property(comp = @Comp(gt = 0)) private int hits; - - @Property + @Property(comp = @Comp(not = "null")) private AnvilRecipe.EnumType type; - - @Property + @Property(comp = @Comp(not = "null")) private AnvilRecipe.EnumTier tier; - + @Property + private boolean inherit; @RecipeBuilderMethodDescription public RecipeBuilder hits(int hits) { @@ -104,7 +135,6 @@ public RecipeBuilder typePickaxe() { return type(AnvilRecipe.EnumType.PICKAXE); } - @RecipeBuilderMethodDescription public RecipeBuilder tier(AnvilRecipe.EnumTier tier) { this.tier = tier; return this; @@ -125,6 +155,17 @@ public RecipeBuilder tierObsidian() { return tier(AnvilRecipe.EnumTier.OBSIDIAN); } + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_anvil_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Anvil Recipe"; @@ -138,21 +179,35 @@ protected int getMaxItemInput() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(hits < 0, "duration must be a non negative integer, yet it was {}", hits); - msg.add(type == null, "type cannot be null. "); + msg.add(hits <= 0, "duration must be a non negative integer that is larger than 0, yet it was {}", hits); + msg.add(type == null, "type cannot be null."); msg.add(tier == null, "tier cannot be null."); - msg.add(super.name == null, "name cannot be null."); msg.add(ModuleTechBasic.Registries.ANVIL_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); + msg.add(tier == AnvilRecipe.EnumTier.OBSIDIAN && inherit, "nothing can inherit from obsidian anvil."); } - @Override @RecipeBuilderRegistrationMethod + @Override public @Nullable AnvilRecipe register() { if (!validate()) return null; - AnvilRecipe recipe = new AnvilRecipe(output.get(0), input.get(0).toMcIngredient(), hits, type, tier).setRegistryName(super.name); - PyroTech.anvil.add(recipe); + ModSupport.PYROTECH.get().anvil.add(recipe); + if (inherit) { + String name = null; + if (tier.ordinal() < 2) { + name = tier.name().toLowerCase(Locale.ENGLISH) + "_anvil"; + AnvilRecipe obsidianRecipe = AnvilObsidianRecipesAdd.INHERIT_TRANSFORMER.apply(recipe); + obsidianRecipe.setRegistryName(new ResourceLocation(super.name.getNamespace(), name + "/" + super.name.getPath())); + ModSupport.PYROTECH.get().anvil.add(obsidianRecipe); + } + if (tier.ordinal() < 1) { + AnvilRecipe ironcladRecipe = AnvilIroncladRecipesAdd.INHERIT_TRANSFORMER.apply(recipe); + ironcladRecipe.setRegistryName(new ResourceLocation(super.name.getNamespace(), name + "/" + super.name.getPath())); + ModSupport.PYROTECH.get().anvil.add(ironcladRecipe); + } + } return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Barrel.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Barrel.java index 24fa76931..b765439a6 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Barrel.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Barrel.java @@ -3,9 +3,11 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.BarrelRecipe; import net.minecraft.item.crafting.Ingredient; @@ -19,6 +21,11 @@ public Barrel() { super(ModuleTechBasic.Registries.BARREL_RECIPE); } + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + @RecipeBuilderDescription( example = @Example( ".input(item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:emerald')).fluidInput(fluid('water') * 1000).fluidOutput(fluid('amongium') * 1000).duration(1000).name('diamond_emerald_and_water_to_amongium')") @@ -38,7 +45,7 @@ public BarrelRecipe add(String name, IIngredient input1, IIngredient input2, IIn .register(); } - @MethodDescription(example = @Example("fluid('freckleberry_wine') * 1000")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("fluid('freckleberry_wine') * 1000")) public void removeByOutput(FluidStack output) { if (GroovyLog.msg("Error removing barrel recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -59,7 +66,7 @@ public void removeByOutput(FluidStack output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int duration; @RecipeBuilderMethodDescription @@ -79,12 +86,17 @@ protected int getMaxItemInput() { return 1; } + @Override + public String getRecipeNamePrefix() { + return "groovyscript_barrel_"; + } + @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 4, 4, 0, 0); validateFluids(msg, 1, 1, 1, 1); - msg.add(duration < 0, "duration must be a non negative integer, yet it was {}", duration); - msg.add(super.name == null, "name cannot be null."); + msg.add(duration <= 0, "duration must be a non negative integer that is larger than 0, yet it was {}", duration); msg.add(ModuleTechBasic.Registries.BARREL_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -92,13 +104,10 @@ public void validate(GroovyLog.Msg msg) { @Override public @Nullable BarrelRecipe register() { if (!validate()) return null; - // Because you need Ingredient[] to register a recipe Ingredient[] inputIngredient = input.stream().map(IIngredient::toMcIngredient).toArray(Ingredient[]::new); - BarrelRecipe recipe = new BarrelRecipe(fluidOutput.get(0), inputIngredient, fluidInput.get(0), duration).setRegistryName(super.name); - PyroTech.barrel.add(recipe); - + ModSupport.PYROTECH.get().barrel.add(recipe); return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Bloomery.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Bloomery.java new file mode 100644 index 000000000..aca0d7a76 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Bloomery.java @@ -0,0 +1,335 @@ +package com.cleanroommc.groovyscript.compat.mods.pyrotech; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.core.mixin.pyrotech.BloomeryRecipeBaseAccessor; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; +import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.AnvilRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.ModuleTechBloomery; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.ModuleTechBloomeryConfig; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.init.recipe.WitherForgeRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.recipe.*; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +@RegistryDescription +public class Bloomery extends ForgeRegistryWrapper { + + public Bloomery() { + super(ModuleTechBloomery.Registries.BLOOMERY_RECIPE); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBloomery.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:iron_block')).bloom(item('minecraft:apple')).failureChance(0.0F).slag(item('minecraft:carrot')).inherit(true).name('metal_vegetation')"), + @Example(".input(item('minecraft:noteblock')).output(item('minecraft:record_13')).experience(0.25F).tierIronclad().bloomYield(1, 1).burnTime(2000).failureChance(0.5F).failureOutput(item('minecraft:record_11'), 1).inherit(true).name('recipe_for_soundphiles')"), + @Example(".input(item('minecraft:sponge')).output(item('minecraft:sponge')).bloomYield(2, 5).typePickaxe().langKey(item('minecraft:stick').getTranslationKey()).inherit(true).name('sponge_duplication')"), + @Example(".input(item('minecraft:birch_boat')).bloom(item('minecraft:dark_oak_boat')).tierObsidian().failureChance(0.1).failureOutput(item('minecraft:spruce_boat'), 5).failureOutput(item('minecraft:jungle_boat'), 2).failureOutput(item('minecraft:boat'), 1).name('boat_smelting')"), + @Example(".input(item('minecraft:sand')).output(item('minecraft:glass')).bloomYield(3, 5).experience(0.1F).burnTime(4000).tierGranite().tierObsidian().anvilHit(2).typePickaxe().failureChance(0.05).failureOutput(item('minecraft:nether_star'), 1).failureOutput(item('minecraft:gold_ingot'), 10).name('glasswork')") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.bloomery.add0") + public BloomeryRecipe add(String name, ItemStack output, IIngredient input) { + return add(name, output, input, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.bloomery.add0.inherit", example = @Example("'loreming_the_ipsum', item('minecraft:redstone'), item('minecraft:lava_bucket'), false")) + public BloomeryRecipe add(String name, ItemStack output, IIngredient input, boolean inherit) { + return recipeBuilder() + .inherit(inherit) + .bloom(output) + .input(input) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.bloomery.add1") + public BloomeryRecipe add(String name, ItemStack output, IIngredient input, int burnTime) { + return add(name, output, input, burnTime, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.bloomery.add1.inherit", example = @Example("'cooking_a_story', item('minecraft:written_book'), item('minecraft:book'), 200, true")) + public BloomeryRecipe add(String name, ItemStack output, IIngredient input, int burnTime, boolean inherit) { + return recipeBuilder() + .inherit(inherit) + .bloom(output) + .burnTime(burnTime) + .input(input) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.bloomery.addBloom0") + public BloomeryRecipe addBloom(String name, ItemStack bloomOutput, IIngredient input) { + return addBloom(name, bloomOutput, input, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.bloomery.addBloom0.inherit", example = @Example("'cyanide', item('minecraft:poisonous_potato'), item('minecraft:potato'), true")) + public BloomeryRecipe addBloom(String name, ItemStack bloomOutput, IIngredient input, boolean inherit) { + return recipeBuilder() + .inherit(inherit) + .output(bloomOutput) + .input(input) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example(value = "item('minecraft:iron_nugget')", commented = true)) + public void removeByOutput(IIngredient output) { + if (GroovyLog.msg("Error removing bloomery recipe") + .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (BloomeryRecipe recipe : getRegistry()) { + if (output.test(recipe.getOutput())) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:gold_ore')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing bloomery recipe") + .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (BloomeryRecipe recipe : getRegistry()) { + if (recipe.getInput().test(input)) { + remove(recipe); + } + } + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + @Property(property = "name") + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property + private ItemStack bloom = ItemStack.EMPTY; + @Property + private ItemStack slag = null; + @Property(comp = @Comp(gt = 0), defaultValue = "21600") + private int burnTime = 21600; + @Property(comp = @Comp(gte = 0)) + private float experience; + @Property(comp = @Comp(gte = 0), defaultValue = "12") + private int bloomYieldMin = 12; + @Property(comp = @Comp(gte = 0), defaultValue = "15") + private int bloomYieldMax = 15; + @Property(comp = @Comp(gte = 0, lte = 1), defaultValue = "0.25") + private float failureChance = 0.25F; + @Property + private final List failureOutput = new ArrayList<>(1); + @Property + private final EnumSet anvilTiers = EnumSet.noneOf(AnvilRecipe.EnumTier.class); + @Property(comp = @Comp(gt = 0)) + private int anvilHit = ModuleTechBloomeryConfig.BLOOM.HAMMER_HITS_IN_ANVIL_REQUIRED; + @Property(comp = @Comp(not = "null"), defaultValue = "hammer") + private AnvilRecipe.EnumType anvilType = AnvilRecipe.EnumType.HAMMER; + @Property + private String langKey; + @Property + private boolean inherit; + + @RecipeBuilderMethodDescription + public RecipeBuilder bloom(ItemStack bloom) { + this.bloom = bloom; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder slag(ItemStack slag) { + this.slag = slag; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder burnTime(int burnTime) { + this.burnTime = burnTime; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder experience(float experience) { + this.experience = experience; + return this; + } + + @RecipeBuilderMethodDescription(field = { + "bloomYieldMin", "bloomYieldMax" + }) + public RecipeBuilder bloomYield(int bloomYieldMin, int bloomYieldMax) { + this.bloomYieldMin = bloomYieldMin; + this.bloomYieldMax = bloomYieldMax; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder failureChance(float failureChance) { + this.failureChance = failureChance; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder failureOutput(ItemStack failureOutput, int weight) { + if (failureOutput == null) failureOutput = ItemStack.EMPTY; + this.failureOutput.add(new BloomeryRecipeBase.FailureItem(failureOutput, weight)); + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder anvilTier(AnvilRecipe.EnumTier tier) { + anvilTiers.add(tier); + return this; + } + + @RecipeBuilderMethodDescription(field = "anvilTier") + public RecipeBuilder tierGranite() { + return anvilTier(AnvilRecipe.EnumTier.GRANITE); + } + + @RecipeBuilderMethodDescription(field = "anvilTier") + public RecipeBuilder tierIronclad() { + return anvilTier(AnvilRecipe.EnumTier.IRONCLAD); + } + + @RecipeBuilderMethodDescription(field = "anvilTier") + public RecipeBuilder tierObsidian() { + return anvilTier(AnvilRecipe.EnumTier.OBSIDIAN); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder anvilType(AnvilRecipe.EnumType type) { + anvilType = type; + return this; + } + + @RecipeBuilderMethodDescription(field = "anvilType") + public RecipeBuilder typeHammer() { + return anvilType(AnvilRecipe.EnumType.HAMMER); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder typePickaxe() { + return anvilType(AnvilRecipe.EnumType.PICKAXE); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder anvilHit(int hit) { + this.anvilHit = hit; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder langKey(String langKey) { + this.langKey = langKey; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_bloomery_"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public String getErrorMsg() { + return "Error adding Pyrotech Bloomery Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateName(); + if (bloom == null) { + bloom = ItemStack.EMPTY; + } + int minOutput = bloom.isEmpty() ? 1 : 0; + if (slag == null) { + slag = bloom.isEmpty() ? new ItemStack(ModuleTechBloomery.Items.SLAG, 4) : ItemStack.EMPTY; + } + if (failureOutput.isEmpty() && failureChance > 0.0F) { + failureOutput.add(new BloomeryRecipeBase.FailureItem(new ItemStack(ModuleTechBloomery.Items.SLAG), 1)); + } + if (anvilTiers.isEmpty()) { + anvilTiers.addAll(EnumSet.allOf(AnvilRecipe.EnumTier.class)); + } + validateItems(msg, 1, 1, minOutput, 1); + msg.add(burnTime <= 0, "burnTime must be a non negative integer that is larger than 0, yet it was {}", burnTime); + msg.add(experience < 0, "experience must be a non negative float, yet it was {}", experience); + msg.add(bloomYieldMin < 0 || bloomYieldMin > bloomYieldMax, "bloomYieldMin must be a non negative integer that is smaller than bloomYieldMax, yet it was {}", burnTime); + msg.add(bloomYieldMax < 0, "bloomYieldMax must be a non negative integer, yet it was {}", burnTime); + msg.add(failureChance < 0 || failureChance > 1, "failureChance must not be negative nor larger than 1.0, yet it was {}", failureChance); + msg.add(anvilType == null, "anvilType must not be null"); + msg.add(anvilHit <= 0, "anvilHit must be a non negative integer that is larger than 0, yet it was {}", anvilHit); + msg.add(ModSupport.PYROTECH.get().bloomery.getRegistry().getValue(super.name) != null, "tried to register {}, but it already exists", super.name); + } + + @RecipeBuilderRegistrationMethod + @Override + public @Nullable BloomeryRecipe register() { + if (!validate()) return null; + BloomeryRecipeBuilder builder = new BloomeryRecipeBuilder(super.name, output.getOrEmpty(0), input.get(0).toMcIngredient()); + failureOutput.forEach(i -> builder.addFailureItem(i.getItemStack(), i.getWeight())); + BloomeryRecipe recipe = builder + .setSlagItem(slag, slag.getCount()) + .setBurnTimeTicks(burnTime) + .setExperience(experience) + .setBloomYield(bloomYieldMin, bloomYieldMax) + .setFailureChance(failureChance) + .setAnvilTiers(anvilTiers.toArray(new AnvilRecipe.EnumTier[0])) + .setLangKey(langKey) + .create(); + ((BloomeryRecipeBaseAccessor) recipe).grs$setOutputBloom(bloom.isEmpty() ? null : bloom); + ModSupport.PYROTECH.get().bloomery.add(recipe); + if (inherit) { + WitherForgeRecipe witherForgeRecipe = WitherForgeRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(new ResourceLocation(super.name.getNamespace(), "bloomery/" + super.name.getPath())); + ((BloomeryRecipeBaseAccessor) recipe).grs$setOutputBloom(((BloomeryRecipeBaseAccessor) recipe).grs$getOutputBloom()); + ModSupport.PYROTECH.get().witherForge.add(witherForgeRecipe); + } + if (bloom.isEmpty() && bloomYieldMax != 0) { + ModSupport.PYROTECH.get().anvil.add( + new BloomAnvilRecipe( + recipe.getOutput(), + com.codetaylor.mc.athenaeum.util.IngredientHelper.fromStackWithNBT(recipe.getOutputBloom()), + anvilHit, + anvilType, + recipe.getAnvilTiers(), + recipe + ).setRegistryName(super.name)); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickCrucible.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickCrucible.java new file mode 100644 index 000000000..a0557e0a2 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickCrucible.java @@ -0,0 +1,125 @@ +package com.cleanroommc.groovyscript.compat.mods.pyrotech; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; +import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.BrickCrucibleRecipe; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription( + admonition = @Admonition( + value = "groovyscript.wiki.pyrotech.brick_crucible.note0", + format = Admonition.Format.STANDARD, + hasTitle = true)) +public class BrickCrucible extends ForgeRegistryWrapper { + + public BrickCrucible() { + super(ModuleTechMachine.Registries.BRICK_CRUCIBLE_RECIPES); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:vine')).fluidOutput(fluid('water') * 250).burnTime(60).name('water_from_vine')")) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'lava_from_obsidian', ore('obsidian'), fluid('lava') * 1000, 2000")) + public BrickCrucibleRecipe add(String name, IIngredient input, FluidStack output, int burnTime) { + return recipeBuilder() + .burnTime(burnTime) + .name(name) + .input(input) + .fluidOutput(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:gravel')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing refractory crucible recipe") + .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (BrickCrucibleRecipe recipe : getRegistry()) { + if (recipe.getInput().test(input)) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("fluid('water') * 125")) + public void removeByOutput(IIngredient output) { + if (GroovyLog.msg("Error removing refractory crucible recipe") + .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (BrickCrucibleRecipe recipe : getRegistry()) { + if (output.test(recipe.getOutput())) { + remove(recipe); + } + } + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "fluidOutput", comp = @Comp(eq = 1)) + @Property(property = "name") + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gt = 0)) + private int burnTime; + + @RecipeBuilderMethodDescription + public RecipeBuilder burnTime(int burnTime) { + this.burnTime = burnTime; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_brick_crucible_"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public String getErrorMsg() { + return "Error adding Pyrotech Refractory Crucible Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateName(); + validateItems(msg, 1, 1, 0, 0); + validateFluids(msg, 0, 0, 1, 1); + msg.add(burnTime <= 0, "burnTime must be a non negative integer that is larger than 0, yet it was {}", burnTime); + msg.add(ModuleTechMachine.Registries.STONE_CRUCIBLE_RECIPES.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); + } + + @RecipeBuilderRegistrationMethod + @Override + public @Nullable BrickCrucibleRecipe register() { + if (!validate()) return null; + BrickCrucibleRecipe recipe = new BrickCrucibleRecipe(fluidOutput.get(0), input.get(0).toMcIngredient(), burnTime).setRegistryName(super.name); + ModSupport.PYROTECH.get().brickCrucible.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickKiln.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickKiln.java index 4a5ed7ccc..4631111bd 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickKiln.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickKiln.java @@ -3,28 +3,39 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.ingredient.ItemStackList; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.BrickKilnRecipe; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.Nullable; -@RegistryDescription +@RegistryDescription( + admonition = @Admonition( + value = "groovyscript.wiki.pyrotech.brick_kiln.note0", + format = Admonition.Format.STANDARD, + hasTitle = true)) public class BrickKiln extends ForgeRegistryWrapper { public BrickKiln() { super(ModuleTechMachine.Registries.BRICK_KILN_RECIPES); } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:iron_ingot')).output(item('minecraft:gold_ingot')).burnTime(400).failureChance(1f).failureOutput(item('minecraft:wheat'), item('minecraft:carrot'), item('minecraft:sponge')).name('iron_to_gold_kiln_with_failure_items_brick')")) + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:fish')).output(item('minecraft:cooked_fish')).burnTime(200000).failureChance(0.99f).failureOutput(item('minecraft:dragon_egg'), item('minecraft:dragon_breath')).name('meaning_of_life')")) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'clay_to_iron_brick', item('minecraft:clay_ball') * 5, item('minecraft:iron_ingot'), 1200, 0.5f, item('minecraft:dirt'), item('minecraft:cobblestone')")) + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'beetroot_soup', item('minecraft:beetroot'), item('minecraft:beetroot_soup'), 1200, 0.1f, item('minecraft:beetroot_seeds')")) public BrickKilnRecipe add(String name, IIngredient input, ItemStack output, int burnTime, float failureChance, ItemStack... failureOutput) { return recipeBuilder() .burnTime(burnTime) @@ -36,7 +47,7 @@ public BrickKilnRecipe add(String name, IIngredient input, ItemStack output, int .register(); } - @MethodDescription + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:cobblestone')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing refractory oven recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -73,9 +84,9 @@ public static class RecipeBuilder extends AbstractRecipeBuilder @Property private final ItemStackList failureOutput = new ItemStackList(); - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int burnTime; - @Property(comp = @Comp(gte = 0)) + @Property(comp = @Comp(gte = 0, lte = 1)) private float failureChance; @RecipeBuilderMethodDescription @@ -106,10 +117,17 @@ public RecipeBuilder failureOutput(ItemStack... failureOutputs) { @RecipeBuilderMethodDescription public RecipeBuilder failureOutput(Iterable failureOutputs) { - for (ItemStack itemStack : failureOutputs) failureOutput(itemStack); + for (ItemStack itemStack : failureOutputs) { + failureOutput(itemStack); + } return this; } + @Override + public String getRecipeNamePrefix() { + return "groovyscript_brick_kiln_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Refractory Kiln Recipe"; @@ -117,12 +135,11 @@ public String getErrorMsg() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); this.failureOutput.trim(); - validateCustom(msg, failureOutput, 1, 100, "failure output"); - msg.add(burnTime < 0, "burnTime must be a non negative integer, yet it was {}", burnTime); - msg.add(failureChance < 0, "failureChance must be a non negative float, yet it was {}", failureChance); - msg.add(super.name == null, "name cannot be null."); + msg.add(burnTime <= 0, "burnTime must be a non negative integer that is larger than 0, yet it was {}", burnTime); + msg.add(failureChance < 0 || failureChance > 1, "failureChance must not be negative nor larger than 1.0, yet it was {}", failureChance); msg.add(ModuleTechMachine.Registries.BRICK_KILN_RECIPES.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -131,7 +148,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable BrickKilnRecipe register() { if (!validate()) return null; BrickKilnRecipe recipe = new BrickKilnRecipe(output.get(0), input.get(0).toMcIngredient(), burnTime, failureChance, failureOutput.toArray(new ItemStack[0])).setRegistryName(super.name); - PyroTech.brickKiln.add(recipe); + ModSupport.PYROTECH.get().brickKiln.add(recipe); return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickOven.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickOven.java index 6a105eb61..cc80b06e7 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickOven.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickOven.java @@ -3,32 +3,46 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.BrickOvenRecipe; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.Nullable; @RegistryDescription( - admonition = @Admonition( - value = "groovyscript.wiki.pyrotech.oven.note0", - type = Admonition.Type.WARNING, - format = Admonition.Format.STANDARD, - hasTitle = true)) + admonition = { + @Admonition( + value = "groovyscript.wiki.pyrotech.brick_oven.note0", + format = Admonition.Format.STANDARD, + hasTitle = true + ), + @Admonition( + value = "groovyscript.wiki.pyrotech.oven.note0", + type = Admonition.Type.WARNING, + format = Admonition.Format.STANDARD, + hasTitle = true) + }) public class BrickOven extends ForgeRegistryWrapper { public BrickOven() { super(ModuleTechMachine.Registries.BRICK_OVEN_RECIPES); } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).duration(400).name('diamond_campfire_to_emerald_brick')")) + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:chorus_fruit')).output(item('minecraft:chorus_fruit_popped')).duration(800).name('chorus_fruit_whats_popping')")) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'apple_to_dirt_brick', item('minecraft:apple'), item('minecraft:dirt'), 1000")) + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'lead_poisoning', item('minecraft:slime_ball'), item('minecraft:lead') * 16, 1000")) public BrickOvenRecipe add(String name, IIngredient input, ItemStack output, int duration) { return recipeBuilder() .duration(duration) @@ -38,7 +52,7 @@ public BrickOvenRecipe add(String name, IIngredient input, ItemStack output, int .register(); } - @MethodDescription(example = @Example("item('minecraft:porkchop')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:porkchop')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing brick oven recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -53,7 +67,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription(example = @Example("item('minecraft:cooked_porkchop')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:cooked_porkchop')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing brick oven recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -73,7 +87,7 @@ public void removeByOutput(IIngredient output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int duration; @RecipeBuilderMethodDescription @@ -82,6 +96,11 @@ public RecipeBuilder duration(int time) { return this; } + @Override + public String getRecipeNamePrefix() { + return "groovyscript_brick_oven_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Brick Oven Recipe"; @@ -89,9 +108,9 @@ public String getErrorMsg() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(duration < 0, "duration must be a non negative integer, yet it was {}", duration); - msg.add(super.name == null, "name cannot be null."); + msg.add(duration <= 0, "duration must be a non negative integer that is larger than 0, yet it was {}", duration); msg.add(ModuleTechMachine.Registries.BRICK_OVEN_RECIPES.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -100,7 +119,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable BrickOvenRecipe register() { if (!validate()) return null; BrickOvenRecipe recipe = new BrickOvenRecipe(output.get(0), input.get(0).toMcIngredient(), duration).setRegistryName(super.name); - PyroTech.brickOven.add(recipe); + ModSupport.PYROTECH.get().brickOven.add(recipe); return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickSawmill.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickSawmill.java new file mode 100644 index 000000000..10fafbe66 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/BrickSawmill.java @@ -0,0 +1,175 @@ +package com.cleanroommc.groovyscript.compat.mods.pyrotech; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.athenaeum.util.ArrayHelper; +import com.codetaylor.mc.pyrotech.ModPyrotech; +import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; +import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachineConfig; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.BrickSawmillRecipe; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +@RegistryDescription( + admonition = { + @Admonition( + value = "groovyscript.wiki.pyrotech.brick_sawmill.note0", + format = Admonition.Format.STANDARD, + hasTitle = true + ), + @Admonition( + value = "groovyscript.wiki.pyrotech.sawmill.note0", + type = Admonition.Type.WARNING, + format = Admonition.Format.STANDARD, + hasTitle = true) + }) +public class BrickSawmill extends ForgeRegistryWrapper { + + public BrickSawmill() { + super(ModuleTechMachine.Registries.BRICK_SAWMILL_RECIPES); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:golden_helmet')).output(item('minecraft:gold_ingot') * 2).duration(1500).woodChips(5).name('golden_helmet_recycling')")) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'bed_to_wool', item('minecraft:bed'), item('minecraft:wool') * 3, 500, 3")) + public BrickSawmillRecipe add(String name, IIngredient input, ItemStack output, int duration, int woodChips) { + return recipeBuilder() + .duration(duration) + .woodChips(woodChips) + .name(name) + .input(input) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'glowstone_to_dust', item('minecraft:glowstone'), item('pyrotech:sawmill_blade_stone'), item('minecraft:glowstone_dust'), 200, 0")) + public BrickSawmillRecipe add(String name, IIngredient input, IIngredient blade, ItemStack output, int duration, int woodChips) { + return recipeBuilder() + .duration(duration) + .woodChips(woodChips) + .name(name) + .input(input, blade) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:planks:1')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing refractory sawmill recipe") + .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (BrickSawmillRecipe recipe : getRegistry()) { + if (recipe.getInput().test(input)) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('pyrotech:material:23')")) + public void removeByOutput(IIngredient output) { + if (GroovyLog.msg("Error removing refractory sawmill recipe") + .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (BrickSawmillRecipe recipe : getRegistry()) { + if (output.test(recipe.getOutput())) { + remove(recipe); + } + } + } + + @Property(property = "input", comp = @Comp(gte = 1, lte = 2)) + @Property(property = "output", comp = @Comp(eq = 1)) + @Property(property = "name") + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gt = 0)) + private int duration; + @Property(value = "wood_chips", comp = @Comp(gte = 0)) + private int woodChips; + + @RecipeBuilderMethodDescription + public RecipeBuilder duration(int time) { + this.duration = time; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder woodChips(int woodChips) { + this.woodChips = woodChips; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_brick_sawmill_"; + } + + @Override + public String getErrorMsg() { + return "Error adding Pyrotech Refractory Sawmill Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateName(); + validateItems(msg, 1, 2, 1, 1); + if (input.size() > 1) { + for (ItemStack stack : input.get(1).toMcIngredient().getMatchingStacks()) { + msg.add(!ArrayHelper.contains(ModuleTechMachineConfig.BRICK_SAWMILL.SAWMILL_BLADES, Objects.requireNonNull(stack.getItem().getRegistryName()).toString()), "{} is not a brick sawmill blade", stack); + } + } + msg.add(duration <= 0, "duration must be a non negative integer that is larger than 0, yet it was {}", duration); + msg.add(ModuleTechMachine.Registries.BRICK_SAWMILL_RECIPES.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); + } + + @RecipeBuilderRegistrationMethod + @Override + public @Nullable BrickSawmillRecipe register() { + if (!validate()) return null; + if (input.size() > 1) { + BrickSawmillRecipe recipe = new BrickSawmillRecipe(output.get(0), input.get(0).toMcIngredient(), duration, input.get(1).toMcIngredient(), woodChips).setRegistryName(super.name); + ModSupport.PYROTECH.get().brickSawmill.add(recipe); + return recipe; + } else { + return addMultiRecipe(output.get(0), input.get(0).toMcIngredient(), woodChips, duration, super.name); + } + } + } + + protected static BrickSawmillRecipe addMultiRecipe(ItemStack output, Ingredient input, int woodChips, int duration, ResourceLocation name) { + BrickSawmillRecipe recipe = new BrickSawmillRecipe(output, input, duration, Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.STONE_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE)), woodChips).setRegistryName(name + "_tier_0"); + ModSupport.PYROTECH.get().brickSawmill.add(recipe); + ItemStack out = output.copy(); + out.setCount(Math.min(output.getMaxStackSize(), output.getCount() * 2)); + ModSupport.PYROTECH.get().brickSawmill.add(new BrickSawmillRecipe(out, input, (int) (1.5 * (double) duration), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.FLINT_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE), new ItemStack(ModuleTechMachine.Items.BONE_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE)), woodChips / 2).setRegistryName(name + "_tier_1")); + ModSupport.PYROTECH.get().brickSawmill.add(new BrickSawmillRecipe(out, input, (int) (0.5 * (double) duration), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.IRON_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE)), woodChips / 4).setRegistryName(name + "_tier_2")); + out = output.copy(); + out.setCount(Math.min(output.getMaxStackSize(), output.getCount() * 3)); + ModSupport.PYROTECH.get().brickSawmill.add(new BrickSawmillRecipe(out, input, (int) (1.5 * (double) duration), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.DIAMOND_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE)), woodChips / 4).setRegistryName(name + "_tier_3")); + return recipe; + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Campfire.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Campfire.java index 03380321a..ee21d0e41 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Campfire.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Campfire.java @@ -3,9 +3,11 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.CampfireRecipe; import net.minecraft.item.ItemStack; @@ -18,6 +20,11 @@ public Campfire() { super(ModuleTechBasic.Registries.CAMPFIRE_RECIPE); } + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).duration(400).name('diamond_campfire_to_emerald')")) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); @@ -33,7 +40,7 @@ public CampfireRecipe add(String name, IIngredient input, ItemStack output, int .register(); } - @MethodDescription(example = @Example("item('minecraft:porkchop')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:porkchop')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing campfire recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -48,7 +55,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription(example = @Example("item('minecraft:cooked_porkchop')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:cooked_porkchop')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing campfire recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -68,7 +75,7 @@ public void removeByOutput(IIngredient output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int duration; @RecipeBuilderMethodDescription @@ -77,6 +84,11 @@ public RecipeBuilder duration(int time) { return this; } + @Override + public String getRecipeNamePrefix() { + return "groovyscript_campfire_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Campfire Recipe"; @@ -90,9 +102,9 @@ protected int getMaxItemInput() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(duration < 0, "duration must be a non negative integer, yet it was {}", duration); - msg.add(super.name == null, "name cannot be null."); + msg.add(duration <= 0, "duration must be a non negative integer that is larger than 0, yet it was {}", duration); msg.add(ModuleTechBasic.Registries.CAMPFIRE_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -101,7 +113,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable CampfireRecipe register() { if (!validate()) return null; CampfireRecipe recipe = new CampfireRecipe(output.get(0), input.get(0).toMcIngredient(), duration).setRegistryName(super.name); - PyroTech.campfire.add(recipe); + ModSupport.PYROTECH.get().campfire.add(recipe); return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/ChoppingBlock.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/ChoppingBlock.java index 48b256733..655909d1d 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/ChoppingBlock.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/ChoppingBlock.java @@ -3,14 +3,22 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.ChoppingBlockRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; +import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachineConfig; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.BrickSawmillRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.StoneSawmillRecipe; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.ResourceLocation; import org.jetbrains.annotations.Nullable; @RegistryDescription @@ -20,13 +28,20 @@ public ChoppingBlock() { super(ModuleTechBasic.Registries.CHOPPING_BLOCK_RECIPE); } + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).chops(25, 1).chops(20, 1).chops(15, 1).chops(10, 2).name('diamond_to_emerald_chopping_block')")) + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).chops(25, 1).chops(20, 1).chops(15, 1).chops(10, 2).name('diamond_to_emerald_chopping_block')"), + @Example(".input(item('minecraft:iron_ingot')).output(item('minecraft:gold_ingot')).inherit(true).name('iron_to_gold_chopping_block')") + }) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(example = @Example("item('minecraft:log2')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:log2')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing chopping block recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -41,7 +56,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription(example = @Example("item('minecraft:planks', 4)")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:planks', 4)")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing chopping block recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -65,6 +80,8 @@ public static class RecipeBuilder extends AbstractRecipeBuilder i <= 0) || quantities.stream().anyMatch(i -> i <= 0), "chops and quantities must not have a negative integer value or zero"); msg.add(ModuleTechBasic.Registries.CHOPPING_BLOCK_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); + msg.add(chops.size() != quantities.size(), "Size of chops and quantities should be equal"); } @RecipeBuilderRegistrationMethod @@ -99,8 +128,39 @@ public void validate(GroovyLog.Msg msg) { public @Nullable ChoppingBlockRecipe register() { if (!validate()) return null; ChoppingBlockRecipe recipe = new ChoppingBlockRecipe(output.get(0), input.get(0).toMcIngredient(), chops.toIntArray(), quantities.toIntArray()).setRegistryName(super.name); - PyroTech.choppingBlock.add(recipe); + ModSupport.PYROTECH.get().choppingBlock.add(recipe); + if (inherit && ModSupport.PYROTECH.get().stoneSawmill.isEnabled()) { + addSawmillRecipes(ModuleTechMachineConfig.STONE_SAWMILL.INHERITED_CHOPPING_BLOCK_RECIPE_DURATION_MODIFIER); + } return recipe; } + + private void addSawmillRecipes(double durationModifier) { + ItemStack out = output.get(0).copy(); + Ingredient in = input.get(0).toMcIngredient(); + out.setCount(!quantities.isEmpty() ? quantities.get(0) : 1); + ResourceLocation registryName = new ResourceLocation(super.name.getNamespace(), "chopping_block/" + super.name.getPath() + "_tier_0"); + StoneSawmillRecipe recipe = (new StoneSawmillRecipe(out, in, (int) ((!chops.isEmpty() ? chops.getInt(0) * 40.0 : 240.0) * durationModifier), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.STONE_MILL_BLADE, 1, 32767)), 4)).setRegistryName(registryName); + ModSupport.PYROTECH.get().stoneSawmill.add(recipe); + ModSupport.PYROTECH.get().brickSawmill.add(BrickSawmillRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(registryName)); + out = output.get(0).copy(); + out.setCount(quantities.size() > 1 ? quantities.get(1) : 2); + registryName = new ResourceLocation(super.name.getNamespace(), "chopping_block/" + super.name.getPath() + "_tier_1"); + recipe = (new StoneSawmillRecipe(out, in, (int) ((chops.size() > 1 ? chops.getInt(1) * 40.0 : 160.0) * durationModifier), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.FLINT_MILL_BLADE, 1, 32767), new ItemStack(ModuleTechMachine.Items.BONE_MILL_BLADE, 1, 32767)), 2)).setRegistryName(registryName); + ModSupport.PYROTECH.get().stoneSawmill.add(recipe); + ModSupport.PYROTECH.get().brickSawmill.add(BrickSawmillRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(registryName)); + out = output.get(0).copy(); + registryName = new ResourceLocation(super.name.getNamespace(), "chopping_block/" + super.name.getPath() + "_tier_2"); + out.setCount(quantities.size() > 2 ? quantities.get(2) : quantities.size() > 1 ? quantities.get(1) : 2); + recipe = (new StoneSawmillRecipe(out, in, (int) ((chops.size() > 2 ? chops.getInt(2) * 60.0 : 120.0) * durationModifier), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.IRON_MILL_BLADE, 1, 32767), new ItemStack(ModuleTechMachine.Items.OBSIDIAN_MILL_BLADE, 1, 32767)), 1)).setRegistryName(registryName); + ModSupport.PYROTECH.get().stoneSawmill.add(recipe); + ModSupport.PYROTECH.get().brickSawmill.add(BrickSawmillRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(registryName)); + out = output.get(0).copy(); + out.setCount(quantities.size() > 3 ? quantities.get(3) : 3); + new ResourceLocation(super.name.getNamespace(), "chopping_block/" + super.name.getPath() + "_tier_3"); + recipe = (new StoneSawmillRecipe(out, in, (int) ((chops.size() > 3 ? chops.getInt(3) * 80.0 : 160.0) * durationModifier), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.DIAMOND_MILL_BLADE, 1, 32767)), 1)).setRegistryName(registryName); + ModSupport.PYROTECH.get().stoneSawmill.add(recipe); + ModSupport.PYROTECH.get().brickSawmill.add(BrickSawmillRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(registryName)); + } } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CompactingBin.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CompactingBin.java index 472700397..f761516af 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CompactingBin.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CompactingBin.java @@ -3,38 +3,58 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; +import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasicConfig; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.CompactingBinRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.MechanicalCompactingBinRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.MechanicalCompactingBinRecipe; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.Nullable; @RegistryDescription public class CompactingBin extends ForgeRegistryWrapper { - public CompactingBin() { super(ModuleTechBasic.Registries.COMPACTING_BIN_RECIPE); } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).toolUses(5).name('diamond_to_emerald_compacting_bin')")) + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).hits(5, 4, 3, 2).inherit(true).name('diamond_to_emerald')"), + @Example(".input(item('minecraft:slime_ball') * 9).output(item('minecraft:slime')).name('slime_compacting')") + }) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'iron_to_clay', ore('ingotIron') * 5, item('minecraft:clay_ball') * 20, 9")) - public CompactingBinRecipe add(String name, IIngredient input, ItemStack output, int hits) { + @MethodDescription(type = MethodDescription.Type.ADDITION) + public CompactingBinRecipe add(String name, IIngredient input, ItemStack output, int... hits) { + return add(name, input, output, false, hits); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.compacting_bin.add.inherit", example = @Example("'iron_to_clay', ore('ingotIron') * 5, item('minecraft:clay_ball') * 20, false, 9, 7, 6, 6")) + public CompactingBinRecipe add(String name, IIngredient input, ItemStack output, boolean inherit, int... hits) { return recipeBuilder() - .toolUses(hits) + .inherit(inherit) + .hits(hits) .name(name) .input(input) .output(output) .register(); } - @MethodDescription(example = @Example("item('minecraft:snowball')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:snowball')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing compacting bin recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -49,7 +69,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription(example = @Example("item('minecraft:bone_block')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:bone_block')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing compacting bin recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -69,15 +89,30 @@ public void removeByOutput(IIngredient output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) - private int toolUses; + @Property + private final IntList hits = new IntArrayList(); + @Property + private boolean inherit; + + @RecipeBuilderMethodDescription + public RecipeBuilder hits(int... hits) { + for (int use : hits) { + this.hits.add(use); + } + return this; + } @RecipeBuilderMethodDescription - public RecipeBuilder toolUses(int toolUses) { - this.toolUses = toolUses; + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; return this; } + @Override + public String getRecipeNamePrefix() { + return "groovyscript_compacting_bin_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Compacting Bin Recipe"; @@ -85,9 +120,9 @@ public String getErrorMsg() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(toolUses < 0, "toolUses must be a non negative integer, yet it was {}", toolUses); - msg.add(super.name == null, "name cannot be null."); + msg.add(hits.stream().anyMatch(i -> i <= 0), "hits must be a non negative integer that is larger than 0"); msg.add(ModuleTechBasic.Registries.COMPACTING_BIN_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -95,8 +130,12 @@ public void validate(GroovyLog.Msg msg) { @Override public @Nullable CompactingBinRecipe register() { if (!validate()) return null; - CompactingBinRecipe recipe = new CompactingBinRecipe(output.get(0), input.get(0).toMcIngredient(), toolUses).setRegistryName(super.name); - PyroTech.compactingBin.add(recipe); + CompactingBinRecipe recipe = new CompactingBinRecipe(output.get(0), input.get(0).toMcIngredient(), input.get(0).getAmount(), hits.isEmpty() ? ModuleTechBasicConfig.COMPACTING_BIN.TOOL_USES_REQUIRED_PER_HARVEST_LEVEL : hits.toIntArray()).setRegistryName(super.name); + ModSupport.PYROTECH.get().compactingBin.add(recipe); + if (inherit && ModSupport.PYROTECH.get().mechanicalCompactingBin.isEnabled()) { + MechanicalCompactingBinRecipe mechanicalCompactingBinRecipe = MechanicalCompactingBinRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(super.name.getNamespace(), "compacting_bin/" + super.name.getPath()); + ModSupport.PYROTECH.get().mechanicalCompactingBin.add(mechanicalCompactingBinRecipe); + } return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CompostBin.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CompostBin.java index ef26472c2..6509e0906 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CompostBin.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CompostBin.java @@ -3,9 +3,11 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.CompostBinRecipe; import net.minecraft.item.ItemStack; @@ -15,17 +17,21 @@ @RegistryDescription public class CompostBin extends ForgeRegistryWrapper { - public CompostBin() { super(ModuleTechBasic.Registries.COMPOST_BIN_RECIPE); } + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald') * 4).compostValue(25).name('diamond_to_emerald_compost_bin')")) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'iron_to_clay2', ore('ingotIron') * 5, item('minecraft:clay_ball') * 20, 2")) + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'iron_to_clay2', ore('ingotIron'), item('minecraft:clay_ball') * 20, 2")) public CompostBinRecipe add(String name, IIngredient input, ItemStack output, int compostValue) { return recipeBuilder() .compostValue(compostValue) @@ -35,7 +41,7 @@ public CompostBinRecipe add(String name, IIngredient input, ItemStack output, in .register(); } - @MethodDescription(example = @Example("item('minecraft:golden_carrot')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:golden_carrot')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing compost bin recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -50,7 +56,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example(value = "item('pyrotech:mulch') * 4", commented = true)) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing compost bin recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -70,7 +76,7 @@ public void removeByOutput(IIngredient output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int compostValue; @RecipeBuilderMethodDescription @@ -79,6 +85,11 @@ public RecipeBuilder compostValue(int compostValue) { return this; } + @Override + public String getRecipeNamePrefix() { + return "groovyscript_compost_bin_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Compost Bin Recipe"; @@ -92,9 +103,9 @@ protected int getMaxItemInput() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(compostValue < 0, "compostValue must be a non negative integer, yet it was {}", compostValue); - msg.add(super.name == null, "name cannot be null."); + msg.add(compostValue <= 0, "compostValue must be a non negative integer that is larger than 0, yet it was {}", compostValue); msg.add(ModuleTechBasic.Registries.COMPACTING_BIN_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -108,12 +119,12 @@ public void validate(GroovyLog.Msg msg) { for (ItemStack i : in) { ResourceLocation rl = new ResourceLocation(super.name.getNamespace(), super.name.getPath() + "_" + (j++)); CompostBinRecipe recipe = new CompostBinRecipe(output.get(0), i, compostValue).setRegistryName(rl); - PyroTech.compostBin.add(recipe); + ModSupport.PYROTECH.get().compostBin.add(recipe); } return null; } CompostBinRecipe recipe = new CompostBinRecipe(output.get(0), in[0], compostValue).setRegistryName(super.name); - PyroTech.compostBin.add(recipe); + ModSupport.PYROTECH.get().compostBin.add(recipe); return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CrudeDryingRack.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CrudeDryingRack.java index eb626fe7e..bc6386f51 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CrudeDryingRack.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/CrudeDryingRack.java @@ -3,30 +3,52 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; +import com.codetaylor.mc.pyrotech.modules.tech.basic.init.recipe.DryingRackRecipesAdd; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.CrudeDryingRackRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.DryingRackRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.BrickOvenRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.StoneOvenRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.BrickOvenRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.StoneOvenRecipe; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import org.jetbrains.annotations.Nullable; @RegistryDescription public class CrudeDryingRack extends ForgeRegistryWrapper { - public CrudeDryingRack() { super(ModuleTechBasic.Registries.CRUDE_DRYING_RACK_RECIPE); } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).dryTime(260).name('diamond_to_emerald_crude_drying_rack')")) + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).dryTime(260).name('diamond_to_emerald_crude_drying_rack')"), + @Example(".input(item('minecraft:glowstone_dust')).output(item('minecraft:redstone')).dryTime(1000).inherit(true).name('glowstone_to_redstone')") + }) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200")) + @MethodDescription(type = MethodDescription.Type.ADDITION) public CrudeDryingRackRecipe add(String name, IIngredient input, ItemStack output, int dryTime) { + return add(name, input, output, dryTime, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.crude_drying_rack.add.inherit", example = @Example("'apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200, true")) + public CrudeDryingRackRecipe add(String name, IIngredient input, ItemStack output, int dryTime, boolean inherit) { return recipeBuilder() + .inherit(inherit) .dryTime(dryTime) .name(name) .input(input) @@ -49,7 +71,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:paper')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing crude drying rack recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -69,8 +91,10 @@ public void removeByOutput(IIngredient output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int dryTime; + @Property + private boolean inherit; @RecipeBuilderMethodDescription public RecipeBuilder dryTime(int time) { @@ -78,6 +102,17 @@ public RecipeBuilder dryTime(int time) { return this; } + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_crude_drying_rack_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Crude Drying Rack Recipe"; @@ -91,9 +126,9 @@ protected int getMaxItemInput() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(dryTime < 0, "dryTime must be a non negative integer, yet it was {}", dryTime); - msg.add(super.name == null, "name cannot be null."); + msg.add(dryTime <= 0, "dryTime must be a non negative integer that is larger than 0, yet it was {}", dryTime); msg.add(ModuleTechBasic.Registries.CRUDE_DRYING_RACK_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -102,7 +137,18 @@ public void validate(GroovyLog.Msg msg) { public @Nullable CrudeDryingRackRecipe register() { if (!validate()) return null; CrudeDryingRackRecipe recipe = new CrudeDryingRackRecipe(output.get(0), input.get(0).toMcIngredient(), dryTime).setRegistryName(super.name); - PyroTech.crudeDryingRack.add(recipe); + ModSupport.PYROTECH.get().crudeDryingRack.add(recipe); + if (inherit) { + ResourceLocation location = new ResourceLocation(super.name.getNamespace(), "crude_drying_rack/" + super.name.getPath()); + DryingRackRecipe dryingRackRecipe = DryingRackRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(location); + ModSupport.PYROTECH.get().dryingRack.add(dryingRackRecipe); + if (ModSupport.PYROTECH.get().stoneOven.isEnabled()) { + StoneOvenRecipe stoneOvenRecipe = StoneOvenRecipesAdd.INHERIT_TRANSFORMER.apply(dryingRackRecipe).setRegistryName(location); + ModSupport.PYROTECH.get().stoneOven.add(stoneOvenRecipe); + BrickOvenRecipe brickOvenRecipe = BrickOvenRecipesAdd.INHERIT_TRANSFORMER.apply(stoneOvenRecipe).setRegistryName(location); + ModSupport.PYROTECH.get().brickOven.add(brickOvenRecipe); + } + } return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/DryingRack.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/DryingRack.java index 24fba6e76..7121244db 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/DryingRack.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/DryingRack.java @@ -3,30 +3,54 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.DryingRackRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.BrickOvenRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.StoneOvenRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.BrickOvenRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.StoneOvenRecipe; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import org.jetbrains.annotations.Nullable; -@RegistryDescription +@RegistryDescription( + admonition = @Admonition( + value = "groovyscript.wiki.pyrotech.drying_rack.note0", + format = Admonition.Format.STANDARD, + hasTitle = true)) public class DryingRack extends ForgeRegistryWrapper { - public DryingRack() { super(ModuleTechBasic.Registries.DRYING_RACK_RECIPE); } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:iron_ingot')).output(item('minecraft:gold_ingot')).dryTime(260).name('iron_to_gold_drying_rack')")) + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:iron_ingot')).output(item('minecraft:gold_ingot')).dryTime(260).name('iron_to_gold_drying_rack')"), + @Example(".input(item('minecraft:ender_eye')).output(item('minecraft:ender_pearl')).dryTime(500).inherit(true).name('ender_eye_to_ender_pearl')") + }) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200")) + @MethodDescription(type = MethodDescription.Type.ADDITION) public DryingRackRecipe add(String name, IIngredient input, ItemStack output, int dryTime) { + return add(name, input, output, dryTime, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.drying_rack.add.inherit", example = @Example("'apple_to_dirt', item('minecraft:apple'), item('minecraft:dirt'), 1200, true")) + public DryingRackRecipe add(String name, IIngredient input, ItemStack output, int dryTime, boolean inherit) { return recipeBuilder() + .inherit(inherit) .dryTime(dryTime) .name(name) .input(input) @@ -34,7 +58,7 @@ public DryingRackRecipe add(String name, IIngredient input, ItemStack output, in .register(); } - @MethodDescription(example = @Example("item('minecraft:wheat')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:wheat')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing drying rack recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -49,7 +73,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:sponge')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing drying rack recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -69,8 +93,10 @@ public void removeByOutput(IIngredient output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int dryTime; + @Property + private boolean inherit; @RecipeBuilderMethodDescription public RecipeBuilder dryTime(int time) { @@ -78,6 +104,17 @@ public RecipeBuilder dryTime(int time) { return this; } + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_drying_rack_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Drying Rack Recipe"; @@ -91,9 +128,9 @@ protected int getMaxItemInput() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(dryTime < 0, "dryTime must be a non negative integer, yet it was {}", dryTime); - msg.add(super.name == null, "name cannot be null."); + msg.add(dryTime <= 0, "dryTime must be a non negative integer that is larger than 0, yet it was {}", dryTime); msg.add(ModuleTechBasic.Registries.DRYING_RACK_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -102,7 +139,14 @@ public void validate(GroovyLog.Msg msg) { public @Nullable DryingRackRecipe register() { if (!validate()) return null; DryingRackRecipe recipe = new DryingRackRecipe(output.get(0), input.get(0).toMcIngredient(), dryTime).setRegistryName(super.name); - PyroTech.dryingRack.add(recipe); + ModSupport.PYROTECH.get().dryingRack.add(recipe); + if (inherit && ModSupport.PYROTECH.get().stoneOven.isEnabled()) { + ResourceLocation location = new ResourceLocation(super.name.getNamespace(), "drying_rack/" + super.name.getPath()); + StoneOvenRecipe stoneOvenRecipe = StoneOvenRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(location); + ModSupport.PYROTECH.get().stoneOven.add(stoneOvenRecipe); + BrickOvenRecipe brickOvenRecipe = BrickOvenRecipesAdd.INHERIT_TRANSFORMER.apply(stoneOvenRecipe).setRegistryName(location); + ModSupport.PYROTECH.get().brickOven.add(brickOvenRecipe); + } return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/MechanicalCompactingBin.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/MechanicalCompactingBin.java new file mode 100644 index 000000000..710958d18 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/MechanicalCompactingBin.java @@ -0,0 +1,129 @@ +package com.cleanroommc.groovyscript.compat.mods.pyrotech; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; +import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; +import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasicConfig; +import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.MechanicalCompactingBinRecipe; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription( + admonition = @Admonition( + value = "groovyscript.wiki.pyrotech.mechanical_compacting_bin.note0", + format = Admonition.Format.STANDARD, + hasTitle = true)) +public class MechanicalCompactingBin extends ForgeRegistryWrapper { + + public MechanicalCompactingBin() { + super(ModuleTechMachine.Registries.MECHANICAL_COMPACTING_BIN_RECIPES); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = { + @Example(".hits(2, 2, 1, 1).input(item('minecraft:melon') * 8).output(item('minecraft:melon_block')).name('melon_compacting')") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = { + @Example("'gold_to_wheat', ore('ingotGold') * 4, item('minecraft:wheat') * 64, 4, 4, 3, 2"), + @Example("'wheat_to_hay_block', ore('cropWheat') * 9, item('minecraft:hay_block')") + }) + public MechanicalCompactingBinRecipe add(String name, IIngredient input, ItemStack output, int... hits) { + return recipeBuilder() + .hits(hits) + .name(name) + .input(input) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:snowball')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing compacting bin recipe") + .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (MechanicalCompactingBinRecipe recipe : getRegistry()) { + if (recipe.getInput().test(input)) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:bone_block')")) + public void removeByOutput(IIngredient output) { + if (GroovyLog.msg("Error removing compacting bin recipe") + .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (MechanicalCompactingBinRecipe recipe : getRegistry()) { + if (output.test(recipe.getOutput())) { + remove(recipe); + } + } + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + @Property(property = "name") + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property + private final IntList hits = new IntArrayList(); + + @RecipeBuilderMethodDescription + public RecipeBuilder hits(int... hits) { + for (int hit : hits) { + this.hits.add(hit); + } + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_mechanical_compacting_bin_"; + } + + @Override + public String getErrorMsg() { + return "Error adding Pyrotech Compacting Bin Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateName(); + validateItems(msg, 1, 1, 1, 1); + msg.add(hits.stream().anyMatch(i -> i <= 0), "hits must be a non negative integer that is larger than 0"); + msg.add(ModuleTechBasic.Registries.COMPACTING_BIN_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); + } + + @RecipeBuilderRegistrationMethod + @Override + public @Nullable MechanicalCompactingBinRecipe register() { + if (!validate()) return null; + MechanicalCompactingBinRecipe recipe = new MechanicalCompactingBinRecipe(output.get(0), input.get(0).toMcIngredient(), input.get(0).getAmount(), hits.isEmpty() ? ModuleTechBasicConfig.COMPACTING_BIN.TOOL_USES_REQUIRED_PER_HARVEST_LEVEL : hits.toIntArray()).setRegistryName(super.name); + ModSupport.PYROTECH.get().mechanicalCompactingBin.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PitBurn.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PitBurn.java new file mode 100644 index 000000000..ef1dfcd13 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PitBurn.java @@ -0,0 +1,274 @@ +package com.cleanroommc.groovyscript.compat.mods.pyrotech; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.ingredient.ItemStackList; +import com.cleanroommc.groovyscript.helper.recipe.IRecipeBuilder; +import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; +import com.codetaylor.mc.pyrotech.library.util.BlockMetaMatcher; +import com.codetaylor.mc.pyrotech.modules.tech.refractory.ModuleTechRefractory; +import com.codetaylor.mc.pyrotech.modules.tech.refractory.recipe.PitBurnRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.refractory.recipe.PitBurnRecipeBuilder; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemBlockSpecial; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Predicate; + +@RegistryDescription +public class PitBurn extends ForgeRegistryWrapper { + + public PitBurn() { + super(ModuleTechRefractory.Registries.BURN_RECIPE); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechRefractory.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:cauldron')).output(item('minecraft:cobblestone')).fluidOutput(fluid('water') * 50).burnStages(6).burnTime(1200).name('water_from_cauldron')"), + @Example(".input(item('minecraft:soul_sand')).output(item('minecraft:sand')).fluidOutput(fluid('lava') * 200).requiresRefractoryBlocks(true).burnStages(2).burnTime(600).failureChance(0.25F).failureOutput(item('minecraft:gravel') * 2).failureOutput(item('minecraft:dirt') * 3).name('lava_to_sand')"), + @Example(".input(blockstate('minecraft:sponge', 'wet=true')).output(item('minecraft:sponge')).fluidOutput(fluid('water') * 25).fluidLevelAffectsFailureChance(true).burnStages(10).burnTime(500).name('sponge_dehydrating')"), + @Example(".input(item('minecraft:chest')).output(item('minecraft:ender_chest')).fluidOutput(fluid('lava') * 125).fluidLevelAffectsFailureChance(true).requiresRefractoryBlocks(true).burnStages(4).burnTime(2000).name('chest_burning')") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:coal', 1) * 10")) + public void removeByOutput(IIngredient output) { + if (GroovyLog.msg("Error removing pit burning recipe") + .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (PitBurnRecipe recipe : getRegistry()) { + if (output.test(recipe.getOutput())) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:coal_block')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing pit burning recipe") + .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + if (input.getMetadata() > 15 && input.getMetadata() != OreDictionary.WILDCARD_VALUE) return; + Block block = getBlock(input); + if (block == Blocks.AIR) return; + for (PitBurnRecipe recipe : getRegistry()) { + BlockMetaMatcher matcher = recipe.getInputMatcher(); + if (matcher.getBlock() == block && (matcher.getMeta() == OreDictionary.WILDCARD_VALUE || input.getMetadata() == OreDictionary.WILDCARD_VALUE || matcher.getMeta() == input.getMetadata())) { + remove(recipe); + } + } + } + + public static class RecipeBuilder implements IRecipeBuilder { + + @Property(comp = @Comp(not = "null")) + private ResourceLocation name; + @Property(comp = @Comp(not = "null")) + private MatcherPredicate input; + @Property(comp = @Comp(not = "null")) + private ItemStack output; + @Property(comp = @Comp(gt = 0)) + private int burnStages; + @Property(comp = @Comp(gt = 0)) + private int burnTime; + private FluidStack fluidOutput; + @Property(comp = @Comp(gte = 0, lte = 1)) + private float failureChance; + @Property + private final ItemStackList failureOutput = new ItemStackList(); + @Property + private boolean requiresRefractoryBlocks; + @Property + private boolean fluidLevelAffectsFailureChance; + + @RecipeBuilderMethodDescription + public RecipeBuilder name(String name) { + if (name.contains(":")) { + this.name = new ResourceLocation(name); + } else { + this.name = new ResourceLocation(GroovyScript.getRunConfig().getPackId(), name); + } + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder name(ResourceLocation name) { + this.name = name; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder input(ItemStack input) { + return input(getBlock(input), input.getMetadata()); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder input(IBlockState state) { + return input(state.getBlock(), state.getBlock().getMetaFromState(state)); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder input(Block block, int metadata) { + if (block == Blocks.AIR) { + return this; + } + Predicate predicate = s -> s.getBlock() == block && (metadata == OreDictionary.WILDCARD_VALUE || s.getBlock().getMetaFromState(s) == metadata); + if (this.input == null) { + this.input = new MatcherPredicate(block, metadata, predicate); + } else if (this.input.getBlock() == Blocks.AIR) { + this.input = new MatcherPredicate(block, metadata, this.input.predicate.or(predicate)); + } else { + this.input = new MatcherPredicate(this.input.getBlock(), this.input.getMeta(), this.input.predicate.or(predicate)); + } + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder output(ItemStack output) { + this.output = output; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder burnStages(int burnStages) { + this.burnStages = burnStages; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder burnTime(int burnTime) { + this.burnTime = burnTime; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder fluidOutput(FluidStack fluidOutput) { + this.fluidOutput = fluidOutput; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder failureChance(float failureChance) { + this.failureChance = failureChance; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder failureOutput(ItemStack failureOutputs) { + this.failureOutput.add(failureOutputs); + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder failureOutput(ItemStack... failureOutputs) { + for (ItemStack itemStack : failureOutputs) { + failureOutput(itemStack); + } + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder failureOutput(Iterable failureOutputs) { + for (ItemStack itemStack : failureOutputs) { + failureOutput(itemStack); + } + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder requiresRefractoryBlocks(boolean requiresRefractoryBlocks) { + this.requiresRefractoryBlocks = requiresRefractoryBlocks; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder fluidLevelAffectsFailureChance(boolean fluidLevelAffectsFailureChance) { + this.fluidLevelAffectsFailureChance = fluidLevelAffectsFailureChance; + return this; + } + + @Override + public boolean validate() { + GroovyLog.Msg msg = GroovyLog.msg("Error adding Pyrotech Pit Burn Recipe"); + msg.add(name == null, "name cannot be null"); + msg.add(input == null, "input is null"); + msg.add(output == null, "output is empty"); + msg.add(burnStages <= 0, "burnStages must be a non negative integer that is larger than 0, yet it was {}", burnStages); + msg.add(burnTime <= 0, "burnTime must be a non negative integer that is larger than 0, yet it was {}", burnTime); + msg.add(failureChance < 0 || failureChance > 1, "failureChance must not be negative nor larger than 1.0, yet it was {}", failureChance); + msg.add(fluidOutput != null && fluidOutput.amount * burnStages > 500, "fluidOutput amount must not be larger than 500"); + msg.add(ModSupport.PYROTECH.get().pitBurn.getRegistry().getValue(name) != null, "tried to register {}, but it already exists.", name); + return false; + } + + @RecipeBuilderRegistrationMethod + @Override + public @Nullable PitBurnRecipe register() { + PitBurnRecipeBuilder builder = new PitBurnRecipeBuilder(output, input) + .setBurnStages(burnStages) + .setTotalBurnTimeTicks(burnTime) + .setFluidProduced(fluidOutput) + .setFailureChance(failureChance) + .setRequiresRefractoryBlocks(requiresRefractoryBlocks) + .setFluidLevelAffectsFailureChance(fluidLevelAffectsFailureChance); + failureOutput.forEach(builder::addFailureItem); + PitBurnRecipe recipe = builder.create(name); + ModSupport.PYROTECH.get().pitBurn.add(recipe); + return recipe; + } + } + + private static class MatcherPredicate extends BlockMetaMatcher { + + private final Predicate predicate; + + public MatcherPredicate(Block block, int metadata, Predicate predicate) { + super(block, metadata); + this.predicate = predicate; + } + + @Override + public boolean test(IBlockState blockState) { + return this.predicate.test(blockState); + } + } + + private static Block getBlock(ItemStack stack) { + Item item = stack.getItem(); + if (item instanceof ItemBlock) { + return ((ItemBlock) item).getBlock(); + } + if (item instanceof ItemBlockSpecial) { + return ((ItemBlockSpecial) item).getBlock(); + } + Block block = ForgeRegistries.BLOCKS.getValue(item.getRegistryName()); + if (block == null) block = Blocks.AIR; + return block; + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PitKiln.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PitKiln.java index 89ead0c33..a58124424 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PitKiln.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PitKiln.java @@ -3,14 +3,20 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.Alias; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.ingredient.ItemStackList; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.KilnPitRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.BrickKilnRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.StoneKilnRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.StoneKilnRecipe; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import org.jetbrains.annotations.Nullable; @RegistryDescription @@ -20,14 +26,28 @@ public PitKiln() { super(ModuleTechBasic.Registries.KILN_PIT_RECIPE, Alias.generateOfClass(PitKiln.class).andGenerate("Kiln")); } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:iron_ingot')).output(item('minecraft:gold_ingot')).burnTime(400).failureChance(1f).failureOutput(item('minecraft:wheat'), item('minecraft:carrot'), item('minecraft:sponge')).name('iron_to_gold_kiln_with_failure_items')")) + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:iron_ingot')).output(item('minecraft:gold_ingot')).burnTime(400).failureChance(1f).failureOutput(item('minecraft:wheat'), item('minecraft:carrot'), item('minecraft:sponge')).name('iron_to_gold_kiln_with_failure_items')"), + @Example(".input(item('minecraft:record_11')).output(item('minecraft:record_13')).burnTime(200).failureChance(0f).inherit(true).name('record_11_to_record_13')") + }) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'clay_to_iron', item('minecraft:clay_ball') * 5, item('minecraft:iron_ingot'), 1200, 0.5f, [item('minecraft:dirt'), item('minecraft:cobblestone')]")) - public KilnPitRecipe add(String name, IIngredient input, ItemStack output, int burnTime, float failureChance, Iterable failureOutput) { + @MethodDescription(type = MethodDescription.Type.ADDITION) + public KilnPitRecipe add(String name, IIngredient input, ItemStack output, int burnTime, float failureChance, ItemStack... failureOutput) { + return add(name, input, output, burnTime, false, failureChance, failureOutput); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.pit_kiln.add.inherit", example = @Example("'brick_to_iron', item('minecraft:brick'), item('minecraft:iron_ingot'), 1200, true, 0.5f, item('minecraft:dirt'), item('minecraft:cobblestone')")) + public KilnPitRecipe add(String name, IIngredient input, ItemStack output, int burnTime, boolean inherit, float failureChance, ItemStack... failureOutput) { return recipeBuilder() + .inherit(inherit) .burnTime(burnTime) .failureChance(failureChance) .failureOutput(failureOutput) @@ -37,7 +57,7 @@ public KilnPitRecipe add(String name, IIngredient input, ItemStack output, int b .register(); } - @MethodDescription + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('pyrotech:bucket_refractory_unfired')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing pit kiln recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -52,7 +72,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription(example = @Example("item('pyrotech:bucket_clay')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('pyrotech:bucket_clay')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing pit kiln recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -74,10 +94,12 @@ public static class RecipeBuilder extends AbstractRecipeBuilder { @Property private final ItemStackList failureOutput = new ItemStackList(); - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int burnTime; - @Property(comp = @Comp(gte = 0)) + @Property(comp = @Comp(gte = 0, lte = 1)) private float failureChance; + @Property + private boolean inherit; @RecipeBuilderMethodDescription public RecipeBuilder burnTime(int time) { @@ -107,10 +129,23 @@ public RecipeBuilder failureOutput(ItemStack... failureOutputs) { @RecipeBuilderMethodDescription public RecipeBuilder failureOutput(Iterable failureOutputs) { - for (ItemStack itemStack : failureOutputs) failureOutput(itemStack); + for (ItemStack itemStack : failureOutputs) { + failureOutput(itemStack); + } + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; return this; } + @Override + public String getRecipeNamePrefix() { + return "groovyscript_pit_kiln_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Pit Kiln Recipe"; @@ -123,12 +158,11 @@ protected int getMaxItemInput() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); this.failureOutput.trim(); - validateCustom(msg, failureOutput, 1, 100, "failure output"); - msg.add(burnTime < 0, "burnTime must be a non negative integer, yet it was {}", burnTime); - msg.add(failureChance < 0, "failureChance must be a non negative float, yet it was {}", failureChance); - msg.add(super.name == null, "name cannot be null."); + msg.add(burnTime <= 0, "burnTime must be a non negative integer that is larger than 0, yet it was {}", burnTime); + msg.add(failureChance < 0, "failureChance must not be negative nor larger than 1.0, yet it was {}", failureChance); msg.add(ModuleTechBasic.Registries.KILN_PIT_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -137,7 +171,13 @@ public void validate(GroovyLog.Msg msg) { public @Nullable KilnPitRecipe register() { if (!validate()) return null; KilnPitRecipe recipe = new KilnPitRecipe(output.get(0), input.get(0).toMcIngredient(), burnTime, failureChance, failureOutput.toArray(new ItemStack[0])).setRegistryName(super.name); - PyroTech.pitKiln.add(recipe); + ModSupport.PYROTECH.get().pitKiln.add(recipe); + if (inherit && ModSupport.PYROTECH.get().stoneKiln.isEnabled()) { + ResourceLocation location = new ResourceLocation(super.name.getNamespace(), "pit_kiln/" + super.name.getPath()); + StoneKilnRecipe stoneKilnRecipe = StoneKilnRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(location); + ModSupport.PYROTECH.get().stoneKiln.add(stoneKilnRecipe); + ModSupport.PYROTECH.get().brickKiln.add(BrickKilnRecipesAdd.INHERIT_TRANSFORMER.apply(stoneKilnRecipe).setRegistryName(location)); + } return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PyroTech.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PyroTech.java index 0df399e31..603bdb932 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PyroTech.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/PyroTech.java @@ -4,19 +4,28 @@ public class PyroTech extends GroovyPropertyContainer { - public static final Barrel barrel = new Barrel(); - public static final Campfire campfire = new Campfire(); - public static final StoneOven stoneOven = new StoneOven(); - public static final BrickOven brickOven = new BrickOven(); - public static final ChoppingBlock choppingBlock = new ChoppingBlock(); - public static final CompactingBin compactingBin = new CompactingBin(); - public static final CompostBin compostBin = new CompostBin(); - public static final CrudeDryingRack crudeDryingRack = new CrudeDryingRack(); - public static final DryingRack dryingRack = new DryingRack(); - public static final PitKiln pitKiln = new PitKiln(); - public static final StoneKiln stoneKiln = new StoneKiln(); - public static final BrickKiln brickKiln = new BrickKiln(); - public static final Anvil anvil = new Anvil(); - public static final SoakingPot soakingPot = new SoakingPot(); - public static final TanningRack tanningRack = new TanningRack(); + public final Anvil anvil = new Anvil(); + public final Barrel barrel = new Barrel(); + public final Bloomery bloomery = new Bloomery(); + public final BrickCrucible brickCrucible = new BrickCrucible(); + public final BrickKiln brickKiln = new BrickKiln(); + public final BrickOven brickOven = new BrickOven(); + public final BrickSawmill brickSawmill = new BrickSawmill(); + public final Campfire campfire = new Campfire(); + public final ChoppingBlock choppingBlock = new ChoppingBlock(); + public final CompactingBin compactingBin = new CompactingBin(); + public final CompostBin compostBin = new CompostBin(); + public final CrudeDryingRack crudeDryingRack = new CrudeDryingRack(); + public final DryingRack dryingRack = new DryingRack(); + public final MechanicalCompactingBin mechanicalCompactingBin = new MechanicalCompactingBin(); + public final PitBurn pitBurn = new PitBurn(); + public final PitKiln pitKiln = new PitKiln(); + public final SoakingPot soakingPot = new SoakingPot(); + public final StoneCrucible stoneCrucible = new StoneCrucible(); + public final StoneKiln stoneKiln = new StoneKiln(); + public final StoneOven stoneOven = new StoneOven(); + public final StoneSawmill stoneSawmill = new StoneSawmill(); + public final TanningRack tanningRack = new TanningRack(); + public final WitherForge witherForge = new WitherForge(); + public final Worktable worktable = new Worktable(); } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/SoakingPot.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/SoakingPot.java index fd742bc58..31d1ed996 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/SoakingPot.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/SoakingPot.java @@ -3,9 +3,11 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.SoakingPotRecipe; import net.minecraft.item.ItemStack; @@ -19,6 +21,11 @@ public SoakingPot() { super(ModuleTechBasic.Registries.SOAKING_POT_RECIPE); } + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).fluidInput(fluid('amongium') * 125).output(item('minecraft:emerald')).time(400).campfireRequired(true).name('diamond_to_emerald_with_amongium_soaking_pot')")) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); @@ -35,7 +42,7 @@ public SoakingPotRecipe add(String name, IIngredient input, FluidStack fluidInpu .register(); } - @MethodDescription + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('pyrotech:hide_washed')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing soaking pot recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -50,7 +57,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription(example = @Example("item('pyrotech:material', 54)")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('pyrotech:material', 54)")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing soaking pot recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -73,8 +80,7 @@ public static class RecipeBuilder extends AbstractRecipeBuilder { + + public StoneCrucible() { + super(ModuleTechMachine.Registries.STONE_CRUCIBLE_RECIPES); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = @Example(".input(ore('sugarcane')).fluidOutput(fluid('water') * 500).burnTime(1000).inherit(true).name('water_from_sugarcane')")) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public StoneCrucibleRecipe add(String name, IIngredient input, FluidStack output, int burnTime) { + return add(name, input, output, burnTime, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.stone_crucible.add.inherit", example = @Example("'water_from_cactus', ore('blockCactus'), fluid('water') * 1000, 600, true")) + public StoneCrucibleRecipe add(String name, IIngredient input, FluidStack output, int burnTime, boolean inherit) { + return recipeBuilder() + .inherit(inherit) + .burnTime(burnTime) + .name(name) + .input(input) + .fluidOutput(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:ice')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing stone crucible recipe") + .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (StoneCrucibleRecipe recipe : getRegistry()) { + if (recipe.getInput().test(input)) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("fluid('water') * 500")) + public void removeByOutput(IIngredient output) { + if (GroovyLog.msg("Error removing stone crucible recipe") + .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (StoneCrucibleRecipe recipe : getRegistry()) { + if (output.test(recipe.getOutput())) { + remove(recipe); + } + } + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "fluidOutput", comp = @Comp(eq = 1)) + @Property(property = "name") + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gt = 0)) + private int burnTime; + @Property + private boolean inherit; + + @RecipeBuilderMethodDescription + public RecipeBuilder burnTime(int burnTime) { + this.burnTime = burnTime; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_stone_crucible_"; + } + + @Override + public String getErrorMsg() { + return "Error adding Pyrotech Stone Crucible Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateName(); + validateItems(msg, 1, 1, 0, 0); + validateFluids(msg, 0, 0, 1, 1); + msg.add(burnTime <= 0, "burnTime must be a non negative integer that is larger than 0, yet it was {}", burnTime); + msg.add(ModuleTechMachine.Registries.STONE_CRUCIBLE_RECIPES.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public @Nullable StoneCrucibleRecipe register() { + if (!validate()) return null; + StoneCrucibleRecipe recipe = new StoneCrucibleRecipe(fluidOutput.get(0), input.get(0).toMcIngredient(), burnTime).setRegistryName(super.name); + ModSupport.PYROTECH.get().stoneCrucible.add(recipe); + if (inherit) { + BrickCrucibleRecipe brickCrucibleRecipe = BrickCrucibleRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(new ResourceLocation(super.name.getNamespace(), "stone_crucible/" + super.name.getPath())); + ModSupport.PYROTECH.get().brickCrucible.add(brickCrucibleRecipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneKiln.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneKiln.java index bcbad0dbb..48011d18e 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneKiln.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneKiln.java @@ -3,30 +3,51 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.ingredient.ItemStackList; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.BrickKilnRecipesAdd; import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.StoneKilnRecipe; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.Nullable; -@RegistryDescription +@RegistryDescription( + admonition = @Admonition( + value = "groovyscript.wiki.pyrotech.stone_kiln.note0", + format = Admonition.Format.STANDARD, + hasTitle = true)) public class StoneKiln extends ForgeRegistryWrapper { public StoneKiln() { super(ModuleTechMachine.Registries.STONE_KILN_RECIPES); } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:iron_ingot')).output(item('minecraft:gold_ingot')).burnTime(400).failureChance(1f).failureOutput(item('minecraft:wheat'), item('minecraft:carrot'), item('minecraft:sponge')).name('iron_to_gold_kiln_with_failure_items_stone')")) + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).burnTime(800).failureChance(0.6f).failureOutput(item('minecraft:egg'), item('minecraft:fish')).name('diamond_to_emerald_with_failure_outputs')"), + @Example(".input(item('minecraft:compass')).output(item('minecraft:clock')).burnTime(1200).failureChance(0f).inherit(true).name('compass_to_clock')") + }) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'clay_to_iron_stone', item('minecraft:clay_ball') * 5, item('minecraft:iron_ingot'), 1200, 0.5f, item('minecraft:dirt'), item('minecraft:cobblestone')")) - public StoneKilnRecipe add(String name, IIngredient input, ItemStack output, int burnTime, float failureChance, ItemStack... failureOutput) { + @MethodDescription(type = MethodDescription.Type.ADDITION) + public StoneKilnRecipe add(String name, IIngredient input, ItemStack output, int burnTime, float failureChance, ItemStack failureOutput) { + return add(name, input, output, burnTime, false, failureChance, failureOutput); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.stone_kiln.add.inherit", example = @Example("'clay_to_iron_stone', item('minecraft:clay_ball'), item('minecraft:iron_ingot'), 1200, true, 0.5f, item('minecraft:dirt'), item('minecraft:cobblestone')")) + public StoneKilnRecipe add(String name, IIngredient input, ItemStack output, int burnTime, boolean inherit, float failureChance, ItemStack... failureOutput) { return recipeBuilder() + .inherit(inherit) .burnTime(burnTime) .failureChance(failureChance) .failureOutput(failureOutput) @@ -36,7 +57,7 @@ public StoneKilnRecipe add(String name, IIngredient input, ItemStack output, int .register(); } - @MethodDescription + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:sand')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing stone kiln recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -51,7 +72,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription(example = @Example("item('pyrotech:bucket_clay')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('pyrotech:bucket_clay')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing stone iln recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -73,10 +94,12 @@ public static class RecipeBuilder extends AbstractRecipeBuilder @Property private final ItemStackList failureOutput = new ItemStackList(); - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int burnTime; - @Property(comp = @Comp(gte = 0)) + @Property(comp = @Comp(gte = 0, lte = 1)) private float failureChance; + @Property + private boolean inherit; @RecipeBuilderMethodDescription public RecipeBuilder burnTime(int time) { @@ -106,10 +129,28 @@ public RecipeBuilder failureOutput(ItemStack... failureOutputs) { @RecipeBuilderMethodDescription public RecipeBuilder failureOutput(Iterable failureOutputs) { - for (ItemStack itemStack : failureOutputs) failureOutput(itemStack); + for (ItemStack itemStack : failureOutputs) { + failureOutput(itemStack); + } return this; } + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_stone_kiln_"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Stone Kiln Recipe"; @@ -117,12 +158,11 @@ public String getErrorMsg() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); this.failureOutput.trim(); - validateCustom(msg, failureOutput, 1, 100, "failure output"); - msg.add(burnTime < 0, "burnTime must be a non negative integer, yet it was {}", burnTime); - msg.add(failureChance < 0, "failureChance must be a non negative float, yet it was {}", failureChance); - msg.add(super.name == null, "name cannot be null."); + msg.add(burnTime <= 0, "burnTime must be a non negative integer that is larger than 0, yet it was {}", burnTime); + msg.add(failureChance < 0 || failureChance > 1, "failureChance must not be negative nor larger than 1.0, yet it was {}", failureChance); msg.add(ModuleTechMachine.Registries.STONE_KILN_RECIPES.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -131,7 +171,10 @@ public void validate(GroovyLog.Msg msg) { public @Nullable StoneKilnRecipe register() { if (!validate()) return null; StoneKilnRecipe recipe = new StoneKilnRecipe(output.get(0), input.get(0).toMcIngredient(), burnTime, failureChance, failureOutput.toArray(new ItemStack[0])).setRegistryName(super.name); - PyroTech.stoneKiln.add(recipe); + ModSupport.PYROTECH.get().stoneKiln.add(recipe); + if (inherit) { + ModSupport.PYROTECH.get().brickKiln.add(BrickKilnRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(super.name.getNamespace(), "stone_kiln/" + super.name.getPath())); + } return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneOven.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneOven.java index 4f5eeabbf..0e93ed862 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneOven.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneOven.java @@ -3,34 +3,57 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.BrickOvenRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.BrickOvenRecipe; import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.StoneOvenRecipe; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import org.jetbrains.annotations.Nullable; @RegistryDescription( - admonition = @Admonition( - value = "groovyscript.wiki.pyrotech.oven.note0", - type = Admonition.Type.WARNING, - format = Admonition.Format.STANDARD, - hasTitle = true)) + admonition = { + @Admonition( + value = "groovyscript.wiki.pyrotech.stone_oven.note0", + format = Admonition.Format.STANDARD, + hasTitle = true + ), + @Admonition( + value = "groovyscript.wiki.pyrotech.oven.note0", + type = Admonition.Type.WARNING, + format = Admonition.Format.STANDARD, + hasTitle = true) + }) public class StoneOven extends ForgeRegistryWrapper { public StoneOven() { super(ModuleTechMachine.Registries.STONE_OVEN_RECIPES); } - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).duration(400).name('diamond_campfire_to_emerald_stone')")) + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:emerald')).duration(400).inherit(true).name('diamond_campfire_to_emerald_stone')")) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } - @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("'apple_to_dirt_stone', item('minecraft:apple'), item('minecraft:dirt'), 1000")) + @MethodDescription(type = MethodDescription.Type.ADDITION) public StoneOvenRecipe add(String name, IIngredient input, ItemStack output, int duration) { + return add(name, input, output, duration, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.stone_oven.add.inherit", example = @Example("'sand_to_dirt', item('minecraft:sand'), item('minecraft:dirt'), 1000, true")) + public StoneOvenRecipe add(String name, IIngredient input, ItemStack output, int duration, boolean inherit) { return recipeBuilder() + .inherit(inherit) .duration(duration) .name(name) .input(input) @@ -38,7 +61,7 @@ public StoneOvenRecipe add(String name, IIngredient input, ItemStack output, int .register(); } - @MethodDescription(example = @Example("item('minecraft:porkchop')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:porkchop')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing stone oven recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -53,7 +76,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription(example = @Example("item('minecraft:cooked_porkchop')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:cooked_porkchop')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing stone oven recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -73,8 +96,10 @@ public void removeByOutput(IIngredient output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int duration; + @Property + private boolean inherit; @RecipeBuilderMethodDescription public RecipeBuilder duration(int time) { @@ -82,6 +107,17 @@ public RecipeBuilder duration(int time) { return this; } + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_stone_oven_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Stone Oven Recipe"; @@ -89,9 +125,9 @@ public String getErrorMsg() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(duration < 0, "duration must be a non negative integer, yet it was {}", duration); - msg.add(super.name == null, "name cannot be null."); + msg.add(duration <= 0, "duration must be a non negative integer that is larger than 0, yet it was {}", duration); msg.add(ModuleTechMachine.Registries.STONE_OVEN_RECIPES.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -100,7 +136,12 @@ public void validate(GroovyLog.Msg msg) { public @Nullable StoneOvenRecipe register() { if (!validate()) return null; StoneOvenRecipe recipe = new StoneOvenRecipe(output.get(0), input.get(0).toMcIngredient(), duration).setRegistryName(super.name); - PyroTech.stoneOven.add(recipe); + ModSupport.PYROTECH.get().stoneOven.add(recipe); + if (inherit) { + ResourceLocation location = new ResourceLocation(super.name.getNamespace(), "stone_oven/" + super.name.getPath()); + BrickOvenRecipe brickOvenRecipe = BrickOvenRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(location); + ModSupport.PYROTECH.get().brickOven.add(brickOvenRecipe); + } return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneSawmill.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneSawmill.java new file mode 100644 index 000000000..81b08326b --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/StoneSawmill.java @@ -0,0 +1,208 @@ +package com.cleanroommc.groovyscript.compat.mods.pyrotech; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.athenaeum.util.ArrayHelper; +import com.codetaylor.mc.pyrotech.ModPyrotech; +import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachine; +import com.codetaylor.mc.pyrotech.modules.tech.machine.ModuleTechMachineConfig; +import com.codetaylor.mc.pyrotech.modules.tech.machine.init.recipe.BrickSawmillRecipesAdd; +import com.codetaylor.mc.pyrotech.modules.tech.machine.recipe.StoneSawmillRecipe; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +@RegistryDescription( + admonition = { + @Admonition( + value = "groovyscript.wiki.pyrotech.stone_sawmill.note0", + type = Admonition.Type.WARNING, + format = Admonition.Format.STANDARD, + hasTitle = true + ), + @Admonition( + value = "groovyscript.wiki.pyrotech.sawmill.note0", + type = Admonition.Type.WARNING, + format = Admonition.Format.STANDARD, + hasTitle = true) + }) +public class StoneSawmill extends ForgeRegistryWrapper { + + public StoneSawmill() { + super(ModuleTechMachine.Registries.STONE_SAWMILL_RECIPES); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechMachine.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:sign')).output(item('minecraft:planks:0') * 2).duration(200).woodChips(5).inherit(true).name('wood_from_sign')"), + @Example(".input(item('minecraft:stone_pickaxe'), item('pyrotech:sawmill_blade_bone')).output(item('minecraft:iron_pickaxe')).duration(5000).name('stone_pickaxe_upgrade')") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public StoneSawmillRecipe add(String name, IIngredient input, ItemStack output, int duration, int woodChips) { + return add(name, input, output, duration, woodChips, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.stone_sawmill.add.inherit", example = @Example("'stone_to_cobblestone', ore('stone'), item('minecraft:cobblestone'), 500, 0, true")) + public StoneSawmillRecipe add(String name, IIngredient input, ItemStack output, int duration, int woodChips, boolean inherit) { + return recipeBuilder() + .duration(duration) + .woodChips(woodChips) + .inherit(inherit) + .name(name) + .input(input) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public StoneSawmillRecipe add(String name, IIngredient input, IIngredient blade, ItemStack output, int duration, int woodChips) { + return add(name, input, blade, output, duration, woodChips, false); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.stone_sawmill.add.inherit", example = @Example("'apple_to_gapple_with_golden_blade', item('minecraft:apple'), item('pyrotech:sawmill_blade_bone'), item('minecraft:golden_apple'), 2000, 0, false")) + public StoneSawmillRecipe add(String name, IIngredient input, IIngredient blade, ItemStack output, int duration, int woodChips, boolean inherit) { + return recipeBuilder() + .duration(duration) + .woodChips(woodChips) + .inherit(inherit) + .name(name) + .input(input, blade) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:planks:1')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing stone sawmill recipe") + .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (StoneSawmillRecipe recipe : getRegistry()) { + if (recipe.getInput().test(input)) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('pyrotech:material:23')")) + public void removeByOutput(IIngredient output) { + if (GroovyLog.msg("Error removing stone sawmill recipe") + .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (StoneSawmillRecipe recipe : getRegistry()) { + if (output.test(recipe.getOutput())) { + remove(recipe); + } + } + } + + @Property(property = "input", comp = @Comp(gte = 1, lte = 2)) + @Property(property = "output", comp = @Comp(eq = 1)) + @Property(property = "name") + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gt = 0)) + private int duration; + @Property(value = "wood_chips", comp = @Comp(gte = 0)) + private int woodChips; + @Property + private boolean inherit; + + @RecipeBuilderMethodDescription + public RecipeBuilder duration(int time) { + this.duration = time; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder woodChips(int woodChips) { + this.woodChips = woodChips; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder inherit(boolean inherit) { + this.inherit = inherit; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_stone_sawmill_"; + } + + @Override + public String getErrorMsg() { + return "Error adding Pyrotech Stone Sawmill Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateName(); + validateItems(msg, 1, 2, 1, 1); + if (input.size() > 1) { + for (ItemStack stack : input.get(1).toMcIngredient().getMatchingStacks()) { + msg.add(!ArrayHelper.contains(ModuleTechMachineConfig.STONE_SAWMILL.SAWMILL_BLADES, Objects.requireNonNull(stack.getItem().getRegistryName()).toString()), "{} is not a stone sawmill blade", stack); + } + } + msg.add(duration <= 0, "duration must be a non negative integer that is larger than 0, yet it was {}", duration); + msg.add(ModuleTechMachine.Registries.STONE_SAWMILL_RECIPES.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); + } + + @RecipeBuilderRegistrationMethod + @Override + public @Nullable StoneSawmillRecipe register() { + if (!validate()) return null; + if (input.size() > 1) { + StoneSawmillRecipe recipe = new StoneSawmillRecipe(output.get(0), input.get(0).toMcIngredient(), duration, input.get(1).toMcIngredient(), woodChips).setRegistryName(super.name); + ModSupport.PYROTECH.get().stoneSawmill.add(recipe); + if (inherit) { + ModSupport.PYROTECH.get().brickSawmill.add(BrickSawmillRecipesAdd.INHERIT_TRANSFORMER.apply(recipe).setRegistryName(new ResourceLocation(super.name.getNamespace(), "stone_sawmill/" + super.name.getPath()))); + } + return recipe; + } else { + StoneSawmillRecipe[] recipes = new StoneSawmillRecipe[4]; + ItemStack out = output.get(0); + Ingredient in = input.get(0).toMcIngredient(); + StoneSawmillRecipe recipe = new StoneSawmillRecipe(out, in, duration, Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.STONE_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE)), woodChips).setRegistryName(name + "_tier_0"); + recipes[0] = recipe; + out = out.copy(); + out.setCount(Math.min(out.getMaxStackSize(), out.getCount() * 2)); + recipes[1] = new StoneSawmillRecipe(out, in, (int) (1.5 * (double) duration), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.FLINT_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE), new ItemStack(ModuleTechMachine.Items.BONE_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE)), woodChips / 2).setRegistryName(name + "_tier_1"); + recipes[2] = new StoneSawmillRecipe(out, in, (int) (0.5 * (double) duration), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.IRON_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE)), woodChips / 4).setRegistryName(name + "_tier_2"); + out = out.copy(); + out.setCount(Math.min(out.getMaxStackSize(), out.getCount() * 3)); + recipes[3] = new StoneSawmillRecipe(out, in, (int) (1.5 * (double) duration), Ingredient.fromStacks(new ItemStack(ModuleTechMachine.Items.DIAMOND_MILL_BLADE, 1, OreDictionary.WILDCARD_VALUE)), woodChips / 4).setRegistryName(name + "_tier_3"); + for (StoneSawmillRecipe r : recipes) { + ModSupport.PYROTECH.get().stoneSawmill.add(r); + if (inherit) { + ModSupport.PYROTECH.get().brickSawmill.add(BrickSawmillRecipesAdd.INHERIT_TRANSFORMER.apply(r).setRegistryName(new ResourceLocation(super.name.getNamespace(), "stone_sawmill/" + super.name.getPath()))); + } + } + return recipe; + } + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/TanningRack.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/TanningRack.java index 101be6bd6..af1f19fd0 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/TanningRack.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/TanningRack.java @@ -3,9 +3,11 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.TanningRackRecipe; import net.minecraft.item.ItemStack; @@ -14,11 +16,15 @@ @RegistryDescription public class TanningRack extends ForgeRegistryWrapper { - public TanningRack() { super(ModuleTechBasic.Registries.TANNING_RACK_RECIPE); } + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:iron_ingot')).output(item('minecraft:gold_ingot')).dryTime(260).name('iron_to_gold_drying_rack')")) public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); @@ -35,7 +41,7 @@ public TanningRackRecipe add(String name, IIngredient input, ItemStack output, i .register(); } - @MethodDescription(example = @Example("item('minecraft:wheat')")) + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:wheat')")) public void removeByInput(ItemStack input) { if (GroovyLog.msg("Error removing tanning rack recipe") .add(IngredientHelper.isEmpty(input), () -> "Input 1 must not be empty") @@ -50,7 +56,7 @@ public void removeByInput(ItemStack input) { } } - @MethodDescription + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:leather')")) public void removeByOutput(IIngredient output) { if (GroovyLog.msg("Error removing tanning rack recipe") .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") @@ -70,10 +76,10 @@ public void removeByOutput(IIngredient output) { @Property(property = "name") public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 1)) + @Property(comp = @Comp(gt = 0)) private int dryTime; - @Property - private ItemStack failureItem; + @Property(comp = @Comp(not = "null")) + private ItemStack failureItem = ItemStack.EMPTY; @RecipeBuilderMethodDescription public RecipeBuilder failureItem(ItemStack stack) { @@ -87,6 +93,11 @@ public RecipeBuilder dryTime(int time) { return this; } + @Override + public String getRecipeNamePrefix() { + return "groovyscript_tanning_rack_"; + } + @Override public String getErrorMsg() { return "Error adding Pyrotech Tanning Rack Recipe"; @@ -100,9 +111,10 @@ protected int getMaxItemInput() { @Override public void validate(GroovyLog.Msg msg) { + validateName(); validateItems(msg, 1, 1, 1, 1); - msg.add(dryTime < 0, "dryTime must be a non negative integer, yet it was {}", dryTime); - msg.add(super.name == null, "name cannot be null."); + msg.add(dryTime <= 0, "dryTime must be a non negative integer that is larger than 0, yet it was {}", dryTime); + msg.add(failureItem == null, "failureItem must not be null"); msg.add(ModuleTechBasic.Registries.TANNING_RACK_RECIPE.getValue(super.name) != null, "tried to register {}, but it already exists.", super.name); } @@ -112,7 +124,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable TanningRackRecipe register() { if (!validate()) return null; TanningRackRecipe recipe = new TanningRackRecipe(output.get(0), input.get(0).toMcIngredient(), failureItem, dryTime).setRegistryName(super.name); - PyroTech.tanningRack.add(recipe); + ModSupport.PYROTECH.get().tanningRack.add(recipe); return recipe; } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/WitherForge.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/WitherForge.java new file mode 100644 index 000000000..0c0c14248 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/WitherForge.java @@ -0,0 +1,324 @@ +package com.cleanroommc.groovyscript.compat.mods.pyrotech; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.core.mixin.pyrotech.BloomeryRecipeBaseAccessor; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.codetaylor.mc.pyrotech.ModPyrotech; +import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.AnvilRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.ModuleTechBloomery; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.ModuleTechBloomeryConfig; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.recipe.BloomAnvilRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.recipe.BloomeryRecipeBase; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.recipe.WitherForgeRecipe; +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.recipe.WitherForgeRecipeBuilder; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +@RegistryDescription( + admonition = @Admonition( + value = "groovyscript.wiki.pyrotech.wither_forge.note0", + format = Admonition.Format.STANDARD, + hasTitle = true)) +public class WitherForge extends ForgeRegistryWrapper { + + public WitherForge() { + super(ModuleTechBloomery.Registries.WITHER_FORGE_RECIPE); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBloomery.class); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:minecart')).output(item('minecraft:furnace_minecart')).slag(item('minecraft:iron_ingot')).experience(0.8F).bloomYield(1, 1).burnTime(2000).failureChance(0.5F).failureOutput(item('minecraft:tnt_minecart'), 1).name('minecart_smelting')"), + @Example(".input(item('minecraft:fishing_rod') | item('minecraft:carrot_on_a_stick')).output(item('minecraft:cooked_fish')).bloomYield(5, 8).langKey(item('minecraft:fishing_rod').getTranslationKey()).name('fishing')"), + @Example(".input(item('minecraft:paper')).bloom(item('minecraft:book')).tierGranite().tierObsidian().failureChance(0.1F).failureOutput(item('minecraft:milk_bucket'), 5).failureOutput(item('minecraft:bone'), 2).name('knowledge')"), + @Example(".input(item('minecraft:comparator')).output(item('minecraft:redstone')).bloomYield(12, 15).experience(0.6F).burnTime(4000).tierGranite().tierIronclad().anvilHit(5).typePickaxe().failureChance(0.15F).failureOutput(item('minecraft:glowstone_dust'), 5).failureOutput(item('minecraft:sugar'), 4).name('comparator_melting')") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.wither_forge.add0", example = @Example("'flower_pot', item('minecraft:flower_pot'), item('minecraft:clay_ball')")) + public WitherForgeRecipe add(String name, ItemStack output, IIngredient input) { + return recipeBuilder() + .bloom(output) + .input(input) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.wither_forge.add1", example = @Example("'hoopify', item('minecraft:hopper') * 4, item('minecraft:chest'), 60")) + public WitherForgeRecipe add(String name, ItemStack output, IIngredient input, int burnTime) { + return recipeBuilder() + .bloom(output) + .burnTime(burnTime) + .input(input) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.wither_forge.addBloom0", example = @Example("'quartz_recipe', item('minecraft:quartz') * 3, ore('oreQuartz')")) + public WitherForgeRecipe addBloom(String name, ItemStack bloomOutput, IIngredient input) { + return recipeBuilder() + .output(bloomOutput) + .input(input) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.pyrotech.wither_forge.addBloom1", example = @Example("'feathery', item('minecraft:feather'), 10, 15, item('minecraft:chicken'), 200, 0.1F, 0.25F, item('minecraft:cooked_chicken')")) + public WitherForgeRecipe addBloom(String name, ItemStack bloomOutput, int minYield, int maxYield, IIngredient input, int burnTime, float experience, float failureChance, ItemStack... failureItems) { + RecipeBuilder builder = recipeBuilder(); + builder.bloomYield(minYield, maxYield) + .input(input) + .output(bloomOutput) + .name(name); + for (ItemStack stack : failureItems) { + builder.failureOutput(stack, 1); + } + return builder + .burnTime(burnTime) + .experience(experience) + .failureChance(failureChance) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example(value = "item('minecraft:iron_nugget')", commented = true)) + public void removeByOutput(IIngredient output) { + if (GroovyLog.msg("Error removing wither forge recipe") + .add(IngredientHelper.isEmpty(output), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (WitherForgeRecipe recipe : getRegistry()) { + if (output.test(recipe.getOutput())) { + remove(recipe); + } + } + } + + @MethodDescription(type = MethodDescription.Type.REMOVAL, example = @Example("item('minecraft:gold_ore')")) + public void removeByInput(ItemStack input) { + if (GroovyLog.msg("Error removing wither forge recipe") + .add(IngredientHelper.isEmpty(input), () -> "Output 1 must not be empty") + .error() + .postIfNotEmpty()) { + return; + } + for (WitherForgeRecipe recipe : getRegistry()) { + if (recipe.getInput().test(input)) { + remove(recipe); + } + } + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + @Property(property = "name") + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(value = "groovyscript.wiki.pyrotech.bloomery.bloom.value") + private ItemStack bloom = ItemStack.EMPTY; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.slag.value") + private ItemStack slag = null; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.burnTime.value", comp = @Comp(gt = 0), defaultValue = "21600") + private int burnTime = 21600; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.experience.value", comp = @Comp(gte = 0)) + private float experience; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.bloomYieldMin.value", comp = @Comp(gte = 0), defaultValue = "12") + private int bloomYieldMin = 12; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.bloomYieldMax.value", comp = @Comp(gte = 0), defaultValue = "15") + private int bloomYieldMax = 15; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.failureChance.value", comp = @Comp(gte = 0, lte = 1)) + private float failureChance = 0.25F; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.failureOutput.value") + private final List failureOutput = new ArrayList<>(1); + @Property(value = "groovyscript.wiki.pyrotech.bloomery.anvilTiers.value") + private final EnumSet anvilTiers = EnumSet.noneOf(AnvilRecipe.EnumTier.class); + @Property(value = "groovyscript.wiki.pyrotech.bloomery.anvilHit.value", comp = @Comp(gt = 0)) + private int anvilHit = ModuleTechBloomeryConfig.BLOOM.HAMMER_HITS_IN_ANVIL_REQUIRED; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.anvilType.value", comp = @Comp(not = "null")) + private AnvilRecipe.EnumType anvilType = AnvilRecipe.EnumType.HAMMER; + @Property(value = "groovyscript.wiki.pyrotech.bloomery.langKey.value") + private String langKey; + + @RecipeBuilderMethodDescription + public RecipeBuilder bloom(ItemStack bloom) { + this.bloom = bloom == null ? ItemStack.EMPTY : bloom; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder slag(ItemStack slag) { + this.slag = slag == null ? ItemStack.EMPTY : slag; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder burnTime(int burnTime) { + this.burnTime = burnTime; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder experience(float experience) { + this.experience = experience; + return this; + } + + @RecipeBuilderMethodDescription(field = { + "bloomYieldMin", "bloomYieldMax" + }) + public RecipeBuilder bloomYield(int bloomYieldMin, int bloomYieldMax) { + this.bloomYieldMin = bloomYieldMin; + this.bloomYieldMax = bloomYieldMax; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder failureChance(float failureChance) { + this.failureChance = failureChance; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder failureOutput(ItemStack failureOutput, int weight) { + this.failureOutput.add(new BloomeryRecipeBase.FailureItem(failureOutput, weight)); + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder anvilTier(AnvilRecipe.EnumTier tier) { + anvilTiers.add(tier); + return this; + } + + @RecipeBuilderMethodDescription(field = "anvilTier") + public RecipeBuilder tierGranite() { + return anvilTier(AnvilRecipe.EnumTier.GRANITE); + } + + @RecipeBuilderMethodDescription(field = "anvilTier") + public RecipeBuilder tierIronclad() { + return anvilTier(AnvilRecipe.EnumTier.IRONCLAD); + } + + @RecipeBuilderMethodDescription(field = "anvilTier") + public RecipeBuilder tierObsidian() { + return anvilTier(AnvilRecipe.EnumTier.OBSIDIAN); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder anvilType(AnvilRecipe.EnumType anvilType) { + this.anvilType = anvilType; + return this; + } + + @RecipeBuilderMethodDescription(field = "anvilType") + public RecipeBuilder typeHammer() { + return anvilType(AnvilRecipe.EnumType.HAMMER); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder typePickaxe() { + return anvilType(AnvilRecipe.EnumType.PICKAXE); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder anvilHit(int hit) { + this.anvilHit = hit; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder langKey(String langKey) { + this.langKey = langKey; + return this; + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_wither_forge_"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public String getErrorMsg() { + return "Error adding Pyrotech Bloomery Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateName(); + if (bloom == null) { + bloom = ItemStack.EMPTY; + } + int minOutput = bloom.isEmpty() ? 1 : 0; + if (slag == null) { + slag = bloom.isEmpty() ? new ItemStack(ModuleTechBloomery.Items.SLAG, 4) : ItemStack.EMPTY; + } + if (failureOutput.isEmpty() && failureChance > 0.0F) { + failureOutput.add(new BloomeryRecipeBase.FailureItem(new ItemStack(ModuleTechBloomery.Items.SLAG), 1)); + } + if (anvilTiers.isEmpty()) { + anvilTiers.addAll(EnumSet.allOf(AnvilRecipe.EnumTier.class)); + } + validateItems(msg, 1, 1, minOutput, 1); + msg.add(burnTime <= 0, "burnTime must be a non negative integer that is larger than 0, yet it was {}", burnTime); + msg.add(experience < 0, "experience must be a non negative float, yet it was {}", experience); + msg.add(bloomYieldMin < 0 || bloomYieldMin > bloomYieldMax, "bloomYieldMin must be a non negative integer that is smaller than bloomYieldMax, yet it was {}", burnTime); + msg.add(bloomYieldMax < 0, "bloomYieldMax must be a non negative integer, yet it was {}", burnTime); + msg.add(failureChance < 0 || failureChance > 1, "failureChance must not be negative nor larger than 1.0, yet it was {}", failureChance); + msg.add(anvilType == null, "anvilType must not be null"); + msg.add(anvilHit <= 0, "anvilHit must be a non negative integer that is larger than 0, yet it was {}", anvilHit); + msg.add(ModSupport.PYROTECH.get().witherForge.getRegistry().getValue(super.name) != null, "tried to register {}, but it already exists", super.name); + } + + @RecipeBuilderRegistrationMethod + @Override + public @Nullable WitherForgeRecipe register() { + if (!validate()) return null; + WitherForgeRecipeBuilder builder = new WitherForgeRecipeBuilder(super.name, !output.isEmpty() ? output.get(0) : ItemStack.EMPTY, input.get(0).toMcIngredient()); + failureOutput.forEach(i -> builder.addFailureItem(i.getItemStack(), i.getWeight())); + WitherForgeRecipe recipe = builder + .setSlagItem(slag, slag.getCount()) + .setBurnTimeTicks(burnTime) + .setExperience(experience) + .setBloomYield(bloomYieldMin, bloomYieldMax) + .setFailureChance(failureChance) + .setAnvilTiers(anvilTiers.toArray(new AnvilRecipe.EnumTier[0])) + .setLangKey(langKey) + .create(); + ((BloomeryRecipeBaseAccessor) recipe).grs$setOutputBloom(bloom.isEmpty() ? null : bloom); + ModSupport.PYROTECH.get().witherForge.add(recipe); + if (bloom.isEmpty() && bloomYieldMax != 0) { + ModSupport.PYROTECH.get().anvil.add( + new BloomAnvilRecipe( + recipe.getOutput(), + com.codetaylor.mc.athenaeum.util.IngredientHelper.fromStackWithNBT(recipe.getOutputBloom()), + anvilHit, + anvilType, + recipe.getAnvilTiers(), + recipe + ).setRegistryName(super.name)); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Worktable.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Worktable.java new file mode 100644 index 000000000..e701e478a --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pyrotech/Worktable.java @@ -0,0 +1,515 @@ +package com.cleanroommc.groovyscript.compat.mods.pyrotech; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.compat.vanilla.ShapedCraftingRecipe; +import com.cleanroommc.groovyscript.compat.vanilla.ShapelessCraftingRecipe; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.registry.AbstractCraftingRecipeBuilder; +import com.cleanroommc.groovyscript.registry.ForgeRegistryWrapper; +import com.cleanroommc.groovyscript.registry.ReloadableRegistryManager; +import com.codetaylor.mc.pyrotech.ModPyrotech; +import com.codetaylor.mc.pyrotech.modules.tech.basic.ModuleTechBasic; +import com.codetaylor.mc.pyrotech.modules.tech.basic.recipe.WorktableRecipe; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.registry.ForgeRegistries; + +import java.util.ArrayList; +import java.util.List; + +@RegistryDescription( + admonition = @Admonition( + value = "groovyscript.wiki.minecraft.crafting.note0", + type = Admonition.Type.WARNING, + format = Admonition.Format.STANDARD, + hasTitle = true)) +public class Worktable extends ForgeRegistryWrapper { + + public Worktable() { + super(ModuleTechBasic.Registries.WORKTABLE_RECIPE); + } + + @Override + public boolean isEnabled() { + return ModPyrotech.INSTANCE.isModuleEnabled(ModuleTechBasic.class); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShaped0", example = @Example(value = "item('minecraft:gold_block'), [[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')],[null, null, null],[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]]", commented = true)) + public void addShaped(ItemStack output, List> input) { + shapedBuilder() + .matrix(input) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShaped1", example = @Example(value = "'gold_v_to_clay', item('minecraft:clay'), [[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[null,item('minecraft:gold_ingot'),null]]", commented = true)) + public void addShaped(String name, ItemStack output, List> input) { + shapedBuilder() + .matrix(input) + .output(output) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShaped1", example = @Example(value = "resource('example:resource_location'), item('minecraft:clay'), [[item('minecraft:cobblestone')],[item('minecraft:nether_star')],[item('minecraft:cobblestone')]]", commented = true)) + public void addShaped(ResourceLocation name, ItemStack output, List> input) { + shapedBuilder() + .matrix(input) + .output(output) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShapeless0", example = @Example(value = "item('minecraft:clay'), [item('minecraft:cobblestone'),item('minecraft:nether_star'),item('minecraft:gold_ingot')]", commented = true)) + public void addShapeless(ItemStack output, List input) { + shapelessBuilder() + .input(input) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShapeless1", example = @Example(value = "'precious_to_clay', item('minecraft:clay'), [item('minecraft:diamond'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]", commented = true)) + public void addShapeless(String name, ItemStack output, List input) { + shapelessBuilder() + .input(input) + .output(output) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShapeless1", example = @Example(value = "resource('example:resource_location2'), item('minecraft:clay'), [item('minecraft:cobblestone'), item('minecraft:gold_ingot')]", commented = true)) + public void addShapeless(ResourceLocation name, ItemStack output, List input) { + shapelessBuilder() + .input(input) + .output(output) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShaped0", example = @Example(value = "item('minecraft:gold_block'), item('minecraft:diamond_pickaxe'), 2, [[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')],[null, null, null],[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]]", commented = true)) + public void addShaped(ItemStack output, IIngredient tool, int damage, List> input) { + shapedBuilder() + .tool(tool, damage) + .matrix(input) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShaped1", example = @Example(value = "'gold_v_to_clay', item('minecraft:clay'), item('minecraft:iron_pickaxe'), 3, [[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[null,item('minecraft:gold_ingot'),null]]", commented = true)) + public void addShaped(String name, ItemStack output, IIngredient tool, int damage, List> input) { + shapedBuilder() + .tool(tool, damage) + .matrix(input) + .output(output) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShaped1", example = @Example(value = "resource('example:resource_location'), item('minecraft:clay'), item('minecraft:iron_shovel'), 2, [[item('minecraft:cobblestone')],[item('minecraft:nether_star')],[item('minecraft:cobblestone')]]", commented = true)) + public void addShaped(ResourceLocation name, ItemStack output, IIngredient tool, int damage, List> input) { + shapedBuilder() + .tool(tool, damage) + .matrix(input) + .output(output) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShapeless0", example = @Example(value = "item('minecraft:clay'), item('minecraft:stone_shovel'), 3, [item('minecraft:cobblestone'),item('minecraft:nether_star'),item('minecraft:gold_ingot')]", commented = true)) + public void addShapeless(ItemStack output, IIngredient tool, int damage, List input) { + shapelessBuilder() + .tool(tool, damage) + .input(input) + .output(output) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShapeless1", example = @Example(value = "'precious_to_clay', item('minecraft:clay'), item('minecraft:iron_shovel'), 2, [item('minecraft:diamond'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]", commented = true)) + public void addShapeless(String name, ItemStack output, IIngredient tool, int damage, List input) { + shapelessBuilder() + .tool(tool, damage) + .input(input) + .output(output) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.addShapeless1", example = @Example(value = "resource('example:resource_location2'), item('minecraft:clay'), item('minecraft:stone_shovel'), 3, [item('minecraft:cobblestone'), item('minecraft:gold_ingot')]", commented = true)) + public void addShapeless(ResourceLocation name, ItemStack output, IIngredient tool, int damage, List input) { + shapelessBuilder() + .tool(tool, damage) + .input(input) + .output(output) + .name(name) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShapeless0", example = @Example(value = "item('minecraft:ender_eye'), [item('minecraft:ender_pearl'),item('minecraft:nether_star')]", commented = true)) + public void replaceShapeless(ItemStack output, List input) { + shapelessBuilder() + .input(input) + .output(output) + .replace() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShapeless1", example = @Example(value = "'minecraft:pink_dye_from_pink_tulp', item('minecraft:clay'), [item('minecraft:nether_star')]", commented = true)) + public void replaceShapeless(String name, ItemStack output, List input) { + shapelessBuilder() + .input(input) + .output(output) + .name(name) + .replaceByName() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShapeless1", example = @Example(value = "resource('minecraft:pink_dye_from_peony'), item('minecraft:clay'), [item('minecraft:cobblestone'), item('minecraft:gold_ingot')]", commented = true)) + public void replaceShapeless(ResourceLocation name, ItemStack output, List input) { + shapelessBuilder() + .input(input) + .output(output) + .name(name) + .replaceByName() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShaped0", example = @Example(value = "item('minecraft:chest'), [[ore('logWood'),ore('logWood'),ore('logWood')],[ore('logWood'),null,ore('logWood')],[ore('logWood'),ore('logWood'),ore('logWood')]]", commented = true)) + public void replaceShaped(ItemStack output, List> input) { + shapedBuilder() + .matrix(input) + .output(output) + .replace() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShaped1", example = @Example(value = "'gold_to_diamonds', item('minecraft:diamond') * 8, [[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]]", commented = true)) + public void replaceShaped(String name, ItemStack output, List> input) { + shapedBuilder() + .matrix(input) + .output(output) + .name(name) + .replaceByName() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShaped1", example = @Example(value = "resource('minecraft:sea_lantern'), item('minecraft:clay'), [[item('minecraft:glowstone')],[item('minecraft:glowstone')],[item('minecraft:glowstone')]]", commented = true)) + public void replaceShaped(ResourceLocation name, ItemStack output, List> input) { + shapedBuilder() + .matrix(input) + .output(output) + .name(name) + .replaceByName() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShapeless0", example = @Example(value = "item('minecraft:ender_eye'), item('minecraft:shears'), 3, [item('minecraft:ender_pearl'),item('minecraft:nether_star')]", commented = true)) + public void replaceShapeless(ItemStack output, IIngredient tool, int damage, List input) { + shapelessBuilder() + .tool(tool, damage) + .input(input) + .output(output) + .replace() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShapeless1", example = @Example(value = "'minecraft:pink_dye_from_pink_tulp', item('minecraft:iron_axe'), 2, item('minecraft:clay'), [item('minecraft:nether_star')]", commented = true)) + public void replaceShapeless(String name, ItemStack output, IIngredient tool, int damage, List input) { + shapelessBuilder() + .tool(tool, damage) + .input(input) + .output(output) + .name(name) + .replaceByName() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShapeless1", example = @Example(value = "resource('minecraft:pink_dye_from_peony'), item('minecraft:clay'), item('minecraft:stone_axe'), 2, [item('minecraft:cobblestone'), item('minecraft:gold_ingot')]", commented = true)) + public void replaceShapeless(ResourceLocation name, ItemStack output, IIngredient tool, int damage, List input) { + shapelessBuilder() + .tool(tool, damage) + .input(input) + .output(output) + .name(name) + .replaceByName() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShaped0", example = @Example(value = "item('minecraft:chest'), item('minecraft:iron_axe') | item('minecraft:stone_axe'), 3, [[ore('logWood'),ore('logWood'),ore('logWood')],[ore('logWood'),null,ore('logWood')],[ore('logWood'),ore('logWood'),ore('logWood')]]", commented = true)) + public void replaceShaped(ItemStack output, IIngredient tool, int damage, List> input) { + shapedBuilder() + .tool(tool, damage) + .matrix(input) + .output(output) + .replace() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShaped1", example = @Example(value = "'gold_to_diamonds', item('minecraft:diamond') * 8, item('minecraft:diamond_pickaxe'), 4, [[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'),item('minecraft:gold_ingot'),item('minecraft:gold_ingot')]]", commented = true)) + public void replaceShaped(String name, ItemStack output, IIngredient tool, int damage, List> input) { + shapedBuilder() + .tool(tool, damage) + .matrix(input) + .output(output) + .name(name) + .replaceByName() + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, description = "groovyscript.wiki.minecraft.crafting.replaceShaped1", example = @Example(value = "resource('minecraft:sea_lantern'), item('minecraft:diamond_pickaxe'), 3, item('minecraft:clay'), [[item('minecraft:glowstone')],[item('minecraft:glowstone')],[item('minecraft:glowstone')]]", commented = true)) + public void replaceShaped(ResourceLocation name, ItemStack output, IIngredient tool, int damage, List> input) { + shapedBuilder() + .tool(tool, damage) + .matrix(input) + .output(output) + .name(name) + .replaceByName() + .register(); + } + + @MethodDescription(example = @Example("item('pyrotech:iron_hunters_knife')")) + public void removeByOutput(IIngredient output) { + removeByOutput(output, true); + } + + @GroovyBlacklist + public void removeByOutput(IIngredient output, boolean log) { + if (IngredientHelper.isEmpty(output)) { + if (log) { + GroovyLog.msg("Error removing Pyrotech Worktable recipe") + .add("Output must not be empty") + .error() + .post(); + } + return; + } + List recipesToRemove = new ArrayList<>(); + for (IRecipe recipe : ForgeRegistries.RECIPES) { + if (recipe.getRegistryName() != null && output.test(recipe.getRecipeOutput())) { + recipesToRemove.add(recipe.getRegistryName()); + } + } + if (recipesToRemove.isEmpty()) { + if (log) { + GroovyLog.msg("Error removing Pyrotech Worktable recipe") + .add("No recipes found for {}", output) + .error() + .post(); + } + return; + } + for (ResourceLocation rl : recipesToRemove) { + ReloadableRegistryManager.removeRegistryEntry(ForgeRegistries.RECIPES, rl); + } + } + + @MethodDescription + public void removeByInput(IIngredient input) { + removeByInput(input, true); + } + + @GroovyBlacklist + public void removeByInput(IIngredient input, boolean log) { + if (IngredientHelper.isEmpty(input)) { + if (log) { + GroovyLog.msg("Error removing Pyrotech Worktable recipe") + .add("Input must not be empty") + .error() + .post(); + } + return; + } + List recipesToRemove = new ArrayList<>(); + for (IRecipe recipe : ForgeRegistries.RECIPES) { + if (recipe.getRegistryName() != null && !recipe.getIngredients().isEmpty() && recipe.getIngredients().stream().anyMatch(i -> i.getMatchingStacks().length > 0 && input.test(i.getMatchingStacks()[0]))) { + recipesToRemove.add(recipe.getRegistryName()); + } + } + if (recipesToRemove.isEmpty()) { + if (log) { + GroovyLog.msg("Error removing Pyrotech Worktable recipe") + .add("No recipes found for {}", input) + .error() + .post(); + } + return; + } + for (ResourceLocation location : recipesToRemove) { + ReloadableRegistryManager.removeRegistryEntry(ForgeRegistries.RECIPES, location); + } + } + + @RecipeBuilderDescription(example = { + @Example(".name('irons_to_dirts').output(item('minecraft:dirt') * 8).shape([[item('minecraft:iron_ingot'),item('minecraft:iron_ingot'),item('minecraft:iron_ingot')],[item('minecraft:iron_ingot'),null,item('minecraft:iron_ingot')],[item('minecraft:iron_ingot'),item('minecraft:iron_ingot'),item('minecraft:iron_ingot')]]).replaceByName()"), + @Example(".name(resource('minecraft:sea_lantern')).output(item('minecraft:clay')).shape([[ore('blockRedstone')],[ore('blockRedstone')],[ore('blockRedstone')]]).replaceByName()"), + @Example(".output(item('minecraft:nether_star')).row('TXT').row('X X').row('!X!').key('T', item('minecraft:gravel')).key('X', item('minecraft:clay').reuse()).key('!', item('minecraft:gunpowder').transform({ _ -> item('minecraft:diamond') })).tool(item('minecraft:diamond_sword'), 5)"), + @Example(".output(item('minecraft:clay_ball') * 3).shape('S S', ' G ', 'SWS').key([S: ore('ingotIron').reuse(), G: ore('gemDiamond'), W: fluid('water') * 1000]).tool(item('minecraft:diamond_axe'), 3)"), + @Example(".name('gold_duplication_with_tnt').output(item('minecraft:gold_block')).row('!!!').row('!S!').row('!!!').key([S: ore('blockGold').reuse(), '!': item('minecraft:tnt').transform(item('minecraft:diamond'))]).tool(item('minecraft:iron_shovel'), 2)"), + @Example(".output(item('minecraft:clay')).row(' B').key('B', item('minecraft:glass_bottle')).tool(item('minecraft:stone_sword'), 3)"), + @Example(".output(item('minecraft:clay')).row(' 1 ').row(' 0 ').row(' 1 ').key('1', item('minecraft:iron_sword')).key('0', item('minecraft:diamond_sword').withNbt([display:[Name:'Sword with Specific NBT data']])).tool(item('minecraft:iron_axe'), 4)"), + }) + public Shaped shapedBuilder() { + return new Shaped(); + } + + @RecipeBuilderDescription(example = { + @Example(".output(item('minecraft:string')).input([item('minecraft:cobblestone'),item('minecraft:feather'),item('minecraft:gold_ingot')])"), + @Example(".name('precious_to_clay').output(item('minecraft:clay')).input([item('minecraft:emerald'),item('minecraft:iron_ore'),item('minecraft:gold_ingot')])"), + @Example(".name(resource('example:resource_location2')).output(item('minecraft:stone')).input([item('minecraft:gold_ore'), item('minecraft:gold_ingot')])"), + @Example(".output(item('minecraft:ender_eye')).input([item('minecraft:ender_pearl'),item('minecraft:bowl')]).replace().tool(item('minecraft:iron_sword'), 4)"), + @Example(".name('minecraft:pink_dye_from_pink_tulp').output(item('minecraft:clay')).input([item('minecraft:stick')]).replaceByName().tool(item('minecraft:iron_pickaxe'), 2)"), + @Example(".name(resource('minecraft:pink_dye_from_peony')).output(item('minecraft:coal')).input([item('minecraft:stone'), item('minecraft:iron_ingot')]).replaceByName().tool(item('minecraft:stone_axe'), 2)"), + }) + public Shapeless shapelessBuilder() { + return new Shapeless(); + } + + @Property(property = "mirrored") + @Property(property = "recipeFunction") + @Property(property = "recipeAction") + @Property(property = "name") + @Property(property = "replace") + public static class Shaped extends AbstractCraftingRecipeBuilder.AbstractShaped { + + @Property(comp = @Comp(not = "null")) + private IIngredient tool = IIngredient.EMPTY; + @Property(comp = @Comp(gte = 0)) + private int damage; + + public Shaped() { + super(3, 3); + } + + public Shaped tool(IIngredient tool, int damage) { + this.tool = tool; + this.damage = damage; + return this; + } + + @Override + protected void handleReplace() { + if (replace == 1) { + ModSupport.PYROTECH.get().worktable.removeByOutput(IngredientHelper.toIIngredient(output), false); + } else if (replace == 2) { + if (name == null) { + GroovyLog.msg("Error replacing Pyrotech Worktable recipe") + .add("Name must not be null when replacing by name") + .error() + .post(); + return; + } + ReloadableRegistryManager.removeRegistryEntry(ModSupport.PYROTECH.get().worktable.getRegistry(), name); + } + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_worktable_shaped"; + } + + @RecipeBuilderRegistrationMethod + @Override + public WorktableRecipe register() { + validateName(); + GroovyLog.Msg msg = GroovyLog.msg("Error adding Pyrotech Worktable Shaped recipe '{}'", this.name) + .error() + .add((keyBasedMatrix == null || keyBasedMatrix.length == 0) && (ingredientMatrix == null || ingredientMatrix.isEmpty()), () -> "No matrix was defined") + .add(keyBasedMatrix != null && ingredientMatrix != null, () -> "A key based matrix AND a ingredient based matrix was defined. This is not allowed!") + .add(IngredientHelper.isEmpty(this.output), () -> "Output must not be empty") + .add(tool == null, "Tool must not be null") + .add(damage < 0, "Damage must not be a negative integer, yet it was {}", damage); + if (msg.postIfNotEmpty()) return null; + + ShapedCraftingRecipe recipe = null; + if (keyBasedMatrix != null) { + recipe = validateShape(msg, errors, keyBasedMatrix, keyMap, ((width1, height1, ingredients) -> new ShapedCraftingRecipe(output, ingredients, width1, height1, mirrored, recipeFunction, recipeAction))); + } else if (ingredientMatrix != null) { + recipe = validateShape(msg, ingredientMatrix, ((width1, height1, ingredients) -> new ShapedCraftingRecipe(output.copy(), ingredients, width1, height1, mirrored, recipeFunction, recipeAction))); + } + + if (recipe != null) { + handleReplace(); + WorktableRecipe rec = ModSupport.PYROTECH.get().worktable.getRegistry().getValue(this.name); + msg.add(rec != null && rec.getRecipe().canFit(1000, 1000), () -> "a recipe with that name already exists! Either replace or remove the recipe first"); + if (msg.postIfNotEmpty()) return null; + WorktableRecipe worktableRecipe = new WorktableRecipe(recipe, tool == IIngredient.EMPTY ? null : tool.toMcIngredient(), damage, null).setRegistryName(name); + ModSupport.PYROTECH.get().worktable.add(worktableRecipe); + return worktableRecipe; + } + + return null; + } + } + + @Property(property = "recipeFunction") + @Property(property = "recipeAction") + @Property(property = "name") + @Property(property = "replace") + public static class Shapeless extends AbstractCraftingRecipeBuilder.AbstractShapeless { + + @Property + private IIngredient tool = IIngredient.EMPTY; + @Property(comp = @Comp(gte = 0)) + private int damage; + + public Shapeless() { + super(3, 3); + } + + public Shapeless tool(IIngredient tool, int damage) { + this.tool = tool; + this.damage = damage; + return this; + } + + @Override + protected void handleReplace() { + if (replace == 1) { + ModSupport.PYROTECH.get().worktable.removeByOutput(IngredientHelper.toIIngredient(output), false); + } else if (replace == 2) { + if (name == null) { + GroovyLog.msg("Error replacing Pyrotech Worktable recipe") + .add("Name must not be null when replacing by name") + .error() + .post(); + return; + } + ReloadableRegistryManager.removeRegistryEntry(ModSupport.PYROTECH.get().worktable.getRegistry(), name); + } + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_worktable_shapeless_"; + } + + @RecipeBuilderRegistrationMethod + @Override + public WorktableRecipe register() { + validateName(); + IngredientHelper.trim(ingredients); + GroovyLog.Msg msg = GroovyLog.msg("Error adding Pyrotech Worktable Shapeless recipe '{}'", this.name); + if (msg.add(IngredientHelper.isEmpty(this.output), () -> "Output must not be empty") + .add(ingredients.isEmpty(), () -> "inputs must not be empty") + .add(ingredients.size() > width * height, () -> "maximum inputs are " + (width * height) + " but found " + ingredients.size()) + .add(tool == null, "Tool must not be null") + .add(damage < 0, "Damage must not be a negative integer, yet it was {}", damage) + .error() + .postIfNotEmpty()) { + return null; + } + handleReplace(); + WorktableRecipe rec = ModSupport.PYROTECH.get().worktable.getRegistry().getValue(this.name); + msg.add(rec != null && rec.getRecipe().canFit(1000, 1000), () -> "a recipe with that name already exists! Either replace or remove the recipe first"); + if (msg.postIfNotEmpty()) return null; + ShapelessCraftingRecipe recipe = new ShapelessCraftingRecipe(output.copy(), ingredients, recipeFunction, recipeAction); + rec = new WorktableRecipe(recipe, tool == IIngredient.EMPTY ? null : tool.toMcIngredient(), damage, null); + ReloadableRegistryManager.addRegistryEntry(ModSupport.PYROTECH.get().worktable.getRegistry(), name, rec); + return rec; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/BloomeryRecipeBaseAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/BloomeryRecipeBaseAccessor.java new file mode 100644 index 000000000..5b42b9dcc --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/BloomeryRecipeBaseAccessor.java @@ -0,0 +1,16 @@ +package com.cleanroommc.groovyscript.core.mixin.pyrotech; + +import com.codetaylor.mc.pyrotech.modules.tech.bloomery.recipe.BloomeryRecipeBase; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(value = BloomeryRecipeBase.class, remap = false) +public interface BloomeryRecipeBaseAccessor { + + @Accessor("outputBloom") + ItemStack grs$getOutputBloom(); + + @Accessor("outputBloom") + void grs$setOutputBloom(ItemStack bloom); +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/JEIRecipeWrapperPitBurnMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/JEIRecipeWrapperPitBurnMixin.java new file mode 100644 index 000000000..a0d02829b --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/JEIRecipeWrapperPitBurnMixin.java @@ -0,0 +1,28 @@ +package com.cleanroommc.groovyscript.core.mixin.pyrotech; + +import com.codetaylor.mc.pyrotech.library.spi.plugin.jei.JEIRecipeWrapperTimed; +import com.codetaylor.mc.pyrotech.library.spi.recipe.IRecipeTimed; +import com.codetaylor.mc.pyrotech.modules.tech.refractory.plugin.jei.wrapper.JEIRecipeWrapperPitBurn; +import net.minecraft.block.Block; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(value = JEIRecipeWrapperPitBurn.class, remap = false) +public abstract class JEIRecipeWrapperPitBurnMixin extends JEIRecipeWrapperTimed { + + public JEIRecipeWrapperPitBurnMixin(IRecipeTimed recipe) { + super(recipe); + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getItemFromBlock(Lnet/minecraft/block/Block;)Lnet/minecraft/item/Item;"), remap = false) + private Item getBlockItemProperly(Block blockIn) { + Item item = Item.getItemFromBlock(blockIn); + if (item == Items.AIR) item = ForgeRegistries.ITEMS.getValue(blockIn.getRegistryName()); + if (item == null) item = Items.AIR; + return item; + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/JEIRecipeWrapperRefractoryBurnMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/JEIRecipeWrapperRefractoryBurnMixin.java new file mode 100644 index 000000000..4c0458bf0 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pyrotech/JEIRecipeWrapperRefractoryBurnMixin.java @@ -0,0 +1,28 @@ +package com.cleanroommc.groovyscript.core.mixin.pyrotech; + +import com.codetaylor.mc.pyrotech.library.spi.plugin.jei.JEIRecipeWrapperTimed; +import com.codetaylor.mc.pyrotech.library.spi.recipe.IRecipeTimed; +import com.codetaylor.mc.pyrotech.modules.tech.refractory.plugin.jei.wrapper.JEIRecipeWrapperRefractoryBurn; +import net.minecraft.block.Block; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(value = JEIRecipeWrapperRefractoryBurn.class, remap = false) +public abstract class JEIRecipeWrapperRefractoryBurnMixin extends JEIRecipeWrapperTimed { + + public JEIRecipeWrapperRefractoryBurnMixin(IRecipeTimed recipe) { + super(recipe); + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getItemFromBlock(Lnet/minecraft/block/Block;)Lnet/minecraft/item/Item;"), remap = false) + private Item getBlockItemProperly(Block blockIn) { + Item item = Item.getItemFromBlock(blockIn); + if (item == Items.AIR) item = ForgeRegistries.ITEMS.getValue(blockIn.getRegistryName()); + if (item == null) item = Items.AIR; + return item; + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/registry/ForgeRegistryWrapper.java b/src/main/java/com/cleanroommc/groovyscript/registry/ForgeRegistryWrapper.java index 3fa6b1def..6f7d8d9f7 100644 --- a/src/main/java/com/cleanroommc/groovyscript/registry/ForgeRegistryWrapper.java +++ b/src/main/java/com/cleanroommc/groovyscript/registry/ForgeRegistryWrapper.java @@ -35,7 +35,7 @@ public ForgeRegistryWrapper(IForgeRegistry registry) { public ForgeRegistryWrapper(IForgeRegistry registry, Collection aliases) { super(aliases); - this.registry = Objects.requireNonNull(registry); + this.registry = isEnabled() ? Objects.requireNonNull(registry) : null; } @GroovyBlacklist diff --git a/src/main/resources/assets/groovyscript/lang/en_us.lang b/src/main/resources/assets/groovyscript/lang/en_us.lang index 2e361f80e..c0b2ce90e 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -2114,10 +2114,12 @@ groovyscript.wiki.prodigytech.zorra_altar.removeEnchantment=Removes an enchantme # Pyrotech groovyscript.wiki.pyrotech.anvil.title=Anvil -groovyscript.wiki.pyrotech.anvil.description=When using hammer or pickaxe it can convert items -groovyscript.wiki.pyrotech.anvil.hits.value=Sets how often the item needs to be hit +groovyscript.wiki.pyrotech.anvil.description=Converts an item to a new item by hitting it with a hammer or pickaxe +groovyscript.wiki.pyrotech.anvil.hits.value=Sets how many times the item needs to be hit groovyscript.wiki.pyrotech.anvil.tier.value=Sets the tier of the required anvil (Granite, Ironclad, Obsidian) groovyscript.wiki.pyrotech.anvil.type.value=Sets the type of tool required (Hammer, Pickaxe) +groovyscript.wiki.pyrotech.anvil.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.anvil.add.inherit=Adds recipes in the format `name`, `input`, `output`, `hits`, `tier`, `type`, `inherit` groovyscript.wiki.pyrotech.anvil.add=Adds recipes in the format `name`, `input`, `output`, `hits`, `tier`, `type` groovyscript.wiki.pyrotech.barrel.title=Barrel @@ -2125,31 +2127,72 @@ groovyscript.wiki.pyrotech.barrel.description=Over time converts a fluid with fo groovyscript.wiki.pyrotech.barrel.duration.value=Sets the time required for the recipe to complete groovyscript.wiki.pyrotech.barrel.add=Adds recipes in the format `name`, `input1`, `input2`, `input3`, `input4`, `fluidInput`, `fluidOutput`, `duration` +groovyscript.wiki.pyrotech.bloomery.title=Bloomery +groovyscript.wiki.pyrotech.bloomery.description=Converts item to a new item or a 'bloom' which are items that needs to be hit with hammer on anvil to get the output with varying amounts +groovyscript.wiki.pyrotech.bloomery.add0.inherit=Adds recipes in the format `name`, `output`, `input`, `inherit` +groovyscript.wiki.pyrotech.bloomery.add0=Adds recipes in the format `name`, `output`, `input` +groovyscript.wiki.pyrotech.bloomery.add1.inherit=Adds recipes in the format `name`, `output`, `input`, `burnTime`, `inherit` +groovyscript.wiki.pyrotech.bloomery.add1=Adds recipes in the format `name`, `output`, `input`, `burnTime` +groovyscript.wiki.pyrotech.bloomery.addBloom0.inherit=Adds recipes in the format `name`, `bloomOutput`, `input`, `inherit` +groovyscript.wiki.pyrotech.bloomery.addBloom0=Adds recipes in the format `name`, `bloomOutput`, `input` +groovyscript.wiki.pyrotech.bloomery.slag.value=Sets the slag item +groovyscript.wiki.pyrotech.bloomery.bloom.value=Sets the actual output (bloom) of the Bloomery. Setting langKey, anvil values, experience, bloom yields and failure values are unnecessary if this is set +groovyscript.wiki.pyrotech.bloomery.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.bloomery.langKey.value=Sets the localization key of output if the output is a bloom. If it's null, the bloom will use lang key of the input. +groovyscript.wiki.pyrotech.bloomery.anvilHit.value=Sets how often the bloom needs to be hit on the anvil +groovyscript.wiki.pyrotech.bloomery.burnTime.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.bloomery.anvilType.value=Sets the tool that needs to be used for hitting the bloom +groovyscript.wiki.pyrotech.bloomery.anvilTiers.value=Sets the tiers anvil can be for bloom to allow you to put on the anvil +groovyscript.wiki.pyrotech.bloomery.experience.value=Sets the experience given from bloom after the anvil recipe +groovyscript.wiki.pyrotech.bloomery.bloomYieldMin.value=Sets minimum amount of drops the bloom can give +groovyscript.wiki.pyrotech.bloomery.bloomYieldMax.value=Sets maximum amount of drops the bloom can give +groovyscript.wiki.pyrotech.bloomery.failureChance.value=Sets the chance for bloom to give failure item instead of the actual output +groovyscript.wiki.pyrotech.bloomery.failureOutput.value=Sets the output to drop on failure + +groovyscript.wiki.pyrotech.brick_crucible.title=Refractory Crucible +groovyscript.wiki.pyrotech.brick_crucible.description=Converts item into a liquid +groovyscript.wiki.pyrotech.brick_crucible.burnTime.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.brick_crucible.add=Adds recipes in the format `name`, `input`, `fluidOutput`, `burnTime` +groovyscript.wiki.pyrotech.brick_crucible.note0=Can inherit recipes from [Stone Crucible](./stone_crucible.md) + groovyscript.wiki.pyrotech.brick_kiln.title=Refractory Kiln -groovyscript.wiki.pyrotech.brick_kiln.description=Converts an item into a new one by burning it. Has a chance to fail +groovyscript.wiki.pyrotech.brick_kiln.description=Converts an item into a new item or one of the failure outputs if the recipe fails groovyscript.wiki.pyrotech.brick_kiln.burnTime.value=Sets the time required for the recipe to complete -groovyscript.wiki.pyrotech.brick_kiln.failureChance.value=Sets the chance to fail the recipe -groovyscript.wiki.pyrotech.brick_kiln.failureOutput.value=Sets the output when the recipe failed +groovyscript.wiki.pyrotech.brick_kiln.failureChance.value=Sets the chance for recipe to fail +groovyscript.wiki.pyrotech.brick_kiln.failureOutput.value=Sets the list of items that can be outputted if the recipe fails groovyscript.wiki.pyrotech.brick_kiln.add=Adds recipes in the format `name`, `input`, `output`, `burnTime`, `failureChance`, `failureOutput` +groovyscript.wiki.pyrotech.brick_kiln.note0=Can inherit recipes from [Pit Kiln](./pit_kiln.md) and [Stone Kiln](./stone_kiln.md) groovyscript.wiki.pyrotech.brick_oven.title=Refractory Oven -groovyscript.wiki.pyrotech.brick_oven.description=When powered by burning fuel can convert items +groovyscript.wiki.pyrotech.brick_oven.description=Converts item into a new item groovyscript.wiki.pyrotech.brick_oven.duration.value=Sets the time required for the recipe to complete groovyscript.wiki.pyrotech.brick_oven.add=Adds recipes in the format `name`, `input`, `output`, `duration` +groovyscript.wiki.pyrotech.brick_oven.note0=Can inherit recipes from [Crude Drying Rack](./crude_drying_rack.md), [Drying Rack](./drying_rack.md) and [Stone Oven](./stone_oven.md) + +groovyscript.wiki.pyrotech.brick_sawmill.title=Refractory Sawmill +groovyscript.wiki.pyrotech.brick_sawmill.description=Converts an item into a new item with an item with durability and drops wood chips on given amount of time +groovyscript.wiki.pyrotech.brick_sawmill.input.value=Sets the input required for the recipe. Second input value is an optional value for setting saw blade. +groovyscript.wiki.pyrotech.brick_sawmill.duration.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.brick_sawmill.wood_chips.value=Sets the amount of wood chip to drop. +groovyscript.wiki.pyrotech.brick_sawmill.add=Adds recipes in the format `name`, `input`, `(optional) blade`, `output`, `duration`, `woodChips` +groovyscript.wiki.pyrotech.brick_sawmill.note0=Can inherit recipes from [Chopping Block](./chopping_block.md) and [Stone Sawmill](./stone_sawmill.md) groovyscript.wiki.pyrotech.campfire.title=Campfire -groovyscript.wiki.pyrotech.campfire.description=When powered by burning logs can convert items +groovyscript.wiki.pyrotech.campfire.description=Converts item into a new item on given amount of time groovyscript.wiki.pyrotech.campfire.duration.value=Sets the time required for the recipe to complete groovyscript.wiki.pyrotech.campfire.add=Adds recipes in the format `name`, `input`, `output`, `duration` groovyscript.wiki.pyrotech.chopping_block.title=Chopping Block groovyscript.wiki.pyrotech.chopping_block.description=When using a axe it can convert items groovyscript.wiki.pyrotech.chopping_block.chops.value=Sets how often the item needs to be hit with output amount. Call it 4 times for 4 different tiers (Crude, Stone, Iron, Diamond) +groovyscript.wiki.pyrotech.chopping_block.inherit.value=Sets if the recipe should be inherited by more advanced machines groovyscript.wiki.pyrotech.chopping_block.quantities.value=Sets the amount of items output for a given tier. Call it 4 times for 4 different tiers (Crude, Stone, Iron, Diamond) groovyscript.wiki.pyrotech.compacting_bin.title=Compacting Bin groovyscript.wiki.pyrotech.compacting_bin.description=When using a shovel it can convert items -groovyscript.wiki.pyrotech.compacting_bin.toolUses.value=Sets how often the item needs to be hit +groovyscript.wiki.pyrotech.compacting_bin.hits.value=Sets how often the item needs to be hit +groovyscript.wiki.pyrotech.compacting_bin.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.compacting_bin.add.inherit=Adds recipes in the format `name`, `input`, `output`, `inherit`, `hits` groovyscript.wiki.pyrotech.compacting_bin.add=Adds recipes in the format `name`, `input`, `output`, `hits` groovyscript.wiki.pyrotech.compost_bin.title=Compost Bin @@ -2160,36 +2203,87 @@ groovyscript.wiki.pyrotech.compost_bin.add=Adds recipes in the format `name`, `i groovyscript.wiki.pyrotech.crude_drying_rack.title=Crude Drying Rack groovyscript.wiki.pyrotech.crude_drying_rack.description=Converts an item over time into a new one groovyscript.wiki.pyrotech.crude_drying_rack.dryTime.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.crude_drying_rack.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.crude_drying_rack.add.inherit=Adds recipes in the format `name`, `input`, `output`, `dryTime`, `inherit` groovyscript.wiki.pyrotech.crude_drying_rack.add=Adds recipes in the format `name`, `input`, `output`, `dryTime` groovyscript.wiki.pyrotech.drying_rack.title=Drying Rack groovyscript.wiki.pyrotech.drying_rack.description=Converts an item over time into a new one groovyscript.wiki.pyrotech.drying_rack.dryTime.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.drying_rack.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.drying_rack.add.inherit=Adds recipes in the format `name`, `input`, `output`, `dryTime`, `inherit` groovyscript.wiki.pyrotech.drying_rack.add=Adds recipes in the format `name`, `input`, `output`, `dryTime` +groovyscript.wiki.pyrotech.drying_rack.note0=Can inherit recipes from [Crude Drying Rack](./crude_drying_rack.md) + +groovyscript.wiki.pyrotech.mechanical_compacting_bin.title=Mechanical Compacting Bin +groovyscript.wiki.pyrotech.mechanical_compacting_bin.description=Converts given amount of item into new item. +groovyscript.wiki.pyrotech.mechanical_compacting_bin.hits.value=Sets how often the item needs to be hit +groovyscript.wiki.pyrotech.mechanical_compacting_bin.add=Adds recipes in the format `name`, `input`, `output`, `hits` +groovyscript.wiki.pyrotech.mechanical_compacting_bin.note0=Can inherit recipes from [Compacting Bin](./compacting_bin.md) + +groovyscript.wiki.pyrotech.pit_burn.title=Pit Burning +groovyscript.wiki.pyrotech.pit_burn.description=Converts a block in world to an item and fluid by burning +groovyscript.wiki.pyrotech.pit_burn.name.value=The recipe registry name +groovyscript.wiki.pyrotech.pit_burn.input.value=Sets the block input +groovyscript.wiki.pyrotech.pit_burn.output.value=Sets the itemstack output +groovyscript.wiki.pyrotech.pit_burn.burnTime.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.pit_burn.burnStages.value=Sets the output amount. Fluid output gets multiplied by it too +groovyscript.wiki.pyrotech.pit_burn.failureChance.value=Sets the chance to fail the recipe +groovyscript.wiki.pyrotech.pit_burn.failureOutput.value=Sets the output when the recipe failed +groovyscript.wiki.pyrotech.pit_burn.requiresRefractoryBlocks.value=Sets the need to use refractory blocks in the recipe +groovyscript.wiki.pyrotech.pit_burn.fluidLevelAffectsFailureChance.value=Sets if fluid level affects failure chance groovyscript.wiki.pyrotech.pit_kiln.title=Pit Kiln groovyscript.wiki.pyrotech.pit_kiln.description=Converts an item into a new one by burning it. Has a chance to fail groovyscript.wiki.pyrotech.pit_kiln.burnTime.value=Sets the time required for the recipe to complete groovyscript.wiki.pyrotech.pit_kiln.failureChance.value=Sets the chance to fail the recipe groovyscript.wiki.pyrotech.pit_kiln.failureOutput.value=Sets the output when the recipe failed +groovyscript.wiki.pyrotech.pit_kiln.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.pit_kiln.add.inherit=Adds recipes in the format `name`, `input`, `output`, `burnTime`, `inherit`, `failureChance`, `failureOutput` groovyscript.wiki.pyrotech.pit_kiln.add=Adds recipes in the format `name`, `input`, `output`, `burnTime`, `failureChance`, `failureOutput` groovyscript.wiki.pyrotech.oven.note0=Stone and Refractory Oven includes some recipes from the Furnace Registry that can't be removed here, you have to use `furnace.add` or `furnace.remove` to manipulate those recipes directly +groovyscript.wiki.pyrotech.sawmill.note0=If sawmill blade is not set, it will add the recipe for all sawmill blades. Sawmill blade needs to be one in the sawmill blades config list. If the blade doesn't have a durability it will never break. + +groovyscript.wiki.pyrotech.stone_crucible.title=Stone Crucible +groovyscript.wiki.pyrotech.stone_crucible.description=Converts an item into a liquid +groovyscript.wiki.pyrotech.stone_crucible.burnTime.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.stone_crucible.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.stone_crucible.add.inherit=Adds recipes in the format `name`, `input`, `fluidOutput`, `burnTime`, `inherit` +groovyscript.wiki.pyrotech.stone_crucible.add=Adds recipes in the format `name`, `input`, `fluidOutput`, `burnTime` +groovyscript.wiki.pyrotech.stone_crucible.note0=Can inherit recipes from [Stone Crucible](./stone_crucible.md) + groovyscript.wiki.pyrotech.stone_kiln.title=Stone Kiln groovyscript.wiki.pyrotech.stone_kiln.description=Converts an item into a new one by burning it. Has a chance to fail groovyscript.wiki.pyrotech.stone_kiln.burnTime.value=Sets the time required for the recipe to complete groovyscript.wiki.pyrotech.stone_kiln.failureChance.value=Sets the chance to fail the recipe groovyscript.wiki.pyrotech.stone_kiln.failureOutput.value=Sets the output when the recipe failed +groovyscript.wiki.pyrotech.stone_kiln.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.stone_kiln.add.inherit=Adds recipes in the format `name`, `input`, `output`, `burnTime`, `inherit`, `failureChance`, `failureOutput` groovyscript.wiki.pyrotech.stone_kiln.add=Adds recipes in the format `name`, `input`, `output`, `burnTime`, `failureChance`, `failureOutput` +groovyscript.wiki.pyrotech.stone_kiln.note0=Can inherit recipes from [Pit Kiln](./pit_kiln.md) groovyscript.wiki.pyrotech.stone_oven.title=Stone Oven groovyscript.wiki.pyrotech.stone_oven.description=When powered by burning fuel can convert items groovyscript.wiki.pyrotech.stone_oven.duration.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.stone_oven.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.stone_oven.add.inherit=Adds recipes in the format `name`, `input`, `output`, `duration`, `inherit` groovyscript.wiki.pyrotech.stone_oven.add=Adds recipes in the format `name`, `input`, `output`, `duration` +groovyscript.wiki.pyrotech.stone_oven.note0=Can inherit recipes from [Crude Drying Rack](./crude_drying_rack.md) and [Drying Rack](./drying_rack.md) + +groovyscript.wiki.pyrotech.stone_sawmill.title=Stone Sawmill +groovyscript.wiki.pyrotech.stone_sawmill.description=Converts an item into a new item with an item with durability and drops wood chips on given amount of time +groovyscript.wiki.pyrotech.stone_sawmill.input.value=Sets the input required for the recipe. Second input value is an optional value for setting sawmill blade +groovyscript.wiki.pyrotech.stone_sawmill.duration.value=Sets the time required for the recipe to complete +groovyscript.wiki.pyrotech.stone_sawmill.wood_chips.value=Sets the wood chip amount that will drop +groovyscript.wiki.pyrotech.stone_sawmill.inherit.value=Sets if the recipe should be inherited by more advanced machines +groovyscript.wiki.pyrotech.stone_sawmill.add.inherit=Adds recipes in the format `name`, `input`, `(optional) blade`, `output`, `duration`, `woodChips`, `inherit` +groovyscript.wiki.pyrotech.stone_sawmill.add=Adds recipes in the format `name`, `input`, `(optional) blade`, `output`, `duration`, `woodChips` +groovyscript.wiki.pyrotech.stone_sawmill.note0=Can inherit recipes from [Chopping Block](./chopping_block.md) groovyscript.wiki.pyrotech.soaking_pot.title=Soaking Pot -groovyscript.wiki.pyrotech.soaking_pot.description=Converts an item into a new one by soaking it in a liquid. Can require a campfire +groovyscript.wiki.pyrotech.soaking_pot.description=Converts an item and liquid into a new item. Can require a campfire below groovyscript.wiki.pyrotech.soaking_pot.time.value=Sets the time required for the recipe to complete groovyscript.wiki.pyrotech.soaking_pot.campfireRequired.value=Sets if a campfire is required underneath groovyscript.wiki.pyrotech.soaking_pot.add=Adds recipes in the format `name`, `input`, `output`, `time` @@ -2200,6 +2294,17 @@ groovyscript.wiki.pyrotech.tanning_rack.dryTime.value=Sets the time required for groovyscript.wiki.pyrotech.tanning_rack.failureItem.value=Sets the output when the recipe failed groovyscript.wiki.pyrotech.tanning_rack.add=Adds recipes in the format `name`, `input`, `output`, `dryTime`, `failureItem` +groovyscript.wiki.pyrotech.wither_forge.title=Wither Forge +groovyscript.wiki.pyrotech.wither_forge.description=Converts item to a new item or a 'bloom' which are items that needs to be hit with hammer on anvil to get the output with varying amounts +groovyscript.wiki.pyrotech.wither_forge.add0=Adds recipes in the format `name`, `output`, `input` +groovyscript.wiki.pyrotech.wither_forge.add1=Adds recipes in the format `name`, `output`, `input`, `burnTime` +groovyscript.wiki.pyrotech.wither_forge.addBloom0=Adds recipes in the format `name`, `bloomOutput`, `input` +groovyscript.wiki.pyrotech.wither_forge.addBloom1=Adds recipes in the format `name`, `bloomOutput`, `minYield`, `maxYield`, `input`, `burnTime`, `experience`, `failureChance`, `failureItems` + +groovyscript.wiki.pyrotech.worktable.title=Worktable +groovyscript.wiki.pyrotech.worktable.description=Crafting table which asks you to hit it with a tool to craft stuff +groovyscript.wiki.pyrotech.worktable.tool.value=Sets the tool that will be used +groovyscript.wiki.pyrotech.worktable.damage.value=Sets the damage to put into that tool # PneumaticCraft groovyscript.wiki.pneumaticcraft.amadron.title=Amadron diff --git a/src/main/resources/mixin.groovyscript.pyrotech.json b/src/main/resources/mixin.groovyscript.pyrotech.json index 73baf6c06..ba3e1f318 100644 --- a/src/main/resources/mixin.groovyscript.pyrotech.json +++ b/src/main/resources/mixin.groovyscript.pyrotech.json @@ -5,6 +5,9 @@ "minVersion": "0.8", "compatibilityLevel": "JAVA_8", "mixins": [ + "BloomeryRecipeBaseAccessor", + "JEIRecipeWrapperPitBurnMixin", + "JEIRecipeWrapperRefractoryBurnMixin", "RegistryInitializerMixin" ] } \ No newline at end of file