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

     1  package iteminternal
     2  
     3  import (
     4  	"github.com/df-mc/dragonfly/server/item/category"
     5  	"golang.org/x/exp/maps"
     6  	"strings"
     7  )
     8  
     9  // ComponentBuilder represents a builder that can be used to construct an item components map to be sent to a client.
    10  type ComponentBuilder struct {
    11  	name       string
    12  	identifier string
    13  	category   category.Category
    14  
    15  	properties map[string]any
    16  	components map[string]any
    17  }
    18  
    19  // NewComponentBuilder returns a new component builder with the provided item data.
    20  func NewComponentBuilder(name, identifier string, category category.Category) *ComponentBuilder {
    21  	return &ComponentBuilder{
    22  		name:       name,
    23  		identifier: identifier,
    24  		category:   category,
    25  
    26  		properties: make(map[string]any),
    27  		components: make(map[string]any),
    28  	}
    29  }
    30  
    31  // AddProperty adds the provided property to the builder.
    32  func (builder *ComponentBuilder) AddProperty(name string, value any) {
    33  	builder.properties[name] = value
    34  }
    35  
    36  // AddComponent adds the provided component to the builder.
    37  func (builder *ComponentBuilder) AddComponent(name string, value any) {
    38  	builder.components[name] = value
    39  }
    40  
    41  // Construct constructs the final item components map and returns it. It also applies the default properties required
    42  // for the item to work without modifying the original maps in the builder.
    43  func (builder *ComponentBuilder) Construct() map[string]any {
    44  	properties := maps.Clone(builder.properties)
    45  	components := maps.Clone(builder.components)
    46  	builder.applyDefaultProperties(properties)
    47  	builder.applyDefaultComponents(components, properties)
    48  	return map[string]any{"components": components}
    49  }
    50  
    51  // applyDefaultProperties applies the default properties to the provided map. It is important that this method does
    52  // not modify the builder's properties map directly otherwise Empty() will return false in future use of the builder.
    53  func (builder *ComponentBuilder) applyDefaultProperties(x map[string]any) {
    54  	x["minecraft:icon"] = map[string]any{
    55  		"textures": map[string]any{
    56  			"default": strings.Split(builder.identifier, ":")[1],
    57  		},
    58  	}
    59  	x["creative_group"] = builder.category.Group()
    60  	x["creative_category"] = int32(builder.category.Uint8())
    61  	if _, ok := x["max_stack_size"]; !ok {
    62  		x["max_stack_size"] = int32(64)
    63  	}
    64  }
    65  
    66  // applyDefaultComponents applies the default components to the provided map. It is important that this method does not
    67  // modify the builder's components map directly otherwise Empty() will return false in future use of the builder.
    68  func (builder *ComponentBuilder) applyDefaultComponents(x, properties map[string]any) {
    69  	x["item_properties"] = properties
    70  	x["minecraft:display_name"] = map[string]any{
    71  		"value": builder.name,
    72  	}
    73  }