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
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:
@@ -0,0 +1,132 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"github.com/df-mc/dragonfly/server/item/category"
|
||||
"github.com/sandertv/gophertunnel/minecraft/nbt"
|
||||
"image"
|
||||
)
|
||||
|
||||
// Item represents an item that may be added to an inventory. It has a method to encode the item to an ID and
|
||||
// a metadata value.
|
||||
type Item interface {
|
||||
// EncodeItem encodes the item to its Minecraft representation, which consists of a numerical ID and a
|
||||
// metadata value.
|
||||
EncodeItem() (name string, meta int16)
|
||||
}
|
||||
|
||||
// CustomItem represents an item that is non-vanilla and requires a resource pack and extra steps to show it
|
||||
// to the client.
|
||||
type CustomItem interface {
|
||||
Item
|
||||
// Name is the name that will be displayed on the item to all clients.
|
||||
Name() string
|
||||
// Texture is the Image of the texture for this item.
|
||||
Texture() image.Image
|
||||
// Category is the category the item will be listed under in the creative inventory.
|
||||
Category() category.Category
|
||||
}
|
||||
|
||||
// RegisterItem registers an item with the ID and meta passed. Once registered, items may be obtained from an
|
||||
// ID and metadata value using itemByID().
|
||||
// If an item with the ID and meta passed already exists, RegisterItem panics.
|
||||
func RegisterItem(item Item) {
|
||||
name, meta := item.EncodeItem()
|
||||
h := itemHash{name: name, meta: meta}
|
||||
|
||||
if _, ok := items[h]; ok {
|
||||
panic(fmt.Sprintf("item registered with name %v and meta %v already exists", name, meta))
|
||||
}
|
||||
if c, ok := item.(CustomItem); ok {
|
||||
nextRID := int32(len(itemNamesToRuntimeIDs))
|
||||
itemRuntimeIDsToNames[nextRID] = name
|
||||
itemNamesToRuntimeIDs[name] = nextRID
|
||||
|
||||
customItems = append(customItems, c)
|
||||
}
|
||||
if _, ok := itemNamesToRuntimeIDs[name]; !ok {
|
||||
panic(fmt.Sprintf("item name %v does not have a runtime ID", name))
|
||||
}
|
||||
items[h] = item
|
||||
}
|
||||
|
||||
// itemHash is a combination of an item's name and metadata. It is used as a key in hash maps.
|
||||
type itemHash struct {
|
||||
name string
|
||||
meta int16
|
||||
}
|
||||
|
||||
var (
|
||||
//go:embed vanilla_items.nbt
|
||||
itemRuntimeIDData []byte
|
||||
// items holds a list of all registered items, indexed using the itemHash created when calling
|
||||
// Item.EncodeItem.
|
||||
items = map[itemHash]Item{}
|
||||
// customItems holds a list of all registered custom items.
|
||||
customItems []CustomItem
|
||||
// itemRuntimeIDsToNames holds a map to translate item runtime IDs to string IDs.
|
||||
itemRuntimeIDsToNames = map[int32]string{}
|
||||
// itemNamesToRuntimeIDs holds a map to translate item string IDs to runtime IDs.
|
||||
itemNamesToRuntimeIDs = map[string]int32{}
|
||||
)
|
||||
|
||||
// init reads all item entries from the resource JSON, and sets the according values in the runtime ID maps.
|
||||
func init() {
|
||||
var m map[string]struct {
|
||||
RuntimeID int32 `nbt:"runtime_id"`
|
||||
ComponentBased bool `nbt:"component_based"`
|
||||
Version int32 `nbt:"version"`
|
||||
Data map[string]any `nbt:"data,omitempty"`
|
||||
}
|
||||
err := nbt.Unmarshal(itemRuntimeIDData, &m)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for name, e := range m {
|
||||
itemNamesToRuntimeIDs[name] = e.RuntimeID
|
||||
itemRuntimeIDsToNames[e.RuntimeID] = name
|
||||
}
|
||||
}
|
||||
|
||||
// ItemByName attempts to return an item by a name and a metadata value.
|
||||
func ItemByName(name string, meta int16) (Item, bool) {
|
||||
it, ok := items[itemHash{name: name, meta: meta}]
|
||||
if !ok {
|
||||
// Also try obtaining the item with a metadata value of 0, for cases with durability.
|
||||
it, ok = items[itemHash{name: name}]
|
||||
}
|
||||
return it, ok
|
||||
}
|
||||
|
||||
// ItemRuntimeID attempts to return the runtime ID of the Item passed. False is returned if the Item is not
|
||||
// registered.
|
||||
func ItemRuntimeID(i Item) (rid int32, meta int16, ok bool) {
|
||||
name, meta := i.EncodeItem()
|
||||
rid, ok = itemNamesToRuntimeIDs[name]
|
||||
return rid, meta, ok
|
||||
}
|
||||
|
||||
// ItemByRuntimeID attempts to return an Item by the runtime ID passed. If no item with that runtime ID exists,
|
||||
// false is returned. ItemByRuntimeID also tries to find the item with a metadata value of 0.
|
||||
func ItemByRuntimeID(rid int32, meta int16) (Item, bool) {
|
||||
name, ok := itemRuntimeIDsToNames[rid]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return ItemByName(name, meta)
|
||||
}
|
||||
|
||||
// Items returns a slice of all registered items.
|
||||
func Items() []Item {
|
||||
m := make([]Item, 0, len(items))
|
||||
for _, i := range items {
|
||||
m = append(m, i)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// CustomItems returns a slice of all registered custom items.
|
||||
func CustomItems() []CustomItem {
|
||||
return customItems
|
||||
}
|
||||
Reference in New Issue
Block a user