From d0844dd6b584f3c81e1666b0434c6a1ef69669e2 Mon Sep 17 00:00:00 2001 From: adman Date: Sat, 2 May 2026 01:36:29 +0200 Subject: [PATCH] anvil chunk to real chunk conversion things --- data/blocks.go | 7 ++++- level/anvil/chunk.go | 62 +++++++++++++++++++++++++++++++++++++++++--- level/storage.go | 9 +++++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/data/blocks.go b/data/blocks.go index f3bae8a..9597df1 100644 --- a/data/blocks.go +++ b/data/blocks.go @@ -99,7 +99,12 @@ func StateIdFromBlocKAndStateMap(version string, name string, stateMap map[strin err = BlockNotFoundErr return } - stateId, err = b.IdFromStateMap(stateMap) + if stateMap == nil { + stateId = b.DefaultState + } else { + stateId, err = b.IdFromStateMap(stateMap) + } + return } diff --git a/level/anvil/chunk.go b/level/anvil/chunk.go index b5d50ab..cce83eb 100644 --- a/level/anvil/chunk.go +++ b/level/anvil/chunk.go @@ -1,5 +1,14 @@ 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 @@ -8,17 +17,64 @@ type Chunk struct { 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.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 + uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.BlockStates.Data))), len(s.BlockStates.Data)) + + toChunk.Sections[i].Blocks, err = f.Import(uintSlice, util.BpeByNum(float64(len(s.BlockStates.Palette))), pallete) + if err != nil { + return + } + toChunk.Sections[i].BlockCount = int16(level.CountStorage(toChunk.Sections[i].Blocks, 0)) + } + + 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 + } + // this is probably fine + uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.Biomes.Data))), len(s.Biomes.Data)) + + toChunk.Sections[i].Biomes, err = f.Import(uintSlice, util.BpeByNum(float64(len(s.BlockStates.Palette))), pallete) + if err != nil { + return + } + } + return +} + type Section struct { Y int8 BlockStates struct { - Data []int64 + Data []int64 `nbt:"data,omitempty"` Palette []struct { Name string Properties map[string]string `nbt:"properties,omitempty"` } } - Biomes []struct { - Data []int64 + Biomes struct { + Data []int64 `nbt:"data,omitempty"` Palette []string } } diff --git a/level/storage.go b/level/storage.go index 83fef6d..d70e958 100644 --- a/level/storage.go +++ b/level/storage.go @@ -255,3 +255,12 @@ func CompareStorage(a, b *Storage) bool { } return true } + +func CountStorage(s *Storage, v int32) (a int) { + for i := range s.format.Len { + if w, _ := s.Get(i); w == v { + a++ + } + } + return +}