some code cleanup

This commit is contained in:
Indyuce 2021-12-20 11:47:15 +01:00
parent f2bb73e2b7
commit 23b9590cf1
8 changed files with 676 additions and 524 deletions

View File

@ -486,7 +486,8 @@ public class MMOItem implements ItemReference {
public void removeGemStone(@NotNull UUID gemUUID, @Nullable String color) { public void removeGemStone(@NotNull UUID gemUUID, @Nullable String color) {
// Get gemstone data // Get gemstone data
if (!hasData(ItemStats.GEM_SOCKETS)) { return; } if (!hasData(ItemStats.GEM_SOCKETS))
return;
//GEM//MMOItems.log("\u00a7b-\u00a78-\u00a79-\u00a77 Extracting \u00a7e" + gemUUID.toString()); //GEM//MMOItems.log("\u00a7b-\u00a78-\u00a79-\u00a77 Extracting \u00a7e" + gemUUID.toString());
StatHistory gemStory = StatHistory.from(this, ItemStats.GEM_SOCKETS); StatHistory gemStory = StatHistory.from(this, ItemStats.GEM_SOCKETS);
@ -497,16 +498,23 @@ public class MMOItem implements ItemReference {
* will purge themselves from extraneous gems (that are * will purge themselves from extraneous gems (that are
* no longer registered onto the GEM_SOCKETS history). * no longer registered onto the GEM_SOCKETS history).
*/ */
if (GemSocketsData.removeGemFrom(((GemSocketsData) gemStory.getOriginalData()), gemUUID, color)) { return; } if (((GemSocketsData) gemStory.getOriginalData()).removeGem(gemUUID, color))
return;
// Attempt gems // Attempt gems
for (UUID gemDataUUID : gemStory.getAllGemstones()) { if (GemSocketsData.removeGemFrom(((GemSocketsData) gemStory.getGemstoneData(gemDataUUID)), gemUUID, color)) { return; } } for (UUID gemDataUUID : gemStory.getAllGemstones())
if (((GemSocketsData) gemStory.getGemstoneData(gemDataUUID)).removeGem(gemUUID, color))
return;
// Attempt externals // Attempt externals
for (StatData externalData : gemStory.getExternalData()) { if (GemSocketsData.removeGemFrom(((GemSocketsData) externalData), gemUUID, color)) { return; } } for (StatData externalData : gemStory.getExternalData())
if (((GemSocketsData) externalData).removeGem(gemUUID, color))
return;
// Attempt gems // Attempt gems
for (UUID gemDataUUID : gemStory.getAllModifiers()) { if (GemSocketsData.removeGemFrom(((GemSocketsData) gemStory.getModifiersBonus(gemDataUUID)), gemUUID, color)) { return; } } for (UUID gemDataUUID : gemStory.getAllModifiers())
if (((GemSocketsData) gemStory.getModifiersBonus(gemDataUUID)).removeGem(gemUUID, color))
return;
} }
//endregion //endregion
} }

View File

@ -2,8 +2,9 @@ package net.Indyuce.mmoitems.api.player;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.api.player.MMOPlayerData;
import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.api.player.MMOPlayerData;
import io.lumine.mythic.lib.api.stat.modifier.ModifierSource;
import io.lumine.mythic.lib.damage.AttackMetadata; import io.lumine.mythic.lib.damage.AttackMetadata;
import io.lumine.mythic.lib.skill.trigger.PassiveSkill; import io.lumine.mythic.lib.skill.trigger.PassiveSkill;
import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.ItemStats;
@ -36,7 +37,6 @@ import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
import java.util.logging.Level;
public class PlayerData { public class PlayerData {
private static final Map<UUID, PlayerData> data = new HashMap<>(); private static final Map<UUID, PlayerData> data = new HashMap<>();
@ -234,10 +234,12 @@ public class PlayerData {
/* /*
* Apply abilities * Apply abilities
*/ */
if (item.hasData(ItemStats.ABILITIES) && (MMOItems.plugin.getConfig().getBoolean("abilities-bypass-encumbering", false) || !fullHands)) if (item.hasData(ItemStats.ABILITIES) && (MMOItems.plugin.getConfig().getBoolean("abilities-bypass-encumbering") || !fullHands))
if (equipped.getSlot() != EquipmentSlot.OFF_HAND || !MMOItems.plugin.getConfig().getBoolean("disable-abilities-in-offhand")) if (equipped.getSlot() != EquipmentSlot.OFF_HAND || !MMOItems.plugin.getConfig().getBoolean("disable-abilities-in-offhand"))
for (AbilityData abilityData : ((AbilityListData) item.getData(ItemStats.ABILITIES)).getAbilities()) for (AbilityData abilityData : ((AbilityListData) item.getData(ItemStats.ABILITIES)).getAbilities()) {
mmoData.registerSkillTrigger(new PassiveSkill("MMOItemsItem", abilityData.getTriggerType(), abilityData)); ModifierSource modSource = equipped.getItem().getType() == null ? ModifierSource.OTHER : equipped.getItem().getType().getItemSet().getModifierSource();
mmoData.registerSkillTrigger(new PassiveSkill("MMOItemsItem", abilityData.getTriggerType(), abilityData, equipped.getSlot(), modSource));
}
/* /*
* Apply permissions if vault exists * Apply permissions if vault exists
@ -314,7 +316,7 @@ public class PlayerData {
return; return;
// perm effects // perm effects
permanentEffects.keySet().forEach(effect -> getPlayer().addPotionEffect(permanentEffects.get(effect))); permanentEffects.values().forEach(effect -> getPlayer().addPotionEffect(effect));
// two handed // two handed
if (fullHands) if (fullHands)
@ -451,7 +453,9 @@ public class PlayerData {
// Might not be null, after all // Might not be null, after all
PlayerData observedData = data.get(uuid); PlayerData observedData = data.get(uuid);
if (observedData != null) { return observedData; } if (observedData != null) {
return observedData;
}
// Attempt to load // Attempt to load
load(uuid); load(uuid);

View File

@ -127,9 +127,9 @@ public class GemSockets extends ItemStat {
if (gTag != null) { if (gTag != null) {
try { try {
// INterpret as Json Object // Interpret as Json Object
JsonObject object = new JsonParser().parse((String) gTag.getValue()).getAsJsonObject(); JsonObject object = new JsonParser().parse((String) gTag.getValue()).getAsJsonObject();
GemSocketsData sockets = new GemSocketsData(toList(object.getAsJsonArray("EmptySlots"))); GemSocketsData sockets = new GemSocketsData(object.getAsJsonArray("EmptySlots"));
JsonArray array = object.getAsJsonArray("Gemstones"); JsonArray array = object.getAsJsonArray("Gemstones");
array.forEach(element -> sockets.add(new GemstoneData(element.getAsJsonObject()))); array.forEach(element -> sockets.add(new GemstoneData(element.getAsJsonObject())));
@ -148,12 +148,6 @@ public class GemSockets extends ItemStat {
return null; return null;
} }
private List<String> toList(JsonArray array) {
List<String> list = new ArrayList<>();
array.forEach(str -> list.add(str.getAsString()));
return list;
}
@Override @Override
public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) { public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) {
if (event.getAction() == InventoryAction.PICKUP_ALL) if (event.getAction() == InventoryAction.PICKUP_ALL)

View File

@ -1,56 +1,41 @@
package net.Indyuce.mmoitems.stat.data; package net.Indyuce.mmoitems.stat.data;
import java.util.*;
import io.lumine.mythic.lib.api.util.Ref;
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
import net.Indyuce.mmoitems.api.interaction.GemStone;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import org.apache.commons.lang.Validate;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder; import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder;
import net.Indyuce.mmoitems.stat.data.random.RandomStatData; import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
import net.Indyuce.mmoitems.stat.data.type.Mergeable; import net.Indyuce.mmoitems.stat.data.type.Mergeable;
import net.Indyuce.mmoitems.stat.data.type.StatData; import net.Indyuce.mmoitems.stat.data.type.StatData;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class GemSocketsData implements StatData, Mergeable, RandomStatData { import java.util.*;
@NotNull private final Set<GemstoneData> gems = new HashSet<>();
@NotNull private final List<String> emptySlots; /**
* A class containing all the information about gemstones on
* an MMOItem. This contains the information of all the item modifiers
* applied by a gem stone as well as the empty gem sockets.
* <p>
* When used as a {@link RandomStatData}, the 'gems' set is useless
* because items do not come with gems applied to it when generated.
*/
public class GemSocketsData implements Mergeable, RandomStatData {
@NotNull
private final Set<GemstoneData> gems = new HashSet<>();
@NotNull
private final List<String> emptySlots;
public GemSocketsData(@NotNull List<String> emptySlots) { public GemSocketsData(@NotNull List<String> emptySlots) {
this.emptySlots = emptySlots; this.emptySlots = emptySlots;
} }
@Override public GemSocketsData(@NotNull JsonArray emptySlots) {
public boolean equals(Object obj) { this.emptySlots = new ArrayList<>();
if (!(obj instanceof GemSocketsData)) { return false; }
if (((GemSocketsData) obj).getEmptySlots().size() != getEmptySlots().size()) { return false; }
if (((GemSocketsData) obj).getGemstones().size() != getGemstones().size()) { return false; }
if (!SilentNumbers.hasAll(((GemSocketsData) obj).getEmptySlots(), getEmptySlots())) { return false; }
for (GemstoneData objGem : ((GemSocketsData) obj).getGemstones()) { emptySlots.forEach(el -> this.emptySlots.add(el.getAsString()));
if (objGem == null) { continue; }
// Validate with ours
boolean unmatched = true;
for (GemstoneData thisGem : getGemstones()) {
// Test match
if (objGem.equals(thisGem)) {
unmatched = false;
break; }
}
if (unmatched) { return false; } }
// All equal
return true;
} }
/** /**
@ -64,75 +49,65 @@ public class GemSocketsData implements StatData, Mergeable, RandomStatData {
} }
/** /**
* Get the first emtpty gem socket that matches this color * Get the first empty gem socket that matches this color.
*
* @return <code>null</code> if none matched. * @return <code>null</code> if none matched.
*/ */
@Nullable public String getEmptySocket(@NotNull String gem) { @Nullable
public String getEmptySocket(@NotNull String gem) {
for (String slot : emptySlots) for (String slot : emptySlots)
if (gem.equals("") || slot.equals(getUncoloredGemSlot()) || gem.equals(slot)) if (gem.equals("") || slot.equals(getUncoloredGemSlot()) || gem.equals(slot))
return slot; return slot;
return null; return null;
} }
@NotNull public static String getUncoloredGemSlot() { String s = MMOItems.plugin.getConfig().getString("gem-sockets.uncolored"); return s == null ? "Uncolored" : s; } @NotNull
public static String getUncoloredGemSlot() {
String s = MMOItems.plugin.getConfig().getString("gem-sockets.uncolored");
return s == null ? "Uncolored" : s;
}
public void add(GemstoneData gem) { public void add(GemstoneData gem) {
gems.add(gem); gems.add(gem);
} }
public void apply(String gem, GemstoneData gemstone) { emptySlots.remove(getEmptySocket(gem)); gems.add(gemstone); } public void apply(String gem, GemstoneData gemstone) {
emptySlots.remove(getEmptySocket(gem));
gems.add(gemstone);
}
public void addEmptySlot(@NotNull String slot) { public void addEmptySlot(@NotNull String slot) {
emptySlots.add(slot); emptySlots.add(slot);
} }
@NotNull public List<String> getEmptySlots() { @NotNull
public List<String> getEmptySlots() {
return emptySlots; return emptySlots;
} }
@NotNull public Set<GemstoneData> getGemstones() { @NotNull
public Set<GemstoneData> getGemstones() {
return gems; return gems;
} }
public void removeGem(@NotNull UUID gem) {
// Find
GemstoneData d = null;
for (GemstoneData data : getGemstones()) {
if (data.getHistoricUUID().equals(gem)) {
//GEM//MMOItems.log("\u00a7b*\u00a77 Found gem to unregister: \u00a7a" + data.getName());
d = data; break; }}
// Remove
gems.remove(d);
}
/** /**
* Removes such gem from this GemSocketsData, if it exists. * Removes such gem from this GemSocketsData, if it exists and
* registers again an empty gem socket if required
* *
* @param data The Data from which to remove the gem * @param gemId The unique ID of the gem to remove
* @param gemUUID The Gem to remove
* @param socket The socket color to replace the gem with, <code>null</code> for no socket. * @param socket The socket color to replace the gem with, <code>null</code> for no socket.
* @return Whether a gem was removed from the data. * @return Whether a gem was removed from the data.
*/ */
public static boolean removeGemFrom(@NotNull GemSocketsData data, @NotNull UUID gemUUID, @Nullable String socket) { public boolean removeGem(@NotNull UUID gemId, @Nullable String socket) {
for (GemstoneData data : getGemstones())
if (data.getHistoricUUID().equals(gemId)) {
if (socket != null)
addEmptySlot(socket);
gems.remove(data);
return true;
}
boolean removal = false; return false;
for (GemstoneData gem : data.getGemstones()) {
// Is it the one we are searching for?
if (gem.getHistoricUUID().equals(gemUUID)) {
// Found it, restore the socket and we're done.
if (socket != null) { data.addEmptySlot(socket); }
// Remove
removal = true; break; } }
// Its time.
if (removal) { data.removeGem(gemUUID); }
return removal;
} }
public JsonObject toJson() { public JsonObject toJson() {
@ -153,34 +128,29 @@ public class GemSocketsData implements StatData, Mergeable, RandomStatData {
public void merge(StatData data) { public void merge(StatData data) {
Validate.isTrue(data instanceof GemSocketsData, "Cannot merge two different stat data types"); Validate.isTrue(data instanceof GemSocketsData, "Cannot merge two different stat data types");
//MRG//MMOItems.log("\u00a73||| \u00a77Merging slots; Original:");
//MRG//for (String str : SilentNumbers.transcribeList(emptySlots, (s) -> "\u00a73|+ \u00a77" + ((String) s))) { MMOItems.log(str); }
//MRG//MMOItems.log("\u00a73||| \u00a77Including");
//MRG//for (String str : SilentNumbers.transcribeList(((GemSocketsData) data).emptySlots, (s) -> "\u00a73|+ \u00a77" + ((String) s))) { MMOItems.log(str); }
// Combine both actual gems, and empty slots // Combine both actual gems, and empty slots
emptySlots.addAll(((GemSocketsData) data).emptySlots); emptySlots.addAll(((GemSocketsData) data).emptySlots);
gems.addAll(((GemSocketsData) data).getGemstones()); gems.addAll(((GemSocketsData) data).getGemstones());
//MRG//MMOItems.log("\u00a73||| \u00a7aResult");
//MRG//for (String str : SilentNumbers.transcribeList(emptySlots, (s) -> "\u00a73|+ \u00a77" + ((String) s))) { MMOItems.log(str); }
//MRG//MMOItems.log("\u00a73||| \u00a7a---------------------------------------");
} }
@Override @Override
public @NotNull StatData cloneData() { public @NotNull
StatData cloneData() {
// Start Fresh // Clone empty slots
GemSocketsData ret = new GemSocketsData(new ArrayList<>(emptySlots)); GemSocketsData ret = new GemSocketsData(new ArrayList<>(emptySlots));
// Add Gems // Clone gems
for (GemstoneData g : getGemstones()) { ret.add(g.cloneGem()); } for (GemstoneData gem : getGemstones())
ret.add(gem.cloneGem());
return ret; return ret;
} }
@Override @Override
public boolean isClear() { return getGemstones().size() == 0 && getEmptySlots().size() == 0; } public boolean isClear() {
return getGemstones().size() == 0 && getEmptySlots().size() == 0;
}
@Override @Override
public StatData randomize(MMOItemBuilder builder) { public StatData randomize(MMOItemBuilder builder) {
@ -188,5 +158,47 @@ public class GemSocketsData implements StatData, Mergeable, RandomStatData {
} }
@Override @Override
public String toString() { return "Empty:\u00a7b " + getEmptySlots().size() + "\u00a77, Gems:\u00a7b " + getGemstones().size(); } public String toString() {
return "Empty:\u00a7b " + getEmptySlots().size() + "\u00a77, Gems:\u00a7b " + getGemstones().size();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof GemSocketsData)) {
return false;
}
if (((GemSocketsData) obj).getEmptySlots().size() != getEmptySlots().size()) {
return false;
}
if (((GemSocketsData) obj).getGemstones().size() != getGemstones().size()) {
return false;
}
if (!SilentNumbers.hasAll(((GemSocketsData) obj).getEmptySlots(), getEmptySlots())) {
return false;
}
for (GemstoneData objGem : ((GemSocketsData) obj).getGemstones()) {
if (objGem == null) {
continue;
}
// Validate with ours
boolean unmatched = true;
for (GemstoneData thisGem : getGemstones()) {
// Test match
if (objGem.equals(thisGem)) {
unmatched = false;
break;
}
}
if (unmatched) {
return false;
}
}
// All equal
return true;
}
} }

View File

@ -3,15 +3,10 @@ package net.Indyuce.mmoitems.stat.data;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.MMOUtils; import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem; import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.stat.GemUpgradeScaling; import net.Indyuce.mmoitems.stat.GemUpgradeScaling;
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
import net.Indyuce.mmoitems.stat.data.type.StatData;
import net.Indyuce.mmoitems.stat.type.ItemStat; import net.Indyuce.mmoitems.stat.type.ItemStat;
import net.Indyuce.mmoitems.stat.type.StatHistory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -19,22 +14,31 @@ import java.util.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class GemstoneData { public class GemstoneData {
@NotNull private final Set<AbilityData> abilities = new HashSet<>(); private final Set<AbilityData> abilities = new HashSet<>();
@NotNull private final List<PotionEffectData> effects = new ArrayList<>(); private final List<PotionEffectData> effects = new ArrayList<>();
@NotNull private final Map<ItemStat, Double> stats = new HashMap<>(); private final Map<ItemStat, Double> stats = new HashMap<>();
@NotNull private final String name; private final String name;
@Nullable Integer levelPut; @NotNull
@NotNull final UUID historicUUID; private final UUID historicUUID;
@Nullable final String mmoitemType; @Nullable
@Nullable final String mmoitemID; private final String mmoitemType;
@Nullable String socketColor; @Nullable
private final String mmoitemID;
@Nullable
private String socketColor;
@Nullable
private Integer levelPut;
public GemstoneData cloneGem() { public GemstoneData cloneGem() {
GemstoneData ret = new GemstoneData(getName(), getMMOItemType(), getMMOItemID(), getSocketColor(), getHistoricUUID()); GemstoneData ret = new GemstoneData(getName(), getMMOItemType(), getMMOItemID(), getSocketColor(), getHistoricUUID());
for (AbilityData d : abilities) { ret.addAbility(d); } for (AbilityData d : abilities)
for (PotionEffectData d : effects) { ret.addPermanentEffect(d); } ret.addAbility(d);
for (ItemStat d : stats.keySet()) { ret.setStat(d, stats.get(d)); } for (PotionEffectData d : effects)
ret.addPermanentEffect(d);
for (ItemStat d : stats.keySet())
ret.setStat(d, stats.get(d));
ret.setLevel(getLevel()); ret.setLevel(getLevel());
return ret; return ret;
@ -49,7 +53,9 @@ public class GemstoneData {
*/ */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (!(obj instanceof GemstoneData)) { return false; } if (!(obj instanceof GemstoneData)) {
return false;
}
return ((GemstoneData) obj).getHistoricUUID().equals(getHistoricUUID()); return ((GemstoneData) obj).getHistoricUUID().equals(getHistoricUUID());
} }
@ -97,29 +103,54 @@ public class GemstoneData {
// Its of this gen of gemstones... // Its of this gen of gemstones...
String hUUID = uuid.getAsString(); String hUUID = uuid.getAsString();
UUID hisUUID = MMOUtils.UUIDFromString(hUUID); UUID hisUUID = MMOUtils.UUIDFromString(hUUID);
if (hisUUID != null) { historicUUID = hisUUID; } if (hisUUID != null) {
else { historicUUID = UUID.randomUUID(); } historicUUID = hisUUID;
} else {
historicUUID = UUID.randomUUID();
}
// Get Type and IDs // Get Type and IDs
JsonElement gType = object.get("Type"); JsonElement gType = object.get("Type");
JsonElement gID = object.get("Id"); JsonElement gID = object.get("Id");
if (gType != null) { mmoitemType = gType.getAsString(); } else { mmoitemType = null; } if (gType != null) {
if (gID != null) { mmoitemID = gID.getAsString(); } else { mmoitemID = null; } mmoitemType = gType.getAsString();
} else {
mmoitemType = null;
}
if (gID != null) {
mmoitemID = gID.getAsString();
} else {
mmoitemID = null;
}
JsonElement level = object.get("Level"); JsonElement level = object.get("Level");
if (level != null && level.isJsonPrimitive()) { levelPut = level.getAsJsonPrimitive().getAsInt(); } else { levelPut = null; } if (level != null && level.isJsonPrimitive()) {
levelPut = level.getAsJsonPrimitive().getAsInt();
} else {
levelPut = null;
}
//LVL//MMOItems.log("\u00a73 -\u00a7b-\u00a73-\u00a77 Read Level: \u00a7b" + levelPut); //LVL//MMOItems.log("\u00a73 -\u00a7b-\u00a73-\u00a77 Read Level: \u00a7b" + levelPut);
JsonElement color = object.get("Color"); JsonElement color = object.get("Color");
if (color != null && color.isJsonPrimitive()) { socketColor = color.getAsJsonPrimitive().getAsString(); } else { socketColor = null; } if (color != null && color.isJsonPrimitive()) {
socketColor = color.getAsJsonPrimitive().getAsString();
} else {
socketColor = null;
}
} else { historicUUID = UUID.randomUUID(); mmoitemID = null; mmoitemType = null; socketColor = null; } } else {
historicUUID = UUID.randomUUID();
mmoitemID = null;
mmoitemType = null;
socketColor = null;
}
} }
/** /**
* Create a GemStoneData from a GemStone MMOItem. * Create a GemStoneData from a GemStone MMOItem.
* <p></p> * <p></p>
* Basically extracts all the useable stats from the MMOItem, to have them ready to apply onto another MMOItem. * Basically extracts all the useable stats from the MMOItem, to have them ready to apply onto another MMOItem.
*
* @param color Color of the slot this gem was inserted onto. * @param color Color of the slot this gem was inserted onto.
*/ */
public GemstoneData(@NotNull LiveMMOItem gemStoneMMOItem, @Nullable String color) { public GemstoneData(@NotNull LiveMMOItem gemStoneMMOItem, @Nullable String color) {
@ -128,10 +159,14 @@ public class GemstoneData {
name = MMOUtils.getDisplayName(gemStoneMMOItem.getNBT().getItem()); name = MMOUtils.getDisplayName(gemStoneMMOItem.getNBT().getItem());
// Extract abilities from the Gem Stone MMOItem into a more accessible form // Extract abilities from the Gem Stone MMOItem into a more accessible form
if (gemStoneMMOItem.hasData(ItemStats.ABILITIES)) { abilities.addAll(((AbilityListData) gemStoneMMOItem.getData(ItemStats.ABILITIES)).getAbilities()); } if (gemStoneMMOItem.hasData(ItemStats.ABILITIES)) {
abilities.addAll(((AbilityListData) gemStoneMMOItem.getData(ItemStats.ABILITIES)).getAbilities());
}
// Extract permenent effects from the Gem Stone MMOItem into a more accessible form // Extract permenent effects from the Gem Stone MMOItem into a more accessible form
if (gemStoneMMOItem.hasData(ItemStats.PERM_EFFECTS)) { effects.addAll(((PotionEffectListData) gemStoneMMOItem.getData(ItemStats.PERM_EFFECTS)).getEffects()); } if (gemStoneMMOItem.hasData(ItemStats.PERM_EFFECTS)) {
effects.addAll(((PotionEffectListData) gemStoneMMOItem.getData(ItemStats.PERM_EFFECTS)).getEffects());
}
// Generate own historic UUID // Generate own historic UUID
@ -146,8 +181,9 @@ public class GemstoneData {
* <p></p> * <p></p>
* You may add whatever you want with <code>addAbility()</code>,<code>addPermamentEffect</code>, or most widely usedly, <code>setStat()</code>. * You may add whatever you want with <code>addAbility()</code>,<code>addPermamentEffect</code>, or most widely usedly, <code>setStat()</code>.
* <p></p> * <p></p>
* @deprecated This gem stone will not have a type/id and will cause problems when trying to remove it from items with a consumable. *
* @param name Name to display in the lore of the item when you put the gemstone into it. * @param name Name to display in the lore of the item when you put the gemstone into it.
* @deprecated This gem stone will not have a type/id and will cause problems when trying to remove it from items with a consumable.
*/ */
public GemstoneData(@NotNull String name) { public GemstoneData(@NotNull String name) {
this.name = name; this.name = name;
@ -165,24 +201,32 @@ public class GemstoneData {
*/ */
public void setLevel(@Nullable Integer l) { public void setLevel(@Nullable Integer l) {
//LVL//MMOItems.log("\u00a73 -\u00a7b-\u00a73-\u00a77 Set Level: \u00a7b" + l); //LVL//MMOItems.log("\u00a73 -\u00a7b-\u00a73-\u00a77 Set Level: \u00a7b" + l);
levelPut = l; } levelPut = l;
}
/** /**
* This is at which level (of the item) the gemstone was placed onto the item. * This is at which level (of the item) the gemstone was placed onto the item.
* <p>A null level means this gem does not scale.</p> * <p>A null level means this gem does not scale.</p>
* <p></p> * <p></p>
* For scaling purposes of stat {@link GemUpgradeScaling} * For scaling purposes of stat {@link GemUpgradeScaling}
*/ */
@Nullable public Integer getLevel() { return levelPut; } @Nullable
public Integer getLevel() {
return levelPut;
}
/** /**
* Does this gem scale with item upgrades? * Does this gem scale with item upgrades?
*/ */
public boolean isScaling() { return levelPut != null; } public boolean isScaling() {
return levelPut != null;
}
/** /**
* This is a completely empty builder. * This is a completely empty builder.
* <p></p> * <p></p>
* You may add whatever you want with <code>addAbility()</code>,<code>addPermamentEffect</code>, or most widely usedly, <code>setStat()</code>. * You may add whatever you want with <code>addAbility()</code>,<code>addPermamentEffect</code>, or most widely usedly, <code>setStat()</code>.
*
* @param name Name to display in the lore of the item when you put the gemstone into it. * @param name Name to display in the lore of the item when you put the gemstone into it.
* @param color Color of the socket this gem is inserted onto * @param color Color of the socket this gem is inserted onto
*/ */
@ -191,12 +235,14 @@ public class GemstoneData {
mmoitemID = id; mmoitemID = id;
mmoitemType = type; mmoitemType = type;
socketColor = color; socketColor = color;
historicUUID = UUID.randomUUID(); } historicUUID = UUID.randomUUID();
}
/** /**
* This is a completely empty builder. * This is a completely empty builder.
* <p></p> * <p></p>
* You may add whatever you want with <code>addAbility()</code>,<code>addPermamentEffect</code>, or most widely usedly, <code>setStat()</code>. * You may add whatever you want with <code>addAbility()</code>,<code>addPermamentEffect</code>, or most widely usedly, <code>setStat()</code>.
*
* @param name Name to display in the lore of the item when you put the gemstone into it. * @param name Name to display in the lore of the item when you put the gemstone into it.
* @param color Color of the socket this gem is inserted onto * @param color Color of the socket this gem is inserted onto
*/ */
@ -205,7 +251,8 @@ public class GemstoneData {
mmoitemID = id; mmoitemID = id;
mmoitemType = type; mmoitemType = type;
socketColor = color; socketColor = color;
historicUUID = uiid; } historicUUID = uiid;
}
/** /**
* Add an ability to this Gem Stone * Add an ability to this Gem Stone
@ -231,34 +278,44 @@ public class GemstoneData {
/** /**
* Get the display text for when this is put into lore. * Get the display text for when this is put into lore.
*/ */
@NotNull public String getName() { @NotNull
public String getName() {
return name; return name;
} }
/** /**
* If known, the socket colour this gem was put into * If known, the socket colour this gem was put into
*/ */
public void setColour(@Nullable String color) { socketColor = color; } public void setColour(@Nullable String color) {
socketColor = color;
}
/** /**
* Want to know which stats were given to the item by this gemstone (after applying upgrade scaling and such)? Use this! * Want to know which stats were given to the item by this gemstone (after applying upgrade scaling and such)? Use this!
*/ */
@NotNull public UUID getHistoricUUID() { @NotNull
public UUID getHistoricUUID() {
return historicUUID; return historicUUID;
} }
/** /**
* To store onto the NBT of the item. * To store onto the NBT of the item.
*/ */
@NotNull public JsonObject toJson() { @NotNull
public JsonObject toJson() {
JsonObject object = new JsonObject(); JsonObject object = new JsonObject();
object.addProperty("Name", name); object.addProperty("Name", name);
object.addProperty("History", historicUUID.toString()); object.addProperty("History", historicUUID.toString());
if (mmoitemID != null) { object.addProperty("Id", mmoitemID); } if (mmoitemID != null) {
if (mmoitemType != null) { object.addProperty("Type", mmoitemType); } object.addProperty("Id", mmoitemID);
}
if (mmoitemType != null) {
object.addProperty("Type", mmoitemType);
}
if (levelPut != null) { if (levelPut != null) {
//LVL//MMOItems.log("\u00a73 -\u00a7b-\u00a73-\u00a77 Saving Level: \u00a7b" + levelPut); //LVL//MMOItems.log("\u00a73 -\u00a7b-\u00a73-\u00a77 Saving Level: \u00a7b" + levelPut);
object.addProperty("Level", levelPut); } object.addProperty("Level", levelPut);
}
object.addProperty("Color", socketColor); object.addProperty("Color", socketColor);
/* /*

View File

@ -4,7 +4,6 @@ import net.Indyuce.mmoitems.stat.data.type.Mergeable;
import net.Indyuce.mmoitems.stat.data.type.StatData; import net.Indyuce.mmoitems.stat.data.type.StatData;
import net.Indyuce.mmoitems.stat.type.ItemStat; import net.Indyuce.mmoitems.stat.type.ItemStat;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/** /**
* When updating items with the RevID system, an interesting case is when * When updating items with the RevID system, an interesting case is when
@ -12,6 +11,9 @@ import org.jetbrains.annotations.Nullable;
* roll in a player's item... unless this roll was unobtainable now, perhaps * roll in a player's item... unless this roll was unobtainable now, perhaps
* the reason the item is getting updated is to fix that roll being too good... * the reason the item is getting updated is to fix that roll being too good...
* *
* Example of unobtainable data: the current numeric stat value is now out
* of the numeric formula bounds (defined by max-spread).
*
* This interface will tell the {@link net.Indyuce.mmoitems.api.util.MMOItemReforger} * This interface will tell the {@link net.Indyuce.mmoitems.api.util.MMOItemReforger}
* if the current roll may be kept, or it is too extreme (under the updated metrics) * if the current roll may be kept, or it is too extreme (under the updated metrics)
* to be considered 'obtainable' and thus must be removed. * to be considered 'obtainable' and thus must be removed.

View File

@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull;
* <b>Strongly encouraged to override the <code>equals</code> method * <b>Strongly encouraged to override the <code>equals</code> method
* to something fitting here as Mergeable stats should support comparisons.</b> * to something fitting here as Mergeable stats should support comparisons.</b>
*/ */
public interface Mergeable { public interface Mergeable extends StatData {
/** /**
* Merging two stat data is used when either applying a gem stone to an item * Merging two stat data is used when either applying a gem stone to an item

View File

@ -1,6 +1,9 @@
package net.Indyuce.mmoitems.stat.type; package net.Indyuce.mmoitems.stat.type;
import com.google.gson.*; import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.lumine.mythic.lib.api.item.ItemTag; import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory;
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
@ -9,7 +12,9 @@ import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.MMOUtils; import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem; import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems; import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
import net.Indyuce.mmoitems.stat.data.*; import net.Indyuce.mmoitems.stat.data.EnchantListData;
import net.Indyuce.mmoitems.stat.data.GemSocketsData;
import net.Indyuce.mmoitems.stat.data.GemstoneData;
import net.Indyuce.mmoitems.stat.data.type.Mergeable; import net.Indyuce.mmoitems.stat.data.type.Mergeable;
import net.Indyuce.mmoitems.stat.data.type.StatData; import net.Indyuce.mmoitems.stat.data.type.StatData;
import net.Indyuce.mmoitems.stat.data.type.UpgradeInfo; import net.Indyuce.mmoitems.stat.data.type.UpgradeInfo;
@ -30,12 +35,29 @@ import java.util.*;
*/ */
@SuppressWarnings({"unused", "SpellCheckingInspection"}) @SuppressWarnings({"unused", "SpellCheckingInspection"})
public class StatHistory { public class StatHistory {
/*
* Which stat is this the history of?
*/
@NotNull
private final ItemStat itemStat; private final ItemStat itemStat;
private final MMOItem parent;
/**
* The final modifier being provided by each gemstone.
* GemStones may have scaled with upgrades, that will be accounted for.
* <p>
* Gem stones all have a UUID bound to them so that MI knows
* what modifiers to take away when removing gem stones.
*/
public final HashMap<UUID, StatData> perGemstoneData = new HashMap<>();
/**
* The total bonus given by modifiers that
* were rolled when the item was first created.
*/
public final HashMap<UUID, StatData> perModifierBonus = new HashMap<>();
private static final String enc_Stat = "Stat";
private static final String enc_OGS = "OGStory";
private static final String enc_GSS = "Gemstory";
private static final String enc_EXS = "Exstory";
private static final String enc_MOD = "Mod";
/** /**
* Which stat is this the history of? * Which stat is this the history of?
@ -81,11 +103,6 @@ public class StatHistory {
return getOriginalData().equals(getMMOItem().getData(getItemStat())); return getOriginalData().equals(getMMOItem().getData(getItemStat()));
} }
/*
* What MMOItem is this StatHistory linked to?
*/
@NotNull
MMOItem parent;
/** /**
* What MMOItem is this StatHistory linked to? * What MMOItem is this StatHistory linked to?
@ -124,13 +141,6 @@ public class StatHistory {
originalData = s; originalData = s;
} }
/**
* The total bonus given by modifiers that
* were rolled when the item was first created.
*/
@NotNull
public HashMap<UUID, StatData> perModifierBonus = new HashMap<>();
/** /**
* @return The total bonus given by modifiers that * @return The total bonus given by modifiers that
* were rolled when the item was first created. * were rolled when the item was first created.
@ -169,17 +179,14 @@ public class StatHistory {
public ArrayList<UUID> getAllModifiers() { public ArrayList<UUID> getAllModifiers() {
return new ArrayList<>(perModifierBonus.keySet()); return new ArrayList<>(perModifierBonus.keySet());
} }
/** /**
* Clears modifier data. No way to undo so be wary of using. * Clears modifier data. No way to undo so be wary of using.
*/ */
public void clearModifiersBonus() { perModifierBonus.clear(); } public void clearModifiersBonus() {
perModifierBonus.clear();
}
/*
* The final modifier being provided by each gemstone.
* GemStones may have scaled with upgrades, that will be accounted for.
*/
@NotNull
public HashMap<UUID, StatData> perGemstoneData = new HashMap<>();
/** /**
* The final modifier being provided by each gemstone. * The final modifier being provided by each gemstone.
* GemStones may have scaled with upgrades, that will be accounted for. * GemStones may have scaled with upgrades, that will be accounted for.
@ -192,17 +199,24 @@ public class StatHistory {
} }
return perGemstoneData.get(of); return perGemstoneData.get(of);
} }
/** /**
* Removes the gem of such UUID from those registered. * Removes the gem of such UUID from those registered.
* *
* @param of UUID of the gem to remove. * @param of UUID of the gem to remove.
*/ */
public void removeGemData(@NotNull UUID of) { perGemstoneData.remove(of); } public void removeGemData(@NotNull UUID of) {
perGemstoneData.remove(of);
}
/** /**
* All the Stat Datas provided by GemStones * All the Stat Datas provided by GemStones
*/ */
@NotNull @NotNull
public ArrayList<UUID> getAllGemstones() { return new ArrayList<>(perGemstoneData.keySet()); } public ArrayList<UUID> getAllGemstones() {
return new ArrayList<>(perGemstoneData.keySet());
}
/** /**
* The final modifier being provided by each gemstone. * The final modifier being provided by each gemstone.
* GemStones may have scaled with upgrades, that will be accounted for. * GemStones may have scaled with upgrades, that will be accounted for.
@ -211,11 +225,16 @@ public class StatHistory {
* <p>originally <code>+5</code>, now at level 2, with <code>+0.25</code> per level</p> * <p>originally <code>+5</code>, now at level 2, with <code>+0.25</code> per level</p>
* The value of this stat data will be <b><code>+5.5</code></b> * The value of this stat data will be <b><code>+5.5</code></b>
*/ */
public void registerGemstoneData(@NotNull UUID of, @NotNull StatData data) { perGemstoneData.put(of, data); } public void registerGemstoneData(@NotNull UUID of, @NotNull StatData data) {
perGemstoneData.put(of, data);
}
/** /**
* Clears gemstone data. No way to undo so be wary of using. * Clears gemstone data. No way to undo so be wary of using.
*/ */
public void clearGemstones() { perGemstoneData.clear(); } public void clearGemstones() {
perGemstoneData.clear();
}
/* /*
* Modifiers of unknown origin. * Modifiers of unknown origin.
@ -235,7 +254,10 @@ public class StatHistory {
* Well, I guess whatever plugin is putting them here may remove them by editing the list directly with <code>StatHistory.getExternalData()</code> * Well, I guess whatever plugin is putting them here may remove them by editing the list directly with <code>StatHistory.getExternalData()</code>
*/ */
@NotNull @NotNull
public ArrayList<StatData> getExternalData() { return perExternalData; } public ArrayList<StatData> getExternalData() {
return perExternalData;
}
/** /**
* Collapses all ExSH stat data into one. * Collapses all ExSH stat data into one.
*/ */
@ -256,6 +278,7 @@ public class StatHistory {
getExternalData().clear(); getExternalData().clear();
registerExternalData(theEXSH); registerExternalData(theEXSH);
} }
/** /**
* Modifiers of unknown origin. * Modifiers of unknown origin.
* Presumably put here by external plugins I guess. * Presumably put here by external plugins I guess.
@ -264,11 +287,16 @@ public class StatHistory {
* <p>They act as gem stones, adding together to produce the total of the item, but cannot be removed, since there is no way to tell them from each other.</p> * <p>They act as gem stones, adding together to produce the total of the item, but cannot be removed, since there is no way to tell them from each other.</p>
* Well, I guess whatever plugin is putting them here may remove them by editing the list directly with <code>StatHistory.getExternalData()</code> * Well, I guess whatever plugin is putting them here may remove them by editing the list directly with <code>StatHistory.getExternalData()</code>
*/ */
public void registerExternalData(@NotNull StatData data) { perExternalData.add(data); } public void registerExternalData(@NotNull StatData data) {
perExternalData.add(data);
}
/** /**
* Clears exsh data. No way to undo so be wary of using. * Clears exsh data. No way to undo so be wary of using.
*/ */
public void clearExternalData() { perExternalData.clear(); } public void clearExternalData() {
perExternalData.clear();
}
/** /**
* Gets the stat history of this item. <b>The stat must be <code>Mergeable</code></b> * Gets the stat history of this item. <b>The stat must be <code>Mergeable</code></b>
@ -281,7 +309,11 @@ public class StatHistory {
* @param ofItem MMOItem to extract stat history from * @param ofItem MMOItem to extract stat history from
* @param ofStat Stat of which to make history * @param ofStat Stat of which to make history
*/ */
@NotNull public static StatHistory from(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat) { return from(ofItem, ofStat, false); } @NotNull
public static StatHistory from(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat) {
return from(ofItem, ofStat, false);
}
/** /**
* Gets the stat history of this item. <b>The stat must be <code>Mergeable</code></b> * Gets the stat history of this item. <b>The stat must be <code>Mergeable</code></b>
* <p></p> * <p></p>
@ -306,7 +338,9 @@ public class StatHistory {
if (hist != null) { if (hist != null) {
//UPGRD//MMOItems.log("Found Stat History of \u00a76" + ofStat.getNBTPath() + "\u00a77 in this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId()); //UPGRD//MMOItems.log("Found Stat History of \u00a76" + ofStat.getNBTPath() + "\u00a77 in this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId());
//UPGRD//hist.log(); //UPGRD//hist.log();
return hist; } } return hist;
}
}
// That is Mergeable right... // That is Mergeable right...
//UPGRD//MMOItems.log("\u00a7aCreated Hisotry of \u00a76" + ofStat.getNBTPath() + "\u00a7a of this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId()); //UPGRD//MMOItems.log("\u00a7aCreated Hisotry of \u00a76" + ofStat.getNBTPath() + "\u00a7a of this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId());
@ -345,7 +379,11 @@ public class StatHistory {
* <p></p> * <p></p>
* Use <code>StatHistory.From()</code> to get the stat history associated to an item. * Use <code>StatHistory.From()</code> to get the stat history associated to an item.
*/ */
public StatHistory(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat, @NotNull StatData ogData) { itemStat = ofStat; originalData = ogData; parent = ofItem; } public StatHistory(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat, @NotNull StatData ogData) {
itemStat = ofStat;
originalData = ogData;
parent = ofItem;
}
/** /**
* Checks the item and makes sure that the UUIDs * Checks the item and makes sure that the UUIDs
@ -357,7 +395,9 @@ public class StatHistory {
// Which will get purged... // Which will get purged...
ArrayList<UUID> extraneous = new ArrayList<>(); ArrayList<UUID> extraneous = new ArrayList<>();
GemSocketsData data = (GemSocketsData) getMMOItem().getData(ItemStats.GEM_SOCKETS); GemSocketsData data = (GemSocketsData) getMMOItem().getData(ItemStats.GEM_SOCKETS);
if (data == null) { data = new GemSocketsData(new ArrayList<>()); } if (data == null) {
data = new GemSocketsData(new ArrayList<>());
}
// For each UUID // For each UUID
for (UUID gem : perGemstoneData.keySet()) { for (UUID gem : perGemstoneData.keySet()) {
@ -401,7 +441,9 @@ public class StatHistory {
public boolean isUpgradeable() { public boolean isUpgradeable() {
// No upgrades no possible // No upgrades no possible
if (!getMMOItem().hasUpgradeTemplate()) { return false; } if (!getMMOItem().hasUpgradeTemplate()) {
return false;
}
// Get Upgrade Info? // Get Upgrade Info?
UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat()); UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat());
@ -416,20 +458,28 @@ public class StatHistory {
* This will not apply the changes, it will just give you the final * This will not apply the changes, it will just give you the final
* <code>StatData</code> that shall be applied (used when upgrading). * <code>StatData</code> that shall be applied (used when upgrading).
*/ */
@NotNull public StatData recalculate(int level) { return recalculate(true, level); } @NotNull
public StatData recalculate(int level) {
return recalculate(true, level);
}
/** /**
* This recalculates final value of the stats of the item. * This recalculates final value of the stats of the item.
* <p></p> * <p></p>
* This will not apply the changes, it will just give you the final * This will not apply the changes, it will just give you the final
* <code>StatData</code> that shall be applied (used when upgrading). * <code>StatData</code> that shall be applied (used when upgrading).
*
* @param withPurge Check if the gemstones UUIDs are valid. * @param withPurge Check if the gemstones UUIDs are valid.
* Leave <code>true</code> unless you know * Leave <code>true</code> unless you know
* what you're doing. * what you're doing.
*/ */
@NotNull public StatData recalculate(boolean withPurge, int level) { @NotNull
public StatData recalculate(boolean withPurge, int level) {
//RECALCULATE//MMOItems.log("\u00a7d|||\u00a77 Recalculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77, Purge? \u00a7e" + withPurge); //RECALCULATE//MMOItems.log("\u00a7d|||\u00a77 Recalculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77, Purge? \u00a7e" + withPurge);
if (withPurge) { purgeGemstones(); } if (withPurge) {
purgeGemstones();
}
// If its upgradeable and not level ZERO, it must apply upgrades // If its upgradeable and not level ZERO, it must apply upgrades
//UPGRD//MMOItems.log("\u00a7d|\u00a79|\u00a76|\u00a77 Upgradeable Requirements: "); //UPGRD//MMOItems.log("\u00a7d|\u00a79|\u00a76|\u00a77 Upgradeable Requirements: ");
@ -454,19 +504,26 @@ public class StatHistory {
* In case someone was wondered the contribution of upgrading the item, just * In case someone was wondered the contribution of upgrading the item, just
* substract it from {@link #recalculate(int)} * substract it from {@link #recalculate(int)}
*/ */
@NotNull public StatData recalculateUnupgraded() { return recalculateUnupgraded(true); } @NotNull
public StatData recalculateUnupgraded() {
return recalculateUnupgraded(true);
}
/** /**
* This recalculates values accounting only for gemstones and external data. * This recalculates values accounting only for gemstones and external data.
* <p></p> * <p></p>
* In case someone was wondered the contribution of upgrading the item, just * In case someone was wondered the contribution of upgrading the item, just
* substract it from {@link #recalculate(int)} * substract it from {@link #recalculate(int)}
*
* @param withPurge Check if the gemstones UUIDs are valid. * @param withPurge Check if the gemstones UUIDs are valid.
* Leave <code>true</code> unless you know * Leave <code>true</code> unless you know
* what you're doing. * what you're doing.
*/ */
@NotNull public StatData recalculateUnupgraded(boolean withPurge) { @NotNull
if (withPurge) { purgeGemstones(); } public StatData recalculateUnupgraded(boolean withPurge) {
if (withPurge) {
purgeGemstones();
}
// Merge Normally // Merge Normally
return recalculateMergeable(); return recalculateMergeable();
@ -489,7 +546,9 @@ public class StatHistory {
UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat()); UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat());
// No Upgrade Information? Looks like you're calculating as a normal merge stat // No Upgrade Information? Looks like you're calculating as a normal merge stat
if (inf == null) { return recalculateMergeable(); } if (inf == null) {
return recalculateMergeable();
}
// Clone original // Clone original
StatData ogCloned = ((Mergeable) originalData).cloneData(); StatData ogCloned = ((Mergeable) originalData).cloneData();
@ -516,7 +575,9 @@ public class StatHistory {
// Whats this gemstone's upgrade level? // Whats this gemstone's upgrade level?
for (GemstoneData gData : getMMOItem().getGemStones()) { for (GemstoneData gData : getMMOItem().getGemStones()) {
if (gData == null) { continue; } if (gData == null) {
continue;
}
//RECALCULATE//MMOItems.log("\u00a76 -\u00a7b-\u00a76-\u00a77 Gemstone " + gData.getName() + "\u00a77 " + gData.getHistoricUUID().toString()); //RECALCULATE//MMOItems.log("\u00a76 -\u00a7b-\u00a76-\u00a77 Gemstone " + gData.getName() + "\u00a77 " + gData.getHistoricUUID().toString());
// Find that one of matching UUID // Find that one of matching UUID
@ -597,7 +658,8 @@ public class StatHistory {
// Add up externals // Add up externals
for (StatData d : getExternalData()) { for (StatData d : getExternalData()) {
//DBL//if (d instanceof DoubleData) MMOItems.log("\u00a73 >\u00a7c> \u00a77 Extraneous Base: \u00a7e" + ((DoubleData) d).getValue()); //DBL//if (d instanceof DoubleData) MMOItems.log("\u00a73 >\u00a7c> \u00a77 Extraneous Base: \u00a7e" + ((DoubleData) d).getValue());
((Mergeable) ret).merge(((Mergeable) d).cloneData()); } ((Mergeable) ret).merge(((Mergeable) d).cloneData());
}
// Return result // Return result
//DBL//if (ret instanceof DoubleData) MMOItems.log("\u00a73:::\u00a77 Result: \u00a7b" + ((DoubleData) ret).getValue()); //DBL//if (ret instanceof DoubleData) MMOItems.log("\u00a73:::\u00a77 Result: \u00a7b" + ((DoubleData) ret).getValue());
@ -612,14 +674,17 @@ public class StatHistory {
* <p></p> * <p></p>
* Still don't abuse calls to this. Try to do so only when necessary * Still don't abuse calls to this. Try to do so only when necessary
*/ */
@NotNull public JsonObject toJson() { @NotNull
public JsonObject toJson() {
JsonObject object = new JsonObject(); JsonObject object = new JsonObject();
// To know the stat it was // To know the stat it was
object.addProperty(enc_Stat, getItemStat().getId()); object.addProperty(enc_Stat, getItemStat().getId());
// Original data // Original data
if (!((Mergeable) getOriginalData()).isClear()) { object.add(enc_OGS, ItemTag.compressTags(getItemStat().getAppliedNBT(getOriginalData()))); } if (!((Mergeable) getOriginalData()).isClear()) {
object.add(enc_OGS, ItemTag.compressTags(getItemStat().getAppliedNBT(getOriginalData())));
}
// Kompress Arrays // Kompress Arrays
JsonArray gemz = new JsonArray(); JsonArray gemz = new JsonArray();
@ -642,7 +707,9 @@ public class StatHistory {
} }
// Include // Include
if (gemz.size() > 0) { object.add(enc_GSS, gemz); } if (gemz.size() > 0) {
object.add(enc_GSS, gemz);
}
// Kompress Arrays // Kompress Arrays
@ -652,14 +719,18 @@ public class StatHistory {
for (StatData ex : getExternalData()) { for (StatData ex : getExternalData()) {
// Skip clear // Skip clear
if (((Mergeable) ex).isClear()) { continue; } if (((Mergeable) ex).isClear()) {
continue;
}
// Put // Put
externals.add(ItemTag.compressTags(getItemStat().getAppliedNBT(ex))); externals.add(ItemTag.compressTags(getItemStat().getAppliedNBT(ex)));
} }
// Include // Include
if (externals.size() > 0) { object.add(enc_EXS, externals); } if (externals.size() > 0) {
object.add(enc_EXS, externals);
}
// Kompress Arrays // Kompress Arrays
JsonArray modz = new JsonArray(); JsonArray modz = new JsonArray();
@ -682,7 +753,9 @@ public class StatHistory {
} }
// Include // Include
if (modz.size() > 0) { object.add(enc_MOD, modz); } if (modz.size() > 0) {
object.add(enc_MOD, modz);
}
return object; return object;
@ -696,7 +769,8 @@ public class StatHistory {
* <p></p> * <p></p>
* Still don't abuse calls to this. Try to do so only when necessary * Still don't abuse calls to this. Try to do so only when necessary
*/ */
@NotNull public String toNBTString() { @NotNull
public String toNBTString() {
// Just convert to string :thinking: // Just convert to string :thinking:
return toJson().toString(); return toJson().toString();
@ -705,9 +779,11 @@ public class StatHistory {
/** /**
* To read from NBT data. This undoes {@link #toJson()} basically. * To read from NBT data. This undoes {@link #toJson()} basically.
* <p></p> * <p></p>
*
* @param iSource The MMOItem you are trying to read the NBT of * @param iSource The MMOItem you are trying to read the NBT of
*/ */
@Nullable public static StatHistory fromJson(@NotNull MMOItem iSource, @NotNull JsonObject json) { @Nullable
public static StatHistory fromJson(@NotNull MMOItem iSource, @NotNull JsonObject json) {
// Get the stat we're searching for // Get the stat we're searching for
JsonElement statEncode; JsonElement statEncode;
@ -717,18 +793,40 @@ public class StatHistory {
JsonElement modEncode = null; JsonElement modEncode = null;
// It has stat information right? // It has stat information right?
if (json.has(enc_Stat)) { statEncode = json.get(enc_Stat); } else { return null; } if (json.has(enc_Stat)) {
if (json.has(enc_OGS)) { ogStatsEncode = json.get(enc_OGS); } statEncode = json.get(enc_Stat);
if (json.has(enc_GSS)) { gemsEncode = json.get(enc_GSS); } } else {
if (json.has(enc_EXS)) { extEncode = json.get(enc_EXS); } return null;
if (json.has(enc_MOD)) { modEncode = json.get(enc_MOD); } }
if (json.has(enc_OGS)) {
ogStatsEncode = json.get(enc_OGS);
}
if (json.has(enc_GSS)) {
gemsEncode = json.get(enc_GSS);
}
if (json.has(enc_EXS)) {
extEncode = json.get(enc_EXS);
}
if (json.has(enc_MOD)) {
modEncode = json.get(enc_MOD);
}
// It is a primitive right // It is a primitive right
if (!statEncode.isJsonPrimitive()) { return null; } if (!statEncode.isJsonPrimitive()) {
if (ogStatsEncode != null && !ogStatsEncode.isJsonArray()) { return null; } return null;
if (gemsEncode != null && !gemsEncode.isJsonArray()) { return null; } }
if (extEncode != null && !extEncode.isJsonArray()) { return null; } if (ogStatsEncode != null && !ogStatsEncode.isJsonArray()) {
if (modEncode != null && !modEncode.isJsonArray()) { return null; } return null;
}
if (gemsEncode != null && !gemsEncode.isJsonArray()) {
return null;
}
if (extEncode != null && !extEncode.isJsonArray()) {
return null;
}
if (modEncode != null && !modEncode.isJsonArray()) {
return null;
}
// Get string // Get string
String statInternalName = statEncode.getAsJsonPrimitive().getAsString(); String statInternalName = statEncode.getAsJsonPrimitive().getAsString();
@ -737,7 +835,9 @@ public class StatHistory {
ItemStat stat = MMOItems.plugin.getStats().get(statInternalName); ItemStat stat = MMOItems.plugin.getStats().get(statInternalName);
// Nope // Nope
if (stat == null) { return null; } if (stat == null) {
return null;
}
// To know the stat it was // To know the stat it was
StatData sData; StatData sData;
@ -755,7 +855,9 @@ public class StatHistory {
} }
// Validate non null // Validate non null
if (sData == null) { return null; } if (sData == null) {
return null;
}
// Can now generate stat history // Can now generate stat history
StatHistory sHistory = new StatHistory(iSource, stat, sData); StatHistory sHistory = new StatHistory(iSource, stat, sData);
@ -892,7 +994,8 @@ public class StatHistory {
* <p></p> * <p></p>
* Will be null if some error happens * Will be null if some error happens
*/ */
@Nullable public static StatHistory fromNBTString(@NotNull MMOItem iSource, @NotNull String codedJson) { @Nullable
public static StatHistory fromNBTString(@NotNull MMOItem iSource, @NotNull String codedJson) {
// Attempt // Attempt
try { try {
@ -935,15 +1038,19 @@ public class StatHistory {
// Register gemstones // Register gemstones
for (UUID exUID : other.getAllGemstones()) { for (UUID exUID : other.getAllGemstones()) {
//noinspection ConstantConditions //noinspection ConstantConditions
registerGemstoneData(exUID, other.getGemstoneData(exUID)); } registerGemstoneData(exUID, other.getGemstoneData(exUID));
}
// Register externals // Register externals
for (StatData ex : other.getExternalData()) { registerExternalData((ex)); } for (StatData ex : other.getExternalData()) {
registerExternalData((ex));
}
// Register modifiers // Register modifiers
for (UUID exUID : other.getAllModifiers()) { for (UUID exUID : other.getAllModifiers()) {
//noinspection ConstantConditions //noinspection ConstantConditions
registerModifierBonus(exUID, other.getModifiersBonus(exUID)); } registerModifierBonus(exUID, other.getModifiersBonus(exUID));
}
//UPDT//MMOItems.log(" \u00a76:\u00a72: \u00a77Final Gemstones \u00a7f" + perGemstoneData.size()); //UPDT//MMOItems.log(" \u00a76:\u00a72: \u00a77Final Gemstones \u00a7f" + perGemstoneData.size());
//UPDT//MMOItems.log(" \u00a76:\u00a72: \u00a77Final Externals \u00a7f" + perExternalData.size()); //UPDT//MMOItems.log(" \u00a76:\u00a72: \u00a77Final Externals \u00a7f" + perExternalData.size());
@ -954,13 +1061,12 @@ public class StatHistory {
/** /**
* Clones this history but linked to another MMOItem. * Clones this history but linked to another MMOItem.
* * <p>
* It does not put it into the MMOItem, you must do that yourself. * It does not put it into the MMOItem, you must do that yourself.
* *
* @see MMOItem#setStatHistory(ItemStat, StatHistory)
*
* @param clonedMMOItem Usually this is called when you are cloning the MMOItem itself, * @param clonedMMOItem Usually this is called when you are cloning the MMOItem itself,
* this is a reference to the new one. * this is a reference to the new one.
* @see MMOItem#setStatHistory(ItemStat, StatHistory)
*/ */
public StatHistory clone(@NotNull MMOItem clonedMMOItem) { public StatHistory clone(@NotNull MMOItem clonedMMOItem) {
@ -969,10 +1075,14 @@ public class StatHistory {
// Add all // Add all
for (UUID uid : getAllGemstones()) { for (UUID uid : getAllGemstones()) {
if (uid == null) { continue; } if (uid == null) {
continue;
}
StatData gem = getGemstoneData(uid); StatData gem = getGemstoneData(uid);
if (!(gem instanceof Mergeable)) { continue; } if (!(gem instanceof Mergeable)) {
continue;
}
// Clone // Clone
res.registerGemstoneData(uid, ((Mergeable) gem).cloneData()); res.registerGemstoneData(uid, ((Mergeable) gem).cloneData());
@ -980,18 +1090,25 @@ public class StatHistory {
// Add all // Add all
for (StatData ex : getExternalData()) { for (StatData ex : getExternalData()) {
if (!(ex instanceof Mergeable)) { continue; } if (!(ex instanceof Mergeable)) {
continue;
}
// Clone // Clone
res.registerExternalData(((Mergeable) ex).cloneData()); } res.registerExternalData(((Mergeable) ex).cloneData());
}
// Clone // Clone
for (UUID uid : getAllModifiers()) { for (UUID uid : getAllModifiers()) {
if (uid == null) { continue; } if (uid == null) {
continue;
}
StatData mod = getModifiersBonus(uid); StatData mod = getModifiersBonus(uid);
if (!(mod instanceof Mergeable)) { continue; } if (!(mod instanceof Mergeable)) {
continue;
}
// Clone // Clone
res.registerModifierBonus(uid, ((Mergeable) mod).cloneData()); res.registerModifierBonus(uid, ((Mergeable) mod).cloneData());
@ -1001,46 +1118,4 @@ public class StatHistory {
return res; return res;
} }
static final String enc_Stat = "Stat";
static final String enc_OGS = "OGStory";
static final String enc_GSS = "Gemstory";
static final String enc_EXS = "Exstory";
static final String enc_MOD = "Mod";
/**
* Logs into the console. Dev Mehtod
*/
public void log() {
MMOItems.print(null, "\u00a76SH of \u00a7e" + getItemStat().getId() + "\u00a77, \u00a7b" + getMMOItem().getType() + " " + getMMOItem().getId(), null);
if (getOriginalData() instanceof StringListData) {
MMOItems.print(null, "\u00a7a++ Original", null);
for (String str : ((StringListData) getOriginalData()).getList()) { MMOItems.print(null, "\u00a7a ++\u00a77 " + str, null); }
MMOItems.print(null, "\u00a7e++ Gemstones", null);
for (UUID ui : getAllGemstones()) { StatData sd = getGemstoneData(ui); if (!(sd instanceof StringListData)) { continue; } for (String str : ((StringListData) sd).getList()) { MMOItems.print(null, "\u00a7e ++\u00a77 " + str, null); } }
MMOItems.print(null, "\u00a7c++ ExSH", null);
for (StatData sd : getExternalData()) { if (!(sd instanceof StringListData)) { continue; } for (String str : ((StringListData) sd).getList()) { MMOItems.print(null, "\u00a7e ++\u00a77 " + str, null); } }
MMOItems.print(null, "\u00a7d++ Modifiers", null);
for (UUID ui : getAllModifiers()) { StatData sd = getModifiersBonus(ui); if (!(sd instanceof StringListData)) { continue; } for (String str : ((StringListData) sd).getList()) { MMOItems.print(null, "\u00a7d ++\u00a77 " + str, null); } }
} else {
MMOItems.print(null, "\u00a7a-- Original", null);
MMOItems.print(null, "\u00a7a ++\u00a77 " + getOriginalData(), null);
MMOItems.print(null, "\u00a7e-- Gemstones", null);
for (UUID ui : getAllGemstones()) { StatData sd = getGemstoneData(ui); if (sd == null) { continue; } MMOItems.print(null, "\u00a7e ++\u00a77 " + sd, null);}
MMOItems.print(null, "\u00a7c-- ExSH", null);
for (StatData sd : getExternalData()) { if (sd == null) { continue; } MMOItems.print(null, "\u00a7e ++\u00a77 " + sd, null); }
MMOItems.print(null, "\u00a7d-- Modifiers", null);
for (UUID ui : getAllModifiers()) { StatData sd = getModifiersBonus(ui); if (sd == null) { continue; } MMOItems.print(null, "\u00a7d ++\u00a77 " + sd, null);}
}
}
} }