Stores original metadata to all armored elytras
This commit is contained in:
parent
20e1bc4550
commit
bb9710acfc
@ -7,6 +7,7 @@ import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -15,7 +16,11 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Integer>> {
|
||||
/**
|
||||
* A container for keeping track of enchantments, with additional filtering capabilities.
|
||||
*/
|
||||
public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Integer>>, Serializable {
|
||||
|
||||
private Map<Enchantment, Integer> enchantments;
|
||||
|
||||
/**
|
||||
@ -219,9 +224,8 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
}
|
||||
|
||||
final List<Enchantment> blackList =
|
||||
second.keySet().stream()
|
||||
.flatMap(enchantment -> getMutuallyExclusiveEnchantments(enchantment).stream())
|
||||
.toList();
|
||||
second.keySet().stream().flatMap(enchantment ->
|
||||
getMutuallyExclusiveEnchantments(enchantment).stream()).toList();
|
||||
blackList.forEach(first.keySet()::remove);
|
||||
|
||||
final Map<Enchantment, Integer> combined = new HashMap<>(first);
|
||||
@ -260,4 +264,5 @@ public class EnchantmentContainer implements Iterable<Map.Entry<Enchantment, Int
|
||||
public Iterator<Map.Entry<Enchantment, Integer>> iterator() {
|
||||
return enchantments.entrySet().iterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ public class NBTEditor {
|
||||
* @param item <p>The item to get item meta for</p>
|
||||
* @return <p>The existing or new item meta</p>
|
||||
*/
|
||||
private static ItemMeta getOrCreateItemMeta(ItemStack item) {
|
||||
public static ItemMeta getOrCreateItemMeta(ItemStack item) {
|
||||
final ItemMeta meta = item.hasItemMeta() ? item.getItemMeta() :
|
||||
Bukkit.getItemFactory().getItemMeta(item.getType());
|
||||
if (meta == null) {
|
||||
|
@ -1,12 +1,11 @@
|
||||
package net.knarcraft.armoredelytra.metadata;
|
||||
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import net.knarcraft.armoredelytra.container.EnchantmentContainer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An object for storing the original metadata for an armored elytra.
|
||||
@ -18,11 +17,11 @@ import java.util.Set;
|
||||
*/
|
||||
public class OriginalMetadata implements Serializable {
|
||||
|
||||
private Set<Enchantment> armorEnchantments = new HashSet<>();
|
||||
private Set<Enchantment> elytraEnchantments = new HashSet<>();
|
||||
private String elytraLore;
|
||||
private EnchantmentContainer armorEnchantments = new EnchantmentContainer();
|
||||
private EnchantmentContainer elytraEnchantments = new EnchantmentContainer();
|
||||
private List<String> elytraLore;
|
||||
private String elytraName;
|
||||
private String armorLore;
|
||||
private List<String> armorLore;
|
||||
private String armorName;
|
||||
|
||||
public OriginalMetadata() {
|
||||
@ -34,8 +33,8 @@ public class OriginalMetadata implements Serializable {
|
||||
*
|
||||
* @return <p>The stored armor enchantments.</p>
|
||||
*/
|
||||
public @NotNull Set<Enchantment> getArmorEnchantments() {
|
||||
return new HashSet<>(armorEnchantments);
|
||||
public @NotNull EnchantmentContainer getArmorEnchantments() {
|
||||
return armorEnchantments;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,8 +42,8 @@ public class OriginalMetadata implements Serializable {
|
||||
*
|
||||
* @return <p>The stored elytra enchantments.</p>
|
||||
*/
|
||||
public @NotNull Set<Enchantment> getElytraEnchantments() {
|
||||
return new HashSet<>(elytraEnchantments);
|
||||
public @NotNull EnchantmentContainer getElytraEnchantments() {
|
||||
return elytraEnchantments;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,7 +51,7 @@ public class OriginalMetadata implements Serializable {
|
||||
*
|
||||
* @return <p>The original elytra lore.</p>
|
||||
*/
|
||||
public @Nullable String getElytraLore() {
|
||||
public @Nullable List<String> getElytraLore() {
|
||||
return this.elytraLore;
|
||||
}
|
||||
|
||||
@ -70,7 +69,7 @@ public class OriginalMetadata implements Serializable {
|
||||
*
|
||||
* @return <p>The original armor lore.</p>
|
||||
*/
|
||||
public @Nullable String getArmorLore() {
|
||||
public @Nullable List<String> getArmorLore() {
|
||||
return this.armorLore;
|
||||
}
|
||||
|
||||
@ -87,80 +86,54 @@ public class OriginalMetadata implements Serializable {
|
||||
* Sets the stored lore of this armored elytra's armor.
|
||||
*
|
||||
* @param armorLore <p>The armor lore to store.</p>
|
||||
* @return <p>This original metadata.</p>
|
||||
*/
|
||||
public OriginalMetadata setArmorLore(@NotNull String armorLore) {
|
||||
public void setArmorLore(@NotNull List<String> armorLore) {
|
||||
this.armorLore = armorLore;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stored elytra lore of this armored elytra's elytra.
|
||||
*
|
||||
* @param elytraLore <p>The elytra lore to store.</p>
|
||||
* @return <p>This original metadata.</p>
|
||||
*/
|
||||
public OriginalMetadata setElytraLore(@NotNull String elytraLore) {
|
||||
public void setElytraLore(@NotNull List<String> elytraLore) {
|
||||
this.elytraLore = elytraLore;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stored elytra name of this armored elytra's elytra.
|
||||
*
|
||||
* @param elytraName <p>The elytra name to store.</p>
|
||||
* @return <p>This original metadata.</p>
|
||||
*/
|
||||
public OriginalMetadata setElytraName(@NotNull String elytraName) {
|
||||
public void setElytraName(@NotNull String elytraName) {
|
||||
this.elytraName = elytraName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stored armor name of this armored elytra's armor.
|
||||
*
|
||||
* @param armorName <p>The armor name to store.</p>
|
||||
* @return <p>This original metadata.</p>
|
||||
*/
|
||||
public OriginalMetadata setArmorName(@NotNull String armorName) {
|
||||
public void setArmorName(@NotNull String armorName) {
|
||||
this.armorName = armorName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stored enchantments for this armored elytra's armor.
|
||||
*
|
||||
* @param armorEnchantments <p>The armor enchantments to store.</p>
|
||||
* @return <p>This original metadata.</p>
|
||||
*/
|
||||
public OriginalMetadata setArmorEnchantments(@NotNull Set<Enchantment> armorEnchantments) {
|
||||
public void setArmorEnchantments(@NotNull EnchantmentContainer armorEnchantments) {
|
||||
this.armorEnchantments = armorEnchantments;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stored enchantments for this armored elytra's elytra.
|
||||
*
|
||||
* @param elytraEnchantments <p>The elytra enchantments to store.</p>
|
||||
* @return <p>This original metadata.</p>
|
||||
*/
|
||||
public OriginalMetadata setElytraEnchantments(@NotNull Set<Enchantment> elytraEnchantments) {
|
||||
public void setElytraEnchantments(@NotNull EnchantmentContainer elytraEnchantments) {
|
||||
this.elytraEnchantments = elytraEnchantments;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given enchantments to armor enchantments.
|
||||
*
|
||||
* <p>The purpose of this method is to combine enchantments for the original chestplate, and any chest-plates used
|
||||
* to upgrade the armored elytra.</p>
|
||||
*
|
||||
* @param enchantments <p>The enchantments to add</p>
|
||||
* @return <p>This original metadata.</p>
|
||||
*/
|
||||
public OriginalMetadata addArmorEnchantments(@NotNull Set<Enchantment> enchantments) {
|
||||
this.armorEnchantments.addAll(enchantments);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import net.knarcraft.armoredelytra.config.ConfigLoader;
|
||||
import net.knarcraft.armoredelytra.container.EnchantmentContainer;
|
||||
import net.knarcraft.armoredelytra.metadata.DurabilityManager;
|
||||
import net.knarcraft.armoredelytra.metadata.NBTEditor;
|
||||
import net.knarcraft.armoredelytra.metadata.OriginalMetadata;
|
||||
import net.knarcraft.armoredelytra.property.ArmorTier;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -16,6 +17,7 @@ public class ArmoredElytraBuilder {
|
||||
private final DurabilityManager durabilityManager;
|
||||
private final ConfigLoader config;
|
||||
private final ArmoredElytra plugin;
|
||||
private final OriginalMetadataBuilder metadataBuilder;
|
||||
|
||||
public ArmoredElytraBuilder(NBTEditor nbtEditor, DurabilityManager durabilityManager,
|
||||
ConfigLoader config, ArmoredElytra plugin) {
|
||||
@ -24,6 +26,7 @@ public class ArmoredElytraBuilder {
|
||||
this.durabilityManager = durabilityManager;
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
this.metadataBuilder = new OriginalMetadataBuilder(plugin, nbtEditor);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,14 +82,16 @@ public class ArmoredElytraBuilder {
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public ItemStack combine(ItemStack elytra, ItemStack combiner, ArmorTier armorTier, @Nullable String name) {
|
||||
return newBuilder().ofElytra(elytra).combineWith(combiner, armorTier).withName(name).build();
|
||||
return getArmoredElytraWithOriginalMetadata(elytra, combiner,
|
||||
newBuilder().ofElytra(elytra).combineWith(combiner, armorTier).withName(name).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #combine(ItemStack, ItemStack, ArmorTier, String)} for unknown armor tiers.
|
||||
*/
|
||||
public ItemStack combine(ItemStack elytra, ItemStack combiner, @Nullable String name) {
|
||||
return newBuilder().ofElytra(elytra).combineWith(combiner).withName(name).build();
|
||||
return getArmoredElytraWithOriginalMetadata(elytra, combiner,
|
||||
newBuilder().ofElytra(elytra).combineWith(combiner).withName(name).build());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,4 +104,18 @@ public class ArmoredElytraBuilder {
|
||||
return newBuilder().newItem(armorTier).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds/Updates the original metadata for an armored elytra, and returns the armored elytra.
|
||||
*
|
||||
* @param elytra <p>The base elytra.</p>
|
||||
* @param armor <p>The armor/armored elytra combined with the elytra.</p>
|
||||
* @param armoredElytra <p>The combined armored elytra.</p>
|
||||
* @return <p>The armored elytra with updated original metadata.</p>
|
||||
*/
|
||||
private ItemStack getArmoredElytraWithOriginalMetadata(ItemStack elytra, ItemStack armor, ItemStack armoredElytra) {
|
||||
OriginalMetadata originalMetadata = metadataBuilder.getMergedOriginalMetaData(elytra, armor);
|
||||
nbtEditor.updateOriginalMetadata(armoredElytra, originalMetadata);
|
||||
return armoredElytra;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,125 @@
|
||||
package net.knarcraft.armoredelytra.metadata.builder;
|
||||
|
||||
import net.knarcraft.armoredelytra.ArmoredElytra;
|
||||
import net.knarcraft.armoredelytra.container.EnchantmentContainer;
|
||||
import net.knarcraft.armoredelytra.metadata.NBTEditor;
|
||||
import net.knarcraft.armoredelytra.metadata.OriginalMetadata;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* A class for building the combined original metadata for the given items.
|
||||
*/
|
||||
public class OriginalMetadataBuilder {
|
||||
|
||||
private final ArmoredElytra plugin;
|
||||
private final NBTEditor nbtEditor;
|
||||
|
||||
/**
|
||||
* Instantiates a new original metadata builder
|
||||
*
|
||||
* @param plugin <p>A reference to the plugin class.</p>
|
||||
* @param nbtEditor <p>A reference to the NBT editor</p>
|
||||
*/
|
||||
public OriginalMetadataBuilder(ArmoredElytra plugin, NBTEditor nbtEditor) {
|
||||
this.plugin = plugin;
|
||||
this.nbtEditor = nbtEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the merged original metadata for two items.
|
||||
*
|
||||
* @param elytra <p>The input (armored) elytra.</p>
|
||||
* @param armor <p>The armored elytra or chestplate to be combined with the elytra.</p>
|
||||
* @return <p>The combined original metadata for the two items.</p>
|
||||
*/
|
||||
public OriginalMetadata getMergedOriginalMetaData(ItemStack elytra, ItemStack armor) {
|
||||
OriginalMetadata elytraMetadata = nbtEditor.getOriginalMetadata(elytra);
|
||||
OriginalMetadata armorMetadata = nbtEditor.getOriginalMetadata(armor);
|
||||
|
||||
// If metadata is missing from one of the items, create new metadata
|
||||
if (elytraMetadata == null) {
|
||||
elytraMetadata = createElytraMetadata(elytra);
|
||||
}
|
||||
if (armorMetadata == null) {
|
||||
armorMetadata = createArmorMetadata(armor);
|
||||
}
|
||||
|
||||
// Merge elytra and armor enchantments
|
||||
elytraMetadata.getElytraEnchantments().merge(armorMetadata.getElytraEnchantments());
|
||||
elytraMetadata.getArmorEnchantments().merge(armorMetadata.getArmorEnchantments());
|
||||
|
||||
// Use the elytra name from the armor if not set for the elytra
|
||||
if (useSecondValue(elytraMetadata.getElytraName(), armorMetadata.getElytraName(), (item) -> !item.isBlank())) {
|
||||
elytraMetadata.setElytraName(Objects.requireNonNull(armorMetadata.getElytraName()));
|
||||
}
|
||||
|
||||
// Use the armor name from the armor if not set for the elytra
|
||||
if (useSecondValue(elytraMetadata.getArmorName(), armorMetadata.getArmorName(), (item) -> !item.isBlank())) {
|
||||
elytraMetadata.setArmorName(Objects.requireNonNull(armorMetadata.getArmorName()));
|
||||
}
|
||||
|
||||
// Use the elytra lore from the armor if not set for the elytra
|
||||
if (useSecondValue(elytraMetadata.getElytraLore(), armorMetadata.getElytraLore(), (item) -> !item.isEmpty())) {
|
||||
elytraMetadata.setElytraLore(Objects.requireNonNull(armorMetadata.getElytraLore()));
|
||||
}
|
||||
|
||||
// Use the armor lore from the armor if not set for the elytra
|
||||
if (useSecondValue(elytraMetadata.getArmorLore(), armorMetadata.getArmorLore(), (item) -> !item.isEmpty())) {
|
||||
elytraMetadata.setArmorLore(Objects.requireNonNull(armorMetadata.getArmorLore()));
|
||||
}
|
||||
|
||||
return elytraMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* A test to see if the second value given matches the predicate, and the first one does not.
|
||||
*
|
||||
* @param value1 <p>The first value to test.</p>
|
||||
* @param value2 <p>The second value to test.</p>
|
||||
* @param predicate <p>The predicate to run.</p>
|
||||
* @param <T> <p>The type of the values.</p>
|
||||
* @return <p>True if the second value matches the predicate, but the first value does not.</p>
|
||||
*/
|
||||
private <T> boolean useSecondValue(T value1, T value2, Predicate<T> predicate) {
|
||||
return (value1 == null || !predicate.test(value1)) && (value2 != null && predicate.test(value2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates metadata for the given elytra item.
|
||||
*
|
||||
* @param elytra <p>The elytra to create original metadata for.</p>
|
||||
* @return <p>The generated metadata.</p>
|
||||
*/
|
||||
private OriginalMetadata createElytraMetadata(ItemStack elytra) {
|
||||
OriginalMetadata newMetadata = new OriginalMetadata();
|
||||
newMetadata.setElytraEnchantments(new EnchantmentContainer(elytra.getEnchantments(), plugin));
|
||||
ItemMeta meta = NBTEditor.getOrCreateItemMeta(elytra);
|
||||
if (meta.getLore() != null) {
|
||||
newMetadata.setElytraLore(meta.getLore());
|
||||
}
|
||||
newMetadata.setElytraName(meta.getDisplayName());
|
||||
return newMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates metadata for the given armor item.
|
||||
*
|
||||
* @param armor <p>The armor to create original metadata for.</p>
|
||||
* @return <p>The generated metadata.</p>
|
||||
*/
|
||||
private OriginalMetadata createArmorMetadata(ItemStack armor) {
|
||||
OriginalMetadata newMetadata = new OriginalMetadata();
|
||||
newMetadata.setArmorEnchantments(new EnchantmentContainer(armor.getEnchantments(), plugin));
|
||||
ItemMeta meta = NBTEditor.getOrCreateItemMeta(armor);
|
||||
if (meta.getLore() != null) {
|
||||
newMetadata.setArmorLore(meta.getLore());
|
||||
}
|
||||
newMetadata.setArmorName(meta.getDisplayName());
|
||||
return newMetadata;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user