26ed99fda6
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
117 lines
3.5 KiB
Go
117 lines
3.5 KiB
Go
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
|
|
}
|