103 lines
2.9 KiB
Go
103 lines
2.9 KiB
Go
|
|
// 村民建造子系统:程序化房屋蓝图 + 逐块建造队列(村民系统.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) }
|