Dynamic Recipe - Low-Drag-MC/Multiblocked GitHub Wiki
"Dynamic" means that the recipe is a recipe that has been modified or created from scratch based on the current properties of the multiple blocks, as well as other conditions.
- Make machines that can be upgraded and modify recipe conditions, like gt5u's large chemical reactor (to remove special conditions from recipes)
- Modify recipe inputs, outputs, duration(Overclocking) and conditions.
All modifications to the recipe are based on this Handler. There are usually two ways to get the Handler, either from an event or using reflection. Currently only SearchRecipeEvent and SetupRecipeEvent provide DynamicRecipeHandler, here are examples(In server script).
onEvent('mbd.setup_recipe.tester.updatable', event => {
let handler = event.getHandlerFromRecipe()//Handler with original recipe data
//do something
})
onEvent('mbd.search_recipe.tester.updatable', event => {
let handler = event.getHandler()//Handler without any data
//do something
})NOTE1: Normally, SetupRecipeEvent is used for operations such as overclocking, rather than modifying the recipe's input, as this will only run your modified recipe once the original recipe meets the conditions, but you can modify the recipe's output here.
NOTE2:
//Don't forget this line unless you want to modify the dynamic recipe!
//check if this is a dynamic recipe,
if (event.getRecipeLogic().dynamic) return
//handle recipeNOTE:Dynamic Recipe Handler has most of the functions that can be called when adding recipes to kubeJs. You can still add new inputs and conditions.
| Name | Parameters | Useage | Descrption |
|---|---|---|---|
| inputHandler | A map of recipe inputs | handler.inputHandler(map =>{//Modify this map}) | Used to manipulate the input to a recipe, use map.get("Capability Name") to get a Pair which has a MultiblockCapability object on the left and the corresponding type of input on the right.For example map.get("item").getRight() would get the input of the item type. |
| tickInputHandler | A map of recipe tick inputs | handler.tickInputHandler(map =>{//Modify this map}) | Similar to inputHandler, but used to modify per-tick input. |
| outputHandler | A map of recipe outputs | handler.outputHandler(map =>{//Modify this map}) | Similar to inputHandler, but for output modifications. |
| Name | Useage | Descrption |
|---|---|---|
| inputAdder(boolean perTick, String capability, double addition) | handler.inputAdder(false, "item", 10) | Increase the quantity requirement for the input of the type corresponding to the capability, and decrease it by setting the addition to a negative number. |
| inputAdder(boolean perTick, String capability, double addition, Predicate predicate) | handler.inputAdder(false, "item", 10, content =>{}) | Modifies the quantity when the predicate is established. |
| inputMultiplier(boolean perTick, String capability, double multiplier) | handler.inputMultiplier(false, "item", 2) | Similar to inputAdder, but multiplicative |
| inputMultiplier(boolean perTick, String capability, double multiplier, Predicate predicate) | - | - |
| outputAdder(boolean perTick, String capability, double addition) | handler.outputHandler(false, "item", 2) | - |
| outputAdder(boolean perTick, String capability, double addition, Predicate predicate) | - | - |
| outputMultiplier(boolean perTick, String capability, double multiplier) | - | - |
| outputMultiplier(boolean perTick, String capability, double addition, Predicate predicate) | - | - |
NOTE:Use MbdRegistry.getCapability(name) to get Capability
| Name | Useage | Descrption |
|---|---|---|
| removeTypedInputs(boolean perTick, MultiblockCapability<?> capability) | handler.removeTypedInputs(false,MbdRegistry.getCapability("item") | Used to delete certain types of input. |
| removeTypedInputs(boolean perTick, MultiblockCapability<?> capability, Predicate predicate) | handler.removeTypedInputs(false, MbdRegistry.getCapability('item'), content => {return content.chance < 1}) | Remove a specific type of input that matches the predicate. |
| removeTypedOutputs(boolean perTick, MultiblockCapability<?> capability) | handler.removeTypedOutputs(false,MbdRegistry.getCapability("item") | Remover for outputs |
| removeTypedOutputs(boolean perTick, MultiblockCapability<?> capability, Predicate predicate) | - | - |
| removeAllConditions | handler.removeAllConditions() | Remove all conditions from the recipe |
| removeTypeCondition(String type) | handler.remove("block") | Remove a certain type of condition |
| removeDimension(ResourceLocation dimension) | - | Remove a dimensional condition |
| removeBiome(ResourceLocation biome) | - | Remove a biome condition |
| removeRain(float level) | - | Remove a rain condition |
| removeThunder(float level) | - | Remove a thunder condition |
| removePosY(int min, int max) | - | Remove a posY condition |
| removeBlock(BlockState blockState, int count) | - | Remove a block condition |
| removeBlock(BlockState blockState) | - | Remove a block condition |
This example shows that if there is a netherite_block in the structure, then it change the output probability of all recipes by *2, decreases the recipe duration when there is a diamond_block, and adds gold ingots to the output when there is a gold_block.
onEvent('mbd.setup_recipe.tester.updatable', event => {
//Don't forget this line unless you want to modify the dynamic recipe!
//check if this is a dynamic recipe,
if (event.getRecipeLogic().dynamic) return
console.info("Ok,this a updatable multiblock machine. I'm going to change the recipe")
let componentData = event.getComponentData()
let goldAmount = componentData.get(Block.getBlock('minecraft:gold_block').defaultBlockState())
let diamondAmount = componentData.get(Block.getBlock('minecraft:diamond_block').defaultBlockState())
let netheriteAmount = componentData.get(Block.getBlock('minecraft:netherite_block').defaultBlockState())
let handler = event.getHandlerFromRecipe()
let duration = diamondAmount > 0 ? event.getRecipe().duration / (diamondAmount * 2) : event.getRecipe().duration;
if (netheriteAmount > 0) {
handler.outputHandler(map => {
let contents = map.get('item').getRight()
for (let i = 0; i < contents.size(); i++) {
var content = contents.get(i)
var nextChance = content.chance * 2
nextChance = nextChance > 1 ? 1 : nextChance
content.chance = nextChance
}
})
}
if (goldAmount > 0) {
handler.outputItems({'item': 'minecraft:gold_ingot', 'count': goldAmount * 2})
}
handler.duration(duration)
event.setRecipe(handler.apply())
})