76 lines
1.8 KiB
Go
76 lines
1.8 KiB
Go
// 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
|
||
}
|