11 func (tc ToolCaps) String() string {
12 b, err := tc.MarshalJSON()
20 func (tc ToolCaps) MarshalJSON() ([]byte, error) {
22 return []byte("null"), nil
27 e := json.NewEncoder(&dgs)
28 for i, dg := range tc.DmgGroups {
32 if i < len(tc.DmgGroups)-1 {
40 e = json.NewEncoder(&gcs)
41 for i, gc := range tc.GroupCaps {
43 for _, t := range gc.Times {
44 if t.Rating >= maxRating {
45 maxRating = t.Rating + 1
49 times := make([]interface{}, maxRating)
50 for _, t := range gc.Times {
51 times[t.Rating] = fmtFloat(t.Time)
56 e.Encode(map[string]interface{}{
58 "maxlevel": gc.MaxLvl,
61 if i < len(tc.GroupCaps)-1 {
67 return json.Marshal(map[string]interface{}{
68 "damage_groups": json.RawMessage(dgs.Bytes()),
69 "full_punch_interval": fmtFloat(tc.AttackCooldown),
70 "groupcaps": json.RawMessage(gcs.Bytes()),
71 "max_drop_level": tc.MaxDropLvl,
72 "punch_attack_uses": tc.PunchUses,
76 func (tc *ToolCaps) UnmarshalJSON(data []byte) error {
77 d := json.NewDecoder(bytes.NewReader(data))
87 if d, ok := t.(json.Delim); !ok || d != '{' {
88 return errors.New("not an object")
99 case "full_punch_interval":
100 err = d.Decode(&tc.AttackCooldown)
101 case "max_drop_level":
102 err = d.Decode(&tc.MaxDropLvl)
108 return fmt.Errorf("groupcaps: %w", err)
110 if d, ok := t.(json.Delim); !ok || d != '{' {
111 return errors.New("groupcaps: not an object")
118 return fmt.Errorf("groupcaps: %w", err)
124 return fmt.Errorf("groupcaps: %w", err)
126 if d, ok := t.(json.Delim); !ok || d != '{' {
127 return errors.New("groupcaps: not an object")
132 return fmt.Errorf("groupcaps: %w", err)
139 err = d.Decode(&gc.Uses)
141 err = d.Decode(&gc.MaxLvl)
147 return fmt.Errorf("groupcaps: times: %w", err)
149 if d, ok := t.(json.Delim); !ok || d != '[' {
150 return errors.New("groupcaps: times: not an array")
152 for i := int16(0); d.More(); i++ {
155 return fmt.Errorf("groupcaps: times: %w", err)
157 switch t := t.(type) {
160 gc.Times = append(gc.Times, DigTime{i, float32(t)})
162 return errors.New("groupcaps: times: not null or a number")
168 return fmt.Errorf("groupcaps: %s: %w", key, err)
171 if _, err := d.Token(); err != nil {
174 tc.GroupCaps = append(tc.GroupCaps, gc)
177 case "damage_groups":
182 return fmt.Errorf("damage_groups: %w", err)
184 if d, ok := t.(json.Delim); !ok || d != '{' {
185 return errors.New("damage_groups: not an object")
196 if err := d.Decode(&g.Rating); err != nil {
197 return fmt.Errorf("damage_groups: %w", err)
200 tc.DmgGroups = append(tc.DmgGroups, g)
203 case "punch_attack_uses":
204 err = d.Decode(&tc.PunchUses)
207 return fmt.Errorf("%s: %w", key, err)
210 if _, err := d.Token(); err != nil {
218 func fmtFloat(f float32) json.Number {
219 buf := make([]byte, 0, 24)
220 buf = strconv.AppendFloat(buf, float64(f), 'g', 17, 32)
221 if !bytes.ContainsRune(buf, '.') {
222 buf = append(buf, '.', '0')
224 return json.Number(buf)