diff --git a/level/section.go b/level/section.go index 097a66c..e280a42 100644 --- a/level/section.go +++ b/level/section.go @@ -42,9 +42,10 @@ func MakeBiomeFormat(version string) StorageFormat { func MakeBlockFormat(version string) StorageFormat { directBpe := uint8(math.Ceil(math.Log2(float64(len(data.BlocksForVersion(version)))))) return StorageFormat{ - AvailableBpes: []uint8{0, 4, 5, 6, 7, 8, directBpe}, - BiggestDirect: true, - Len: BlocksPerChunkSection, + RedirectingBpes: []uint8{1, 2, 3}, + AvailableBpes: []uint8{0, 4, 5, 6, 7, 8, directBpe}, + BiggestDirect: true, + Len: BlocksPerChunkSection, } } diff --git a/level/storage.go b/level/storage.go index 67adae3..1a4dfe4 100644 --- a/level/storage.go +++ b/level/storage.go @@ -6,12 +6,15 @@ import ( "io" "math" "slices" + + "github.com/admin-else/strom/util" ) type StorageFormat struct { - AvailableBpes []uint8 - BiggestDirect bool - Len int32 + RedirectingBpes []uint8 // block bpe 1 2 3 redirect to 4 + AvailableBpes []uint8 + BiggestDirect bool + Len int32 } var OutOfBoundsErr = errors.New("out of bounds") @@ -33,24 +36,16 @@ func (r StorageFormat) Import(data []uint64, bpe uint8, palette []int32) (s *Sto s.resize(bpe) if !slices.Contains(r.AvailableBpes, bpe) { - var newBpe uint8 - for _, newBpe = range r.AvailableBpes { - if bpe <= newBpe { - break - } + if !slices.Contains(r.RedirectingBpes, bpe) { + err = NoAvailableBpeErr + return } - var tmps *Storage - tmps, err = StorageFormat{ - AvailableBpes: []uint8{bpe}, - BiggestDirect: false, - Len: r.Len, - }.ImportDataDirect(data) - if err != nil { + var found bool + bpe, found = util.GetNextLargestNumberSlice(bpe, r.AvailableBpes) + if !found { + err = NoAvailableBpeErr return } - tmps.resize(newBpe) - data = tmps.data - bpe = newBpe } if bpe == 0 && len(palette) != 1 { err = Bpe0PalletMustBeLenOneErr diff --git a/util/slices.go b/util/slices.go index caed0f1..70987f5 100644 --- a/util/slices.go +++ b/util/slices.go @@ -85,3 +85,12 @@ func SliceRange[T Numeric](s, e T) (ret []T) { func IsLastElement[T comparable](s []T, e T) bool { return len(s) > 0 && s[len(s)-1] == e } + +func GetNextLargestNumberSlice[T Numeric](a T, s []T) (ret T, found bool) { + for _, v := range s { + if v > a { + return v, true + } + } + return +}