Files
ngzz-mc/internal/entity/villager.go

103 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 村民建造子系统:程序化房屋蓝图 + 逐块建造队列(村民系统.md §6 特色功能)。
package entity
import (
"mc/internal/block"
)
// Villager 村民附加数据(村民系统.md §3–§6)。
type Villager struct {
Profession uint8 // 0 农民 1 建造者 2 铁匠 3 商人
Home [3]int32
// 建造队列(村民系统.md §6.3:按顺序逐块放置)
BuildQueue []BuildTask
}
// BuildTask 一个建造任务(建造顺序已定)。
type BuildTask struct {
X, Y, Z int32
BlockID uint16
Meta uint8
Order uint32 // 地基 → 墙 → 门 → 屋顶 → 火把
}
// Blueprint 程序化房屋蓝图(村民系统.md §6.2):
// 矩形地基 W×D、墙高 3、门朝 +x、平顶、四角火把;确定性(seed 派生尺寸)。
func Blueprint(origin [3]int32, seed uint64) []BuildTask {
w := 5 + int(seed%3) // 5–7
d := 4 + int(seed%3) // 4–6
wall := uint16(8) // oak_planks(与 assets/config/blocks.json 一致)
door := uint16(0) // 门后置:先留空
roof := uint16(8)
torch := uint16(17)
var tasks []BuildTask
order := uint32(0)
add := func(x, y, z int32, id uint16, o uint32) {
tasks = append(tasks, BuildTask{X: x, Y: y, Z: z, BlockID: id, Order: o})
}
ox, oy, oz := origin[0], origin[1], origin[2]
// 1) 地基(order 0)
for x := 0; x < w; x++ {
for z := 0; z < d; z++ {
add(ox+int32(x), oy, oz+int32(z), wall, order)
}
}
order++
// 2) 墙(order 1–2,高 3;门位置留空)
for y := 1; y <= 2; y++ {
for x := 0; x < w; x++ {
for z := 0; z < d; z++ {
edge := x == 0 || x == w-1 || z == 0 || z == d-1
if !edge {
continue
}
if y == 1 && x == 0 && z == d/2 {
continue // 门洞
}
add(ox+int32(x), oy+int32(y), oz+int32(z), wall, order)
}
}
order++
}
// 3) 屋顶(order 3,平顶 + 一圈外沿)
for x := -1; x <= w; x++ {
for z := -1; z <= d; z++ {
edge := x == -1 || x == w || z == -1 || z == d
add(ox+int32(x), oy+3, oz+int32(z), roof, order+uint32(boolToInt(edge)))
}
}
order += 2
// 4) 火把(order 5,四角)
for _, c := range [4][2]int{{0, 0}, {w - 1, 0}, {0, d - 1}, {w - 1, d - 1}} {
add(ox+int32(c[0]), oy+2, oz+int32(c[1]), torch, order)
}
_ = door
return tasks
}
// boolToInt bool → int。
func boolToInt(b bool) int {
if b {
return 1
}
return 0
}
// BuildTick 建造者村民执行建造队列:每 tick 1–2 块(村民系统.md §6.3 防瞬建突兀)。
// place:放置回调(世界层 SetBlock);返回剩余任务数。
func (v *Villager) BuildTick(place func(x, y, z int32, id uint16, meta uint8) bool) int {
n := 0
for len(v.BuildQueue) > 0 && n < 2 {
t := v.BuildQueue[0]
v.BuildQueue = v.BuildQueue[1:]
if place(t.X, t.Y, t.Z, t.BlockID, t.Meta) {
n++
}
}
return len(v.BuildQueue)
}
// 方块状态工具(避免测试重复导入)。
func stateOf(id uint16, meta uint8) block.State { return block.NewState(id, meta) }