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.AttributeModifier;
025import net.tnemc.item.component.helper.EquipSlot;
026import net.tnemc.item.platform.ItemPlatform;
027import org.json.simple.JSONArray;
028import org.json.simple.JSONObject;
029
030import java.util.ArrayList;
031import java.util.Arrays;
032import java.util.List;
033import java.util.Objects;
034
035/**
036 * AttributeModifiesComponent
037 *
038 * @see <a href="https://minecraft.wiki/w/Data_component_format#attribute_modifiers">Reference</a>
039 *
040 * @author creatorfromhell
041 * @since 0.2.0.0
042 */
043public abstract class AttributeModifiersComponent<I extends AbstractItemStack<T>, T> implements SerialComponent<I, T> {
044
045  protected final List<AttributeModifier> modifiers = new ArrayList<>();
046
047  /**
048   * Constructor for AttributeModifiersComponent.
049   * Initializes an empty list of AttributeModifiers.
050   * @since 0.2.0.0
051   */
052  public AttributeModifiersComponent() {
053  }
054
055  /**
056   * Constructor for AttributeModifiersComponent.
057   * Initializes the component with a list of AttributeModifiers and a boolean flag to show in tooltip.
058   *
059   * @param modifiers The list of AttributeModifiers to associate with this component.
060   * @since 0.2.0.0
061   */
062  public AttributeModifiersComponent(final List<AttributeModifier> modifiers) {
063
064    this.modifiers.addAll(modifiers);
065  }
066
067  /**
068   * @return the type of component this is.
069   * @since 0.2.0.0
070   */
071  @Override
072  public String identifier() {
073    return "attribute_modifiers";
074  }
075
076  /**
077   * Converts this component's data to a JSON object.
078   *
079   * @return The JSONObject representing this component's data.
080   * @since 0.2.0.0
081   */
082  @Override
083  public JSONObject toJSON() {
084    final JSONObject json = new JSONObject();
085
086    final JSONArray modifiersArray = new JSONArray();
087    for(final AttributeModifier modifier : modifiers) {
088
089      final JSONObject modifierJson = new JSONObject();
090      modifierJson.put("type", modifier.getType());
091      modifierJson.put("slot", modifier.getSlot().name());
092      modifierJson.put("id", modifier.getId());
093      modifierJson.put("amount", modifier.getAmount());
094      modifierJson.put("operation", modifier.getOperation());
095      modifiersArray.add(modifierJson);
096    }
097    json.put("modifiers", modifiersArray);
098
099    return json;
100  }
101
102  /**
103   * Reads JSON data and converts it back to this component's data.
104   *
105   * @param json The JSONHelper instance of the JSON data.
106   * @param platform The ItemPlatform instance.
107   * @since 0.2.0.0
108   */
109  @Override
110  public void readJSON(final JSONHelper json, final ItemPlatform<I, T, ?> platform) {
111
112    modifiers.clear();
113
114    final JSONArray modifiersArray = (JSONArray) json.getObject().get("modifiers");
115    if(modifiersArray != null) {
116
117      for(final Object obj : modifiersArray) {
118
119        final JSONObject modifierJson = (JSONObject) obj;
120
121        final String type = modifierJson.get("type").toString();
122        final String id = modifierJson.get("id").toString();
123        final String operation = modifierJson.get("operation").toString();
124
125        final AttributeModifier modifier = new AttributeModifier(type, id, operation);
126
127        if(modifierJson.containsKey("slot")) {
128          modifier.setSlot(EquipSlot.valueOf(modifierJson.get("slot").toString()));
129        }
130
131        if(modifierJson.containsKey("amount")) {
132          modifier.setAmount(Double.parseDouble(modifierJson.get("amount").toString()));
133        }
134
135        modifiers.add(modifier);
136      }
137    }
138  }
139
140  /**
141   * Used to determine if some data is equal to this data. This means that it has to be an exact
142   * copy of this data.
143   *
144   * @param component The component to compare.
145   * @return True if similar, otherwise false.
146   * @since 0.2.0.0
147   */
148  @Override
149  public boolean similar(final SerialComponent<?, ?> component) {
150    if(!(component instanceof final AttributeModifiersComponent<?, ?> other)) return false;
151    return Objects.equals(this.modifiers, other.modifiers);
152  }
153
154  @Override
155  public int hashCode() {
156    return Objects.hash(modifiers);
157  }
158
159  /**
160   * Retrieves the list of AttributeModifiers associated with this component.
161   *
162   * @return The list of AttributeModifiers.
163   * @since 0.2.0.0
164   */
165  public List<AttributeModifier> modifiers() {
166
167    return modifiers;
168  }
169
170  /**
171   * Sets the list of AttributeModifiers for this component.
172   *
173   * @param modifiers The list of AttributeModifiers to set.
174   * @since 0.2.0.0
175   */
176  public void modifiers(final List<AttributeModifier> modifiers) {
177    this.modifiers.clear();
178    this.modifiers.addAll(modifiers);
179  }
180
181  public void modifiers(final AttributeModifier... modifiers) {
182    this.modifiers.clear();
183    this.modifiers.addAll(Arrays.asList(modifiers));
184  }
185
186  /**
187   * Adds a new AttributeModifier to the list of modifiers for this component.
188   *
189   * @param modifier The AttributeModifier to add to the list of modifiers.
190   * @since 0.2.0.0
191   */
192  public void modifiers(final AttributeModifier modifier) {
193    this.modifiers.add(modifier);
194  }
195}