//go:build generate // +build generate // gen_blocks.go generates block information. package main import ( "encoding/json" "fmt" "net/http" "os" "text/template" "github.com/iancoleman/strcase" ) const ( version = "1.17" infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/" + version + "/blocks.json" //language=gohtml blockTmpl = `// Code generated by gen_block.go; DO NOT EDIT. // Package block stores information about blocks in Minecraft. package block import ( "math" ) // BitsPerBlock indicates how many bits are needed to represent all possible // block states. This value is used to determine the size of the global palette. var BitsPerBlock = int(math.Ceil(math.Log2(float64(len(StateID))))) // ID describes the numeric ID of a block. type ID uint32 // Block describes information about a type of block. type Block struct { ID ID DisplayName string Name string Hardness float64 Diggable bool DropIDs []uint32 NeedsTools map[uint32]bool MinStateID uint32 MaxStateID uint32 Transparent bool FilterLightLevel int EmitLightLevel int } var ( {{- range .}} {{.CamelName}} = Block{ ID: {{.ID}}, DisplayName: "{{.DisplayName}}", Name: "{{.Name}}", Hardness: {{.Hardness}}, Diggable: {{.Diggable}}, DropIDs: []uint32{ {{- range .DropIDs}}{{.}},{{end -}} }, NeedsTools: map[uint32]bool{ {{- range $key, $val := .NeedsTools}}{{$key}}: {{$val}},{{end -}} }, MinStateID: {{.MinStateID}}, MaxStateID: {{.MaxStateID}}, Transparent: {{.Transparent}}, FilterLightLevel: {{.FilterLightLevel}}, EmitLightLevel: {{.EmitLightLevel}}, }{{end}} ) // ByID is an index of minecraft blocks by their ID. var ByID = map[ID]*Block{ {{range .}} {{.ID}}: &{{.CamelName}},{{end}} } // StateID maps all possible state IDs to a corresponding block ID. var StateID = map[uint32]ID{ {{range $block := .}} {{- range .States}} {{.}}: {{$block.ID}}, {{- end}}{{end}} }` ) type Block struct { ID uint32 `json:"id"` CamelName string `json:"-"` DisplayName string `json:"displayName"` Name string `json:"name"` Hardness float64 `json:"hardness"` Diggable bool `json:"diggable"` DropIDs []uint32 `json:"drops"` NeedsTools map[uint32]bool `json:"harvestTools"` MinStateID uint32 `json:"minStateId"` MaxStateID uint32 `json:"maxStateId"` Transparent bool `json:"transparent"` FilterLightLevel int `json:"filterLight"` EmitLightLevel int `json:"emitLight"` } func (b Block) States() []uint32 { if b.MinStateID == b.MaxStateID { return []uint32{b.MinStateID} } states := make([]uint32, 0) for i := b.MinStateID; i <= b.MaxStateID; i++ { states = append(states, i) } return states } func downloadInfo() ([]*Block, error) { resp, err := http.Get(infoURL) if err != nil { return nil, err } defer resp.Body.Close() var data []*Block if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { return nil, err } for _, d := range data { d.CamelName = strcase.ToCamel(d.Name) } return data, nil } //go:generate go run $GOFILE //go:generate go fmt block.go func main() { fmt.Println("generating block.go") blocks, err := downloadInfo() if err != nil { panic(err) } f, err := os.Create("block.go") if err != nil { panic(err) } defer f.Close() if err := template.Must(template.New("").Parse(blockTmpl)).Execute(f, blocks); err != nil { panic(err) } }