110 lines
2.8 KiB
Go
110 lines
2.8 KiB
Go
package anvil
|
|
|
|
import (
|
|
"strings"
|
|
"unsafe"
|
|
|
|
"github.com/admin-else/strom/data"
|
|
"github.com/admin-else/strom/level"
|
|
"github.com/admin-else/strom/util"
|
|
)
|
|
|
|
type Chunk struct {
|
|
DataVersion int32
|
|
Heightmaps map[string][]int64
|
|
InhabitedTime int64
|
|
XPos, YPos, ZPos int32
|
|
Sections []Section
|
|
}
|
|
|
|
const McPrefix = "minecraft:"
|
|
|
|
func (c Chunk) ToStorage(version string) (toChunk *level.Chunk, err error) {
|
|
f := level.MakeBlockFormat(version)
|
|
toChunk = new(level.Chunk)
|
|
toChunk.Version = version
|
|
|
|
toChunk.Sections = make([]level.Section, len(c.Sections))
|
|
for i, s := range c.Sections {
|
|
pallete := make([]int32, len(s.BlockStates.Palette))
|
|
for j, p := range s.BlockStates.Palette {
|
|
pallete[j], err = data.StateIdFromBlocKAndStateMap(version, strings.TrimPrefix(p.Name, McPrefix), p.Properties)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
// this is probably fine
|
|
|
|
if s.BlockStates.Data != nil {
|
|
uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.BlockStates.Data))), len(s.BlockStates.Data))
|
|
bpe := util.BpeByNum(float64(len(s.BlockStates.Palette)))
|
|
toChunk.Sections[i].Blocks, err = f.Import(uintSlice, bpe, pallete)
|
|
if err != nil {
|
|
return
|
|
}
|
|
toChunk.Sections[i].BlockCount = int16(level.BlocksPerChunkSection - level.CountStorage(toChunk.Sections[i].Blocks, 0))
|
|
} else {
|
|
var fillerId = int32(0)
|
|
if len(pallete) == 1 {
|
|
fillerId = pallete[0]
|
|
if fillerId != 0 {
|
|
toChunk.Sections[i].BlockCount = level.BlocksPerChunkSection
|
|
}
|
|
}
|
|
toChunk.Sections[i].Blocks, err = f.FullWith(fillerId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
f = level.MakeBiomeFormat(version)
|
|
for i, s := range c.Sections {
|
|
pallete := make([]int32, len(s.Biomes.Palette))
|
|
for j, p := range s.Biomes.Palette {
|
|
var b *data.Biome
|
|
b, ok := data.LookupBiomeByName(version, strings.TrimPrefix(p, McPrefix))
|
|
if !ok {
|
|
err = data.UnknownBiomeNameErr
|
|
return
|
|
}
|
|
pallete[j] = b.Id
|
|
}
|
|
|
|
if s.Biomes.Data != nil {
|
|
|
|
// this is probably fine
|
|
uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.Biomes.Data))), len(s.Biomes.Data))
|
|
bpe := util.BpeByNum(float64(len(pallete)))
|
|
toChunk.Sections[i].Biomes, err = f.Import(uintSlice, bpe, pallete)
|
|
if err != nil {
|
|
return
|
|
}
|
|
} else {
|
|
var fillerId = int32(0)
|
|
if len(pallete) == 1 {
|
|
fillerId = pallete[0]
|
|
}
|
|
toChunk.Sections[i].Biomes, err = f.FullWith(fillerId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
type Section struct {
|
|
Y int8
|
|
BlockStates struct {
|
|
Data []int64 `nbt:"data,omitempty"`
|
|
Palette []struct {
|
|
Name string
|
|
Properties map[string]string `nbt:"Properties,omitempty"`
|
|
}
|
|
} `nbt:"block_states,omitempty"`
|
|
Biomes struct {
|
|
Data []int64 `nbt:"data,omitempty"`
|
|
Palette []string
|
|
} `nbt:"biomes,omitempty"`
|
|
}
|