Added ability to create custom enchants in config via libreforge

This commit is contained in:
Auxilor
2022-01-08 13:36:00 +00:00
parent 1d5e22a986
commit 5e264a3631
19 changed files with 724 additions and 18 deletions

View File

@@ -46,12 +46,17 @@ allprojects {
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
}
shadowJar {
relocate('com.willfp.libreforge', 'com.willfp.ecoenchants.libreforge')
}
compileJava {
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
}
dependencies {
compileOnly 'com.willfp:eco:6.17.1'
implementation 'com.willfp:libreforge:2.13.0'
compileOnly 'org.jetbrains:annotations:19.0.0'

View File

@@ -8,12 +8,15 @@ import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.util.TelekinesisUtils;
import com.willfp.ecoenchants.command.CommandEcoEnchants;
import com.willfp.ecoenchants.command.CommandEnchantinfo;
import com.willfp.ecoenchants.config.CustomEnchantsYml;
import com.willfp.ecoenchants.config.RarityYml;
import com.willfp.ecoenchants.config.TargetYml;
import com.willfp.ecoenchants.config.VanillaEnchantsYml;
import com.willfp.ecoenchants.display.EnchantDisplay;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import com.willfp.ecoenchants.enchantments.custom.CustomEnchantEnableListeners;
import com.willfp.ecoenchants.enchantments.custom.CustomEnchantLookup;
import com.willfp.ecoenchants.enchantments.support.merging.anvil.AnvilListeners;
import com.willfp.ecoenchants.enchantments.support.merging.grindstone.GrindstoneListeners;
import com.willfp.ecoenchants.enchantments.support.obtaining.EnchantingListeners;
@@ -26,6 +29,7 @@ import com.willfp.ecoenchants.integrations.mythicmobs.MythicMobsManager;
import com.willfp.ecoenchants.integrations.mythicmobs.plugins.IntegrationMythicMobs;
import com.willfp.ecoenchants.integrations.registration.RegistrationManager;
import com.willfp.ecoenchants.integrations.registration.plugins.IntegrationEssentials;
import com.willfp.libreforge.LibReforge;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.event.HandlerList;
@@ -33,6 +37,7 @@ import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -59,20 +64,30 @@ public class EcoEnchantsPlugin extends EcoPlugin {
*/
private final VanillaEnchantsYml vanillaEnchantsYml;
/**
* CustomEnchants.yml.
*/
private final CustomEnchantsYml customEnchantsYml;
/**
* Internal constructor called by bukkit on plugin load.
*/
public EcoEnchantsPlugin() {
super(490, 7666, "com.willfp.ecoenchants.proxy", "&a", true);
LibReforge.init(this);
instance = this;
rarityYml = new RarityYml(this);
targetYml = new TargetYml(this);
vanillaEnchantsYml = new VanillaEnchantsYml(this);
customEnchantsYml = new CustomEnchantsYml(this);
LibReforge.registerJavaHolderProvider(player -> new ArrayList<>(CustomEnchantLookup.provideLevels(player)));
}
@Override
protected void handleEnable() {
LibReforge.enable(this);
this.getLogger().info(EcoEnchants.values().size() + " Enchantments Loaded");
TelekinesisUtils.registerTest(player -> FastItemStack.wrap(player.getInventory().getItemInMainHand()).getLevelOnItem(EcoEnchants.TELEKINESIS, false) > 0);
@@ -80,6 +95,7 @@ public class EcoEnchantsPlugin extends EcoPlugin {
@Override
protected void handleDisable() {
LibReforge.disable(this);
for (World world : Bukkit.getServer().getWorlds()) {
world.getPopulators().removeIf(blockPopulator -> blockPopulator instanceof LootPopulator);
}
@@ -87,6 +103,7 @@ public class EcoEnchantsPlugin extends EcoPlugin {
@Override
protected void handleReload() {
LibReforge.reload(this);
this.getDisplayModule().update();
for (EcoEnchant enchant : EcoEnchants.values()) {
HandlerList.unregisterAll(enchant);
@@ -142,7 +159,8 @@ public class EcoEnchantsPlugin extends EcoPlugin {
new AnvilListeners(this),
new WatcherTriggers(this),
new VillagerListeners(this),
new ItemConversions(this)
new ItemConversions(this),
new CustomEnchantEnableListeners(this)
);
}
@@ -200,4 +218,13 @@ public class EcoEnchantsPlugin extends EcoPlugin {
public VanillaEnchantsYml getVanillaEnchantsYml() {
return this.vanillaEnchantsYml;
}
/**
* Get customenchants.yml
*
* @return customenchants.yml.
*/
public CustomEnchantsYml getCustomEnchantsYml() {
return customEnchantsYml;
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.ecoenchants.config;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.core.config.ConfigType;
import org.jetbrains.annotations.NotNull;
public class CustomEnchantsYml extends BaseConfig {
/**
* Instantiate target.yml.
*
* @param plugin Instance of EcoEnchants.
*/
public CustomEnchantsYml(@NotNull final EcoPlugin plugin) {
super("customenchants", plugin, true, ConfigType.YAML);
}
}

View File

@@ -3,6 +3,7 @@ package com.willfp.ecoenchants.config;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
@@ -46,4 +47,22 @@ public class TargetYml extends BaseConfig {
return materials;
}
/**
* Get the slot for a target name.
*
* @param target The target.
* @return The slot, or {@link com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget.Slot#ANY}
*/
public EnchantmentTarget.Slot getSlot(@NotNull final String target) {
for (String str : this.getStrings("targets." + target)) {
if (str.startsWith("slot:")) {
return EnchantmentTarget.Slot.valueOf(
str.replace("slot:", "").toUpperCase()
);
}
}
return EnchantmentTarget.Slot.ANY;
}
}

View File

@@ -0,0 +1,24 @@
package com.willfp.ecoenchants.config.configs;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.ExtendableConfig;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import org.jetbrains.annotations.NotNull;
public class BaseEnchantmentConfig extends ExtendableConfig {
/**
* Instantiate a new config for an enchantment.
*
* @param name The name of the config.
* @param source The class in the jar where the config is contained.
* @param plugin The provider of the enchantment.
* @param enchant The enchantment.
*/
public BaseEnchantmentConfig(@NotNull final String name,
@NotNull final Class<?> source,
@NotNull final EcoEnchant enchant,
@NotNull final EcoPlugin plugin) {
super(name, true, plugin, source, "enchants/" + enchant.getType().getName() + "/", ConfigType.YAML);
}
}

View File

@@ -1,8 +1,9 @@
package com.willfp.ecoenchants.config.configs;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.ExtendableConfig;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentRarity;
@@ -18,7 +19,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class EnchantmentConfig extends ExtendableConfig {
public class EnchantmentConfig extends ConfigWrapper<Config> {
/**
* The name of the config.
*/
@@ -40,16 +41,16 @@ public class EnchantmentConfig extends ExtendableConfig {
/**
* Instantiate a new config for an enchantment.
*
* @param name The name of the config.
* @param source The class in the jar where the config is contained.
* @param plugin The provider of the enchantment.
* @param enchant The enchantment.
* @param handle The handle.
* @param name The config name.
* @param enchant The enchant.
* @param plugin Instance of EcoEnchants.
*/
public EnchantmentConfig(@NotNull final String name,
@NotNull final Class<?> source,
public EnchantmentConfig(@NotNull final Config handle,
@NotNull final String name,
@NotNull final EcoEnchant enchant,
@NotNull final EcoPlugin plugin) {
super(name, true, plugin, source, "enchants/" + enchant.getType().getName() + "/", ConfigType.YAML);
super(handle);
this.name = name;
this.enchant = enchant;
this.plugin = plugin;
@@ -119,7 +120,9 @@ public class EnchantmentConfig extends ExtendableConfig {
this.getPlugin().getLangYml().set("enchantments." + this.getEnchant().getKey().getKey(), null);
try {
this.save();
if (this.getHandle() instanceof LoadableConfig loadableConfig) {
loadableConfig.save();
}
this.getPlugin().getLangYml().save();
this.getPlugin().getLangYml().clearCache();
} catch (IOException e) {

View File

@@ -6,6 +6,7 @@ import com.willfp.eco.core.requirement.Requirement;
import com.willfp.eco.core.requirement.Requirements;
import com.willfp.eco.util.StringUtils;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.config.configs.BaseEnchantmentConfig;
import com.willfp.ecoenchants.config.configs.EnchantmentConfig;
import com.willfp.ecoenchants.display.EnchantmentCache;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentRarity;
@@ -189,7 +190,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Watche
this.type = type;
this.permissionName = key.replace("_", "");
this.config = new EnchantmentConfig(this.permissionName, this.getClass(), this, this.getPlugin());
this.config = generateConfig();
if (Bukkit.getPluginManager().getPermission("ecoenchants.fromtable." + permissionName) == null) {
Permission permission = new Permission(
@@ -209,7 +210,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Watche
return;
}
enabled = config.getBool("enabled");
enabled = Objects.requireNonNullElse(config.getBoolOrNull("enabled"), true);
if (!this.isEnabled() && this.getPlugin().getConfigYml().getBool("advanced.hard-disable.enabled")) {
return;
@@ -220,6 +221,20 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Watche
EcoEnchants.addNewEcoEnchant(this);
}
protected EnchantmentConfig generateConfig() {
return new EnchantmentConfig(
new BaseEnchantmentConfig(
this.permissionName,
this.getClass(),
this,
this.getPlugin()
),
this.permissionName,
this,
this.getPlugin()
);
}
/**
* Update the enchantment based off config values.
* This can be overridden but may lead to unexpected behavior.

View File

@@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableList;
import com.willfp.eco.core.config.updating.ConfigUpdater;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.enchantments.custom.CustomEcoEnchants;
import com.willfp.ecoenchants.enchantments.ecoenchants.artifact.AngerArtifact;
import com.willfp.ecoenchants.enchantments.ecoenchants.artifact.AshArtifact;
import com.willfp.ecoenchants.enchantments.ecoenchants.artifact.CloudsArtifact;
@@ -565,6 +566,8 @@ public class EcoEnchants {
*/
@ConfigUpdater
public static void update(@NotNull final EcoEnchantsPlugin plugin) {
CustomEcoEnchants.update(plugin);
for (EcoEnchant ecoEnchant : new HashSet<>(values())) {
ecoEnchant.update();
}

View File

@@ -0,0 +1,78 @@
package com.willfp.ecoenchants.enchantments.custom;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.ecoenchants.config.configs.EnchantmentConfig;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class CustomEcoEnchant extends EcoEnchant {
/**
* The config.
*/
private final Config config;
/**
* The levels.
*/
private final Map<Integer, CustomEcoEnchantLevel> levels;
/**
* Create custom EcoEnchant.
*
* @param config The config.
*/
public CustomEcoEnchant(@NotNull final Config config) {
super(
config.getString("id"), EnchantmentType.getByName(config.getString("type"))
);
this.config = config;
this.levels = new HashMap<>();
int i = 1;
for (Config levelConfig : this.config.getSubsections("levels")) {
levels.put(i, new CustomEcoEnchantLevel(this, levelConfig));
i++;
}
}
/**
* Get the level.
*
* @param level The level.
* @return The level.
*/
public CustomEcoEnchantLevel getLevel(final int level) {
return levels.get(level);
}
/**
* Get the levels.
*
* @return The levels.
*/
public Set<CustomEcoEnchantLevel> getLevels() {
return new HashSet<>(levels.values());
}
@Override
protected EnchantmentConfig generateConfig() {
return new EnchantmentConfig(
this.config,
this.getPermissionName(),
this,
this.getPlugin()
);
}
@Override
public int getMaxLevel() {
return this.levels.size();
}
}

View File

@@ -0,0 +1,63 @@
package com.willfp.ecoenchants.enchantments.custom;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.libreforge.Holder;
import com.willfp.libreforge.conditions.Conditions;
import com.willfp.libreforge.conditions.ConfiguredCondition;
import com.willfp.libreforge.effects.ConfiguredEffect;
import com.willfp.libreforge.effects.Effects;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
public class CustomEcoEnchantLevel implements Holder {
/**
* The parent EcoEnchant.
*/
@Getter
private final EcoEnchant parent;
/**
* The conditions.
*/
private final Set<ConfiguredCondition> conditions = new HashSet<>();
/**
* The effects.
*/
private final Set<ConfiguredEffect> effects = new HashSet<>();
/**
* Create custom EcoEnchant level.
*
* @param parent The parent.
* @param config The config.
*/
public CustomEcoEnchantLevel(@NotNull final EcoEnchant parent,
@NotNull final Config config) {
this.parent = parent;
for (Config cfg : config.getSubsections("effects")) {
effects.add(Effects.compile(cfg, "Custom EcoEnchant ID " + parent.getKey().getKey()));
}
for (Config cfg : config.getSubsections("conditions")) {
conditions.add(Conditions.compile(cfg, "Custom EcoEnchant ID " + parent.getKey().getKey()));
}
}
@NotNull
@Override
public Set<ConfiguredCondition> getConditions() {
return conditions;
}
@NotNull
@Override
public Set<ConfiguredEffect> getEffects() {
return effects;
}
}

View File

@@ -0,0 +1,36 @@
package com.willfp.ecoenchants.enchantments.custom;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import com.willfp.ecoenchants.enchantments.util.EnchantmentUtils;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
@UtilityClass
public class CustomEcoEnchants {
/**
* Custom EcoEnchants.
*/
private static final Set<EcoEnchant> VALUES = new HashSet<>();
/**
* Update the map.
*
* @param plugin Instance of EcoEnchants.
*/
public static void update(@NotNull final EcoEnchantsPlugin plugin) {
for (EcoEnchant enchant : VALUES) {
EcoEnchants.removeEcoEnchant(enchant);
EnchantmentUtils.unregister(enchant);
}
for (Config cfg : plugin.getCustomEnchantsYml().getSubsections("enchants")) {
VALUES.add(new CustomEcoEnchant(cfg));
}
}
}

View File

@@ -0,0 +1,147 @@
package com.willfp.ecoenchants.enchantments.custom;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.events.ArmorChangeEvent;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
import com.willfp.libreforge.LibReforgeUtils;
import com.willfp.libreforge.effects.ConfiguredEffect;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.jetbrains.annotations.NotNull;
public class CustomEnchantEnableListeners extends PluginDependent<EcoPlugin> implements Listener {
/**
* Initialize new listeners and link them to a plugin.
*
* @param plugin The plugin to link to.
*/
public CustomEnchantEnableListeners(@NotNull final EcoPlugin plugin) {
super(plugin);
}
/**
* Called on item pickup.
*
* @param event The event to listen for.
*/
@EventHandler
public void onItemPickup(@NotNull final EntityPickupItemEvent event) {
if (!(event.getEntity() instanceof Player player)) {
return;
}
if (!EnchantmentTarget.ALL.getMaterials().contains(event.getItem().getItemStack().getType())) {
return;
}
refreshPlayer(player);
}
/**
* Called on player join.
*
* @param event The event to listen for.
*/
@EventHandler
public void onPlayerJoin(@NotNull final PlayerJoinEvent event) {
refresh();
}
/**
* Called on player leave.
*
* @param event The event to listen for.
*/
@EventHandler
public void onPlayerLeave(@NotNull final PlayerQuitEvent event) {
refresh();
Player player = event.getPlayer();
for (EcoEnchant value : EcoEnchants.values()) {
if (!(value instanceof CustomEcoEnchant enchant)) {
continue;
}
for (CustomEcoEnchantLevel level : enchant.getLevels()) {
for (ConfiguredEffect effect : level.getEffects()) {
effect.getEffect().disableForPlayer(player);
}
}
}
}
/**
* Called on item drop.
*
* @param event The event to listen for.
*/
@EventHandler
public void onInventoryDrop(@NotNull final PlayerDropItemEvent event) {
if (!EnchantmentTarget.ALL.getMaterials().contains(event.getItemDrop().getItemStack().getType())) {
return;
}
refreshPlayer(event.getPlayer());
}
/**
* Called on slot change.
*
* @param event The event to listen for.
*/
@EventHandler
public void onChangeSlot(@NotNull final PlayerItemHeldEvent event) {
refreshPlayer(event.getPlayer());
this.getPlugin().getScheduler().run(() -> refreshPlayer(event.getPlayer()));
}
/**
* Called on armor change.
*
* @param event The event to listen for.
*/
@EventHandler
public void onArmorChange(@NotNull final ArmorChangeEvent event) {
refreshPlayer(event.getPlayer());
}
/**
* Called on inventory click.
*
* @param event The event to listen for.
*/
@EventHandler
public void onInventoryClick(@NotNull final InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
refreshPlayer((Player) event.getWhoClicked());
}
/**
* Force refresh all online players.
* <p>
* This is a very expensive method.
*/
public void refresh() {
this.getPlugin().getServer().getOnlinePlayers().forEach(this::refreshPlayer);
}
private void refreshPlayer(@NotNull final Player player) {
CustomEnchantLookup.clearCache(player);
LibReforgeUtils.updateEffects(player);
}
}

View File

@@ -0,0 +1,155 @@
package com.willfp.ecoenchants.enchantments.custom;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
import com.willfp.ecoenchants.enchantments.util.EnchantChecks;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
public class CustomEnchantLookup {
/**
* All registered providers.
*/
private static final Set<Function<Player, Map<ItemStack, EnchantmentTarget.Slot>>> PROVIDERS = new HashSet<>();
/**
* Cached items.
*/
private static final Map<UUID, Map<ItemStack, EnchantmentTarget.Slot>> ITEM_CACHE = new WeakHashMap<>();
/**
* Cached enchant levels.
*/
private static final Map<UUID, Collection<CustomEcoEnchantLevel>> ENCHANT_LEVELS_CACHE = new WeakHashMap<>();
/**
* Instance of EcoEnchants.
*/
private static final EcoPlugin PLUGIN = EcoEnchantsPlugin.getInstance();
/**
* Register provider.
*
* @param provider The provider.
*/
public static void registerProvider(@NotNull final Function<Player, Map<ItemStack, EnchantmentTarget.Slot>> provider) {
PROVIDERS.add(provider);
}
/**
* Provide ItemStacks.
*
* @param player The player.
* @return The ItemStacks.
*/
public static Map<ItemStack, EnchantmentTarget.Slot> provide(@NotNull final Player player) {
if (ITEM_CACHE.containsKey(player.getUniqueId())) {
return new HashMap<>(ITEM_CACHE.get(player.getUniqueId()));
}
Map<ItemStack, EnchantmentTarget.Slot> found = new HashMap<>();
for (Function<Player, Map<ItemStack, EnchantmentTarget.Slot>> provider : PROVIDERS) {
found.putAll(provider.apply(player));
}
found.keySet().removeIf(Objects::isNull);
ITEM_CACHE.put(player.getUniqueId(), found);
PLUGIN.getScheduler().runLater(() -> ITEM_CACHE.remove(player.getUniqueId()), 40);
return found;
}
/**
* Provide levels.
*
* @param player The player.
* @return The levels.
*/
public static List<CustomEcoEnchantLevel> provideLevels(@NotNull final Player player) {
if (ENCHANT_LEVELS_CACHE.containsKey(player.getUniqueId())) {
return new ArrayList<>(ENCHANT_LEVELS_CACHE.get(player.getUniqueId()));
}
List<CustomEcoEnchantLevel> found = new ArrayList<>();
for (Map.Entry<ItemStack, EnchantmentTarget.Slot> entry : provide(player).entrySet()) {
ItemStack itemStack = entry.getKey();
EnchantmentTarget.Slot slot = entry.getValue();
if (itemStack == null) {
continue;
}
Map<EcoEnchant, Integer> enchants = EnchantChecks.getEnchantsOnItem(itemStack);
if (enchants.isEmpty()) {
continue;
}
for (Map.Entry<EcoEnchant, Integer> enchantEntry : enchants.entrySet()) {
if (!(enchantEntry.getKey() instanceof CustomEcoEnchant enchant)) {
continue;
}
if (slot != EnchantmentTarget.Slot.ANY) {
if (!enchant.getTargets().stream()
.map(EnchantmentTarget::getSlot)
.collect(Collectors.toList())
.contains(slot)) {
continue;
}
}
found.add(enchant.getLevel(enchantEntry.getValue()));
}
}
ENCHANT_LEVELS_CACHE.put(player.getUniqueId(), found);
PLUGIN.getScheduler().runLater(() -> ENCHANT_LEVELS_CACHE.remove(player.getUniqueId()), 40);
return found;
}
/**
* Clear cache.
*
* @param player The player.
*/
public static void clearCache(@NotNull final Player player) {
ITEM_CACHE.remove(player.getUniqueId());
ENCHANT_LEVELS_CACHE.remove(player.getUniqueId());
}
static {
registerProvider(player -> Map.of(
player.getInventory().getItemInMainHand(),
EnchantmentTarget.Slot.HANDS
));
registerProvider(player -> Map.of(
player.getInventory().getItemInOffHand(),
EnchantmentTarget.Slot.HANDS
));
registerProvider(player -> {
Map<ItemStack, EnchantmentTarget.Slot> items = new HashMap<>();
for (ItemStack stack : player.getInventory().getArmorContents()) {
items.put(stack, EnchantmentTarget.Slot.ARMOR);
}
return items;
});
}
}

View File

@@ -17,7 +17,7 @@ public class EnchantmentTarget {
/**
* Target containing the materials from all other targets.
*/
public static final EnchantmentTarget ALL = new EnchantmentTarget("all", new HashSet<>());
public static final EnchantmentTarget ALL = new EnchantmentTarget("all", new HashSet<>(), Slot.ANY);
/**
* All registered targets.
*/
@@ -33,12 +33,19 @@ public class EnchantmentTarget {
*/
@Getter
private final String name;
/**
* The materials of the target.
*/
@Getter
private final Set<Material> materials;
/**
* The slot to check for custom enchants.
*/
@Getter
private final Slot slot;
/**
* Create new rarity.
*
@@ -46,10 +53,12 @@ public class EnchantmentTarget {
* @param materials The items for the target
*/
public EnchantmentTarget(@NotNull final String name,
@NotNull final Set<Material> materials) {
@NotNull final Set<Material> materials,
@NotNull final Slot slot) {
this.name = name;
materials.removeIf(Objects::isNull);
this.materials = materials;
this.slot = slot;
}
/**
@@ -74,7 +83,7 @@ public class EnchantmentTarget {
ALL.materials.clear();
targetNames.forEach(name -> {
Set<Material> materials = plugin.getTargetYml().getTargetMaterials(name);
new EnchantmentTarget(name, materials).register();
new EnchantmentTarget(name, materials, plugin.getTargetYml().getSlot(name)).register();
});
}
@@ -94,4 +103,24 @@ public class EnchantmentTarget {
REGISTERED.add(this);
ALL.getMaterials().addAll(this.getMaterials());
}
/**
* Enchant slots.
*/
public enum Slot {
/**
* In hands.
*/
HANDS,
/**
* In armor.
*/
ARMOR,
/**
* In inventory.
*/
ANY
}
}

View File

@@ -143,6 +143,41 @@ public class EnchantmentUtils {
}
}
/**
* Unregister enchantment with the server.
*
* @param enchantment The enchantment.
*/
public static void unregister(@NotNull final Enchantment enchantment) {
try {
Field byIdField = Enchantment.class.getDeclaredField("byKey");
Field byNameField = Enchantment.class.getDeclaredField("byName");
byIdField.setAccessible(true);
byNameField.setAccessible(true);
Map<NamespacedKey, Enchantment> byKey = (Map<NamespacedKey, Enchantment>) byIdField.get(null);
Map<String, Enchantment> byName = (Map<String, Enchantment>) byNameField.get(null);
byKey.remove(enchantment.getKey());
byName.remove(enchantment.getName());
if (enchantment instanceof EcoEnchant) {
byName.remove(((EcoEnchant) enchantment).getDisplayName());
}
Map<String, Enchantment> byNameClone = new HashMap<>(byName);
for (Map.Entry<String, Enchantment> entry : byNameClone.entrySet()) {
if (entry.getValue().getKey().equals(enchantment.getKey())) {
byName.remove(entry.getKey());
}
}
Field f = Enchantment.class.getDeclaredField("acceptingNew");
f.setAccessible(true);
f.set(null, true);
f.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
}
/**
* Rehandle breaking in a fast way that doesn't call Player#updateInventory.
*

View File

@@ -0,0 +1,28 @@
enchants:
- id: demo
name: "Demo Custom Enchantment"
description: Damages your opponents armor by &a%value%&r.
obtaining:
table: true
villager: true
loot: true
rarity: legendary
general-config:
flags: [ ]
targets:
- sword
- axe
grindstoneable: true
disabled-in-worlds: [ ]
requirements:
list: [ ]
not-met-lore: [ ]
conflicts: [ ]
levels:
- effects: [ ]
conditions: [ ]
- effects: [ ]
conditions: [ ]

View File

@@ -11,6 +11,10 @@ depend:
softdepend:
- Essentials
- MythicMobs
- EcoSkills
- AureliumSkills
libraries:
- 'org.jetbrains.kotlin:kotlin-stdlib:1.6.0'
commands:
enchantinfo:

View File

@@ -8,6 +8,7 @@ extra-enchantable-items:
targets:
axe:
- target:hands
- wooden_axe
- stone_axe
- iron_axe
@@ -20,6 +21,7 @@ targets:
- enchanted_book
pickaxe:
- target:hands
- wooden_pickaxe
- stone_pickaxe
- iron_pickaxe
@@ -28,6 +30,7 @@ targets:
- netherite_pickaxe
hoe:
- target:hands
- wooden_hoe
- stone_hoe
- iron_hoe
@@ -36,6 +39,7 @@ targets:
- netherite_hoe
shovel:
- target:hands
- wooden_shovel
- stone_shovel
- iron_shovel
@@ -44,6 +48,7 @@ targets:
- netherite_shovel
sword:
- target:hands
- wooden_sword
- stone_sword
- iron_sword
@@ -52,6 +57,7 @@ targets:
- netherite_sword
helmet:
- target:armor
- turtle_helmet
- leather_helmet
- chainmail_helmet
@@ -61,6 +67,7 @@ targets:
- netherite_helmet
chestplate:
- target:armor
- leather_chestplate
- chainmail_chestplate
- iron_chestplate
@@ -69,6 +76,7 @@ targets:
- netherite_chestplate
leggings:
- target:armor
- leather_leggings
- chainmail_leggings
- iron_leggings
@@ -77,6 +85,7 @@ targets:
- netherite_leggings
boots:
- target:armor
- leather_boots
- chainmail_boots
- iron_boots
@@ -85,28 +94,37 @@ targets:
- netherite_boots
elytra:
- target:armor
- elytra
bow:
- target:hands
- bow
crossbow:
- target:hands
- crossbow
shears:
- target:hands
- shears
trident:
- target:hands
- trident
shield:
- target:hands
- shield
rod:
- target:hands
- fishing_rod
flintandsteel:
- target:hands
- flint_and_steel
carrot_stick:
- target:hands
- carrot_on_a_stick

View File

@@ -5,7 +5,7 @@ include ':eco-core'
include ':eco-core:core-nms'
include ':eco-core:core-nms:v1_16_R3'
include ':eco-core:core-nms:v1_17_R1'
include ':eco-core:core-nms:v1_18_R1'
//include ':eco-core:core-nms:v1_18_R1'
include ':eco-core:core-proxy'
include ':eco-core:core-plugin'
include ':eco-core:core-stub'