- 音频(音频.md §2):Session.Sound 事件回调,破坏/放置/攻击/村民环境音接入, 客户端 audio.Manager 3D 衰减 + 监听器跟随 + 音量可调 - 原版掉落:草方块→泥土、石头→圆石、树叶无掉落(no_drop);掉落物实体 用物品图标小广告牌渲染(物品纹理并入实体图集) - 动物攻击(动物体系.md §5):左键优先射线命中实体(半径 0.6 球体判定), 伤害/击退/死亡移除+肉类掉落;僵尸掉腐肉 - 村庄村民(村民系统.md §2):Generator.VillageAt 定位村庄中心,会话扫描 已加载区块在村庄生成 3 名村民 - 种子与灵敏度配置:client.yaml world.seed/name、mouse_sensitivity; 存档与种子联动;鼠标左右反转修复(右移应右转) - 设置界面(UI与输入.md §6):屏幕状态 4,灵敏度/音量滑条、世界种子显示、 按键教程多行列表(cjkfont 支持 \\n)、完成按钮;主菜单/暂停菜单入口 - 准星指向方块名:左下角 CJK 显示(lang 本地化,tick 光栅化渲染线程上传) - 截图统一存项目根目录 jietu/(paths.RootDir;dev 构建识别 bin/ 布局)
87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
// Package item 物品注册表与物品栈(场景/物品与背包.md §2)。
|
||
package item
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"os"
|
||
"sort"
|
||
)
|
||
|
||
// 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
|
||
}
|
||
|
||
// Names 返回全部物品名(排序,掉落物图集构建等遍历用)。
|
||
func (r *Registry) Names() []string {
|
||
names := make([]string, 0, len(r.byName))
|
||
for n := range r.byName {
|
||
names = append(names, n)
|
||
}
|
||
sort.Strings(names)
|
||
return names
|
||
}
|
||
|
||
// 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
|
||
}
|