Added option to keep external SH data past updating items.

Fixed bug where Updating an item would cause the template to become leveled up (this was absolutely ridiculous and hilarious btw), fixes Ticket #mmoitems-1283
This commit is contained in:
Gunging 2021-03-29 12:09:00 -05:00
parent 9108b9fd81
commit aa6800b237
7 changed files with 154 additions and 48 deletions

View File

@ -9,7 +9,8 @@ public class ReforgeOptions {
keepEnchantments,
keepUpgrades,
keepGemStones,
keepSoulbind;
keepSoulbind,
keepExternalSH;
public ReforgeOptions(ConfigurationSection config) {
this.keepName = config.getBoolean("display-name");
@ -18,6 +19,7 @@ public class ReforgeOptions {
this.keepUpgrades = config.getBoolean("upgrades");
this.keepGemStones = config.getBoolean("gemstones");
this.keepSoulbind = config.getBoolean("soulbound");
this.keepExternalSH = config.getBoolean("external-sh", true);
}
/**
@ -43,6 +45,13 @@ public class ReforgeOptions {
return keepEnchantments;
}
/**
* Keep 'extraneous' data registered onto the Stat History
*/
public boolean shouldKeepExternalSH() {
return keepExternalSH;
}
/**
* Retains the upgrade level of the item.
*/

View File

@ -114,9 +114,6 @@ public class ItemStackBuilder {
//GEM//MMOItems.Log("\u00a7e -+- \u00a77Applying \u00a76" + stat.getNBTPath());
// Make necessary lore changes
stat.whenApplied(this, builtMMOItem.getData(stat));
// Does the item have any stat history regarding thay?
StatHistory s = builtMMOItem.getStatHistory(stat);
@ -127,8 +124,14 @@ public class ItemStackBuilder {
// Add to NBT
addItemTag(new ItemTag(histroy_keyword + stat.getId(), s.toNBTString()));
// Recalculate
builtMMOItem.setData(stat, s.recalculate(true));
}
// Make necessary lore changes
stat.whenApplied(this, builtMMOItem.getData(stat));
// Something went wrong...
} catch (IllegalArgumentException|NullPointerException exception) {

View File

@ -195,9 +195,8 @@ public class MMOItemReforger {
public void reforge(@Nullable RPGPlayer player, @NotNull ReforgeOptions options) {
// Initialize as Volatile, find source template. GemStones require a Live MMOItem though (to correctly load all Stat Histories and sh)
if (!options.shouldKeepGemStones()) { loadVolatileMMOItem(); } else { loadLiveMMOItem(); }
MMOItemTemplate template = MMOItems.plugin.getTemplates().getTemplate(mmoItem.getType(), mmoItem.getId());
ItemMeta meta = nbtItem.getItem().getItemMeta();
if (!options.shouldKeepGemStones() && !options.shouldKeepExternalSH()) { loadVolatileMMOItem(); } else { loadLiveMMOItem(); }
MMOItemTemplate template = MMOItems.plugin.getTemplates().getTemplate(mmoItem.getType(), mmoItem.getId()); ItemMeta meta = nbtItem.getItem().getItemMeta();
Validate.isTrue(meta != null, FriendlyFeedbackProvider.quickForConsole(FFPMMOItems.get(), "Invalid item meta prevented $f{0}$b from updating.", template.getType().toString() + " " + template.getId()));
// Keep name
@ -326,16 +325,23 @@ public class MMOItemReforger {
}
// Gather Gemstones
if (options.shouldKeepGemStones() && mmoItem.hasData(ItemStats.GEM_SOCKETS)) {
//UPDT//MMOItems.Log(" \u00a7a> \u00a77Keeping Gem Sockets");
if (options.shouldKeepGemStones() || options.shouldKeepExternalSH()) {
// Cache that gemstone data
cachedGemStones = (GemSocketsData) mmoItem.getData(ItemStats.GEM_SOCKETS);
// Got any gem sockets bro?
if (mmoItem.hasData(ItemStats.GEM_SOCKETS) && options.shouldKeepGemStones()) {
//UPDT//MMOItems.Log(" \u00a7a> \u00a77Keeping Gem Sockets");
// Cache that gemstone data
cachedGemStones = (GemSocketsData) mmoItem.getData(ItemStats.GEM_SOCKETS); }
// Store all the history of stat proceedings.
for (StatHistory hist : mmoItem.getStatHistories()) {
//UPDT//MMOItems.Log(" \u00a7a + \u00a77History of \u00a7f" + hist.getItemStat().getNBTPath());
// Clear externals
if (!options.shouldKeepExternalSH()) { hist.getExternalData().clear(); }
// Get and set
itemDataHistory.put(hist.getItemStat(), hist);
}
@ -499,6 +505,7 @@ public class MMOItemReforger {
public boolean hasChanges() { return mmoItem != null; }
public ItemStack toStack() {
MMOItem buildingMMOItem = mmoItem.clone();
// For every cached stat (presumably due to its importance)
for (ItemStat stat : itemData.keySet()) {
@ -512,7 +519,7 @@ public class MMOItemReforger {
//UPDT//MMOItems.Log(" \u00a72@\u00a78@ \u00a77Old stat \u00a7f" + stat.getNBTPath());
// Set, replace, begone the previous!
mmoItem.setData(stat, data);
buildingMMOItem.setData(stat, data);
}
}
@ -526,13 +533,13 @@ public class MMOItemReforger {
//UPDT//MMOItems.Log(" \u00a72 *\u00a76* \u00a77Of old stat \u00a7f" + histOld.getItemStat().getNBTPath());
// Regenerate the original data
StatHistory hist = StatHistory.from(mmoItem, stat);
StatHistory hist = StatHistory.from(buildingMMOItem, stat);
// Remember...
hist.assimilate(histOld);
// Recalculate
mmoItem.setData(hist.getItemStat(), hist.recalculate(false));
buildingMMOItem.setData(hist.getItemStat(), hist.recalculate(false));
}
}
@ -541,7 +548,7 @@ public class MMOItemReforger {
//UPDT//MMOItems.Log(" \u00a7c@ \u00a77Applying Soulbind");
// Apply
mmoItem.setData(ItemStats.SOULBOUND, cachedSoulbound);
buildingMMOItem.setData(ItemStats.SOULBOUND, cachedSoulbound);
}
// Contained enchantments huh
@ -551,7 +558,7 @@ public class MMOItemReforger {
// Register as extraneous obviously
StatHistory hist = StatHistory.from(mmoItem, ItemStats.ENCHANTS);
StatHistory hist = StatHistory.from(buildingMMOItem, ItemStats.ENCHANTS);
hist.registerExternalData(cachedEnchantments.cloneData());
//UPDT//MMOItems.Log(" \u00a7b:\u00a73:\u00a7: \u00a77Late Arcane Report: \u00a79-------------------------");
@ -564,35 +571,39 @@ public class MMOItemReforger {
//UPDT//for (StatData data : hist.getExternalData()) { MMOItems.Log(" \u00a7b==\u00a73> \u00a77 --------- "); for (Enchantment e : ((EnchantListData) data).getEnchants()) { MMOItems.Log(" \u00a7b *\u00a73* \u00a77" + e.getName() + " \u00a7f" + ((EnchantListData) data).getLevel(e)); } }
// Recalculate and put
mmoItem.setData(ItemStats.ENCHANTS, hist.recalculate());
buildingMMOItem.setData(ItemStats.ENCHANTS, hist.recalculate());
}
// Upgrade Information
if (cachedUpgradeLevel != null) {
//UPDT//MMOItems.Log(" \u00a7e@ \u00a77Applying Upgrade");
// If has a upgrade template defined, just remember the level
if (mmoItem.hasData(ItemStats.UPGRADE)) {
if (buildingMMOItem.hasData(ItemStats.UPGRADE)) {
//UPDT//MMOItems.Log(" \u00a7e* \u00a77Existing Upgrade Detected");
// Get current ig
UpgradeData current = ((UpgradeData) mmoItem.getData(ItemStats.UPGRADE));
UpgradeData current = ((UpgradeData) buildingMMOItem.getData(ItemStats.UPGRADE));
UpgradeData processed = new UpgradeData(current.getReference(), current.getTemplateName(), current.isWorkbench(), current.isDestroy(), current.getMax(), current.getSuccess());
// Edit level
current.setLevel(Math.min(cachedUpgradeLevel.getLevel(), current.getMaxUpgrades()));
processed.setLevel(Math.min(cachedUpgradeLevel.getLevel(), current.getMaxUpgrades()));
//UPDT//MMOItems.Log(" \u00a7e + \u00a77Set to level \u00a7f" + current.getLevel());
// Re-set cuz why not
mmoItem.setData(ItemStats.UPGRADE, current);
buildingMMOItem.setData(ItemStats.UPGRADE, processed);
// Otherwise, the level AND template shall prevail
} else {
}
/*else {
//UPDT//MMOItems.Log(" \u00a7e* \u00a77Using Cached");
// Set from the cached
mmoItem.setData(ItemStats.UPGRADE, cachedUpgradeLevel);
buildingMMOItem.setData(ItemStats.UPGRADE, new UpgradeData(cachedUpgradeLevel.getReference(), cachedUpgradeLevel.getTemplateName(), cachedUpgradeLevel.isWorkbench(), cachedUpgradeLevel.isDestroy(), cachedUpgradeLevel.getMax(), cachedUpgradeLevel.getSuccess()));
//UPDT//MMOItems.Log(" \u00a7e + \u00a77Set to level \u00a7f" + cachedUpgradeLevel.getLevel());
}
} //*/
}
// Gem Stones
@ -600,11 +611,11 @@ public class MMOItemReforger {
//UPDT//MMOItems.Log(" \u00a7a@ \u00a77Applying Gemstones");
// If has a upgrade template defined, just remember the level
if (mmoItem.hasData(ItemStats.GEM_SOCKETS)) {
if (buildingMMOItem.hasData(ItemStats.GEM_SOCKETS)) {
//UPDT//MMOItems.Log(" \u00a7a* \u00a77Existing Data Detected");
// Get current ig
GemSocketsData current = ((GemSocketsData) mmoItem.getData(ItemStats.GEM_SOCKETS));
GemSocketsData current = ((GemSocketsData) buildingMMOItem.getData(ItemStats.GEM_SOCKETS));
// Get those damn empty sockets
ArrayList<String> availableSockets = new ArrayList<>(current.getEmptySlots());
@ -656,7 +667,7 @@ public class MMOItemReforger {
}
// Set the data, as changed as it may be
mmoItem.setData(ItemStats.GEM_SOCKETS, cachedGemStones);
buildingMMOItem.setData(ItemStats.GEM_SOCKETS, cachedGemStones);
}
// Lore
@ -664,11 +675,11 @@ public class MMOItemReforger {
//UPDT//MMOItems.Log(" \u00a7d@ \u00a77Applying Lore");
// If it has lore, add I guess
if (mmoItem.hasData(ItemStats.LORE)) {
if (buildingMMOItem.hasData(ItemStats.LORE)) {
//UPDT//MMOItems.Log(" \u00a7d* \u00a77Inserting first");
// Get current ig
StringListData current = ((StringListData) mmoItem.getData(ItemStats.LORE));
StringListData current = ((StringListData) buildingMMOItem.getData(ItemStats.LORE));
// Get those damn empty sockets
ArrayList<String> listYes = new ArrayList<>(current.getList());
@ -682,7 +693,7 @@ public class MMOItemReforger {
//UPDT//for (String lr : cachedLore) { //UPDT//MMOItems.Log(" \u00a7d + \u00a77" + lr); }
// Set that as the lore
mmoItem.setData(ItemStats.LORE, sData);
buildingMMOItem.setData(ItemStats.LORE, sData);
}
// Name
@ -690,14 +701,14 @@ public class MMOItemReforger {
//UPDT//MMOItems.Log(" \u00a73@ \u00a77Applying Name \u00a7f" + cachedName);
// Replace name completely
mmoItem.setData(ItemStats.NAME, new StringData(cachedName));
buildingMMOItem.setData(ItemStats.NAME, new StringData(cachedName));
}
// Apply upgrades
if (mmoItem.hasUpgradeTemplate()) { mmoItem.getUpgradeTemplate().upgradeTo(mmoItem, mmoItem.getUpgradeLevel()); }
if (buildingMMOItem.hasUpgradeTemplate()) { buildingMMOItem.getUpgradeTemplate().upgradeTo(buildingMMOItem, buildingMMOItem.getUpgradeLevel()); }
// Build and set amount
ItemStack stack = mmoItem.newBuilder().build();
ItemStack stack = buildingMMOItem.newBuilder().build();
stack.setAmount(amount);
return stack;
}

View File

@ -39,6 +39,7 @@ public class RevisionInventory extends EditionInventory {
static ItemStack upgrades;
static ItemStack gemstones;
static ItemStack soulbind;
static ItemStack external;
static ItemStack revisionID;
@ -63,7 +64,7 @@ public class RevisionInventory extends EditionInventory {
, 40, "\u00a77")).build();
upgrades = ItemFactory.of(Material.NETHER_STAR).name("\u00a7aUpgrades").lore(SilentNumbers.chop(
"Will this item retain the upgrade level after updating?"
"Will this item retain the upgrade level after updating? Only the Upgrade Level is kept (as long as it does not exceed the new max)."
, 40, "\u00a77")).build();
gemstones = ItemFactory.of(Material.EMERALD).name("\u00a7eGem Stones").lore(SilentNumbers.chop(
@ -74,6 +75,10 @@ public class RevisionInventory extends EditionInventory {
"If the old item is soulbound, updating will transfer the soulbind to the new item."
, 40, "\u00a77")).build();
external = ItemFactory.of(Material.SPRUCE_SIGN).name("\u00a79External SH").lore(SilentNumbers.chop(
"Data registered onto the item's StatHistory by external plugins (like GemStones but not removable)"
, 40, "\u00a77")).build();
// Fill stack
revisionID = ItemFactory.of(Material.ITEM_FRAME).name(REVISION).lore(SilentNumbers.chop(
@ -105,6 +110,10 @@ public class RevisionInventory extends EditionInventory {
which = enchantments.clone();
enable = MMOItems.plugin.getLanguage().revisionOptions.shouldKeepEnchantments();
break;
case 22:
which = external.clone();
enable = MMOItems.plugin.getLanguage().revisionOptions.shouldKeepExternalSH();
break;
case 28:
which = upgrades.clone();
enable = MMOItems.plugin.getLanguage().revisionOptions.shouldKeepUpgrades();

View File

@ -41,15 +41,55 @@ public class DisplayName extends StringStat {
if (suffix != null) {
// Bake old indices for removal
// Crop lvl
int lvlOFFSET = suffix.indexOf("#lvl#");
String sB4 = suffix.substring(0, lvlOFFSET);
String aFt = suffix.substring(lvlOFFSET + "#lvl#".length());
String sB4_alt = sB4.replace("+", "-");
String aFt_alt = sB4.replace("+", "-");
// Remove it
if (format.contains(sB4)) {
// Get offsets
int sB4_offset = format.indexOf(sB4);
int aFt_offset = format.lastIndexOf(aFt);
// No after = to completion
if (aFt_offset < 0) { aFt_offset = format.length(); } else { aFt_offset += aFt.length(); }
// Remove that
String beforePrefix = format.substring(0, sB4_offset);
String afterPrefix = format.substring(aFt_offset);
// Replace
format = beforePrefix + afterPrefix; }
// Remove it
if (format.contains(sB4_alt)) {
// Get offsets
int sB4_offset = format.indexOf(sB4_alt);
int aFt_offset = format.lastIndexOf(aFt_alt);
// No after = to completion
if (aFt_offset < 0) { aFt_offset = format.length(); } else { aFt_offset += aFt_alt.length(); }
// Remove that
String beforePrefix = format.substring(0, sB4_offset);
String afterPrefix = format.substring(aFt_offset);
// Replace
format = beforePrefix + afterPrefix; }
/*/ Bake old indices for removal
ArrayList<String> oldSuffixii = new ArrayList<>(); boolean negativity = false;
if (upgradeLevel < 0) { upgradeLevel = -upgradeLevel; negativity = true; }
for (int i = upgradeLevel + 3; i >= 1; i--) {
if (negativity) {
oldSuffixii.add(levelPrefix(suffix, -i));
} else {
oldSuffixii.add(levelPrefix(suffix, i)); }}
oldSuffixii.add(levelPrefix(suffix, i)); } }
for (String str : oldSuffixii) {
//MMOItems.getConsole().sendMessage("Found " + str);
@ -58,7 +98,7 @@ public class DisplayName extends StringStat {
format = format.replace(str, "");
//MMOItems.getConsole().sendMessage("Edited " + format);
}
} //*/
// Add a prefix anew if the upgrade level worked
if (upgradeLevel != 0) {

View File

@ -7,9 +7,11 @@ import net.Indyuce.mmoitems.api.UpgradeTemplate;
import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
import net.Indyuce.mmoitems.stat.data.type.StatData;
import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmoitems.stat.type.StatHistory;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -22,19 +24,46 @@ import org.jetbrains.annotations.Nullable;
* </p> May it get destroyed if unsucessful upgrade?
*/
public class UpgradeData implements StatData, RandomStatData {
/**
* @return The String a consumable must match to Upgrade this Item
*/
@Nullable public String getReference() { return reference; }
/**
* @return If upgrades must be done through workbench
*/
public boolean isWorkbench() {
return workbench;
}
/**
* @return Will this destroy the item if they fail?
*/
public boolean isDestroy() {
return destroy;
}
/**
* @return Max amount of upgrades this can hold
*/
public int getMax() {
return max;
}
@Nullable private final String reference, template;
private final boolean workbench, destroy;
private final double success;
private final int max;
private int level;
public UpgradeData(@Nullable String referenc, @Nullable String templat, boolean workbenc, boolean destro, int maxx, double succes) {
reference = referenc;
template = templat;
workbench = workbenc;
destroy = destro;
max = maxx;
success = succes;
public UpgradeData(@Nullable String reference, @Nullable String template, boolean workbench, boolean destroy, int max, double success) {
this.reference = reference;
this.template = template;
this.workbench = workbench;
this.destroy = destroy;
this.max = max;
this.success = success;
}
public UpgradeData(ConfigurationSection section) {
@ -60,9 +89,12 @@ public class UpgradeData implements StatData, RandomStatData {
* @return The template associated to this data, if it is loaded.
*/
@Nullable public UpgradeTemplate getTemplate() {
if (template == null) { return null; }
return MMOItems.plugin.getUpgrades().getTemplate(template);
}
@Nullable public String getTemplateName() {return template; }
public int getLevel() { return level; }
/**

View File

@ -208,7 +208,7 @@ public class StatHistory {
// Unregister
for (UUID ext : extraneous) {
//UPGRD//MMOItems.Log("\u00a76 ||\u00a77 Purged Stone: \u00a7e" + ext.toString());
//UPGRD//MMOItems.log("\u00a76 ||\u00a77 Purged Stone: \u00a7e" + ext.toString());
// Remove
perGemstoneData.remove(ext);
@ -232,6 +232,8 @@ public class StatHistory {
* what you're doing.
*/
@NotNull public StatData recalculate(boolean withPurge) {
//UPGRD//MMOItems.log("\u00a7d|||\u00a77 Recalculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77, Purge? \u00a7e" + withPurge);
if (withPurge) { purgeGemstones(); }
// If its upgradeable and not level ZERO, it must apply upgrades
@ -282,7 +284,7 @@ public class StatHistory {
* <p>5: Sums external data (modifiers that are not linked to an ID, I suppose by external plugins).
*/
private StatData recalculateUpgradeable() {
//UPGRD//MMOItems.Log("\u00a76|||\u00a77 Calculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77 as Upgradeable");
//UPGRD//MMOItems.log("\u00a76|||\u00a77 Calculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77 as Upgradeable");
// Get Upgrade Info?
UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat());
@ -361,7 +363,7 @@ public class StatHistory {
* <p>4: Sums external data (modifiers that are not linked to an ID, I suppose by external plugins).
*/
private StatData recalculateMergeable() {
//UPGRD//MMOItems.Log("\u00a73|||\u00a77 Calculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77 as Mergeable");
//UPGRD//MMOItems.log("\u00a73|||\u00a77 Calculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77 as Mergeable");
// Just clone bro
StatData ret = ((Mergeable) getOriginalData()).cloneData();