package recipe import ( "github.com/df-mc/dragonfly/server/item" "github.com/df-mc/dragonfly/server/world" ) // Recipe is implemented by all recipe types. type Recipe interface { // Input returns the items required to craft the recipe. Input() []Item // Output returns the items that are produced when the recipe is crafted. Output() []item.Stack // Block returns the block that is used to craft the recipe. Block() string // Priority returns the priority of the recipe. Recipes with lower priority are preferred compared to recipes with // higher priority. Priority() uint32 } // DynamicRecipe represents a recipe whose output depends on the specific items used in crafting. // These recipes are not sent to the client and are validated server-side. type DynamicRecipe interface { // Match checks if the given input items match this dynamic recipe pattern. // It returns true if the pattern matches, along with the computed output items. Match(input []Item) (output []item.Stack, ok bool) // Block returns the block that is used to craft the recipe. Block() string } // Shapeless is a recipe that has no particular shape. type Shapeless struct { recipe } // NewShapeless creates a new shapeless recipe and returns it. The recipe can only be crafted on the block passed in the // parameters. If the block given a crafting table, the recipe can also be crafted in the 2x2 crafting grid in the // player's inventory. func NewShapeless(input []Item, output item.Stack, block string) Shapeless { return Shapeless{recipe: recipe{ input: input, output: []item.Stack{output}, block: block, }} } // SmithingTransform represents a recipe only craftable on a smithing table. type SmithingTransform struct { recipe } // NewSmithingTransform creates a new smithing recipe and returns it. func NewSmithingTransform(base, addition, template Item, output item.Stack, block string) SmithingTransform { return SmithingTransform{recipe: recipe{ input: []Item{base, addition, template}, output: []item.Stack{output}, block: block, }} } // SmithingTrim represents a recipe only craftable on a smithing table using an armour trim. type SmithingTrim struct { recipe } // NewSmithingTrim creates a new smithing trim recipe and returns it. This is // almost identical to SmithingTransform except there is no output item. func NewSmithingTrim(base, addition, template Item, block string) SmithingTrim { return SmithingTrim{recipe: recipe{ input: []Item{base, addition, template}, block: block, }} } // PotionContainerChange is a recipe to convert a potion from one type to another, such as from a drinkable potion to a // splash potion, or from a splash potion to a lingering potion. type PotionContainerChange struct { recipe } // NewPotionContainerChange creates a new potion container change recipe and returns it. func NewPotionContainerChange(input, output world.Item, reagent item.Stack) PotionContainerChange { return PotionContainerChange{recipe: recipe{ input: []Item{item.NewStack(input, 1), reagent}, output: []item.Stack{item.NewStack(output, 1)}, block: "brewing_stand", }} } // Potion is a potion mixing recipe which may be used in the brewing stand. type Potion struct { recipe } // NewPotion creates a new potion recipe and returns it. func NewPotion(input, reagent Item, output item.Stack) Potion { return Potion{recipe: recipe{ input: []Item{input, reagent}, output: []item.Stack{output}, block: "brewing_stand", }} } // Shaped is a recipe that has a specific shape that must be used to craft the output of the recipe. type Shaped struct { recipe // shape contains the width and height of the shaped recipe. shape Shape } // NewShaped creates a new shaped recipe and returns it. The recipe can only be crafted on the block passed in the // parameters. If the block given a crafting table, the recipe can also be crafted in the 2x2 crafting grid in the // player's inventory. If nil is passed, the block will be autofilled as a crafting table. The inputs must always match // the width*height of the shape. func NewShaped(input []Item, output item.Stack, shape Shape, block string) Shaped { return Shaped{ shape: shape, recipe: recipe{ input: input, output: []item.Stack{output}, block: block, }, } } // Shape returns the shape of the recipe. func (r Shaped) Shape() Shape { return r.shape } // recipe implements the Recipe interface. Structs in this package may embed it to gets its functionality // out of the box. type recipe struct { // input is a list of items that serve as the input of the shaped recipe. These items are the items // required to craft the output. The amount of input items must be exactly equal to Width * Height. input []Item // output contains items that are created as a result of crafting the recipe. output []item.Stack // block is the block that is used to craft the recipe. block string // priority is the priority of the recipe versus others. priority uint32 } // Input ... func (r recipe) Input() []Item { return r.input } // Output ... func (r recipe) Output() []item.Stack { return r.output } // Block ... func (r recipe) Block() string { return r.block } // Priority ... func (r recipe) Priority() uint32 { return r.priority }