94 lines
2.2 KiB
Go
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
|
|
}
|