Files
ngzz-mc/internal/item/item.go

76 lines
1.8 KiB
Go
Raw Normal View History

// Package item 物品注册表与物品栈(场景/物品与背包.md §2)。
package item
import (
"encoding/json"
"fmt"
"os"
)
// Def 物品定义(items.json 条目)。
type Def struct {
Name string `json:"-"`
Stack int `json:"stack"`
Texture string `json:"texture"`
Place string `json:"place"` // 可放置的方块 ID
Tool string `json:"tool"` // pickaxe / shovel / axe
Tier int `json:"tier"` // 工具等级门槛(挖矿与矿物.md §3)
Speed float64 `json:"speed"` // 挖掘速度倍率
Durability int `json:"durability"`
}
// Registry 物品注册表。
type Registry struct {
byName map[string]*Def
}
// Load 解析 items.json。
func Load(path string) (*Registry, error) {
b, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("item.Load %s: %w", path, err)
}
var doc struct {
Items map[string]Def `json:"items"`
}
if err := json.Unmarshal(b, &doc); err != nil {
return nil, fmt.Errorf("item.Load %s: %w", path, err)
}
r := &Registry{byName: make(map[string]*Def, len(doc.Items))}
for name, d := range doc.Items {
d.Name = name
if d.Stack <= 0 {
d.Stack = 64
}
cp := d
r.byName[name] = &cp
}
return r, nil
}
// Get 按名称取定义。
func (r *Registry) Get(name string) (*Def, bool) {
d, ok := r.byName[name]
return d, ok
}
// Stack 物品栈:空栈 = Name == "" 且 Count == 0(物品与背包.md §2:禁止 nil 栈)。
type Stack struct {
Name string
Count uint8
Durability int32
}
// Empty 是否空栈。
func (s Stack) Empty() bool { return s.Name == "" || s.Count == 0 }
// Limit 堆叠上限。
func (s Stack) Limit(reg *Registry) uint8 {
if d, ok := reg.Get(s.Name); ok {
if d.Stack > 0 && d.Stack < 255 {
return uint8(d.Stack)
}
}
return 64
}