v3.5.0 New Enchants!

This commit is contained in:
nulli0n 2023-07-13 20:24:17 +05:00
parent c534fa7caa
commit 7635ab4082
20 changed files with 380 additions and 48 deletions

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<version>3.4.5</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -95,27 +95,27 @@
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId> <artifactId>NMS</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_17_R1</artifactId> <artifactId>V1_17_R1</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_18_R2</artifactId> <artifactId>V1_18_R2</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R3</artifactId> <artifactId>V1_19_R3</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R1</artifactId> <artifactId>V1_20_R1</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -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_DURATION = "%enchantment_potion_duration%";
public static final String ENCHANTMENT_POTION_TYPE = "%enchantment_potion_type%"; 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 = "%enchantment_name%";
public static final String ENCHANTMENT_NAME_FORMATTED = "%enchantment_name_formatted%"; public static final String ENCHANTMENT_NAME_FORMATTED = "%enchantment_name_formatted%";
public static final String ENCHANTMENT_DESCRIPTION = "%enchantment_description%"; public static final String ENCHANTMENT_DESCRIPTION = "%enchantment_description%";

View File

@ -106,6 +106,7 @@ public class EnchantRegistry {
this.register(EnchantRegrowth.ID, () -> new EnchantRegrowth(plugin)); this.register(EnchantRegrowth.ID, () -> new EnchantRegrowth(plugin));
this.register(EnchantSaturation.ID, () -> new EnchantSaturation(plugin)); this.register(EnchantSaturation.ID, () -> new EnchantSaturation(plugin));
this.register(EnchantSelfDestruction.ID, () -> new EnchantSelfDestruction(plugin)); this.register(EnchantSelfDestruction.ID, () -> new EnchantSelfDestruction(plugin));
this.register(StoppingForceEnchant.ID, () -> new StoppingForceEnchant(plugin));
this.register(EnchantSonic.ID, () -> new EnchantSonic(plugin)); this.register(EnchantSonic.ID, () -> new EnchantSonic(plugin));
// Bow enchants // Bow enchants
@ -115,6 +116,7 @@ public class EnchantRegistry {
this.register(EnchantElectrifiedArrows.ID, () -> new EnchantElectrifiedArrows(plugin)); this.register(EnchantElectrifiedArrows.ID, () -> new EnchantElectrifiedArrows(plugin));
this.register(EnchantEnderBow.ID, () -> new EnchantEnderBow(plugin)); this.register(EnchantEnderBow.ID, () -> new EnchantEnderBow(plugin));
this.register(EnchantExplosiveArrows.ID, () -> new EnchantExplosiveArrows(plugin)); this.register(EnchantExplosiveArrows.ID, () -> new EnchantExplosiveArrows(plugin));
this.register(FlareEnchant.ID, () -> new FlareEnchant(plugin));
this.register(EnchantGhast.ID, () -> new EnchantGhast(plugin)); this.register(EnchantGhast.ID, () -> new EnchantGhast(plugin));
this.register(EnchantHover.ID, () -> new EnchantHover(plugin)); this.register(EnchantHover.ID, () -> new EnchantHover(plugin));
this.register(EnchantPoisonedArrows.ID, () -> new EnchantPoisonedArrows(plugin)); this.register(EnchantPoisonedArrows.ID, () -> new EnchantPoisonedArrows(plugin));
@ -122,6 +124,7 @@ public class EnchantRegistry {
// Universal // Universal
this.register(EnchantCurseOfFragility.ID, () -> new EnchantCurseOfFragility(plugin)); this.register(EnchantCurseOfFragility.ID, () -> new EnchantCurseOfFragility(plugin));
this.register(CurseOfMediocrityEnchant.ID, () -> new CurseOfMediocrityEnchant(plugin));
Enchantment.stopAcceptingRegistrations(); Enchantment.stopAcceptingRegistrations();
this.plugin.info("Enchantments Registered: " + getRegistered().size()); this.plugin.info("Enchantments Registered: " + getRegistered().size());

View File

@ -27,6 +27,7 @@ public class EnchantDefaults {
private String displayName; private String displayName;
private Tier tier; private Tier tier;
private List<String> description; private List<String> description;
private boolean hiddenFromList;
private boolean isTreasure; private boolean isTreasure;
private int levelMin; private int levelMin;
private int levelMax; private int levelMax;
@ -46,6 +47,7 @@ public class EnchantDefaults {
this.setDisplayName(StringUtil.capitalizeUnderscored(enchant.getId())); this.setDisplayName(StringUtil.capitalizeUnderscored(enchant.getId()));
this.setTier(0.1); this.setTier(0.1);
this.setDescription(new ArrayList<>()); this.setDescription(new ArrayList<>());
this.setHiddenFromList(false);
this.setTreasure(false); this.setTreasure(false);
this.setLevelMin(1); this.setLevelMin(1);
this.setLevelMax(3); this.setLevelMax(3);
@ -72,6 +74,9 @@ public class EnchantDefaults {
"You can use 'Enchantment' placeholders: " + Placeholders.URL_PLACEHOLDERS) "You can use 'Enchantment' placeholders: " + Placeholders.URL_PLACEHOLDERS)
.read(cfg)); .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(), this.setTreasure(JOption.create("Is_Treasure", this.isTreasure(),
"Sets whether this enchantment is a treasure enchantment.", "Sets whether this enchantment is a treasure enchantment.",
"Treasure enchantments can only be received via looting, trading, or fishing.").read(cfg)); "Treasure enchantments can only be received via looting, trading, or fishing.").read(cfg));
@ -169,6 +174,14 @@ public class EnchantDefaults {
return description; return description;
} }
public boolean isHiddenFromList() {
return hiddenFromList;
}
public void setHiddenFromList(boolean hiddenFromList) {
this.hiddenFromList = hiddenFromList;
}
public boolean isTreasure() { public boolean isTreasure() {
return isTreasure; return isTreasure;
} }

View File

@ -65,6 +65,7 @@ public abstract class ExcellentEnchant extends Enchantment implements IEnchantme
PlaceholderMap map = new PlaceholderMap() PlaceholderMap map = new PlaceholderMap()
.add(Placeholders.ENCHANTMENT_DESCRIPTION, () -> String.join("\n", this.getDescription())) .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, this::getDisplayName)
.add(Placeholders.ENCHANTMENT_NAME_FORMATTED, () -> this.getNameFormatted(level)) .add(Placeholders.ENCHANTMENT_NAME_FORMATTED, () -> this.getNameFormatted(level))
.add(Placeholders.ENCHANTMENT_LEVEL, () -> NumberUtil.toRoman(level)) .add(Placeholders.ENCHANTMENT_LEVEL, () -> NumberUtil.toRoman(level))

View File

@ -8,13 +8,13 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.Placeholders; 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.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned; import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant; 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.ChanceImplementation;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation; import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
import su.nightexpress.excellentenchants.enchantment.util.EnchantPriority;
public class EnchantHardened extends ExcellentEnchant implements Chanced, Potioned, CombatEnchant { public class EnchantHardened extends ExcellentEnchant implements Chanced, Potioned, CombatEnchant {

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -7,7 +7,6 @@ import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption; import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.utils.EntityUtil; import su.nexmedia.engine.utils.EntityUtil;
@ -21,11 +20,11 @@ import su.nightexpress.excellentenchants.hook.impl.NoCheatPlusHook;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID;
public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant { public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant {
public static final String ID = "tunnel"; 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 // 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 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<Material> INTERACTABLE_BLOCKS = new HashSet<>(); private static final Set<Material> INTERACTABLE_BLOCKS = new HashSet<>();
@ -35,10 +34,13 @@ public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant
INTERACTABLE_BLOCKS.add(Material.DEEPSLATE_REDSTONE_ORE); INTERACTABLE_BLOCKS.add(Material.DEEPSLATE_REDSTONE_ORE);
} }
private final Set<UUID> activePlayers;
private boolean disableOnSneak; private boolean disableOnSneak;
public EnchantTunnel(@NotNull ExcellentEnchants plugin) { public EnchantTunnel(@NotNull ExcellentEnchants plugin) {
super(plugin, ID, EnchantPriority.HIGH); super(plugin, ID, EnchantPriority.HIGH);
this.activePlayers = new HashSet<>();
this.getDefaults().setDescription("Mines multiple blocks at once in a certain shape."); this.getDefaults().setDescription("Mines multiple blocks at once in a certain shape.");
this.getDefaults().setLevelMax(3); this.getDefaults().setLevelMax(3);
this.getDefaults().setTier(1.0); this.getDefaults().setTier(1.0);
@ -64,14 +66,19 @@ public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant
return EnchantmentTarget.TOOL; return EnchantmentTarget.TOOL;
} }
public boolean isTunneling(@NotNull Player player) {
return this.activePlayers.contains(player.getUniqueId());
}
@Override @Override
public boolean onBreak(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) { 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.isAvailableToUse(player)) return false;
if (this.disableOnSneak && player.isSneaking()) return false; if (this.disableOnSneak && player.isSneaking()) return false;
if (EnchantUtils.contains(item, EnchantVeinminer.ID)) return false; if (EnchantUtils.contains(item, EnchantVeinminer.ID)) return false;
if (EnchantUtils.contains(item, EnchantBlastMining.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.getType().isInteractable() && !INTERACTABLE_BLOCKS.contains(block.getType())) return false;
if (block.getDrops(item).isEmpty()) 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 == 2) blocksBroken = 5;
else if (level == 3) blocksBroken = 9; else if (level == 3) blocksBroken = 9;
this.activePlayers.add(player.getUniqueId());
NoCheatPlusHook.exemptBlocks(player); NoCheatPlusHook.exemptBlocks(player);
for (int i = 0; i < blocksBroken; i++) { 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.BEDROCK || addType == Material.END_PORTAL || addType == Material.END_PORTAL_FRAME) continue;
if (addType == Material.OBSIDIAN && addType != block.getType()) 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); player.breakBlock(blockAdd);
blockAdd.removeMetadata(META_BLOCK_TUNNEL, plugin);
} }
NoCheatPlusHook.unexemptBlocks(player); NoCheatPlusHook.unexemptBlocks(player);
this.activePlayers.remove(player.getUniqueId());
return true; return true;
} }
} }

View File

@ -8,7 +8,6 @@ import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption; import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.utils.Scaler; import su.nexmedia.engine.utils.Scaler;
@ -24,6 +23,7 @@ import su.nightexpress.excellentenchants.hook.impl.NoCheatPlusHook;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -31,15 +31,21 @@ public class EnchantVeinminer extends ExcellentEnchant implements BlockBreakEnch
public static final String ID = "veinminer"; 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 BlockFace[] AREA = {
private static final String META_BLOCK_VEINED = ID + "_block_veined"; BlockFace.UP, BlockFace.DOWN, BlockFace.EAST,
BlockFace.WEST, BlockFace.SOUTH, BlockFace.NORTH
};
private static final String PLACEHOLDER_BLOCK_LIMIT = "%enchantment_block_limit%"; private static final String PLACEHOLDER_BLOCK_LIMIT = "%enchantment_block_limit%";
private Scaler blocksLimit; private Scaler blocksLimit;
private Set<Material> blocksAffected; private Set<Material> blocksAffected;
private final Set<UUID> activePlayers;
public EnchantVeinminer(@NotNull ExcellentEnchants plugin) { public EnchantVeinminer(@NotNull ExcellentEnchants plugin) {
super(plugin, ID, EnchantPriority.HIGH); 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().setDescription("Mines up to " + PLACEHOLDER_BLOCK_LIMIT + " blocks of the ore vein at once.");
this.getDefaults().setLevelMax(3); this.getDefaults().setLevelMax(3);
this.getDefaults().setTier(0.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()); .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) { private void vein(@NotNull Player player, @NotNull Block source, int level) {
Set<Block> ores = new HashSet<>(); Set<Block> ores = new HashSet<>();
Set<Block> prepare = new HashSet<>(this.getNearby(source)); Set<Block> prepare = new HashSet<>(this.getNearby(source));
@ -118,31 +128,25 @@ public class EnchantVeinminer extends ExcellentEnchant implements BlockBreakEnch
prepare.addAll(nearby); prepare.addAll(nearby);
} }
ores.remove(source); ores.remove(source);
ores.forEach(ore -> { ores.forEach(player::breakBlock);
// 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);
});
} }
@Override @Override
public boolean onBreak(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack tool, int level) { 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 (!this.isAvailableToUse(player)) return false;
if (EnchantUtils.contains(tool, EnchantBlastMining.ID)) return false; if (EnchantUtils.contains(tool, EnchantBlastMining.ID)) return false;
if (EnchantUtils.contains(tool, EnchantTunnel.ID)) return false; if (EnchantUtils.contains(tool, EnchantTunnel.ID)) return false;
Block block = e.getBlock(); Block block = e.getBlock();
if (block.hasMetadata(META_BLOCK_VEINED)) return false;
if (block.getDrops(tool).isEmpty()) return false; if (block.getDrops(tool).isEmpty()) return false;
if (!this.getBlocksAffected().contains(block.getType())) return false; if (!this.getBlocksAffected().contains(block.getType())) return false;
this.activePlayers.add(player.getUniqueId());
NoCheatPlusHook.exemptBlocks(player); NoCheatPlusHook.exemptBlocks(player);
this.vein(player, block, level); this.vein(player, block, level);
NoCheatPlusHook.unexemptBlocks(player); NoCheatPlusHook.unexemptBlocks(player);
this.activePlayers.remove(player.getUniqueId());
return true; return true;
} }

View File

@ -5,12 +5,14 @@ import org.bukkit.Sound;
import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.api.particle.SimpleParticle; import su.nexmedia.engine.api.particle.SimpleParticle;
import su.nexmedia.engine.utils.LocationUtil; import su.nexmedia.engine.utils.LocationUtil;
import su.nexmedia.engine.utils.NumberUtil; import su.nexmedia.engine.utils.NumberUtil;
@ -31,6 +33,8 @@ public class EnchantCutter extends ExcellentEnchant implements Chanced, CombatEn
private EnchantScaler durabilityReduction; private EnchantScaler durabilityReduction;
private ChanceImplementation chanceImplementation; private ChanceImplementation chanceImplementation;
private boolean allowPlayers;
private boolean allowMobs;
public EnchantCutter(@NotNull ExcellentEnchants plugin) { public EnchantCutter(@NotNull ExcellentEnchants plugin) {
super(plugin, ID, EnchantPriority.LOWEST); super(plugin, ID, EnchantPriority.LOWEST);
@ -48,6 +52,12 @@ public class EnchantCutter extends ExcellentEnchant implements Chanced, CombatEn
Placeholders.ENCHANTMENT_LEVEL + " / 100", Placeholders.ENCHANTMENT_LEVEL + " / 100",
"Amount (in percent) of how much item durability will be reduced."); "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)); 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(); ItemStack[] armor = equipment.getArmorContents();
if (armor.length == 0) return false; 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); int get = Rnd.get(armor.length);
ItemStack itemCut = armor[get]; ItemStack itemCut = armor[get];

View File

@ -24,6 +24,7 @@ import su.nightexpress.excellentenchants.enchantment.EnchantRegistry;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant; import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import java.util.*; import java.util.*;
import java.util.function.Predicate;
public class EnchantmentsListMenu extends ConfigMenu<ExcellentEnchants> implements AutoPaged<ExcellentEnchant> { public class EnchantmentsListMenu extends ConfigMenu<ExcellentEnchants> implements AutoPaged<ExcellentEnchant> {
@ -82,6 +83,7 @@ public class EnchantmentsListMenu extends ConfigMenu<ExcellentEnchants> implemen
@NotNull @NotNull
public List<ExcellentEnchant> getObjects(@NotNull Player player) { public List<ExcellentEnchant> getObjects(@NotNull Player player) {
return new ArrayList<>(EnchantRegistry.getRegistered().stream() return new ArrayList<>(EnchantRegistry.getRegistered().stream()
.filter(Predicate.not(enchant -> enchant.getDefaults().isHiddenFromList()))
.sorted(Comparator.comparing(ExcellentEnchant::getName)).toList()); .sorted(Comparator.comparing(ExcellentEnchant::getName)).toList());
} }

View File

@ -199,6 +199,7 @@ public class EnchantUtils {
if (sizeReal > 0) { if (sizeReal > 0) {
PDCUtil.set(meta, KEY_LORE_SIZE, sizeReal); PDCUtil.set(meta, KEY_LORE_SIZE, sizeReal);
} }
else PDCUtil.remove(meta, KEY_LORE_SIZE);
item.setItemMeta(meta); item.setItemMeta(meta);
return true; return true;
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<version>3.4.5</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<version>3.4.5</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -26,7 +26,7 @@
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId> <artifactId>NMS</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<version>3.4.5</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -26,7 +26,7 @@
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId> <artifactId>NMS</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<version>3.4.5</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -26,7 +26,7 @@
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId> <artifactId>NMS</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<version>3.4.5</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -26,7 +26,7 @@
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId> <artifactId>NMS</artifactId>
<version>3.4.5</version> <version>3.5.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -7,7 +7,7 @@
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.4.5</version> <version>3.5.0</version>
<modules> <modules>
<module>Core</module> <module>Core</module>
<module>NMS</module> <module>NMS</module>