feat(game): 掉落物单堆叠上限 9999 + 拾取按栈上限拆分;挖掘按住循环挥动
- 地上掉落合并上限 64→9999,超出生成新堆(TestDropStackCap) - 拾取按物品栈上限拆成多栈入包,放不下回吐地面 - 按住左键挖掘时每 0.3 秒循环挥动手部(swingTimer), 挥动幅度收窄并抬高持手位置保持可见 - 新增 -digtest/-swingtest dev 截图测试开关
This commit is contained in:
@@ -8,10 +8,10 @@ import (
|
||||
|
||||
// 掉落物参数(实体系统.md §5)。
|
||||
const (
|
||||
dropMergeDist = 1.0 // 同物品合并距离
|
||||
dropStackMax = 64 // 合并上限
|
||||
dropPickupDist = 1.5 // 拾取半径
|
||||
dropPerChunk = 32 // 每区块掉落物上限
|
||||
dropMergeDist = 1.0 // 同物品合并距离
|
||||
dropStackMax = 9999 // 单堆叠合并上限(地上大堆;拾取时按背包栈上限拆分)
|
||||
dropPickupDist = 1.5 // 拾取半径
|
||||
dropPerChunk = 32 // 每区块掉落物上限
|
||||
)
|
||||
|
||||
// dropPickupDelay 生成后可拾取延迟(测试可置 0)。
|
||||
|
||||
@@ -87,6 +87,31 @@ func TestDropMerge(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestDropStackCap 单堆叠上限 9999:合并到上限后,多余部分生成新堆(实体系统.md §5)。
|
||||
func TestDropStackCap(t *testing.T) {
|
||||
m := NewManager()
|
||||
m.SpawnDrop("cobblestone", 9999, 0.5, 64, 0.5)
|
||||
m.SpawnDrop("cobblestone", 5, 0.6, 64, 0.5) // 9999+5 超上限 → 不合并,生成新堆
|
||||
cnt, total := 0, 0
|
||||
for _, e := range m.List() {
|
||||
if e.Kind != KindItemDrop {
|
||||
continue
|
||||
}
|
||||
d, ok := e.Data.(*Drop)
|
||||
if !ok {
|
||||
t.Fatalf("掉落物数据缺失: %+v", e.Data)
|
||||
}
|
||||
cnt++
|
||||
total += d.Count
|
||||
if d.Count > dropStackMax {
|
||||
t.Fatalf("单堆超上限: %d > %d", d.Count, dropStackMax)
|
||||
}
|
||||
}
|
||||
if cnt != 2 || total != 10004 {
|
||||
t.Fatalf("期望 2 堆共 10004,实际 %d 堆共 %d", cnt, total)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBlueprint 房屋蓝图确定性 + 建造执行顺序(村民系统.md §6)。
|
||||
func TestBlueprint(t *testing.T) {
|
||||
a := Blueprint([3]int32{10, 64, 10}, 42)
|
||||
|
||||
@@ -91,9 +91,9 @@ func (s *Session) Tick(dt float64) {
|
||||
s.Entities.Tick(dt, s.World, s.Player.Pos)
|
||||
// 方块实体(熔炉烧炼,物品与背包.md §6)
|
||||
s.tickBlockEntities()
|
||||
// 掉落物拾取(实体系统.md §5)
|
||||
// 掉落物拾取(实体系统.md §5;大堆叠按背包栈上限拆分成多栈,放不下回吐地面)
|
||||
for _, d := range s.Entities.PickupNearby(s.Player.Pos[0], s.Player.Pos[1], s.Player.Pos[2]) {
|
||||
s.Inv.Add(item.Stack{Name: d.Item, Count: uint8(min(d.Count, 127))})
|
||||
s.pickupDrop(d)
|
||||
}
|
||||
// 夜间刷僵尸(僵尸与敌对生物.md §5:黑暗处、距玩家 24 格、限频)
|
||||
s.spawnZombies(dt)
|
||||
@@ -246,6 +246,29 @@ func (s *Session) DropSelected() {
|
||||
s.Player.Pos[0]+f[0]*1.5, s.Player.Pos[1]+1, s.Player.Pos[2]+f[2]*1.5)
|
||||
}
|
||||
|
||||
// pickupDrop 拾取掉落:按物品栈上限拆分成多栈放入背包;背包放不下的部分
|
||||
// 重新掉回地面(物品与背包.md §3、实体系统.md §5)。
|
||||
func (s *Session) pickupDrop(d entity.Drop) {
|
||||
rem := d.Count
|
||||
for rem > 0 {
|
||||
chunk := rem
|
||||
limit := 64
|
||||
if def, ok := s.Items.Get(d.Item); ok && def.Stack > 0 && def.Stack < limit {
|
||||
limit = def.Stack
|
||||
}
|
||||
if chunk > limit {
|
||||
chunk = limit
|
||||
}
|
||||
leftover := s.Inv.Add(item.Stack{Name: d.Item, Count: uint8(chunk)})
|
||||
if !leftover.Empty() {
|
||||
// 背包满:剩余重新掉回地面(含未放入部分)
|
||||
s.Entities.SpawnDrop(d.Item, rem, s.Player.Pos[0], s.Player.Pos[1]+1, s.Player.Pos[2])
|
||||
return
|
||||
}
|
||||
rem -= chunk
|
||||
}
|
||||
}
|
||||
|
||||
// spawnVillagers 村庄村民生成(村民系统.md §2):扫描已加载区块,村庄中心处生成 3 名村民。
|
||||
func (s *Session) spawnVillagers(dt float64) {
|
||||
s.villagerTimer -= dt
|
||||
|
||||
Reference in New Issue
Block a user