164 lines
5.2 KiB
Go
164 lines
5.2 KiB
Go
|
|
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
|
||
|
|
}
|