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
|
|||
|
|
}
|