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