From 7635ab4082cfab995301fa3688b4316f8b652ba2 Mon Sep 17 00:00:00 2001 From: nulli0n Date: Thu, 13 Jul 2023 20:24:17 +0500 Subject: [PATCH] v3.5.0 New Enchants! --- Core/pom.xml | 12 +- .../excellentenchants/Placeholders.java | 1 + .../enchantment/EnchantRegistry.java | 3 + .../enchantment/config/EnchantDefaults.java | 17 ++- .../enchantment/impl/ExcellentEnchant.java | 1 + .../impl/armor/EnchantHardened.java | 4 +- .../impl/armor/StoppingForceEnchant.java | 76 ++++++++++++ .../enchantment/impl/bow/FlareEnchant.java | 115 ++++++++++++++++++ .../impl/tool/CurseOfMediocrityEnchant.java | 105 ++++++++++++++++ .../enchantment/impl/tool/EnchantTunnel.java | 28 ++--- .../impl/tool/EnchantVeinminer.java | 30 +++-- .../impl/weapon/EnchantCutter.java | 13 ++ .../menu/EnchantmentsListMenu.java | 2 + .../enchantment/util/EnchantUtils.java | 1 + NMS/pom.xml | 2 +- V1_17_R1/pom.xml | 4 +- V1_18_R2/pom.xml | 4 +- V1_19_R3/pom.xml | 4 +- V1_20_R1/pom.xml | 4 +- pom.xml | 2 +- 20 files changed, 380 insertions(+), 48 deletions(-) create mode 100644 Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/StoppingForceEnchant.java create mode 100644 Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/bow/FlareEnchant.java create mode 100644 Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/CurseOfMediocrityEnchant.java diff --git a/Core/pom.xml b/Core/pom.xml index 8c4fc26..59c391b 100644 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.4.5 + 3.5.0 4.0.0 @@ -95,27 +95,27 @@ su.nightexpress.excellentenchants NMS - 3.4.5 + 3.5.0 su.nightexpress.excellentenchants V1_17_R1 - 3.4.5 + 3.5.0 su.nightexpress.excellentenchants V1_18_R2 - 3.4.5 + 3.5.0 su.nightexpress.excellentenchants V1_19_R3 - 3.4.5 + 3.5.0 su.nightexpress.excellentenchants V1_20_R1 - 3.4.5 + 3.5.0 diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/Placeholders.java b/Core/src/main/java/su/nightexpress/excellentenchants/Placeholders.java index 8387f9c..2c6a306 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/Placeholders.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/Placeholders.java @@ -17,6 +17,7 @@ public class Placeholders extends su.nexmedia.engine.utils.Placeholders { public static final String ENCHANTMENT_POTION_DURATION = "%enchantment_potion_duration%"; public static final String ENCHANTMENT_POTION_TYPE = "%enchantment_potion_type%"; + public static final String ENCHANTMENT_ID = "%enchantment_id%"; public static final String ENCHANTMENT_NAME = "%enchantment_name%"; public static final String ENCHANTMENT_NAME_FORMATTED = "%enchantment_name_formatted%"; public static final String ENCHANTMENT_DESCRIPTION = "%enchantment_description%"; diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/EnchantRegistry.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/EnchantRegistry.java index 40a5ca0..81578ba 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/EnchantRegistry.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/EnchantRegistry.java @@ -106,6 +106,7 @@ public class EnchantRegistry { this.register(EnchantRegrowth.ID, () -> new EnchantRegrowth(plugin)); this.register(EnchantSaturation.ID, () -> new EnchantSaturation(plugin)); this.register(EnchantSelfDestruction.ID, () -> new EnchantSelfDestruction(plugin)); + this.register(StoppingForceEnchant.ID, () -> new StoppingForceEnchant(plugin)); this.register(EnchantSonic.ID, () -> new EnchantSonic(plugin)); // Bow enchants @@ -115,6 +116,7 @@ public class EnchantRegistry { this.register(EnchantElectrifiedArrows.ID, () -> new EnchantElectrifiedArrows(plugin)); this.register(EnchantEnderBow.ID, () -> new EnchantEnderBow(plugin)); this.register(EnchantExplosiveArrows.ID, () -> new EnchantExplosiveArrows(plugin)); + this.register(FlareEnchant.ID, () -> new FlareEnchant(plugin)); this.register(EnchantGhast.ID, () -> new EnchantGhast(plugin)); this.register(EnchantHover.ID, () -> new EnchantHover(plugin)); this.register(EnchantPoisonedArrows.ID, () -> new EnchantPoisonedArrows(plugin)); @@ -122,6 +124,7 @@ public class EnchantRegistry { // Universal this.register(EnchantCurseOfFragility.ID, () -> new EnchantCurseOfFragility(plugin)); + this.register(CurseOfMediocrityEnchant.ID, () -> new CurseOfMediocrityEnchant(plugin)); Enchantment.stopAcceptingRegistrations(); this.plugin.info("Enchantments Registered: " + getRegistered().size()); diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/config/EnchantDefaults.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/config/EnchantDefaults.java index 4daa453..c7be3ac 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/config/EnchantDefaults.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/config/EnchantDefaults.java @@ -26,8 +26,9 @@ public class EnchantDefaults { private String displayName; private Tier tier; - private List description; - private boolean isTreasure; + private List description; + private boolean hiddenFromList; + private boolean isTreasure; private int levelMin; private int levelMax; private EnchantScaler levelByEnchantCost; @@ -46,6 +47,7 @@ public class EnchantDefaults { this.setDisplayName(StringUtil.capitalizeUnderscored(enchant.getId())); this.setTier(0.1); this.setDescription(new ArrayList<>()); + this.setHiddenFromList(false); this.setTreasure(false); this.setLevelMin(1); this.setLevelMax(3); @@ -72,6 +74,9 @@ public class EnchantDefaults { "You can use 'Enchantment' placeholders: " + Placeholders.URL_PLACEHOLDERS) .read(cfg)); + this.setHiddenFromList(JOption.create("Hide_From_List", false, + "Sets whether or not this enchantment will be hidden from Enchants GUI.").read(cfg)); + this.setTreasure(JOption.create("Is_Treasure", this.isTreasure(), "Sets whether this enchantment is a treasure enchantment.", "Treasure enchantments can only be received via looting, trading, or fishing.").read(cfg)); @@ -169,6 +174,14 @@ public class EnchantDefaults { return description; } + public boolean isHiddenFromList() { + return hiddenFromList; + } + + public void setHiddenFromList(boolean hiddenFromList) { + this.hiddenFromList = hiddenFromList; + } + public boolean isTreasure() { return isTreasure; } diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/ExcellentEnchant.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/ExcellentEnchant.java index 07f4f8e..91d14ba 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/ExcellentEnchant.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/ExcellentEnchant.java @@ -65,6 +65,7 @@ public abstract class ExcellentEnchant extends Enchantment implements IEnchantme PlaceholderMap map = new PlaceholderMap() .add(Placeholders.ENCHANTMENT_DESCRIPTION, () -> String.join("\n", this.getDescription())) + .add(Placeholders.ENCHANTMENT_ID, this::getId) .add(Placeholders.ENCHANTMENT_NAME, this::getDisplayName) .add(Placeholders.ENCHANTMENT_NAME_FORMATTED, () -> this.getNameFormatted(level)) .add(Placeholders.ENCHANTMENT_LEVEL, () -> NumberUtil.toRoman(level)) diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/EnchantHardened.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/EnchantHardened.java index d15c978..c15b446 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/EnchantHardened.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/EnchantHardened.java @@ -8,13 +8,13 @@ import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.Placeholders; -import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant; import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced; import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned; import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant; -import su.nightexpress.excellentenchants.enchantment.util.EnchantPriority; +import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant; import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation; import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation; +import su.nightexpress.excellentenchants.enchantment.util.EnchantPriority; public class EnchantHardened extends ExcellentEnchant implements Chanced, Potioned, CombatEnchant { diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/StoppingForceEnchant.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/StoppingForceEnchant.java new file mode 100644 index 0000000..f51a849 --- /dev/null +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/StoppingForceEnchant.java @@ -0,0 +1,76 @@ +package su.nightexpress.excellentenchants.enchantment.impl.armor; + +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import su.nexmedia.engine.utils.NumberUtil; +import su.nightexpress.excellentenchants.ExcellentEnchants; +import su.nightexpress.excellentenchants.Placeholders; +import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced; +import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant; +import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler; +import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant; +import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation; +import su.nightexpress.excellentenchants.enchantment.util.EnchantPriority; + +public class StoppingForceEnchant extends ExcellentEnchant implements Chanced, CombatEnchant { + + public static final String ID = "stopping_force"; + + public static final String PLACEHOLDER_KNOCKBACK_RESISTANCE = "%knockback_resistance%"; + + private ChanceImplementation chanceImplementation; + private EnchantScaler knockbackModifier; + + public StoppingForceEnchant(@NotNull ExcellentEnchants plugin) { + super(plugin, ID, EnchantPriority.MEDIUM); + this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to resist knockback in combat by " + PLACEHOLDER_KNOCKBACK_RESISTANCE + "%."); + this.getDefaults().setLevelMax(3); + this.getDefaults().setTier(0.5); + } + + @Override + public void loadSettings() { + super.loadSettings(); + this.chanceImplementation = ChanceImplementation.create(this, "100.0"); + this.knockbackModifier = EnchantScaler.read(this, "Settings.Knockback_Modifier", + "0.7 - " + Placeholders.ENCHANTMENT_LEVEL + " / 5.0", + "Sets the knockback multiplier when taking damage.", "Lower value = less knockback."); + + this.addPlaceholder(PLACEHOLDER_KNOCKBACK_RESISTANCE, level -> NumberUtil.format(this.getKnockbackModifier(level) * 100)); + } + + public double getKnockbackModifier(int level) { + return this.knockbackModifier.getValue(level); + } + + @NotNull + @Override + public EnchantmentTarget getItemTarget() { + return EnchantmentTarget.ARMOR_LEGS; + } + + @NotNull + @Override + public Chanced getChanceImplementation() { + return this.chanceImplementation; + } + + @Override + public boolean onAttack(@NotNull EntityDamageByEntityEvent e, @NotNull LivingEntity damager, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) { + return false; + } + + @Override + public boolean onProtect(@NotNull EntityDamageByEntityEvent e, @NotNull LivingEntity damager, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) { + if (!this.isAvailableToUse(victim)) return false; + if (!this.checkTriggerChance(level)) return false; + + this.plugin.runTask(task -> { + victim.setVelocity(victim.getVelocity().multiply(this.getKnockbackModifier(level))); + }); + return true; + } +} diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/bow/FlareEnchant.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/bow/FlareEnchant.java new file mode 100644 index 0000000..2ca511c --- /dev/null +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/bow/FlareEnchant.java @@ -0,0 +1,115 @@ +package su.nightexpress.excellentenchants.enchantment.impl.bow; + +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Directional; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.event.block.BlockCanBuildEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import su.nexmedia.engine.api.particle.SimpleParticle; +import su.nightexpress.excellentenchants.ExcellentEnchants; +import su.nightexpress.excellentenchants.Placeholders; +import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed; +import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced; +import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant; +import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant; +import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation; +import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation; +import su.nightexpress.excellentenchants.enchantment.util.EnchantPriority; + +public class FlareEnchant extends ExcellentEnchant implements Chanced, Arrowed, BowEnchant { + + public static final String ID = "flare"; + + private ChanceImplementation chanceImplementation; + private ArrowImplementation arrowImplementation; + + public FlareEnchant(@NotNull ExcellentEnchants plugin) { + super(plugin, ID, EnchantPriority.LOWEST); + + this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to create a torch where arrow lands."); + this.getDefaults().setLevelMax(1); + this.getDefaults().setTier(0.4); + } + + @Override + public void loadSettings() { + super.loadSettings(); + this.chanceImplementation = ChanceImplementation.create(this, "100.0"); + this.arrowImplementation = ArrowImplementation.create(this, SimpleParticle.of(Particle.FIREWORKS_SPARK)); + } + + @NotNull + @Override + public EnchantmentTarget getItemTarget() { + return EnchantmentTarget.BOW; + } + + @NotNull + @Override + public Chanced getChanceImplementation() { + return this.chanceImplementation; + } + + @NotNull + @Override + public ArrowImplementation getArrowImplementation() { + return this.arrowImplementation; + } + + @Override + public boolean onShoot(@NotNull EntityShootBowEvent e, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) { + if (!(e.getProjectile() instanceof Arrow arrow)) return false; + if (!this.isAvailableToUse(shooter)) return false; + if (!this.checkTriggerChance(level)) return false; + + this.addData(arrow); + return true; + } + + @Override + public boolean onHit(@NotNull ProjectileHitEvent e, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) { + Block block = e.getHitBlock(); + if (block == null) return false; + + BlockFace face = e.getHitBlockFace(); + if (face == null || face == BlockFace.DOWN) return false; + + Block relative = block.getRelative(face); + if (!relative.getType().isAir()) return false; + + if (projectile.getShooter() instanceof Player player) { + BlockCanBuildEvent event = new BlockCanBuildEvent(relative, player, Material.TORCH.createBlockData(), true); + plugin.getPluginManager().callEvent(event); + if (!event.isBuildable()) return false; + } + + if (face == BlockFace.UP) { + relative.setType(Material.TORCH); + } + else { + relative.setType(Material.WALL_TORCH); + + Directional directional = (Directional) relative.getBlockData(); + directional.setFacing(face); + relative.setBlockData(directional, true); + } + + return true; + } + + @Override + public boolean onDamage(@NotNull EntityDamageByEntityEvent e, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) { + return false; + } +} diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/CurseOfMediocrityEnchant.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/CurseOfMediocrityEnchant.java new file mode 100644 index 0000000..77b218b --- /dev/null +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/CurseOfMediocrityEnchant.java @@ -0,0 +1,105 @@ +package su.nightexpress.excellentenchants.enchantment.impl.tool; + +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockDropItemEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import su.nexmedia.engine.utils.ItemUtil; +import su.nightexpress.excellentenchants.ExcellentEnchants; +import su.nightexpress.excellentenchants.Placeholders; +import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced; +import su.nightexpress.excellentenchants.api.enchantment.type.BlockDropEnchant; +import su.nightexpress.excellentenchants.api.enchantment.type.DeathEnchant; +import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant; +import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation; +import su.nightexpress.excellentenchants.enchantment.type.FitItemType; +import su.nightexpress.excellentenchants.enchantment.util.EnchantDropContainer; +import su.nightexpress.excellentenchants.enchantment.util.EnchantPriority; + +public class CurseOfMediocrityEnchant extends ExcellentEnchant implements Chanced, BlockDropEnchant, DeathEnchant { + + public static final String ID = "curse_of_mediocrity"; + + private ChanceImplementation chanceImplementation; + + public CurseOfMediocrityEnchant(@NotNull ExcellentEnchants plugin) { + super(plugin, ID, EnchantPriority.LOWEST); + this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to disenchant item drops."); + this.getDefaults().setLevelMax(3); + this.getDefaults().setTier(0D); + } + + @Override + public void loadSettings() { + super.loadSettings(); + this.chanceImplementation = ChanceImplementation.create(this, "25.0 * " + Placeholders.ENCHANTMENT_LEVEL); + } + + @NotNull + @Override + public EnchantmentTarget getItemTarget() { + return EnchantmentTarget.BREAKABLE; + } + + @Override + @NotNull + public FitItemType[] getFitItemTypes() { + return new FitItemType[] {FitItemType.WEAPON, FitItemType.TOOL}; + } + + @NotNull + @Override + public Chanced getChanceImplementation() { + return this.chanceImplementation; + } + + @Override + public boolean isCursed() { + return true; + } + + @Override + public boolean onDrop(@NotNull BlockDropItemEvent e, @NotNull EnchantDropContainer dropContainer, + @NotNull Player player, @NotNull ItemStack item, int level) { + if (!this.isAvailableToUse(player)) return false; + if (!this.checkTriggerChance(level)) return false; + + e.getItems().forEach(drop -> { + ItemStack stack = drop.getItemStack(); + ItemUtil.mapMeta(stack, meta -> { + meta.getEnchants().keySet().forEach(meta::removeEnchant); + }); + drop.setItemStack(stack); + }); + + dropContainer.getDrop().forEach(stack -> { + ItemUtil.mapMeta(stack, meta -> { + meta.getEnchants().keySet().forEach(meta::removeEnchant); + }); + }); + + return true; + } + + @Override + public boolean onDeath(@NotNull EntityDeathEvent e, @NotNull LivingEntity entity, int level) { + return false; + } + + @Override + public boolean onKill(@NotNull EntityDeathEvent e, @NotNull LivingEntity entity, @NotNull Player killer, int level) { + if (!this.isAvailableToUse(killer)) return false; + if (!this.checkTriggerChance(level)) return false; + + e.getDrops().forEach(stack -> { + ItemUtil.mapMeta(stack, meta -> { + meta.getEnchants().keySet().forEach(meta::removeEnchant); + }); + }); + + return true; + } +} diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantTunnel.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantTunnel.java index ba28789..c10d3c9 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantTunnel.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantTunnel.java @@ -7,7 +7,6 @@ import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; -import org.bukkit.metadata.FixedMetadataValue; import org.jetbrains.annotations.NotNull; import su.nexmedia.engine.api.config.JOption; import su.nexmedia.engine.utils.EntityUtil; @@ -21,11 +20,11 @@ import su.nightexpress.excellentenchants.hook.impl.NoCheatPlusHook; import java.util.HashSet; import java.util.Set; +import java.util.UUID; public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant { public static final String ID = "tunnel"; - private static final String META_BLOCK_TUNNEL = ID + "_block_tunneled"; // X and Z offsets for each block AoE mined private static final int[][] MINING_COORD_OFFSETS = new int[][]{{0, 0}, {0, -1}, {-1, 0}, {0, 1}, {1, 0}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1},}; private static final Set INTERACTABLE_BLOCKS = new HashSet<>(); @@ -35,10 +34,13 @@ public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant INTERACTABLE_BLOCKS.add(Material.DEEPSLATE_REDSTONE_ORE); } + private final Set activePlayers; private boolean disableOnSneak; public EnchantTunnel(@NotNull ExcellentEnchants plugin) { super(plugin, ID, EnchantPriority.HIGH); + this.activePlayers = new HashSet<>(); + this.getDefaults().setDescription("Mines multiple blocks at once in a certain shape."); this.getDefaults().setLevelMax(3); this.getDefaults().setTier(1.0); @@ -64,14 +66,19 @@ public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant return EnchantmentTarget.TOOL; } + public boolean isTunneling(@NotNull Player player) { + return this.activePlayers.contains(player.getUniqueId()); + } + @Override public boolean onBreak(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) { - Block block = e.getBlock(); + if (this.isTunneling(player)) return false; if (!this.isAvailableToUse(player)) return false; if (this.disableOnSneak && player.isSneaking()) return false; if (EnchantUtils.contains(item, EnchantVeinminer.ID)) return false; if (EnchantUtils.contains(item, EnchantBlastMining.ID)) return false; - if (block.hasMetadata(META_BLOCK_TUNNEL)) return false; + + Block block = e.getBlock(); if (block.getType().isInteractable() && !INTERACTABLE_BLOCKS.contains(block.getType())) return false; if (block.getDrops(item).isEmpty()) return false; @@ -85,6 +92,7 @@ public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant else if (level == 2) blocksBroken = 5; else if (level == 3) blocksBroken = 9; + this.activePlayers.add(player.getUniqueId()); NoCheatPlusHook.exemptBlocks(player); for (int i = 0; i < blocksBroken; i++) { @@ -113,21 +121,11 @@ public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant if (addType == Material.BEDROCK || addType == Material.END_PORTAL || addType == Material.END_PORTAL_FRAME) continue; if (addType == Material.OBSIDIAN && addType != block.getType()) continue; - // Play block break particles before it's broken. - /*SimpleParticle.of(Particle.BLOCK_CRACK, blockAdd.getType()) - .play(damager.getEyeLocation(), 0.25, 0.1, 20); - EffectUtil.playEffect(LocationUtil.getCenter(blockAdd.getLocation()), Particle.BLOCK_CRACK.name(), blockAdd.getType().name(), 0.2, 0.2, 0.2, 0.1, 20); - - */ - - // Add metadata to prevent enchantment triggering in a loop. - blockAdd.setMetadata(META_BLOCK_TUNNEL, new FixedMetadataValue(plugin, true)); - //plugin.getNMS().breakBlock(player, blockAdd); player.breakBlock(blockAdd); - blockAdd.removeMetadata(META_BLOCK_TUNNEL, plugin); } NoCheatPlusHook.unexemptBlocks(player); + this.activePlayers.remove(player.getUniqueId()); return true; } } diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantVeinminer.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantVeinminer.java index 07fd5e2..4889c7a 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantVeinminer.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantVeinminer.java @@ -8,7 +8,6 @@ import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; -import org.bukkit.metadata.FixedMetadataValue; import org.jetbrains.annotations.NotNull; import su.nexmedia.engine.api.config.JOption; import su.nexmedia.engine.utils.Scaler; @@ -24,6 +23,7 @@ import su.nightexpress.excellentenchants.hook.impl.NoCheatPlusHook; import java.util.HashSet; import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -31,15 +31,21 @@ public class EnchantVeinminer extends ExcellentEnchant implements BlockBreakEnch public static final String ID = "veinminer"; - private static final BlockFace[] AREA = {BlockFace.UP, BlockFace.DOWN, BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH, BlockFace.NORTH}; - private static final String META_BLOCK_VEINED = ID + "_block_veined"; + private static final BlockFace[] AREA = { + BlockFace.UP, BlockFace.DOWN, BlockFace.EAST, + BlockFace.WEST, BlockFace.SOUTH, BlockFace.NORTH + }; + private static final String PLACEHOLDER_BLOCK_LIMIT = "%enchantment_block_limit%"; private Scaler blocksLimit; private Set blocksAffected; + private final Set activePlayers; public EnchantVeinminer(@NotNull ExcellentEnchants plugin) { super(plugin, ID, EnchantPriority.HIGH); + this.activePlayers = new HashSet<>(); + this.getDefaults().setDescription("Mines up to " + PLACEHOLDER_BLOCK_LIMIT + " blocks of the ore vein at once."); this.getDefaults().setLevelMax(3); this.getDefaults().setTier(0.3); @@ -104,6 +110,10 @@ public class EnchantVeinminer extends ExcellentEnchant implements BlockBreakEnch .filter(blockAdded -> blockAdded.getType() == block.getType()).collect(Collectors.toSet()); } + public boolean isInVein(@NotNull Player player) { + return this.activePlayers.contains(player.getUniqueId()); + } + private void vein(@NotNull Player player, @NotNull Block source, int level) { Set ores = new HashSet<>(); Set prepare = new HashSet<>(this.getNearby(source)); @@ -118,31 +128,25 @@ public class EnchantVeinminer extends ExcellentEnchant implements BlockBreakEnch prepare.addAll(nearby); } ores.remove(source); - ores.forEach(ore -> { - // Play block break particles before the block broken. - //EffectUtil.playEffect(LocationUtil.getCenter(ore.getLocation()), Particle.BLOCK_CRACK.name(), ore.getType().name(), 0.2, 0.2, 0.2, 0.1, 20); - - ore.setMetadata(META_BLOCK_VEINED, new FixedMetadataValue(plugin, true)); - //plugin.getNMS().breakBlock(player, ore); - player.breakBlock(ore); - ore.removeMetadata(META_BLOCK_VEINED, plugin); - }); + ores.forEach(player::breakBlock); } @Override public boolean onBreak(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack tool, int level) { + if (this.isInVein(player)) return false; if (!this.isAvailableToUse(player)) return false; if (EnchantUtils.contains(tool, EnchantBlastMining.ID)) return false; if (EnchantUtils.contains(tool, EnchantTunnel.ID)) return false; Block block = e.getBlock(); - if (block.hasMetadata(META_BLOCK_VEINED)) return false; if (block.getDrops(tool).isEmpty()) return false; if (!this.getBlocksAffected().contains(block.getType())) return false; + this.activePlayers.add(player.getUniqueId()); NoCheatPlusHook.exemptBlocks(player); this.vein(player, block, level); NoCheatPlusHook.unexemptBlocks(player); + this.activePlayers.remove(player.getUniqueId()); return true; } diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/weapon/EnchantCutter.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/weapon/EnchantCutter.java index 4095c45..3d570da 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/weapon/EnchantCutter.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/weapon/EnchantCutter.java @@ -5,12 +5,14 @@ import org.bukkit.Sound; import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import su.nexmedia.engine.api.config.JOption; import su.nexmedia.engine.api.particle.SimpleParticle; import su.nexmedia.engine.utils.LocationUtil; import su.nexmedia.engine.utils.NumberUtil; @@ -31,6 +33,8 @@ public class EnchantCutter extends ExcellentEnchant implements Chanced, CombatEn private EnchantScaler durabilityReduction; private ChanceImplementation chanceImplementation; + private boolean allowPlayers; + private boolean allowMobs; public EnchantCutter(@NotNull ExcellentEnchants plugin) { super(plugin, ID, EnchantPriority.LOWEST); @@ -48,6 +52,12 @@ public class EnchantCutter extends ExcellentEnchant implements Chanced, CombatEn Placeholders.ENCHANTMENT_LEVEL + " / 100", "Amount (in percent) of how much item durability will be reduced."); + this.allowPlayers = JOption.create("Settings.Allow_Players", true, + "Sets whether or not this enchantment will have effect on players.").read(cfg); + + this.allowMobs = JOption.create("Settings.Allow_Mobs", true, + "Sets whether or not this enchantment will have effect on mobs.").read(cfg); + this.addPlaceholder(PLACEHOLDER_DURABILITY_DAMAGE, level -> NumberUtil.format(this.getDurabilityReduction(level) * 100D)); } @@ -77,6 +87,9 @@ public class EnchantCutter extends ExcellentEnchant implements Chanced, CombatEn ItemStack[] armor = equipment.getArmorContents(); if (armor.length == 0) return false; + boolean isPlayer = victim instanceof Player; + if (isPlayer && !this.allowPlayers || (!isPlayer && !this.allowMobs)) return false; + int get = Rnd.get(armor.length); ItemStack itemCut = armor[get]; diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/menu/EnchantmentsListMenu.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/menu/EnchantmentsListMenu.java index 5dd50f3..77aeea2 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/menu/EnchantmentsListMenu.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/menu/EnchantmentsListMenu.java @@ -24,6 +24,7 @@ import su.nightexpress.excellentenchants.enchantment.EnchantRegistry; import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant; import java.util.*; +import java.util.function.Predicate; public class EnchantmentsListMenu extends ConfigMenu implements AutoPaged { @@ -82,6 +83,7 @@ public class EnchantmentsListMenu extends ConfigMenu implemen @NotNull public List getObjects(@NotNull Player player) { return new ArrayList<>(EnchantRegistry.getRegistered().stream() + .filter(Predicate.not(enchant -> enchant.getDefaults().isHiddenFromList())) .sorted(Comparator.comparing(ExcellentEnchant::getName)).toList()); } diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/util/EnchantUtils.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/util/EnchantUtils.java index f38ce2e..9f679e5 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/util/EnchantUtils.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/util/EnchantUtils.java @@ -199,6 +199,7 @@ public class EnchantUtils { if (sizeReal > 0) { PDCUtil.set(meta, KEY_LORE_SIZE, sizeReal); } + else PDCUtil.remove(meta, KEY_LORE_SIZE); item.setItemMeta(meta); return true; } diff --git a/NMS/pom.xml b/NMS/pom.xml index 57c1252..fdadd60 100644 --- a/NMS/pom.xml +++ b/NMS/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.4.5 + 3.5.0 4.0.0 diff --git a/V1_17_R1/pom.xml b/V1_17_R1/pom.xml index f949ea7..7ca0768 100644 --- a/V1_17_R1/pom.xml +++ b/V1_17_R1/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.4.5 + 3.5.0 4.0.0 @@ -26,7 +26,7 @@ su.nightexpress.excellentenchants NMS - 3.4.5 + 3.5.0 diff --git a/V1_18_R2/pom.xml b/V1_18_R2/pom.xml index 18554b4..b0e98e7 100644 --- a/V1_18_R2/pom.xml +++ b/V1_18_R2/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.4.5 + 3.5.0 4.0.0 @@ -26,7 +26,7 @@ su.nightexpress.excellentenchants NMS - 3.4.5 + 3.5.0 diff --git a/V1_19_R3/pom.xml b/V1_19_R3/pom.xml index a0f13b0..2802c8a 100644 --- a/V1_19_R3/pom.xml +++ b/V1_19_R3/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.4.5 + 3.5.0 4.0.0 @@ -26,7 +26,7 @@ su.nightexpress.excellentenchants NMS - 3.4.5 + 3.5.0 diff --git a/V1_20_R1/pom.xml b/V1_20_R1/pom.xml index f879353..bc8ef76 100644 --- a/V1_20_R1/pom.xml +++ b/V1_20_R1/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.4.5 + 3.5.0 4.0.0 @@ -26,7 +26,7 @@ su.nightexpress.excellentenchants NMS - 3.4.5 + 3.5.0 diff --git a/pom.xml b/pom.xml index d4960c9..c9f83d3 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ su.nightexpress.excellentenchants ExcellentEnchants pom - 3.4.5 + 3.5.0 Core NMS