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 }