up3
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled

This commit is contained in:
2026-07-09 08:33:57 +08:00
commit 26ed99fda6
845 changed files with 75419 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
package recipe
import (
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"math"
)
// Item represents an item that can be used as either the input or output of an item. These do not
// necessarily resolve to an actual item, but can be just as simple as a tag etc.
type Item interface {
// Count returns the amount of items that is present on the stack. The count is guaranteed never to be
// negative.
Count() int
// Empty checks if the stack is empty (has a count of 0).
Empty() bool
}
// inputItem is a type representing an input item, with a helper function to convert it to an Item.
type inputItem struct {
// Name is the name of the item being inputted.
Name string `nbt:"name"`
// Meta is the meta of the item. This can change the item almost completely, or act as durability.
Meta int32 `nbt:"meta"`
// Count is the amount of the item.
Count int32 `nbt:"count"`
// State is included if the output is a block. If it's not included, the meta can be discarded and the output item can be incorrect.
State struct {
Name string `nbt:"name"`
Properties map[string]interface{} `nbt:"states"`
Version int32 `nbt:"version"`
} `nbt:"block"`
// Tag is included if the input item is defined by a tag instead of a specific item.
Tag string `nbt:"tag"`
}
// Item converts an input item to a recipe item.
func (i inputItem) Item() (Item, bool) {
if i.Tag != "" {
return NewItemTag(i.Tag, int(i.Count)), true
}
it, ok := world.ItemByName(i.Name, int16(i.Meta))
if !ok {
return nil, false
}
st := item.NewStack(it, int(i.Count))
if i.Meta == math.MaxInt16 {
st = st.WithValue("variants", true)
}
return st, true
}
// inputItems is a type representing a list of input items, with a helper function to convert it to an Item.
type inputItems []inputItem
// Items converts input items to recipe items.
func (d inputItems) Items() ([]Item, bool) {
s := make([]Item, 0, len(d))
for _, i := range d {
itemInput, ok := i.Item()
if !ok {
return nil, false
}
s = append(s, itemInput)
}
return s, true
}
// outputItem is an output item.
type outputItem struct {
// Name is the name of the item being output.
Name string `nbt:"name"`
// Meta is the meta of the item. This can change the item almost completely, or act as durability.
Meta int32 `nbt:"meta"`
// Count is the amount of the item.
Count int16 `nbt:"count"`
// State is included if the output is a block. If it's not included, the meta can be discarded and the output item can be incorrect.
State struct {
Name string `nbt:"name"`
Properties map[string]interface{} `nbt:"states"`
Version int32 `nbt:"version"`
} `nbt:"block"`
// NBTData contains extra NBTData which may modify the item in other, more discreet ways.
NBTData map[string]interface{} `nbt:"data"`
}
// Stack converts an output item to an item stack.
func (o outputItem) Stack() (item.Stack, bool) {
it, ok := world.ItemByName(o.Name, int16(o.Meta))
if !ok {
return item.Stack{}, false
}
if n, ok := it.(world.NBTer); ok {
it = n.DecodeNBT(o.NBTData).(world.Item)
}
return item.NewStack(it, int(o.Count)), true
}
// outputItems is an array of output items.
type outputItems []outputItem
// Stacks converts output items to item stacks.
func (d outputItems) Stacks() ([]item.Stack, bool) {
s := make([]item.Stack, 0, len(d))
for _, o := range d {
itemOutput, ok := o.Stack()
if !ok {
return nil, false
}
s = append(s, itemOutput)
}
return s, true
}