github.com/df-mc/dragonfly@v0.9.13/server/internal/packbuilder/blocks.go (about)

     1  package packbuilder
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"github.com/df-mc/dragonfly/server/world"
     7  	"image"
     8  	"image/png"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  	_ "unsafe" // Imported for compiler directives.
    13  )
    14  
    15  // buildBlocks builds all the block-related files for the resource pack. This includes textures, geometries, language
    16  // entries and terrain texture atlas.
    17  func buildBlocks(dir string) (count int, lang []string) {
    18  	if err := os.MkdirAll(filepath.Join(dir, "models/blocks"), os.ModePerm); err != nil {
    19  		panic(err)
    20  	}
    21  	if err := os.MkdirAll(filepath.Join(dir, "textures/blocks"), os.ModePerm); err != nil {
    22  		panic(err)
    23  	}
    24  
    25  	textureData := make(map[string]any)
    26  	for identifier, blk := range world.CustomBlocks() {
    27  		b, ok := blk.(world.CustomBlockBuildable)
    28  		if !ok {
    29  			continue
    30  		}
    31  
    32  		name := strings.Split(identifier, ":")[1]
    33  		lang = append(lang, fmt.Sprintf("tile.%s.name=%s", identifier, b.Name()))
    34  		for name, texture := range b.Textures() {
    35  			textureData[name] = map[string]string{"textures": "textures/blocks/" + name}
    36  			buildBlockTexture(dir, name, texture)
    37  		}
    38  		if b.Geometry() != nil {
    39  			if err := os.WriteFile(filepath.Join(dir, "models/blocks", fmt.Sprintf("%s.geo.json", name)), b.Geometry(), 0666); err != nil {
    40  				panic(err)
    41  			}
    42  		}
    43  		count++
    44  	}
    45  
    46  	buildBlockAtlas(dir, map[string]any{
    47  		"resource_pack_name": "vanilla",
    48  		"texture_name":       "atlas.terrain",
    49  		"padding":            8,
    50  		"num_mip_levels":     4,
    51  		"texture_data":       textureData,
    52  	})
    53  	return
    54  }
    55  
    56  // buildBlockTexture creates a PNG file for the block from the provided image and name and writes it to the pack.
    57  func buildBlockTexture(dir, name string, img image.Image) {
    58  	texture, err := os.Create(filepath.Join(dir, fmt.Sprintf("textures/blocks/%s.png", name)))
    59  	if err != nil {
    60  		panic(err)
    61  	}
    62  	if err := png.Encode(texture, img); err != nil {
    63  		_ = texture.Close()
    64  		panic(err)
    65  	}
    66  	if err := texture.Close(); err != nil {
    67  		panic(err)
    68  	}
    69  }
    70  
    71  // buildBlockAtlas creates the identifier to texture mapping and writes it to the pack.
    72  func buildBlockAtlas(dir string, atlas map[string]any) {
    73  	b, err := json.Marshal(atlas)
    74  	if err != nil {
    75  		panic(err)
    76  	}
    77  	if err := os.WriteFile(filepath.Join(dir, "textures/terrain_texture.json"), b, 0666); err != nil {
    78  		panic(err)
    79  	}
    80  }