mirror of
https://github.com/Auxilor/EcoArmor.git
synced 2025-12-28 11:29:18 +00:00
Began migrating to JSON
This commit is contained in:
@@ -46,7 +46,7 @@ allprojects {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'com.willfp:eco:5.2.0'
|
||||
compileOnly 'com.willfp:eco:5.5.0'
|
||||
|
||||
compileOnly 'org.jetbrains:annotations:19.0.0'
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.willfp.ecoarmor.commands.CommandEagive;
|
||||
import com.willfp.ecoarmor.commands.CommandEareload;
|
||||
import com.willfp.ecoarmor.commands.TabcompleterEagive;
|
||||
import com.willfp.ecoarmor.conditions.Conditions;
|
||||
import com.willfp.ecoarmor.config.SetsJson;
|
||||
import com.willfp.ecoarmor.display.ArmorDisplay;
|
||||
import com.willfp.ecoarmor.effects.Effect;
|
||||
import com.willfp.ecoarmor.effects.Effects;
|
||||
@@ -36,12 +37,20 @@ public class EcoArmorPlugin extends EcoPlugin {
|
||||
@Getter
|
||||
private static EcoArmorPlugin instance;
|
||||
|
||||
/**
|
||||
* sets.json.
|
||||
*/
|
||||
@Getter
|
||||
private final SetsJson setsJson;
|
||||
|
||||
/**
|
||||
* Internal constructor called by bukkit on plugin load.
|
||||
*/
|
||||
public EcoArmorPlugin() {
|
||||
super("EcoArmor", 88246, 10002, "com.willfp.ecoarmor.proxy", "&c");
|
||||
instance = this;
|
||||
|
||||
this.setsJson = new SetsJson(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.willfp.ecoarmor.config;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.config.JsonStaticBaseConfig;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SetsJson extends JsonStaticBaseConfig {
|
||||
/**
|
||||
* Create sets.json.
|
||||
*
|
||||
* @param plugin Instance of EcoArmor.
|
||||
*/
|
||||
public SetsJson(@NotNull final EcoPlugin plugin) {
|
||||
super("sets", plugin);
|
||||
}
|
||||
}
|
||||
@@ -1,93 +1,56 @@
|
||||
package com.willfp.ecoarmor.sets;
|
||||
|
||||
import com.willfp.eco.core.config.Config;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import com.willfp.eco.core.items.CustomItem;
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe;
|
||||
import com.willfp.eco.util.SkullUtils;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import com.willfp.ecoarmor.EcoArmorPlugin;
|
||||
import com.willfp.ecoarmor.conditions.Condition;
|
||||
import com.willfp.ecoarmor.conditions.Conditions;
|
||||
import com.willfp.ecoarmor.effects.Effect;
|
||||
import com.willfp.ecoarmor.effects.Effects;
|
||||
import com.willfp.ecoarmor.sets.meta.ArmorSlot;
|
||||
import com.willfp.ecoarmor.sets.util.ArmorUtils;
|
||||
import com.willfp.ecoarmor.upgrades.Tier;
|
||||
import com.willfp.ecoarmor.upgrades.Tiers;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@AllArgsConstructor
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ArmorSet {
|
||||
/**
|
||||
* Instance of EcoArmor.
|
||||
*/
|
||||
private static final EcoArmorPlugin PLUGIN = EcoArmorPlugin.getInstance();
|
||||
|
||||
/**
|
||||
* The name of the set.
|
||||
*/
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The config of the set.
|
||||
*/
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
private final Config config;
|
||||
|
||||
/**
|
||||
* Conditions and their values.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<Condition<?>, Object> conditions = new HashMap<>();
|
||||
private final Map<Condition<?>, Object> conditions;
|
||||
|
||||
/**
|
||||
* Effects and their strengths.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<Effect<?>, Object> effects = new HashMap<>();
|
||||
private final Map<Effect<?>, Object> effects;
|
||||
|
||||
/**
|
||||
* Effects and their strengths on advanced armor.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<Effect<?>, Object> advancedEffects = new HashMap<>();
|
||||
private final Map<Effect<?>, Object> advancedEffects;
|
||||
|
||||
/**
|
||||
* Potion effects to be applied on equip.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<PotionEffectType, Integer> potionEffects = new HashMap<>();
|
||||
private final Map<PotionEffectType, Integer> potionEffects;
|
||||
|
||||
/**
|
||||
* Potion effects to be applied on equipping advanced.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<PotionEffectType, Integer> advancedPotionEffects = new HashMap<>();
|
||||
private final Map<PotionEffectType, Integer> advancedPotionEffects;
|
||||
|
||||
/**
|
||||
* The base64 texture of a skull used as a helmet.
|
||||
@@ -96,17 +59,17 @@ public class ArmorSet {
|
||||
*/
|
||||
@Getter
|
||||
@Nullable
|
||||
private String skullBase64;
|
||||
private final String skullBase64;
|
||||
|
||||
/**
|
||||
* Items in set.
|
||||
*/
|
||||
private final Map<ArmorSlot, ItemStack> items = new HashMap<>();
|
||||
private final Map<ArmorSlot, ItemStack> items;
|
||||
|
||||
/**
|
||||
* Items in advanced set.
|
||||
*/
|
||||
private final Map<ArmorSlot, ItemStack> advancedItems = new HashMap<>();
|
||||
private final Map<ArmorSlot, ItemStack> advancedItems;
|
||||
|
||||
/**
|
||||
* Advancement shard item.
|
||||
@@ -114,278 +77,6 @@ public class ArmorSet {
|
||||
@Getter
|
||||
private final ItemStack advancementShardItem;
|
||||
|
||||
/**
|
||||
* Create a new Armor Set.
|
||||
*
|
||||
* @param name The name of the set.
|
||||
* @param config The set's config.
|
||||
*/
|
||||
public ArmorSet(@NotNull final String name,
|
||||
@NotNull final Config config) {
|
||||
this.config = config;
|
||||
this.name = name;
|
||||
|
||||
for (String definedKey : this.getConfig().getStrings("conditions")) {
|
||||
String[] split = definedKey.split(":");
|
||||
String key = split[0].trim();
|
||||
String value = split[1].trim();
|
||||
Condition<?> condition = Conditions.getByName(key);
|
||||
if (condition == null) {
|
||||
Bukkit.getLogger().warning("Invalid condition specified in " + this.name);
|
||||
} else {
|
||||
conditions.put(condition, ArmorUtils.getConditionValue(value, condition));
|
||||
}
|
||||
}
|
||||
|
||||
for (String definedKey : this.getConfig().getStrings("set-bonus")) {
|
||||
String[] split = definedKey.split(":");
|
||||
String key = split[0].trim();
|
||||
String value = split[1].trim();
|
||||
Effect<?> effect = Effects.getByName(key);
|
||||
if (effect == null) {
|
||||
Bukkit.getLogger().warning("Invalid effect specified in " + this.name);
|
||||
} else {
|
||||
effects.put(effect, ArmorUtils.getEffectValue(value, effect));
|
||||
}
|
||||
}
|
||||
|
||||
for (String definedKey : this.getConfig().getStrings("advanced-set-bonus")) {
|
||||
String[] split = definedKey.split(":");
|
||||
String key = split[0].trim();
|
||||
String value = split[1].trim();
|
||||
Effect<?> effect = Effects.getByName(key);
|
||||
if (effect == null) {
|
||||
Bukkit.getLogger().warning("Invalid advanced effect specified in " + this.name);
|
||||
} else {
|
||||
advancedEffects.put(effect, ArmorUtils.getEffectValue(value, effect));
|
||||
}
|
||||
}
|
||||
|
||||
for (String definedKey : this.getConfig().getStrings("potion-effects")) {
|
||||
String[] split = definedKey.split(":");
|
||||
String key = split[0].trim();
|
||||
String value = split[1].trim();
|
||||
PotionEffectType type = PotionEffectType.getByName(key.toUpperCase());
|
||||
if (type == null) {
|
||||
Bukkit.getLogger().warning("Invalid potion effect specified in " + this.name);
|
||||
} else {
|
||||
potionEffects.put(type, Integer.parseInt(value));
|
||||
}
|
||||
}
|
||||
|
||||
for (String definedKey : this.getConfig().getStrings("advanced-potion-effects")) {
|
||||
String[] split = definedKey.split(":");
|
||||
String key = split[0].trim();
|
||||
String value = split[1].trim();
|
||||
PotionEffectType type = PotionEffectType.getByName(key.toUpperCase());
|
||||
if (type == null) {
|
||||
Bukkit.getLogger().warning("Invalid advanced potion effect specified in " + this.name);
|
||||
} else {
|
||||
advancedPotionEffects.put(type, Integer.parseInt(value));
|
||||
}
|
||||
}
|
||||
|
||||
for (ArmorSlot slot : ArmorSlot.values()) {
|
||||
ItemStack item = construct(slot, this.getConfig().getSubsection(slot.name().toLowerCase()), false);
|
||||
items.put(slot, item);
|
||||
if (this.getConfig().getBool("enabled")) {
|
||||
constructRecipe(slot, this.getConfig().getSubsection(slot.name().toLowerCase()), item);
|
||||
}
|
||||
|
||||
ItemStack advancedItem = construct(slot, this.getConfig().getSubsection(slot.name().toLowerCase()), true);
|
||||
advancedItems.put(slot, advancedItem);
|
||||
}
|
||||
|
||||
if (this.getConfig().getBool("enabled")) {
|
||||
ArmorSets.addNewSet(this);
|
||||
}
|
||||
|
||||
this.advancementShardItem = constructShard();
|
||||
}
|
||||
|
||||
private ItemStack constructShard() {
|
||||
ItemStack shardItem = new ItemStack(Objects.requireNonNull(Material.getMaterial(PLUGIN.getConfigYml().getString("advancement-shard-material").toUpperCase())));
|
||||
ItemMeta shardMeta = shardItem.getItemMeta();
|
||||
assert shardMeta != null;
|
||||
shardMeta.setDisplayName(this.getConfig().getString("advancement-shard-name"));
|
||||
|
||||
shardMeta.addEnchant(Enchantment.DURABILITY, 3, true);
|
||||
shardMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
|
||||
List<String> shardLore = new ArrayList<>();
|
||||
for (String loreLine : this.getConfig().getStrings("advancement-shard-lore")) {
|
||||
shardLore.add(Display.PREFIX + StringUtils.translate(loreLine));
|
||||
}
|
||||
|
||||
shardMeta.setLore(shardLore);
|
||||
shardMeta.getPersistentDataContainer().set(PLUGIN.getNamespacedKeyFactory().create("advancement-shard"), PersistentDataType.STRING, name);
|
||||
|
||||
shardItem.setItemMeta(shardMeta);
|
||||
|
||||
if (this.getConfig().getBool("shard-craftable")) {
|
||||
ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(PLUGIN, this.getName() + "_shard").setOutput(shardItem);
|
||||
|
||||
List<String> recipeStrings = this.getConfig().getStrings("shard-recipe");
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
builder.setRecipePart(i, Items.lookup(recipeStrings.get(i)));
|
||||
}
|
||||
|
||||
ShapedCraftingRecipe recipe = builder.build();
|
||||
recipe.register();
|
||||
}
|
||||
|
||||
return shardItem;
|
||||
}
|
||||
|
||||
private ItemStack construct(@NotNull final ArmorSlot slot,
|
||||
@NotNull final Config slotConfig,
|
||||
final boolean advanced) {
|
||||
Material material = Material.getMaterial(slotConfig.getString("material").toUpperCase());
|
||||
Map<Enchantment, Integer> enchants = new HashMap<>();
|
||||
|
||||
for (String definedKey : slotConfig.getStrings("enchants")) {
|
||||
String[] split = definedKey.split(":");
|
||||
String key = split[0].trim();
|
||||
String value = split[1].trim();
|
||||
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(key));
|
||||
if (enchantment == null) {
|
||||
Bukkit.getLogger().warning("Invalid enchantment specified in " + this.name + " " + slot.name().toLowerCase());
|
||||
} else {
|
||||
enchants.put(enchantment, Integer.valueOf(value));
|
||||
}
|
||||
}
|
||||
|
||||
assert material != null;
|
||||
|
||||
ItemStack itemStack = new ItemStack(material);
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
assert meta != null;
|
||||
|
||||
String displayName;
|
||||
if (advanced) {
|
||||
displayName = slotConfig.getString("advanced-name");
|
||||
} else {
|
||||
displayName = slotConfig.getString("name");
|
||||
}
|
||||
|
||||
List<ItemFlag> flags = new ArrayList<>();
|
||||
for (String flagName : slotConfig.getStrings("flags")) {
|
||||
ItemFlag flag = ItemFlag.valueOf(flagName.toUpperCase());
|
||||
flags.add(flag);
|
||||
}
|
||||
meta.addItemFlags(flags.toArray(new ItemFlag[0]));
|
||||
|
||||
int data = slotConfig.getInt("custom-model-data");
|
||||
if (data != -1) {
|
||||
meta.setCustomModelData(data);
|
||||
}
|
||||
|
||||
boolean unbreakable = slotConfig.getBool("unbreakable");
|
||||
meta.setUnbreakable(unbreakable);
|
||||
|
||||
List<String> lore = new ArrayList<>();
|
||||
for (String loreLine : slotConfig.getStrings("lore")) {
|
||||
lore.add(Display.PREFIX + StringUtils.translate(loreLine));
|
||||
}
|
||||
|
||||
if (advanced) {
|
||||
for (String loreLine : this.getConfig().getStrings("advanced-lore")) {
|
||||
lore.add(Display.PREFIX + StringUtils.translate(loreLine));
|
||||
}
|
||||
}
|
||||
|
||||
if (meta instanceof SkullMeta) {
|
||||
this.skullBase64 = slotConfig.getString("skull-texture");
|
||||
SkullUtils.setSkullTexture((SkullMeta) meta, skullBase64);
|
||||
}
|
||||
|
||||
if (meta instanceof LeatherArmorMeta) {
|
||||
String colorString = slotConfig.getString("leather-color");
|
||||
java.awt.Color awtColor = java.awt.Color.decode(colorString);
|
||||
Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue());
|
||||
((LeatherArmorMeta) meta).setColor(color);
|
||||
|
||||
meta.addItemFlags(ItemFlag.HIDE_DYE);
|
||||
}
|
||||
|
||||
meta.setDisplayName(displayName);
|
||||
|
||||
meta.setLore(lore);
|
||||
|
||||
enchants.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true));
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
container.set(PLUGIN.getNamespacedKeyFactory().create("set"), PersistentDataType.STRING, name);
|
||||
container.set(PLUGIN.getNamespacedKeyFactory().create("effective-durability"), PersistentDataType.INTEGER, slotConfig.getInt("effective-durability"));
|
||||
itemStack.setItemMeta(meta);
|
||||
|
||||
ArmorUtils.setAdvanced(itemStack, advanced);
|
||||
Tier defaultTier = Tiers.getByName(slotConfig.getString("default-tier"));
|
||||
if (defaultTier == null) {
|
||||
Bukkit.getLogger().warning("Default tier specified in " + this.name + " " + slot.name().toLowerCase() + " is invalid! Defaulting to 'default'");
|
||||
ArmorUtils.setTier(itemStack, Tiers.DEFAULT);
|
||||
} else {
|
||||
ArmorUtils.setTier(itemStack, defaultTier);
|
||||
}
|
||||
|
||||
if (advanced) {
|
||||
new CustomItem(PLUGIN.getNamespacedKeyFactory().create("set_" + name.toLowerCase() + "_" + slot.name().toLowerCase() + "_advanced"), test -> {
|
||||
if (ArmorSlot.getSlot(test) != ArmorSlot.getSlot(itemStack)) {
|
||||
return false;
|
||||
}
|
||||
if (!ArmorUtils.isAdvanced(itemStack)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this, ArmorUtils.getSetOnItem(test));
|
||||
}, itemStack).register();
|
||||
} else {
|
||||
new CustomItem(PLUGIN.getNamespacedKeyFactory().create("set_" + name.toLowerCase() + "_" + slot.name().toLowerCase()), test -> {
|
||||
if (ArmorSlot.getSlot(test) != ArmorSlot.getSlot(itemStack)) {
|
||||
return false;
|
||||
}
|
||||
if (ArmorUtils.isAdvanced(itemStack)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this, ArmorUtils.getSetOnItem(test));
|
||||
}, itemStack).register();
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private void constructRecipe(@NotNull final ArmorSlot slot,
|
||||
@NotNull final Config slotConfig,
|
||||
@NotNull final ItemStack out) {
|
||||
if (slotConfig.getBool("craftable")) {
|
||||
ItemStack formattedOut = out.clone();
|
||||
ItemMeta meta = formattedOut.getItemMeta();
|
||||
assert meta != null;
|
||||
assert meta.getLore() != null;
|
||||
|
||||
List<String> lore = new ArrayList<>();
|
||||
|
||||
for (String s : meta.getLore()) {
|
||||
s = s.replace("%tier%", Tiers.DEFAULT.getDisplayName());
|
||||
lore.add(s);
|
||||
}
|
||||
|
||||
meta.setLore(lore);
|
||||
formattedOut.setItemMeta(meta);
|
||||
|
||||
ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(PLUGIN, this.getName() + "_" + slot.name().toLowerCase()).setOutput(formattedOut);
|
||||
|
||||
List<String> recipeStrings = slotConfig.getStrings("recipe");
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
builder.setRecipePart(i, Items.lookup(recipeStrings.get(i)));
|
||||
}
|
||||
|
||||
ShapedCraftingRecipe recipe = builder.build();
|
||||
recipe.register();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item stack from slot.
|
||||
*
|
||||
@@ -455,23 +146,22 @@ public class ArmorSet {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof ArmorSet)) {
|
||||
if (!(o instanceof ArmorSet set)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ArmorSet set = (ArmorSet) o;
|
||||
return this.getName().equals(set.getName());
|
||||
return this.name.equals(set.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.getName());
|
||||
return Objects.hash(this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ArmorSet{"
|
||||
+ this.getName()
|
||||
+ this.name
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
package com.willfp.ecoarmor.sets;
|
||||
|
||||
import com.willfp.eco.core.config.Config;
|
||||
import com.willfp.eco.core.config.JSONConfig;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import com.willfp.eco.core.items.CustomItem;
|
||||
import com.willfp.eco.core.items.builder.ItemBuilder;
|
||||
import com.willfp.eco.core.items.builder.ItemStackBuilder;
|
||||
import com.willfp.eco.core.items.builder.LeatherArmorBuilder;
|
||||
import com.willfp.eco.core.items.builder.SkullBuilder;
|
||||
import com.willfp.eco.core.recipe.Recipes;
|
||||
import com.willfp.ecoarmor.EcoArmorPlugin;
|
||||
import com.willfp.ecoarmor.conditions.Condition;
|
||||
import com.willfp.ecoarmor.conditions.Conditions;
|
||||
import com.willfp.ecoarmor.effects.Effect;
|
||||
import com.willfp.ecoarmor.effects.Effects;
|
||||
import com.willfp.ecoarmor.sets.meta.ArmorSlot;
|
||||
import com.willfp.ecoarmor.sets.util.ArmorUtils;
|
||||
import com.willfp.ecoarmor.upgrades.Tier;
|
||||
import com.willfp.ecoarmor.upgrades.Tiers;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ArmorSetFactory {
|
||||
|
||||
/**
|
||||
* Instance of EcoArmor.
|
||||
*/
|
||||
private static final EcoArmorPlugin PLUGIN = EcoArmorPlugin.getInstance();
|
||||
|
||||
/**
|
||||
* The name of the set.
|
||||
*/
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The config of the set.
|
||||
*/
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
private final JSONConfig config;
|
||||
|
||||
/**
|
||||
* Conditions and their values.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<Condition<?>, Object> conditions = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Effects and their strengths.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<Effect<?>, Object> effects = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Effects and their strengths on advanced armor.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<Effect<?>, Object> advancedEffects = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Potion effects to be applied on equip.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<PotionEffectType, Integer> potionEffects = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Potion effects to be applied on equipping advanced.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<PotionEffectType, Integer> advancedPotionEffects = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The base64 texture of a skull used as a helmet.
|
||||
* <p>
|
||||
* Null if no skull.
|
||||
*/
|
||||
@Getter
|
||||
@Nullable
|
||||
private String skullBase64;
|
||||
|
||||
/**
|
||||
* Items in set.
|
||||
*/
|
||||
private final Map<ArmorSlot, ItemStack> items = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Items in advanced set.
|
||||
*/
|
||||
private final Map<ArmorSlot, ItemStack> advancedItems = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Advancement shard item.
|
||||
*/
|
||||
@Getter
|
||||
private final ItemStack advancementShardItem;
|
||||
|
||||
/**
|
||||
* Create a new Armor Set.
|
||||
*
|
||||
* @param config The set's config.
|
||||
*/
|
||||
public ArmorSetFactory(@NotNull final JSONConfig config) {
|
||||
this.config = config;
|
||||
this.name = config.getString("name");
|
||||
|
||||
for (String definedKey : this.getConfig().getStrings("conditions")) {
|
||||
String[] split = definedKey.split(":");
|
||||
String key = split[0].trim();
|
||||
String value = split[1].trim();
|
||||
Condition<?> condition = Conditions.getByName(key);
|
||||
if (condition == null) {
|
||||
Bukkit.getLogger().warning("Invalid condition specified in " + this.name);
|
||||
} else {
|
||||
conditions.put(condition, ArmorUtils.getConditionValue(value, condition));
|
||||
}
|
||||
}
|
||||
|
||||
for (JSONConfig cfg : this.getConfig().getSubsections("effects")) {
|
||||
Effect<?> effect = Effects.getByName(cfg.getString("id"));
|
||||
Object value = cfg.get("args");
|
||||
effects.put(effect, value);
|
||||
}
|
||||
|
||||
for (JSONConfig cfg : this.getConfig().getSubsections("advanced-effects")) {
|
||||
Effect<?> effect = Effects.getByName(cfg.getString("id"));
|
||||
Object value = cfg.get("args");
|
||||
advancedEffects.put(effect, value);
|
||||
}
|
||||
|
||||
for (JSONConfig cfg : this.getConfig().getSubsections("potion-effects")) {
|
||||
PotionEffectType effect = PotionEffectType.getByName(cfg.getString("id").toUpperCase());
|
||||
int level = cfg.getInt("level");
|
||||
potionEffects.put(effect, level);
|
||||
}
|
||||
|
||||
for (JSONConfig cfg : this.getConfig().getSubsections("advanced-potion-effects")) {
|
||||
PotionEffectType effect = PotionEffectType.getByName(cfg.getString("id").toUpperCase());
|
||||
int level = cfg.getInt("level");
|
||||
advancedPotionEffects.put(effect, level);
|
||||
}
|
||||
|
||||
for (ArmorSlot slot : ArmorSlot.values()) {
|
||||
ItemStack item = construct(slot, (JSONConfig) this.getConfig().getSubsection(slot.name().toLowerCase()), false);
|
||||
items.put(slot, item);
|
||||
if (this.getConfig().getBool("enabled")) {
|
||||
constructRecipe(slot, this.getConfig().getSubsection(slot.name().toLowerCase()), item);
|
||||
}
|
||||
|
||||
ItemStack advancedItem = construct(slot, (JSONConfig) this.getConfig().getSubsection(slot.name().toLowerCase()), true);
|
||||
advancedItems.put(slot, advancedItem);
|
||||
}
|
||||
|
||||
this.advancementShardItem = constructShard();
|
||||
}
|
||||
|
||||
private ItemStack constructShard() {
|
||||
ItemStack shard = new ItemStackBuilder(Objects.requireNonNull(Material.getMaterial(PLUGIN.getConfigYml().getString("advancement-shard-material").toUpperCase())))
|
||||
.setDisplayName(this.getConfig().getString("advancement-shard-name"))
|
||||
.addEnchantment(Enchantment.DURABILITY, 3)
|
||||
.addItemFlag(ItemFlag.HIDE_ENCHANTS)
|
||||
.addLoreLines(this.getConfig().getStrings("advancement-shard-lore"))
|
||||
.writeMetaKey(PLUGIN.getNamespacedKeyFactory().create("advancement-shard"), PersistentDataType.STRING, name)
|
||||
.build();
|
||||
|
||||
if (this.getConfig().getBool("shard-craftable")) {
|
||||
Recipes.createAndRegisterRecipe(PLUGIN,
|
||||
this.getName() + "_shard",
|
||||
shard,
|
||||
this.getConfig().getStrings("shard-recipe"));
|
||||
}
|
||||
|
||||
return shard;
|
||||
}
|
||||
|
||||
private ItemStack construct(@NotNull final ArmorSlot slot,
|
||||
@NotNull final JSONConfig slotConfig,
|
||||
final boolean advanced) {
|
||||
Material material = Material.getMaterial(slotConfig.getString("material").toUpperCase());
|
||||
|
||||
assert material != null;
|
||||
|
||||
ItemBuilder builder;
|
||||
|
||||
builder = switch (material) {
|
||||
case PLAYER_HEAD -> new SkullBuilder();
|
||||
case LEATHER_HELMET, LEATHER_CHESTPLATE, LEATHER_LEGGINGS, LEATHER_BOOTS -> new LeatherArmorBuilder(material);
|
||||
default -> new ItemStackBuilder(material);
|
||||
};
|
||||
|
||||
builder.setDisplayName(advanced ? slotConfig.getString("advanced-name") : slotConfig.getString("name"))
|
||||
.addItemFlag(
|
||||
slotConfig.getStrings("flags").stream()
|
||||
.map(s -> ItemFlag.valueOf(s.toUpperCase()))
|
||||
.toArray(ItemFlag[]::new)
|
||||
)
|
||||
.setUnbreakable(slotConfig.getBool("unbreakable"))
|
||||
.addLoreLines(slotConfig.getStrings("lore").stream().map(s -> Display.PREFIX + s).collect(Collectors.toList()))
|
||||
.addLoreLines(() -> {
|
||||
if (advanced) {
|
||||
return slotConfig.getStrings("advanced-lore").stream().map(s -> Display.PREFIX + s).collect(Collectors.toList());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.setCustomModelData(() -> {
|
||||
int data = slotConfig.getInt("custom-model-data");
|
||||
return data != -1 ? data : null;
|
||||
})
|
||||
.setDisplayName(() -> advanced ? slotConfig.getString("advanced-name") : slotConfig.getString("name"));
|
||||
|
||||
|
||||
if (builder instanceof SkullBuilder skullBuilder) {
|
||||
this.skullBase64 = slotConfig.getString("skull-texture");
|
||||
skullBuilder.setSkullTexture(skullBase64);
|
||||
}
|
||||
|
||||
if (builder instanceof LeatherArmorBuilder leatherArmorBuilder) {
|
||||
String colorString = slotConfig.getString("leather-color");
|
||||
java.awt.Color awtColor = java.awt.Color.decode(colorString);
|
||||
leatherArmorBuilder.setColor(awtColor);
|
||||
builder.addItemFlag(ItemFlag.HIDE_DYE);
|
||||
}
|
||||
|
||||
|
||||
Map<Enchantment, Integer> enchants = new HashMap<>();
|
||||
|
||||
for (JSONConfig enchantSection : slotConfig.getSubsections("enchants")) {
|
||||
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantSection.getString("id")));
|
||||
int level = enchantSection.getInt("level");
|
||||
enchants.put(enchantment, level);
|
||||
}
|
||||
|
||||
enchants.forEach(builder::addEnchantment);
|
||||
|
||||
builder.writeMetaKey(
|
||||
PLUGIN.getNamespacedKeyFactory().create("set"),
|
||||
PersistentDataType.STRING,
|
||||
name
|
||||
).writeMetaKey(
|
||||
PLUGIN.getNamespacedKeyFactory().create("effective-durability"),
|
||||
PersistentDataType.INTEGER,
|
||||
slotConfig.getInt("effective-durability")
|
||||
);
|
||||
|
||||
ItemStack itemStack = builder.build();
|
||||
|
||||
ArmorUtils.setAdvanced(itemStack, advanced);
|
||||
Tier defaultTier = Tiers.getByName(slotConfig.getString("default-tier"));
|
||||
if (defaultTier == null) {
|
||||
Bukkit.getLogger().warning("Default tier specified in " + this.name + " " + slot.name().toLowerCase() + " is invalid! Defaulting to 'default'");
|
||||
ArmorUtils.setTier(itemStack, Tiers.DEFAULT);
|
||||
} else {
|
||||
ArmorUtils.setTier(itemStack, defaultTier);
|
||||
}
|
||||
|
||||
if (advanced) {
|
||||
new CustomItem(PLUGIN.getNamespacedKeyFactory().create("set_" + name.toLowerCase() + "_" + slot.name().toLowerCase() + "_advanced"), test -> {
|
||||
if (ArmorSlot.getSlot(test) != ArmorSlot.getSlot(itemStack)) {
|
||||
return false;
|
||||
}
|
||||
if (!ArmorUtils.isAdvanced(itemStack)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.getName(), ArmorUtils.getSetOnItem(test).getName());
|
||||
}, itemStack).register();
|
||||
} else {
|
||||
new CustomItem(PLUGIN.getNamespacedKeyFactory().create("set_" + name.toLowerCase() + "_" + slot.name().toLowerCase()), test -> {
|
||||
if (ArmorSlot.getSlot(test) != ArmorSlot.getSlot(itemStack)) {
|
||||
return false;
|
||||
}
|
||||
if (ArmorUtils.isAdvanced(itemStack)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.getName(), ArmorUtils.getSetOnItem(test).getName());
|
||||
}, itemStack).register();
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private void constructRecipe(@NotNull final ArmorSlot slot,
|
||||
@NotNull final Config slotConfig,
|
||||
@NotNull final ItemStack out) {
|
||||
if (slotConfig.getBool("craftable")) {
|
||||
ItemStack formattedOut = out.clone();
|
||||
ItemMeta meta = formattedOut.getItemMeta();
|
||||
assert meta != null;
|
||||
assert meta.getLore() != null;
|
||||
|
||||
List<String> lore = new ArrayList<>();
|
||||
|
||||
for (String s : meta.getLore()) {
|
||||
s = s.replace("%tier%", Tiers.DEFAULT.getDisplayName());
|
||||
lore.add(s);
|
||||
}
|
||||
|
||||
meta.setLore(lore);
|
||||
formattedOut.setItemMeta(meta);
|
||||
|
||||
Recipes.createAndRegisterRecipe(
|
||||
PLUGIN,
|
||||
this.getName() + "_" + slot.name().toLowerCase(),
|
||||
formattedOut,
|
||||
slotConfig.getStrings("recipe")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Armor Set.
|
||||
*
|
||||
* @return The set.
|
||||
*/
|
||||
public ArmorSet create() {
|
||||
return new ArmorSet(
|
||||
name,
|
||||
conditions,
|
||||
effects,
|
||||
advancedEffects,
|
||||
potionEffects,
|
||||
advancedPotionEffects,
|
||||
skullBase64,
|
||||
items,
|
||||
advancedItems,
|
||||
advancementShardItem
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,38 +5,26 @@ import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.willfp.eco.core.config.ConfigUpdater;
|
||||
import com.willfp.eco.core.config.JSONConfig;
|
||||
import com.willfp.ecoarmor.EcoArmorPlugin;
|
||||
import com.willfp.ecoarmor.config.BaseEcoArmorConfig;
|
||||
import com.willfp.ecoarmor.config.CustomConfig;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
public class ArmorSets {
|
||||
/**
|
||||
* Instance of EcoArmor.
|
||||
*/
|
||||
private static final EcoArmorPlugin PLUGIN = EcoArmorPlugin.getInstance();
|
||||
|
||||
/**
|
||||
* Registered armor sets.
|
||||
*/
|
||||
private static final BiMap<String, ArmorSet> BY_NAME = HashBiMap.create();
|
||||
|
||||
/**
|
||||
* Sets that exist by default.
|
||||
*/
|
||||
private static final List<String> DEFAULT_SET_NAMES = Arrays.asList(
|
||||
"miner",
|
||||
"reaper",
|
||||
"ender",
|
||||
"young"
|
||||
);
|
||||
|
||||
/**
|
||||
* Get all registered {@link ArmorSet}s.
|
||||
*
|
||||
@@ -66,22 +54,8 @@ public class ArmorSets {
|
||||
removeSet(set);
|
||||
}
|
||||
|
||||
for (String defaultSetName : DEFAULT_SET_NAMES) {
|
||||
new ArmorSet(defaultSetName, new BaseEcoArmorConfig(defaultSetName));
|
||||
}
|
||||
|
||||
try {
|
||||
Files.walk(Paths.get(new File(EcoArmorPlugin.getInstance().getDataFolder(), "sets/").toURI()))
|
||||
.filter(Files::isRegularFile)
|
||||
.forEach(path -> {
|
||||
String name = path.getFileName().toString().replace(".yml", "");
|
||||
new ArmorSet(
|
||||
name,
|
||||
new CustomConfig(name, YamlConfiguration.loadConfiguration(path.toFile()))
|
||||
);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
for (JSONConfig setConfig : PLUGIN.getSetsJson().getSubsections("sets")) {
|
||||
addNewSet(new ArmorSetFactory(setConfig).create());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.willfp.ecoarmor.sets.util;
|
||||
|
||||
import com.willfp.ecoarmor.EcoArmorPlugin;
|
||||
import com.willfp.ecoarmor.conditions.Condition;
|
||||
import com.willfp.ecoarmor.effects.Effect;
|
||||
import com.willfp.ecoarmor.sets.ArmorSet;
|
||||
import com.willfp.ecoarmor.sets.ArmorSets;
|
||||
import com.willfp.ecoarmor.sets.meta.ArmorSlot;
|
||||
@@ -403,32 +402,6 @@ public class ArmorUtils {
|
||||
return ArmorSets.getByName(shardSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of effect.
|
||||
*
|
||||
* @param string Value as string.
|
||||
* @param effect Effect.
|
||||
* @param <T> The type of the effect.
|
||||
* @return Value.
|
||||
*/
|
||||
@NotNull
|
||||
public static <T> Object getEffectValue(@NotNull final String string,
|
||||
@NotNull final Effect<T> effect) {
|
||||
if (effect.getTypeClass().equals(Boolean.class)) {
|
||||
return Boolean.parseBoolean(string);
|
||||
}
|
||||
|
||||
if (effect.getTypeClass().equals(Integer.class)) {
|
||||
return Integer.parseInt(string);
|
||||
}
|
||||
|
||||
if (effect.getTypeClass().equals(Double.class)) {
|
||||
return Double.parseDouble(string);
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of condition.
|
||||
*
|
||||
|
||||
261
eco-core/core-plugin/src/main/resources/sets.json
Normal file
261
eco-core/core-plugin/src/main/resources/sets.json
Normal file
@@ -0,0 +1,261 @@
|
||||
{
|
||||
"sets": [
|
||||
{
|
||||
"name": "ender",
|
||||
"conditions": [],
|
||||
"effects": [
|
||||
{
|
||||
"id": "warp-chance",
|
||||
"args": 20
|
||||
},
|
||||
{
|
||||
"id": "evade-chance",
|
||||
"args": 10
|
||||
}
|
||||
],
|
||||
"advanced-effects": [
|
||||
{
|
||||
"id": "warp-chance",
|
||||
"args": 30
|
||||
},
|
||||
{
|
||||
"id": "evade-chance",
|
||||
"args": 20
|
||||
}
|
||||
],
|
||||
"potion-effects": [
|
||||
],
|
||||
"advanced-potion-effects": [
|
||||
],
|
||||
"advanced-lore": [
|
||||
"",
|
||||
"<GRADIENT:f12711>&lADVANCED BONUS</GRADIENT:f5af19>",
|
||||
"&8» &330% Chance to warp behind your opponent",
|
||||
"&8» &320% Chance to evade attacks",
|
||||
"&8&oRequires full set to be worn"
|
||||
],
|
||||
"advancement-shard-name": "<GRADIENT:f12711>Advancement Shard:</GRADIENT:f5af19> &3Ender",
|
||||
"advancement-shard-lore": [
|
||||
"&8Drop this onto &3Ender Armor",
|
||||
"&8to make it <GRADIENT:f12711>Advanced</GRADIENT:f5af19>."
|
||||
],
|
||||
"shard-craftable": true,
|
||||
"shard-recipe": [
|
||||
"prismarine_shard",
|
||||
"ecoarmor:set_ender_helmet",
|
||||
"prismarine_shard",
|
||||
"ecoarmor:set_ender_chestplate",
|
||||
"nether_star",
|
||||
"ecoarmor:set_ender_leggings",
|
||||
"prismarine_shard",
|
||||
"ecoarmor:set_ender_boots",
|
||||
"prismarine_shard"
|
||||
],
|
||||
"helmet": {
|
||||
"enchants": [
|
||||
{
|
||||
"id": "protection",
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "unbreaking",
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"material": "player_head",
|
||||
"skull-texture": "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGFhOGZjOGRlNjQxN2I0OGQ0OGM4MGI0NDNjZjUzMjZlM2Q5ZGE0ZGJlOWIyNWZjZDQ5NTQ5ZDk2MTY4ZmMwIn19fQ==",
|
||||
"name": "&bEnder Helmet",
|
||||
"advanced-name": "<GRADIENT:f12711>Advanced</GRADIENT:f5af19>&3 Ender Helmet",
|
||||
"effective-durability": 1024,
|
||||
"unbreakable": false,
|
||||
"flags": [],
|
||||
"custom-model-data": -1,
|
||||
"lore": [
|
||||
"&3&lENDER SET BONUS",
|
||||
"&8» &320% Chance to warp behind your opponent",
|
||||
"&8» &310% Chance to evade attacks",
|
||||
"&8&oRequires full set to be worn",
|
||||
"",
|
||||
"&fTier: %tier%",
|
||||
"&8&oUpgrade with an Upgrade Crystal"
|
||||
],
|
||||
"craftable": true,
|
||||
"default-tier": "default",
|
||||
"recipe": [
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"iron_helmet",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye"
|
||||
]
|
||||
},
|
||||
"chestplate": {
|
||||
"enchants": [
|
||||
{
|
||||
"id": "protection",
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "unbreaking",
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"material": "leather_chestplate",
|
||||
"leather-color": "#0d6961",
|
||||
"name": "&3Ender Chestplate",
|
||||
"advanced-name": "<GRADIENT:f12711>Advanced</GRADIENT:f5af19>&3 Ender Chestplate",
|
||||
"effective-durability": 1024,
|
||||
"unbreakable": false,
|
||||
"flags": [],
|
||||
"custom-model-data": -1,
|
||||
"lore": [
|
||||
"&3&lENDER SET BONUS",
|
||||
"&8» &320% Chance to warp behind your opponent",
|
||||
"&8» &310% Chance to evade attacks",
|
||||
"&8&oRequires full set to be worn",
|
||||
"",
|
||||
"&fTier: %tier%",
|
||||
"&8&oUpgrade with an Upgrade Crystal"
|
||||
],
|
||||
"craftable": true,
|
||||
"default-tier": "diamond",
|
||||
"recipe": [
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"iron_chestplate",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye"
|
||||
]
|
||||
},
|
||||
"elytra": {
|
||||
"enchants": [
|
||||
{
|
||||
"id": "unbreaking",
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"material": "elytra",
|
||||
"name": "&3Ender Elytra",
|
||||
"advanced-name": "<GRADIENT:f12711>Advanced</GRADIENT:f5af19>&3 Ender Elytra",
|
||||
"effective-durability": 1024,
|
||||
"unbreakable": false,
|
||||
"flags": [],
|
||||
"custom-model-data": -1,
|
||||
"lore": [
|
||||
"&3&lENDER SET BONUS",
|
||||
"&8» &320% Chance to warp behind your opponent",
|
||||
"&8» &310% Chance to evade attacks",
|
||||
"&8&oRequires full set to be worn",
|
||||
"",
|
||||
"&fTier: %tier%",
|
||||
"&8&oUpgrade with an Upgrade Crystal"
|
||||
],
|
||||
"craftable": true,
|
||||
"default-tier": "default",
|
||||
"recipe": [
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"elytra",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye"
|
||||
]
|
||||
},
|
||||
"leggings": {
|
||||
"enchants": [
|
||||
{
|
||||
"id": "protection",
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "unbreaking",
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"material": "leather_leggings",
|
||||
"leather-color": "#0d6961",
|
||||
"name": "&3Ender Leggings",
|
||||
"advanced-name": "<GRADIENT:f12711>Advanced</GRADIENT:f5af19>&3 Ender Leggings",
|
||||
"effective-durability": 1024,
|
||||
"unbreakable": false,
|
||||
"flags": [],
|
||||
"custom-model-data": -1,
|
||||
"lore": [
|
||||
"&3&lENDER SET BONUS",
|
||||
"&8» &320% Chance to warp behind your opponent",
|
||||
"&8» &310% Chance to evade attacks",
|
||||
"&8&oRequires full set to be worn",
|
||||
"",
|
||||
"&fTier: %tier%",
|
||||
"&8&oUpgrade with an Upgrade Crystal"
|
||||
],
|
||||
"craftable": true,
|
||||
"default-tier": "default",
|
||||
"recipe": [
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"iron_leggings",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye"
|
||||
]
|
||||
},
|
||||
"boots": {
|
||||
"enchants": [
|
||||
{
|
||||
"id": "protection",
|
||||
"level": 3
|
||||
},
|
||||
{
|
||||
"id": "unbreaking",
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"material": "leather_boots",
|
||||
"leather-color": "#0d6961",
|
||||
"name": "&3Ender Boots",
|
||||
"advanced-name": "<GRADIENT:f12711>Advanced</GRADIENT:f5af19>&3 Ender Boots",
|
||||
"effective-durability": 1024,
|
||||
"unbreakable": false,
|
||||
"flags": [],
|
||||
"custom-model-data": -1,
|
||||
"lore": [
|
||||
"&3&lENDER SET BONUS",
|
||||
"&8» &320% Chance to warp behind your opponent",
|
||||
"&8» &310% Chance to evade attacks",
|
||||
"&8&oRequires full set to be worn",
|
||||
"",
|
||||
"&fTier: %tier%",
|
||||
"&8&oUpgrade with an Upgrade Crystal"
|
||||
],
|
||||
"craftable": true,
|
||||
"default-tier": "default",
|
||||
"recipe": [
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"iron_boots",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye",
|
||||
"ender_eye"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
version = 4.3.2
|
||||
version = 5.0.0
|
||||
plugin-name = EcoArmor
|
||||
Reference in New Issue
Block a user