Files
strom/level/chunk_builder.go
T
2026-04-19 17:41:13 +02:00

94 lines
2.2 KiB
Go

package level
import (
"bytes"
"errors"
"github.com/admin-else/strom/data"
"github.com/admin-else/strom/util"
)
type ChunkBuilder struct {
Biomes, Blocks [][]int32
Bottom, Top int32
Version string
}
func NewChunkBuilder(bottom, top int32, version string) *ChunkBuilder {
return &ChunkBuilder{Bottom: bottom, Top: top, Version: version}
}
func NewOverworldChunkBuilder(version string) *ChunkBuilder {
return NewChunkBuilder(-64, 320, version)
}
func (cb *ChunkBuilder) ColumnHeight() int32 {
absBottom := cb.Bottom
if absBottom < 0 {
absBottom *= -1
}
return absBottom + cb.Top
}
func (cb *ChunkBuilder) FillAllById(block, biome int32) {
numSections := cb.ColumnHeight() / ChunkWidth
blockSection := util.MakeSingleValuedSlice(block, BlocksPerChunkSection)
biomeSection := util.MakeSingleValuedSlice(biome, BiomesPerChunkSection)
cb.Blocks = make([][]int32, numSections)
cb.Biomes = make([][]int32, numSections)
for i := range cb.Blocks {
cb.Blocks[i] = blockSection
cb.Biomes[i] = biomeSection
}
return
}
func (cb *ChunkBuilder) FillAll(biome, block string) (err error) {
blockData, ok := data.LookupBlockByName(cb.Version, block)
if !ok {
err = data.UnknownBlockNameErr
return
}
biomeData, ok := data.LookupBiomeByName(cb.Version, biome)
if !ok {
err = data.UnknownBiomeNameErr
return
}
cb.FillAllById(blockData.DefaultState, biomeData.Id)
return
}
var InvalidChunkPositionErr = errors.New("invalid chunk position")
func (cb *ChunkBuilder) SetBlockId(x, y, z, id int32) (err error) {
if x < 0 || x >= ChunkWidth || z < 0 || z >= ChunkWidth || y < cb.Bottom || y >= cb.Top {
err = InvalidChunkPositionErr
return
}
y += cb.Bottom * -1
section := util.FloorDiv(y, ChunkWidth)
i := (y%ChunkWidth)*ChunkWidth*ChunkWidth + z*ChunkWidth + x
cb.Blocks[section][i] = id
return
}
func (cb *ChunkBuilder) SetBlock(x, y, z int32, block string) (err error) {
blockData, ok := data.LookupBlockByName(cb.Version, block)
if !ok {
err = data.UnknownBlockNameErr
return
}
return cb.SetBlockId(x, y, z, blockData.DefaultState)
}
func (cb *ChunkBuilder) Build() (data []byte, err error) {
b := bytes.NewBuffer(nil)
err = PackSections(cb.Blocks, cb.Biomes, cb.Version, b)
if err != nil {
return
}
data = b.Bytes()
return
}