001package net.tnemc.item.component.impl;
002/*
003 * The New Item Library
004 * Copyright (C) 2022 - 2025 Daniel "creatorfromhell" Vidmar
005 *
006 * This program is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020
021
022import net.tnemc.item.AbstractItemStack;
023import net.tnemc.item.JSONHelper;
024import net.tnemc.item.component.SerialComponent;
025import net.tnemc.item.component.helper.ToolRule;
026import net.tnemc.item.platform.ItemPlatform;
027import org.json.simple.JSONObject;
028
029import java.util.Arrays;
030import java.util.LinkedList;
031import java.util.List;
032import java.util.Objects;
033
034/**
035 * ToolComponent
036 *
037 * @author creatorfromhell
038 * @since 0.2.0.0
039 */
040public abstract class ToolComponent<I extends AbstractItemStack<T>, T> implements SerialComponent<I, T> {
041
042  protected final List<ToolRule> rules = new LinkedList<>();
043
044  protected float defaultSpeed = 1.0f;
045  protected int blockDamage;
046  protected boolean canDestroyBlocksCreative = true; //since MC Snapshot 25w02a
047
048  public ToolComponent(final int blockDamage) {
049
050    this.blockDamage = blockDamage;
051  }
052
053  public ToolComponent(final float defaultSpeed, final int blockDamage) {
054
055    this.defaultSpeed = defaultSpeed;
056    this.blockDamage = blockDamage;
057  }
058
059  public ToolComponent(final boolean canDestroyBlocksCreative, final int blockDamage) {
060
061    this.canDestroyBlocksCreative = canDestroyBlocksCreative;
062    this.blockDamage = blockDamage;
063  }
064
065  public ToolComponent(final float defaultSpeed, final int blockDamage, final boolean canDestroyBlocksCreative) {
066
067    this.defaultSpeed = defaultSpeed;
068    this.blockDamage = blockDamage;
069    this.canDestroyBlocksCreative = canDestroyBlocksCreative;
070  }
071
072  public ToolComponent(final float defaultSpeed, final int blockDamage, final boolean canDestroyBlocksCreative,
073                       final ToolRule rule) {
074
075    this.defaultSpeed = defaultSpeed;
076    this.blockDamage = blockDamage;
077    this.canDestroyBlocksCreative = canDestroyBlocksCreative;
078
079    this.rules.add(rule);
080  }
081
082  public ToolComponent(final float defaultSpeed, final int blockDamage, final boolean canDestroyBlocksCreative,
083                       final List<ToolRule> rules) {
084
085    this.defaultSpeed = defaultSpeed;
086    this.blockDamage = blockDamage;
087    this.canDestroyBlocksCreative = canDestroyBlocksCreative;
088
089    this.rules.addAll(rules);
090  }
091
092  /**
093   * @return the type of component this is.
094   * @since 0.2.0.0
095   */
096  @Override
097  public String identifier() {
098
099    return "tool";
100  }
101
102  /**
103   * Converts the {@link SerialComponent} to a JSON object.
104   *
105   * @return The JSONObject representing this {@link SerialComponent}.
106   * @since 0.2.0.0
107   */
108  @Override
109  public JSONObject toJSON() {
110
111    final JSONObject tool = new JSONObject();
112    tool.put("name", "tool-component");
113    tool.put("defaultSpeed", defaultSpeed);
114    tool.put("blockDamage", blockDamage);
115
116    if(!rules.isEmpty()) {
117      final JSONObject rulesObj = new JSONObject();
118      for(int it = 0; it < rules.size(); it++) {
119        rulesObj.put(it, rules.get(it).toJSON());
120      }
121      tool.put("rules", rulesObj);
122    }
123    return tool;
124  }
125
126  /**
127   * Reads JSON data and converts it back to a {@link SerialComponent} object.
128   *
129   * @param json The JSONHelper instance of the json data.
130   * @since 0.2.0.0
131   */
132  @Override
133  public void readJSON(final JSONHelper json, final ItemPlatform<I, T, ?> platform) {
134
135    defaultSpeed = json.getFloat("defaultSpeed");
136    blockDamage = json.getInteger("blockDamage");
137
138    if(json.has("rules")) {
139      final JSONHelper rulesObj = json.getHelper("rules");
140      rules.clear();
141
142      rulesObj.getObject().forEach((key, value)->rules.add(ToolRule.readJSON(new JSONHelper((JSONObject)value))));
143    }
144  }
145
146  /**
147   * Used to determine if some data is equal to this data. This means that it has to be an exact
148   * copy of this data. For instance, book copies will return false when compared to the original.
149   *
150   * @param component The component to compare.
151   *
152   * @return True if similar, otherwise false.
153   * @since 0.2.0.0
154   */
155  @Override
156  public boolean similar(final SerialComponent<?, ?> component) {
157
158    if(component instanceof final ToolComponent<?, ?> tool) {
159      return Float.compare(this.defaultSpeed, tool.defaultSpeed) == 0 &&
160             this.blockDamage == tool.blockDamage &&
161             this.canDestroyBlocksCreative == tool.canDestroyBlocksCreative &&
162             Objects.equals(this.rules, tool.rules);
163    }
164    return false;
165  }
166
167  public List<ToolRule> rules() {
168
169    return rules;
170  }
171
172  public void rules(final List<ToolRule> rules) {
173    this.rules.clear();
174    this.rules.addAll(rules);
175  }
176
177  public void rules(final ToolRule... rules) {
178    this.rules.clear();
179    this.rules.addAll(Arrays.asList(rules));
180  }
181
182  public float defaultSpeed() {
183
184    return defaultSpeed;
185  }
186
187  public void defaultSpeed(final float defaultSpeed) {
188
189    this.defaultSpeed = defaultSpeed;
190  }
191
192  public int blockDamage() {
193
194    return blockDamage;
195  }
196
197  public void blockDamage(final int blockDamage) {
198
199    this.blockDamage = blockDamage;
200  }
201
202  public boolean canDestroyBlocksCreative() {
203
204    return canDestroyBlocksCreative;
205  }
206
207  public void canDestroyBlocksCreative(final boolean canDestroyBlocksCreative) {
208
209    this.canDestroyBlocksCreative = canDestroyBlocksCreative;
210  }
211}