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
021import net.tnemc.item.AbstractItemStack;
022import net.tnemc.item.JSONHelper;
023import net.tnemc.item.component.SerialComponent;
024import net.tnemc.item.component.helper.EquipSlot;
025import net.tnemc.item.platform.ItemPlatform;
026import org.json.simple.JSONObject;
027
028import java.util.ArrayList;
029import java.util.Arrays;
030import java.util.List;
031import java.util.Objects;
032
033/**
034 * EquippableComponent
035 *
036 * @see <a href="https://minecraft.wiki/w/Data_component_format#equippable">Reference</a>
037 *
038 * @author creatorfromhell
039 * @since 0.2.0.0
040 */
041public abstract class EquipComponent<I extends AbstractItemStack<T>, T> implements SerialComponent<I, T> {
042
043  protected final List<String> entities = new ArrayList<>();
044
045  protected String cameraKey;
046  protected String equipSound;
047  protected String modelKey;
048  protected EquipSlot slot;
049  protected boolean damageOnHurt;
050  protected boolean dispensable;
051  protected boolean swappable;
052  protected boolean equipOnInteract; //as of SnapShot 25w03a
053
054  public EquipComponent(final String cameraKey) {
055
056    this.cameraKey = cameraKey;
057  }
058
059  public EquipComponent(final String cameraKey, final String equipSound) {
060
061    this.cameraKey = cameraKey;
062    this.equipSound = equipSound;
063  }
064
065  public EquipComponent(final String cameraKey, final String equipSound, final String modelKey) {
066
067    this.cameraKey = cameraKey;
068    this.equipSound = equipSound;
069    this.modelKey = modelKey;
070  }
071
072  public EquipComponent(final String cameraKey, final String equipSound, final String modelKey,
073                        final EquipSlot slot) {
074
075    this.cameraKey = cameraKey;
076    this.equipSound = equipSound;
077    this.modelKey = modelKey;
078    this.slot = slot;
079  }
080
081  public EquipComponent(final String cameraKey, final String equipSound, final String modelKey,
082                        final EquipSlot slot, final boolean damageOnHurt) {
083
084    this.cameraKey = cameraKey;
085    this.equipSound = equipSound;
086    this.modelKey = modelKey;
087    this.slot = slot;
088    this.damageOnHurt = damageOnHurt;
089  }
090
091  public EquipComponent(final String cameraKey, final String equipSound, final String modelKey,
092                        final EquipSlot slot, final boolean damageOnHurt, final boolean dispensable) {
093
094    this.cameraKey = cameraKey;
095    this.equipSound = equipSound;
096    this.modelKey = modelKey;
097    this.slot = slot;
098    this.damageOnHurt = damageOnHurt;
099    this.dispensable = dispensable;
100  }
101
102  public EquipComponent(final String cameraKey, final String equipSound, final String modelKey,
103                        final EquipSlot slot, final boolean damageOnHurt, final boolean dispensable,
104                        final boolean swappable) {
105
106    this.cameraKey = cameraKey;
107    this.equipSound = equipSound;
108    this.modelKey = modelKey;
109    this.slot = slot;
110    this.damageOnHurt = damageOnHurt;
111    this.dispensable = dispensable;
112    this.swappable = swappable;
113  }
114
115  public EquipComponent(final String cameraKey, final String equipSound, final String modelKey,
116                        final EquipSlot slot, final boolean damageOnHurt, final boolean dispensable,
117                        final boolean swappable, final boolean equipOnInteract) {
118
119    this.cameraKey = cameraKey;
120    this.equipSound = equipSound;
121    this.modelKey = modelKey;
122    this.slot = slot;
123    this.damageOnHurt = damageOnHurt;
124    this.dispensable = dispensable;
125    this.swappable = swappable;
126    this.equipOnInteract = equipOnInteract;
127  }
128
129  public EquipComponent(final String cameraKey, final String equipSound, final String modelKey,
130                        final EquipSlot slot, final boolean damageOnHurt, final boolean dispensable,
131                        final boolean swappable, final boolean equipOnInteract, final List<String> entities) {
132
133    this.cameraKey = cameraKey;
134    this.equipSound = equipSound;
135    this.modelKey = modelKey;
136    this.slot = slot;
137    this.damageOnHurt = damageOnHurt;
138    this.dispensable = dispensable;
139    this.swappable = swappable;
140    this.equipOnInteract = equipOnInteract;
141    this.entities.addAll(entities);
142  }
143
144  /**
145   * @return the type of component this is.
146   * @since 0.2.0.0
147   */
148  @Override
149  public String identifier() {
150
151    return "equip";
152  }
153
154  /**
155   * Converts the {@link SerialComponent} to a JSON object.
156   *
157   * @return The JSONObject representing this {@link SerialComponent}.
158   * @since 0.2.0.0
159   */
160  @Override
161  public JSONObject toJSON() {
162
163    final JSONObject equip = new JSONObject();
164    equip.put("name", "equip-component");
165    equip.put("cameraKey", cameraKey);
166    equip.put("equipSound", equipSound);
167    equip.put("modelKey", modelKey);
168    equip.put("slot", slot.name());
169    equip.put("damageWithEntity", damageOnHurt);
170    equip.put("dispensable", dispensable);
171    equip.put("swappable", swappable);
172    equip.put("equipOnInteract", equipOnInteract);
173
174    if(!entities.isEmpty()) {
175
176      final JSONObject entitiesOBJ = new JSONObject();
177      for(int i = 0; i < entities.size(); i++) {
178        entitiesOBJ.put(i, entities.get(i));
179      }
180      equip.put("entities", entitiesOBJ);
181    }
182    return equip;
183  }
184
185  /**
186   * Reads JSON data and converts it back to a {@link SerialComponent} object.
187   *
188   * @param json The JSONHelper instance of the json data.
189   * @since 0.2.0.0
190   */
191  @Override
192  public void readJSON(final JSONHelper json, final ItemPlatform<I, T, ?> platform) {
193
194    cameraKey = json.getString("cameraKey");
195    equipSound = json.getString("equipSound");
196    modelKey = json.getString("modelKey");
197    slot = EquipSlot.valueOf(json.getString("slot"));
198    damageOnHurt = json.getBoolean("damageWithEntity");
199    dispensable = json.getBoolean("dispensable");
200    swappable = json.getBoolean("swappable");
201    equipOnInteract = json.getBoolean("equipOnInteract");
202
203    entities.clear();
204    entities.addAll(json.getStringList("entities"));
205  }
206
207  /**
208   * Used to determine if some data is equal to this data. This means that it has to be an exact
209   * copy of this data. For instance, book copies will return false when compared to the original.
210   *
211   * @param component The component to compare.
212   *
213   * @return True if similar, otherwise false.
214   * @since 0.2.0.0
215   */
216  @Override
217  public boolean similar(final SerialComponent<?, ?> component) {
218
219    if(component instanceof final EquipComponent<?, ?> equipComponent) {
220
221      return Objects.equals(this.cameraKey, equipComponent.cameraKey) &&
222             Objects.equals(this.equipSound, equipComponent.equipSound) &&
223             Objects.equals(this.modelKey, equipComponent.modelKey) &&
224             Objects.equals(this.slot.name(), equipComponent.slot.name()) &&
225             this.damageOnHurt == equipComponent.damageOnHurt &&
226             this.dispensable == equipComponent.dispensable &&
227             this.swappable == equipComponent.swappable &&
228             this.equipOnInteract == equipComponent.equipOnInteract &&
229             this.entities.equals(equipComponent.entities);
230
231    }
232    return false;
233  }
234
235  public List<String> entities() {
236
237    return entities;
238  }
239
240  public void entities(final List<String> entities) {
241
242    this.entities.clear();
243    this.entities.addAll(entities);
244  }
245
246  public void entities(final String... entities) {
247
248    this.entities.clear();
249    this.entities.addAll(Arrays.asList(entities));
250  }
251
252  public String cameraKey() {
253
254    return cameraKey;
255  }
256
257  public void cameraKey(final String cameraKey) {
258
259    this.cameraKey = cameraKey;
260  }
261
262  public String equipSound() {
263
264    return equipSound;
265  }
266
267  public void equipSound(final String equipSound) {
268
269    this.equipSound = equipSound;
270  }
271
272  public String modelKey() {
273
274    return modelKey;
275  }
276
277  public void modelKey(final String modelKey) {
278
279    this.modelKey = modelKey;
280  }
281
282  public EquipSlot slot() {
283
284    return slot;
285  }
286
287  public void slot(final EquipSlot slot) {
288
289    this.slot = slot;
290  }
291
292  public boolean damageOnHurt() {
293
294    return damageOnHurt;
295  }
296
297  public void damageOnHurt(final boolean damageOnHurt) {
298
299    this.damageOnHurt = damageOnHurt;
300  }
301
302  public boolean dispensable() {
303
304    return dispensable;
305  }
306
307  public void dispensable(final boolean dispensable) {
308
309    this.dispensable = dispensable;
310  }
311
312  public boolean swappable() {
313
314    return swappable;
315  }
316
317  public void swappable(final boolean swappable) {
318
319    this.swappable = swappable;
320  }
321
322  public boolean equipOnInteract() {
323
324    return equipOnInteract;
325  }
326
327  public void equipOnInteract(final boolean equipOnInteract) {
328
329    this.equipOnInteract = equipOnInteract;
330  }
331}