feat: Added the generate command to load existing world saves
This commit is contained in:
		
							
								
								
									
										75
									
								
								world/chunk_data.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								world/chunk_data.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
package world
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/Tnze/go-mc/save"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const ChunkSectionCount = 16
 | 
			
		||||
 | 
			
		||||
type ChunkData struct {
 | 
			
		||||
	Pos      ChunkPos                        `json:"pos"`
 | 
			
		||||
	Sections [ChunkSectionCount]ChunkSection `json:"sections"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cd *ChunkData) SectionFor(pos BlockPos) *ChunkSection {
 | 
			
		||||
	return &cd.Sections[pos.Y%ChunkSectionCount]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func extractPaletteIndexes(compressed int64) [16]byte {
 | 
			
		||||
	var outputs [16]byte
 | 
			
		||||
	var outputIndex int
 | 
			
		||||
 | 
			
		||||
	for index := 0; index < 64; index += 4 {
 | 
			
		||||
		shifted := compressed >> index
 | 
			
		||||
		// Mask off the lowest four bits
 | 
			
		||||
		shifted &= 0xf
 | 
			
		||||
		outputs[outputIndex] = byte(shifted)
 | 
			
		||||
		outputIndex += 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return outputs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cd *ChunkData) FromMCAChunk(other save.Chunk) {
 | 
			
		||||
	// Load the chunk's position
 | 
			
		||||
	cd.Pos = ChunkPos{X: int(other.XPos), Z: int(other.ZPos)}
 | 
			
		||||
 | 
			
		||||
	// Load the data from the chunk
 | 
			
		||||
	for sectionIndex, section := range other.Sections {
 | 
			
		||||
		// TODO: Enable chunks to have more than 16 sections
 | 
			
		||||
		if sectionIndex >= ChunkSectionCount {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var currentSection ChunkSection
 | 
			
		||||
 | 
			
		||||
		paletteIndexes := []int{}
 | 
			
		||||
		for _, compress := range section.BlockStates.Data {
 | 
			
		||||
			indexes := extractPaletteIndexes(int64(compress))
 | 
			
		||||
 | 
			
		||||
			converted := make([]int, 16)
 | 
			
		||||
			for i := 0; i < 16; i++ {
 | 
			
		||||
				converted[i] = int(indexes[i])
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			paletteIndexes = append(paletteIndexes, converted...)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for blockIndex, paletteIndex := range paletteIndexes {
 | 
			
		||||
			var state BlockID
 | 
			
		||||
			if section.BlockStates.Palette[paletteIndex].Name == "minecraft:air" {
 | 
			
		||||
				state = Empty
 | 
			
		||||
			} else {
 | 
			
		||||
				cd.Sections[sectionIndex].BlockCount += 1
 | 
			
		||||
				state = Generic
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// TODO: Remove this workaround for larger bit sizes in palettes
 | 
			
		||||
			if blockIndex < 4096 {
 | 
			
		||||
				currentSection.BlockStates[blockIndex] = state
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cd.Sections[sectionIndex] = currentSection
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -31,15 +31,6 @@ func (b BlockPos) ToChunkPos() ChunkPos {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ChunkData struct {
 | 
			
		||||
	Pos      ChunkPos         `json:"pos"`
 | 
			
		||||
	Sections [16]ChunkSection `json:"sections"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cd *ChunkData) SectionFor(pos BlockPos) *ChunkSection {
 | 
			
		||||
	return &cd.Sections[pos.Y%16]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ChunkPos struct {
 | 
			
		||||
	X int `json:"x"`
 | 
			
		||||
	Z int `json:"z"`
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user