This commit is contained in:
nulli0n 2024-08-15 18:04:28 +05:00
parent fe6d37f3de
commit 8623159ca6
30 changed files with 512 additions and 138 deletions

View File

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

View File

@ -3,4 +3,10 @@ package su.nightexpress.excellentenchants.api;
public class EnchantmentID {
public static final String FLAME_WALKER = "flame_walker";
public static final String REBOUND = "rebound";
public static final String LINGERING = "lingering";
public static final String NIMBLE = "nimble";
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.2.0</version>
<version>4.2.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -44,6 +44,11 @@
<url>http://mvn.lumine.io/repository/maven-snapshots/</url>
</repository>
<repository>
<id>codemc-releases</id>
<url>https://repo.codemc.io/repository/maven-releases/</url>
</repository>
</repositories>
<dependencies>
@ -68,6 +73,13 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.retrooper</groupId>
<artifactId>packetevents-spigot</artifactId>
<version>2.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
@ -78,19 +90,19 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>API</artifactId>
<version>4.2.0</version>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>4.2.0</version>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>MC_1_21</artifactId>
<version>4.2.0</version>
<version>4.2.1</version>
</dependency>
</dependencies>

View File

@ -12,6 +12,7 @@ import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.excellentenchants.config.Perms;
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
import su.nightexpress.excellentenchants.hook.HookPlugin;
import su.nightexpress.excellentenchants.hook.impl.PacketEventsHook;
import su.nightexpress.excellentenchants.hook.impl.PlaceholderHook;
import su.nightexpress.excellentenchants.hook.impl.ProtocolLibHook;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
@ -100,11 +101,14 @@ public class EnchantsPlugin extends NightPlugin implements ImprovedCommands {
private void loadHooks() {
if (Config.isDescriptionEnabled()) {
if (Plugins.isInstalled(HookPlugin.PROTOCOL_LIB)) {
if (Plugins.isInstalled(HookPlugin.PACKET_EVENTS)) {
PacketEventsHook.setup(this);
}
else if (Plugins.isInstalled(HookPlugin.PROTOCOL_LIB)) {
ProtocolLibHook.setup(this);
}
else {
this.warn(HookPlugin.PROTOCOL_LIB + " is not installed. Enchantment descriptions won't display.");
this.warn("You need to install " + HookPlugin.PACKET_EVENTS + " or " + HookPlugin.PROTOCOL_LIB + " for enchantment description to work.");
}
}

View File

@ -1,6 +1,5 @@
package su.nightexpress.excellentenchants.config;
import org.bukkit.permissions.PermissionDefault;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.nightcore.util.wrapper.UniPermission;
@ -9,13 +8,13 @@ public class Perms {
private static final String PREFIX = "excellentenchants.";
private static final String PREFIX_COMMAND = PREFIX + "command.";
public static final UniPermission PLUGIN = new UniPermission(PREFIX + Placeholders.WILDCARD, "Access to all the plugin functions.");
public static final UniPermission COMMAND = new UniPermission(PREFIX_COMMAND + Placeholders.WILDCARD, "Access to all the plugin commands.");
public static final UniPermission PLUGIN = new UniPermission(PREFIX + Placeholders.WILDCARD);
public static final UniPermission COMMAND = new UniPermission(PREFIX_COMMAND + Placeholders.WILDCARD);
public static final UniPermission COMMAND_BOOK = new UniPermission(PREFIX_COMMAND + "book");
public static final UniPermission COMMAND_ENCHANT = new UniPermission(PREFIX_COMMAND + "enchant");
public static final UniPermission COMMAND_GET_FUEL = new UniPermission(PREFIX_COMMAND + "getfuel");
public static final UniPermission COMMAND_LIST = new UniPermission(PREFIX_COMMAND + "list", PermissionDefault.TRUE);
public static final UniPermission COMMAND_LIST = new UniPermission(PREFIX_COMMAND + "list");
public static final UniPermission COMMAND_LIST_OTHERS = new UniPermission(PREFIX_COMMAND + "list.others");
public static final UniPermission COMMAND_RARITY_BOOK = new UniPermission(PREFIX_COMMAND + "raritybook");
public static final UniPermission COMMAND_RELOAD = new UniPermission(PREFIX_COMMAND + "reload");

View File

@ -89,8 +89,7 @@ public class EnchantDistribution implements Distribution {
this.tradable = ConfigValue.create("Distribution.Tradeable",
this.tradable,
"Tradable enchantments are those that can be generated on Enchanted Books sold by librarians.",
"[*] Reboot required when changed.",
"[**] Has no effect if 'Treasure' is set on 'true' and Villager Trade Rebalance is disabled."
"[*] Reboot required when changed."
).read(config);
this.tradeTypes = ConfigValue.forSet("Distribution.TradeTypes",

View File

@ -102,6 +102,7 @@ public class ElementalProtectionEnchant extends GameEnchantment implements Simpe
int level = EnchantUtils.getLevel(armor, this.getBukkitEnchantment());
if (level <= 0) continue;
if (this.isOutOfCharges(armor)) continue;
protectionAmount += this.getProtectionAmount(level);
this.consumeCharges(armor, level);

View File

@ -6,6 +6,8 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
@ -18,6 +20,7 @@ import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.rarity.EnchantRarity;
import su.nightexpress.excellentenchants.util.ItemCategories;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.NumberUtil;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
@ -33,6 +36,7 @@ public class FireShieldEnchant extends GameEnchantment implements ChanceMeta, Co
public static final String ID = "fire_shield";
private Modifier fireDuration;
private boolean addFireImmune;
public FireShieldEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.DESERT_COMMON));
@ -56,7 +60,13 @@ public class FireShieldEnchant extends GameEnchantment implements ChanceMeta, Co
Modifier.multiply(2, 1, 1, 600),
"Sets the fire duration (in seconds).",
"If entity's current fire ticks amount is less than this value, it will be set to this value.",
"If entity's current fire ticks amount is greater than this value, it won't be changed.");
"If entity's current fire ticks amount is greater than this value, it won't be changed."
);
this.addFireImmune = ConfigValue.create("Settings.Fire.AddImmune",
true,
"Sets whether or not to add Fire Resistance effect to the enchantment's wearer as well."
).read(config);
this.addPlaceholder(GENERIC_DURATION, level -> NumberUtil.format(this.getFireDuration(level)));
}
@ -78,20 +88,27 @@ public class FireShieldEnchant extends GameEnchantment implements ChanceMeta, Co
@Override
public boolean onProtect(@NotNull EntityDamageByEntityEvent event,
@NotNull LivingEntity damager, @NotNull LivingEntity victim,
@NotNull ItemStack weapon, int level) {
@NotNull LivingEntity damager,
@NotNull LivingEntity victim,
@NotNull ItemStack weapon,
int level) {
if (!this.checkTriggerChance(level)) return false;
int ticksToSet = (int) (this.getFireDuration(level) * 20);
int ticksHas = damager.getFireTicks();
if (ticksHas >= ticksToSet) return false;
int fireTicks = (int) (this.getFireDuration(level) * 20);
if (this.addFireImmune) {
victim.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, fireTicks, 0));
}
int damagerFireTicks = damager.getFireTicks();
if (damagerFireTicks >= fireTicks) return false;
if (this.hasVisualEffects()) {
UniParticle.of(Particle.FLAME).play(victim.getEyeLocation(), 0.5, 0.1, 35);
UniSound.of(Sound.ITEM_FIRECHARGE_USE).play(victim.getLocation());
}
damager.setFireTicks(ticksToSet);
damager.setFireTicks(fireTicks);
return true;
}
}

View File

@ -14,7 +14,7 @@ import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
@ -140,6 +140,7 @@ public class FlameWalkerEnchant extends GameEnchantment implements GenericEnchan
int level = EnchantUtils.getLevel(boots, this.getBukkitEnchantment());
if (level <= 0) return;
if (this.isOutOfCharges(boots)) return;
Block bTo = to.getBlock().getRelative(BlockFace.DOWN);
boolean hasLava = Stream.of(FACES).anyMatch(face -> bTo.getRelative(face).getType() == Material.LAVA);
@ -153,17 +154,15 @@ public class FlameWalkerEnchant extends GameEnchantment implements GenericEnchan
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onMagmaDamage(EntityDamageEvent event) {
if (event.getCause() != EntityDamageEvent.DamageCause.HOT_FLOOR) return;
if (!(event.getEntity() instanceof LivingEntity livingEntity)) return;
if (!this.isAvailableToUse(livingEntity)) return;
if (!(event.getEntity() instanceof LivingEntity entity)) return;
if (!this.isAvailableToUse(entity)) return;
EntityEquipment equipment = livingEntity.getEquipment();
if (equipment == null) return;
ItemStack boots = equipment.getBoots();
ItemStack boots = EnchantUtils.getEquipped(entity, EquipmentSlot.FEET);
if (boots == null || boots.getType().isAir()) return;
int level = EnchantUtils.getLevel(boots, this.getBukkitEnchantment());
if (level <= 0) return;
if (this.isOutOfCharges(boots)) return;
event.setCancelled(true);
this.consumeCharges(boots, level);

View File

@ -0,0 +1,97 @@
package su.nightexpress.excellentenchants.enchantment.impl.armor;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.type.GenericEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDefinition;
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDistribution;
import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
import su.nightexpress.excellentenchants.rarity.EnchantRarity;
import su.nightexpress.excellentenchants.util.EnchantUtils;
import su.nightexpress.excellentenchants.util.ItemCategories;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.manager.SimpeListener;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Lists;
import java.io.File;
public class ReboundEnchant extends GameEnchantment implements GenericEnchant, SimpeListener {
private Modifier modifier;
private Modifier capacity;
public ReboundEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.SWAMP_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
Lists.newList("Effect of landing on a slime block."),
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOOTS,
null,
Lists.newSet(BukkitThing.toString(Enchantment.FEATHER_FALLING))
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.modifier = Modifier.read(config, "Settings.Modifier.Step",
Modifier.add(0, 0.1, 0),
"Sets bounce power modifier based on fall distance.",
"Greater value = greater rebound."
);
this.capacity = Modifier.read(config, "Settings.Modifier.Capacity",
Modifier.add(0.75, 0.15, 0),
"Sets maximal bounce power modifier value.",
"Greater value = greater rebound."
);
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onFall(EntityDamageEvent event) {
if (event.getCause() != EntityDamageEvent.DamageCause.FALL) return;
if (!(event.getEntity() instanceof LivingEntity entity)) return;
if (entity instanceof Player player && player.isSneaking()) return;
if (!this.isAvailableToUse(entity)) return;
ItemStack boots = EnchantUtils.getEquipped(entity, EquipmentSlot.FEET);
if (boots == null) return;
int level = EnchantUtils.getLevel(boots, this.getBukkitEnchantment());
if (level <= 0) return;
if (this.isOutOfCharges(boots)) return;
event.setCancelled(true);
this.bounceUp(entity, event.getDamage(), level);
this.consumeCharges(boots, level);
}
private void bounceUp(@NotNull LivingEntity entity, double power, int level) {
double limit = this.capacity.getValue(level);
double step = this.modifier.getValue(level);
double modifier = Math.min(limit, power * step);
Vector velocity = entity.getVelocity();
if (velocity.getY() < 0D) {
entity.setVelocity(velocity.setY(modifier));
}
}
}

View File

@ -107,6 +107,7 @@ public class TreasureHunterEnchant extends GameEnchantment implements ChanceMeta
int level = EnchantUtils.getLevel(helmet, this.getBukkitEnchantment());
if (level < 1) return;
if (this.isOutOfCharges(helmet)) return;
if (!this.checkTriggerChance(level)) return;
InventoryHolder holder = event.getInventoryHolder();

View File

@ -3,7 +3,6 @@ package su.nightexpress.excellentenchants.enchantment.impl.bow;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.*;
@ -21,21 +20,20 @@ import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ArrowEffects;
import su.nightexpress.excellentenchants.api.enchantment.meta.ArrowMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.ArrowEffects;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDefinition;
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDistribution;
import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
import su.nightexpress.excellentenchants.util.ItemCategories;
import su.nightexpress.excellentenchants.rarity.EnchantRarity;
import su.nightexpress.excellentenchants.util.ItemCategories;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.ItemUtil;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.NumberUtil;
import su.nightexpress.nightcore.util.Version;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
import java.io.File;
@ -56,7 +54,7 @@ public class DragonfireArrowsEnchant extends GameEnchantment implements ChanceMe
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to launch an dragonfire arrow (R=" + GENERIC_RADIUS + ", " + GENERIC_DURATION + "s).",
ENCHANTMENT_CHANCE + "% chance to add an dragonfire effect (R=" + GENERIC_RADIUS + ", " + GENERIC_DURATION + "s).",
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOWS,
@ -72,11 +70,13 @@ public class DragonfireArrowsEnchant extends GameEnchantment implements ChanceMe
this.fireDuration = Modifier.read(config, "Settings.Fire.Duration",
Modifier.multiply(100, 1, 1, 60 * 20),
"Sets the dragonfire cloud effect duration (in ticks). 20 ticks = 1 second.");
"Sets the dragonfire cloud effect duration (in ticks). 20 ticks = 1 second."
);
this.fireRadius = Modifier.read(config, "Settings.Fire.Radius",
Modifier.add(1, 1, 1, 5),
"Sets the dragonfire cloud effect radius.");
"Sets the dragonfire cloud effect radius."
);
this.addPlaceholder(GENERIC_DURATION, level -> NumberUtil.format(this.getFireDuration(level) / 20D));
this.addPlaceholder(GENERIC_RADIUS, level -> NumberUtil.format(this.getFireRadius(level)));
@ -110,14 +110,14 @@ public class DragonfireArrowsEnchant extends GameEnchantment implements ChanceMe
return false;
}
private void createCloud(@NotNull ProjectileSource shooter, @NotNull Location location,
@Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace,
private void createCloud(@NotNull ProjectileSource shooter,
@NotNull Location location,
@Nullable Entity hitEntity,
@Nullable Block hitBlock,
@Nullable BlockFace hitFace,
int level) {
World world = location.getWorld();
if (world == null) return;
// There are some tweaks to respect protection plugins by using event call.
ItemStack item = new ItemStack(Material.LINGERING_POTION);
ItemUtil.editMeta(item, meta -> {
if (meta instanceof PotionMeta potionMeta) {
@ -129,7 +129,7 @@ public class DragonfireArrowsEnchant extends GameEnchantment implements ChanceMe
potion.setItem(item);
potion.teleport(location);
AreaEffectCloud cloud = world.spawn(location, AreaEffectCloud.class);
AreaEffectCloud cloud = potion.getWorld().spawn(location, AreaEffectCloud.class);
cloud.clearCustomEffects();
cloud.setSource(shooter);
cloud.setParticle(Particle.DRAGON_BREATH);
@ -138,15 +138,7 @@ public class DragonfireArrowsEnchant extends GameEnchantment implements ChanceMe
cloud.setRadiusPerTick((7.0F - cloud.getRadius()) / (float) cloud.getDuration());
cloud.addCustomEffect(new PotionEffect(PotionEffectType.INSTANT_DAMAGE, 1, 1), true);
LingeringPotionSplashEvent splashEvent;
if (Version.isAtLeast(Version.V1_20_R3)) {
splashEvent = new LingeringPotionSplashEvent(potion, hitEntity, hitBlock, hitFace, cloud);
}
else {
splashEvent = new LingeringPotionSplashEvent(potion, cloud);
}
LingeringPotionSplashEvent splashEvent = new LingeringPotionSplashEvent(potion, hitEntity, hitBlock, hitFace, cloud);
plugin.getPluginManager().callEvent(splashEvent);
if (splashEvent.isCancelled()) {
cloud.remove();

View File

@ -0,0 +1,136 @@
package su.nightexpress.excellentenchants.enchantment.impl.bow;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.*;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.LingeringPotionSplashEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.projectiles.ProjectileSource;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDefinition;
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDistribution;
import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
import su.nightexpress.excellentenchants.rarity.EnchantRarity;
import su.nightexpress.excellentenchants.util.ItemCategories;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.ItemUtil;
import su.nightexpress.nightcore.util.Lists;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
public class LingeringEnchant extends GameEnchantment implements BowEnchant, ChanceMeta {
public LingeringEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.TAIGA_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
Lists.newList(ENCHANTMENT_CHANCE + "% chance for tipped arrows to generate a lingering effect."),
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOWS,
null,
Lists.newSet(BomberEnchant.ID, EnderBowEnchant.ID, GhastEnchant.ID)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.meta.setProbability(Probability.create(config, Modifier.add(5, 5, 1, 100)));
}
@Override
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
return this.checkTriggerChance(level);
}
@Override
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
if (event.getHitEntity() != null) return false;
if (projectile.getShooter() == null) return false;
if (!(projectile instanceof Arrow arrow)) return false;
this.createCloud(arrow, arrow.getShooter(), arrow.getLocation(), event.getHitEntity(), event.getHitBlock(), event.getHitBlockFace(), level);
return false;
}
@Override
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
return false;
}
@Override
@NotNull
public EventPriority getHitPriority() {
return EventPriority.HIGHEST;
}
private void createCloud(@NotNull Arrow arrow,
@NotNull ProjectileSource shooter,
@NotNull Location location,
@Nullable Entity hitEntity,
@Nullable Block hitBlock,
@Nullable BlockFace hitFace,
int level) {
Set<PotionEffect> effects = new HashSet<>();
if (arrow.hasCustomEffects()) {
effects.addAll(arrow.getCustomEffects());
}
if (arrow.getBasePotionType() != null) {
effects.addAll(arrow.getBasePotionType().getPotionEffects());
}
if (effects.isEmpty()) return;
// There are some tweaks to respect protection plugins by using event call.
ItemStack item = new ItemStack(Material.LINGERING_POTION);
ItemUtil.editMeta(item, meta -> {
if (meta instanceof PotionMeta potionMeta) {
effects.forEach(potionEffect -> potionMeta.addCustomEffect(potionEffect, true));
}
});
ThrownPotion potion = shooter.launchProjectile(ThrownPotion.class);
potion.setItem(item);
potion.teleport(location);
AreaEffectCloud cloud = potion.getWorld().spawn(location, AreaEffectCloud.class);
cloud.clearCustomEffects();
cloud.setSource(shooter);
cloud.setWaitTime(10);
cloud.setRadius(3F); // 3.0
cloud.setRadiusOnUse(-0.5F);
cloud.setDuration(600); // 600
cloud.setRadiusPerTick(-cloud.getRadius() / (float)cloud.getDuration());
cloud.setBasePotionType(arrow.getBasePotionType());
effects.forEach(potionEffect -> cloud.addCustomEffect(potionEffect, false));
LingeringPotionSplashEvent splashEvent = new LingeringPotionSplashEvent(potion, hitEntity, hitBlock, hitFace, cloud);
plugin.getPluginManager().callEvent(splashEvent);
if (splashEvent.isCancelled()) {
cloud.remove();
}
potion.remove();
}
}

View File

@ -70,7 +70,6 @@ public class RiverMasterEnchant extends GameEnchantment implements GenericEnchan
int level = EnchantUtils.getLevel(rod, this.getBukkitEnchantment());
if (level < 1) return;
if (this.isOutOfCharges(rod)) return;
hook.setVelocity(hook.getVelocity().multiply(this.getDistanceMod(level)));

View File

@ -16,17 +16,18 @@ import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.spawner.Spawner;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockDropEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDefinition;
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDistribution;
import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.rarity.EnchantRarity;
import su.nightexpress.excellentenchants.util.ItemCategories;
import su.nightexpress.nightcore.config.ConfigValue;
@ -41,6 +42,7 @@ import su.nightexpress.nightcore.util.text.NightMessage;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
import java.io.File;
import java.util.HashSet;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_TYPE;
@ -100,8 +102,10 @@ public class SilkSpawnerEnchant extends GameEnchantment implements ChanceMeta, B
if (stateItem == null || spawnerBlock.getSpawnedType() == null) return itemSpawner;
CreatureSpawner spawnerItem = (CreatureSpawner) stateItem.getBlockState();
spawnerItem.setSpawnedType(spawnerBlock.getSpawnedType());
this.transferSettings(spawnerBlock, spawnerItem);
spawnerItem.update(true);
stateItem.setBlockState(spawnerItem);
stateItem.setDisplayName(NightMessage.asLegacy(this.spawnerName.replace(GENERIC_TYPE, LangAssets.get(spawnerBlock.getSpawnedType()))));
itemSpawner.setItemMeta(stateItem);
@ -122,7 +126,7 @@ public class SilkSpawnerEnchant extends GameEnchantment implements ChanceMeta, B
this.plugin.populateResource(event, this.getSpawner(spawnerBlock));
if (this.hasVisualEffects()) {
Location location = LocationUtil.getCenter(block.getLocation());
Location location = LocationUtil.setCenter3D(block.getLocation());
UniParticle.of(Particle.HAPPY_VILLAGER).play(location, 0.3, 0.15, 30);
}
return true;
@ -148,13 +152,31 @@ public class SilkSpawnerEnchant extends GameEnchantment implements ChanceMeta, B
Player player = event.getPlayer();
ItemStack spawner = player.getInventory().getItem(event.getHand());
if (spawner == null || spawner.getType() != Material.SPAWNER || !(spawner.getItemMeta() instanceof BlockStateMeta meta)) return;
if (spawner == null || spawner.getType() != Material.SPAWNER || !(spawner.getItemMeta() instanceof BlockStateMeta stateMeta)) return;
if (PDCUtil.getBoolean(spawner, this.spawnerKey).isEmpty()) return;
CreatureSpawner spawnerItem = (CreatureSpawner) meta.getBlockState();
CreatureSpawner spawnerItem = (CreatureSpawner) stateMeta.getBlockState();
CreatureSpawner spawnerBlock = (CreatureSpawner) block.getState();
spawnerBlock.setSpawnedType(spawnerItem.getSpawnedType());
spawnerBlock.update();
this.transferSettings(spawnerItem, spawnerBlock);
spawnerBlock.update(true);
}
private void transferSettings(@NotNull Spawner from, @NotNull Spawner to) {
to.setPotentialSpawns(new HashSet<>());
if (from.getPotentialSpawns().isEmpty()) {
to.setSpawnedType(from.getSpawnedType());
}
else {
from.getPotentialSpawns().forEach(to::addPotentialSpawn);
}
to.setDelay(from.getDelay());
to.setMinSpawnDelay(from.getMinSpawnDelay());
to.setMaxSpawnDelay(from.getMaxSpawnDelay());
to.setMaxNearbyEntities(from.getMaxNearbyEntities());
to.setRequiredPlayerRange(from.getRequiredPlayerRange());
to.setSpawnCount(from.getSpawnCount());
to.setSpawnRange(from.getSpawnRange());
}
}

View File

@ -71,6 +71,7 @@ public class InfernusEnchant extends GameEnchantment implements GenericEnchant,
int level = EnchantUtils.getLevel(item, this.getBukkitEnchantment());
if (level <= 0) return;
if (this.isOutOfCharges(item)) return;
trident.setFireTicks(Integer.MAX_VALUE);
}

View File

@ -17,6 +17,7 @@ import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.rarity.EnchantRarity;
import su.nightexpress.excellentenchants.util.ItemCategories;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Players;
@ -24,16 +25,16 @@ import java.io.File;
public class NimbleEnchant extends GameEnchantment implements ChanceMeta, DeathEnchant {
public static final String ID = "nimble";
private boolean ignorePlayers;
public NimbleEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.SWAMP_COMMON));
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.SNOW_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Moves all mob's loot directly to your inventory.",
"Moves all entity's loot directly to your inventory.",
EnchantRarity.RARE,
1,
ItemCategories.WEAPON
@ -43,6 +44,11 @@ public class NimbleEnchant extends GameEnchantment implements ChanceMeta, DeathE
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.meta.setProbability(Probability.create(config));
this.ignorePlayers = ConfigValue.create("Settings.Effect.Ignore_Players",
false,
"Sets whether or not to ignore drops from players."
).read(config);
}
@NotNull
@ -54,6 +60,7 @@ public class NimbleEnchant extends GameEnchantment implements ChanceMeta, DeathE
@Override
public boolean onKill(@NotNull EntityDeathEvent event, @NotNull LivingEntity entity, @NotNull Player killer, ItemStack weapon, int level) {
if (!this.checkTriggerChance(level)) return false;
if (this.ignorePlayers && entity instanceof Player) return false;
event.getDrops().forEach(item -> Players.addItem(killer, item));
event.getDrops().clear();

View File

@ -60,23 +60,6 @@ public class SwiperEnchant extends GameEnchantment implements CombatEnchant, Cha
return (int) this.xpAmount.getValue(level);
}
private int getExpRequired(int level) {
if (level <= 15) return 2 * level + 7;
if (level <= 30) return 5 * level - 38;
return 9 * level - 158;
}
private void addXP(@NotNull Player player, int amount) {
//int levelHas = player.getLevel();
int xpHas = player.getTotalExperience();
xpHas = Math.max(0, xpHas + amount);
player.setExp(0F);
player.setTotalExperience(0);
player.setLevel(0);
player.giveExp(xpHas);
}
@Override
public boolean onAttack(@NotNull EntityDamageByEntityEvent event, @NotNull LivingEntity damager, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
if (!(damager instanceof Player attacker)) return false;
@ -87,8 +70,8 @@ public class SwiperEnchant extends GameEnchantment implements CombatEnchant, Cha
int amount = this.getXPAmount(level);
if (defender.getTotalExperience() < amount) amount = defender.getTotalExperience();
this.addXP(defender, -amount);
this.addXP(attacker, amount);
defender.giveExp(-amount);
attacker.giveExp(amount);
return true;
}

View File

@ -48,7 +48,8 @@ public class TemperEnchant extends GameEnchantment implements CombatEnchant {
protected void loadAdditional(@NotNull FileConfig config) {
this.damageAmount = Modifier.read(config, "Settings.Damage.Amount",
Modifier.add(0, 5, 1, 100),
"Extra damage (in %)");
"Extra damage (in %)"
);
this.damageStep = Modifier.read(config, "Settings.Damage.Step",
Modifier.add(0.5, 0, 0),
@ -81,10 +82,9 @@ public class TemperEnchant extends GameEnchantment implements CombatEnchant {
double steps = Math.floor(missingHealth / step);
if (steps == 0) return false;
double percent = this.getDamageAmount(level) / 100D;
double damagePercent = percent * steps;
double percent = 1D + (this.getDamageAmount(level) * steps / 100D);
event.setDamage(event.getDamage() * damagePercent);
event.setDamage(event.getDamage() * percent);
return true;
}

View File

@ -4,4 +4,5 @@ public class HookPlugin {
public static final String MYTHIC_MOBS = "MythicMobs";
public static final String PROTOCOL_LIB = "ProtocolLib";
public static final String PACKET_EVENTS = "packetevents";
}

View File

@ -0,0 +1,77 @@
package su.nightexpress.excellentenchants.hook.impl;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketListener;
import com.github.retrooper.packetevents.event.PacketListenerPriority;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
import com.github.retrooper.packetevents.protocol.recipe.data.MerchantOffer;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerMerchantOffers;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowItems;
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.util.EnchantUtils;
import java.util.List;
public class PacketEventsHook {
private static boolean registered;
public static void setup(@NotNull EnchantsPlugin plugin) {
if (registered) return;
PacketEvents.getAPI().getEventManager().registerListener(new Listener(), PacketListenerPriority.NORMAL);
registered = true;
}
// public static void shutdown() {
// if (!registered) return;
// }
private static class Listener implements PacketListener {
@Override
public void onPacketSend(PacketSendEvent event) {
PacketTypeCommon type = event.getPacketType();
Player player = (Player) event.getPlayer();
if (player == null) return;
if (!EnchantUtils.canUpdateDisplay(player)) return;
if (type == PacketType.Play.Server.SET_SLOT) {
WrapperPlayServerSetSlot setSlot = new WrapperPlayServerSetSlot(event);
ItemStack item = SpigotConversionUtil.toBukkitItemStack(setSlot.getItem());
item = EnchantUtils.addDescription(item);
setSlot.setItem(SpigotConversionUtil.fromBukkitItemStack(item));
event.markForReEncode(true);
}
else if (type == PacketType.Play.Server.WINDOW_ITEMS) {
WrapperPlayServerWindowItems windowItems = new WrapperPlayServerWindowItems(event);
windowItems.getItems().replaceAll(packetItem -> {
return SpigotConversionUtil.fromBukkitItemStack(EnchantUtils.addDescription(SpigotConversionUtil.toBukkitItemStack(packetItem)));
});
event.markForReEncode(true);
}
else if (type == PacketType.Play.Server.MERCHANT_OFFERS) {
WrapperPlayServerMerchantOffers merchantOffers = new WrapperPlayServerMerchantOffers(event);
List<MerchantOffer> offers = merchantOffers.getMerchantOffers();
offers.forEach(offer -> {
ItemStack result = SpigotConversionUtil.toBukkitItemStack(offer.getOutputItem());
offer.setOutputItem(SpigotConversionUtil.fromBukkitItemStack(EnchantUtils.addDescription(result)));
});
event.markForReEncode(true);
}
}
}
}

View File

@ -6,20 +6,14 @@ import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
import su.nightexpress.excellentenchants.util.EnchantUtils;
import su.nightexpress.nightcore.util.text.NightMessage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ProtocolLibHook {
@ -37,7 +31,7 @@ public class ProtocolLibHook {
if (!EnchantUtils.canUpdateDisplay(event.getPlayer())) return;
ItemStack item = packet.getItemModifier().read(0);
packet.getItemModifier().write(0, update(item));
packet.getItemModifier().write(0, EnchantUtils.addDescription(item));
}
});
@ -48,7 +42,7 @@ public class ProtocolLibHook {
if (!EnchantUtils.canUpdateDisplay(event.getPlayer())) return;
List<ItemStack> items = packet.getItemListModifier().readSafely(0);
items.replaceAll(ProtocolLibHook::update);
items.replaceAll(EnchantUtils::addDescription);
packet.getItemListModifier().write(0, items);
}
@ -62,7 +56,7 @@ public class ProtocolLibHook {
List<MerchantRecipe> list = new ArrayList<>();
packet.getMerchantRecipeLists().read(0).forEach(recipe -> {
ItemStack result = update(recipe.getResult());
ItemStack result = EnchantUtils.addDescription(recipe.getResult());
if (result == null) return;
MerchantRecipe r2 = new MerchantRecipe(result, recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier(), recipe.getDemand(), recipe.getSpecialPrice());
@ -77,27 +71,4 @@ public class ProtocolLibHook {
registered = true;
}
@Nullable
public static ItemStack update(@Nullable ItemStack item) {
if (item == null || item.getType().isAir() || !EnchantUtils.canHaveDescription(item)) return item;
ItemStack copy = new ItemStack(item);
ItemMeta meta = copy.getItemMeta();
if (meta == null || meta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) return item;
Map<CustomEnchantment, Integer> enchants = EnchantUtils.getCustomEnchantments(meta);
if (enchants.isEmpty()) return item;
List<String> metaLore = meta.getLore();
List<String> lore = metaLore == null ? new ArrayList<>() : metaLore;
enchants.forEach((enchant, level) -> {
int chargesAmount = enchant.getCharges(meta);
lore.addAll(NightMessage.asLegacy(enchant.getDescription(level, chargesAmount)));
});
meta.setLore(lore);
copy.setItemMeta(meta);
return copy;
}
}

View File

@ -3,6 +3,7 @@ package su.nightexpress.excellentenchants.rarity;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.util.EnchantUtils;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
@ -31,7 +32,7 @@ public class EnchantRarity implements Rarity {
this.id = id;
this.name = name;
this.nameFormat = nameFormat;
this.weight = weight;
this.weight = Math.min(weight, EnchantUtils.WEIGHT_CAP);
}
@NotNull
@ -49,8 +50,10 @@ public class EnchantRarity implements Rarity {
int weight = ConfigValue.create(path + ".Weight",
10,
"Controls the probability of enchantment with this rarity when enchanting",
"The probability is determined 'weight / total weight * 100%', where 'total_weight' is the sum of the weights of all available enchantments.",
"Value between 1 and 1024.",
"Controls the probability of enchantment with this rarity when enchanting.",
"The probability is determined 'weight / total weight * 100%', where 'total_weight' is the sum of the weights of all available enchantments INCLUDING vanilla ones.",
"Vanilla enchantment weights: https://minecraft.wiki/w/Enchanting#Summary_of_enchantments",
"[*] Reboot required when changed!"
).read(config);

View File

@ -116,7 +116,7 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
this.register(WisdomEnchant.ID, file -> new WisdomEnchant(plugin, file));
this.register(IceAspectEnchant.ID, file -> new IceAspectEnchant(plugin, file));
this.register(InfernusEnchant.ID, file -> new InfernusEnchant(plugin, file));
this.register(NimbleEnchant.ID, file -> new NimbleEnchant(plugin, file));
this.register(EnchantmentID.NIMBLE, file -> new NimbleEnchant(plugin, file));
this.register(ParalyzeEnchant.ID, file -> new ParalyzeEnchant(plugin, file));
this.register(CureEnchant.ID, file -> new CureEnchant(plugin, file));
this.register(RageEnchant.ID, file -> new RageEnchant(plugin, file));
@ -145,6 +145,7 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
this.register(RegrowthEnchant.ID, file -> new RegrowthEnchant(plugin, file));
this.register(SaturationEnchant.ID, file -> new SaturationEnchant(plugin, file));
this.register(KamikadzeEnchant.ID, file -> new KamikadzeEnchant(plugin, file));
this.register(EnchantmentID.REBOUND, file -> new ReboundEnchant(plugin, file));
this.register(StoppingForceEnchant.ID, file -> new StoppingForceEnchant(plugin, file));
this.register(SpeedyEnchant.ID, file -> new SpeedyEnchant(plugin, file));
@ -155,6 +156,7 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
this.register(ElectrifiedArrowsEnchant.ID, file -> new ElectrifiedArrowsEnchant(plugin, file));
this.register(EnderBowEnchant.ID, file -> new EnderBowEnchant(plugin, file));
this.register(ExplosiveArrowsEnchant.ID, file -> new ExplosiveArrowsEnchant(plugin, file));
this.register(EnchantmentID.LINGERING, file -> new LingeringEnchant(plugin, file));
this.register(FlareEnchant.ID, file -> new FlareEnchant(plugin, file));
this.register(GhastEnchant.ID, file -> new GhastEnchant(plugin, file));
this.register(HoverEnchant.ID, file -> new HoverEnchant(plugin, file));

View File

@ -9,7 +9,9 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
@ -23,6 +25,7 @@ import su.nightexpress.excellentenchants.registry.EnchantRegistry;
import su.nightexpress.nightcore.language.LangAssets;
import su.nightexpress.nightcore.util.*;
import su.nightexpress.nightcore.util.random.Rnd;
import su.nightexpress.nightcore.util.text.NightMessage;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@ -123,6 +126,30 @@ public class EnchantUtils {
.replace(GENERIC_CHARGES, compChrages);
}
@Nullable
public static ItemStack addDescription(@Nullable ItemStack item) {
if (item == null || item.getType().isAir() || !canHaveDescription(item)) return item;
ItemStack copy = new ItemStack(item);
ItemMeta meta = copy.getItemMeta();
if (meta == null || meta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) return item;
Map<CustomEnchantment, Integer> enchants = getCustomEnchantments(meta);
if (enchants.isEmpty()) return item;
List<String> metaLore = meta.getLore();
List<String> lore = metaLore == null ? new ArrayList<>() : metaLore;
enchants.forEach((enchant, level) -> {
int chargesAmount = enchant.getCharges(meta);
lore.addAll(NightMessage.asLegacy(enchant.getDescription(level, chargesAmount)));
});
meta.setLore(lore);
copy.setItemMeta(meta);
return copy;
}
public static boolean isEnchantedBook(@NotNull ItemStack item) {
return item.getType() == Material.ENCHANTED_BOOK;
}
@ -295,6 +322,19 @@ public class EnchantUtils {
return getEquipped(entity, clazz, EQUIPMENT_SLOTS);
}*/
@Nullable
public static ItemStack getEquipped(@NotNull LivingEntity entity, @NotNull EquipmentSlot slot) {
EntityEquipment equipment = entity.getEquipment();
if (equipment == null) return null;
return equipment.getItem(slot);
}
public static int getEquippedLevel(@NotNull LivingEntity entity, @NotNull Enchantment enchantment, @NotNull EquipmentSlot slot) {
ItemStack itemStack = getEquipped(entity, slot);
return itemStack == null ? 0 : getLevel(itemStack, enchantment);
}
@NotNull
public static <T extends CustomEnchantment> Map<ItemStack, Map<T, Integer>> getEquipped(@NotNull LivingEntity entity,
@NotNull Class<T> clazz,

View File

@ -4,6 +4,10 @@ name: ExcellentEnchants
author: NightExpress
desciption: A lot of new enchantments properly integrated into the server!
depend: [ nightcore ]
softdepend: [ ProtocolLib, PlaceholderAPI, MythicMobs ]
softdepend:
- ProtocolLib
- packetevents
- PlaceholderAPI
- MythicMobs
api-version: 1.21
load: STARTUP

View File

@ -6,7 +6,7 @@
<parent>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>ExcellentEnchants</artifactId>
<version>4.2.0</version>
<version>4.2.1</version>
</parent>
<artifactId>MC_1_21</artifactId>
@ -28,13 +28,13 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>API</artifactId>
<version>4.2.0</version>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>4.2.0</version>
<version>4.2.1</version>
</dependency>
</dependencies>

View File

@ -212,20 +212,21 @@ public class Internal_1_21 implements EnchantNMS {
if (distribution.isOnTradedEquipment()) {
addInTag(EnchantmentTags.ON_TRADED_EQUIPMENT, reference);
}
if (!experimentalTrades) {
if (distribution.isTradable()) {
addInTag(EnchantmentTags.TRADEABLE, reference);
}
else removeFromTag(EnchantmentTags.TRADEABLE, reference);
}
}
// Any enchantment can be on rebalanced trades.
if (experimentalTrades && distribution.isTradable()) {
distribution.getTrades().forEach(tradeType -> {
addInTag(getTradeKey(tradeType), reference);
});
// Any enchantment can be tradable.
if (experimentalTrades) {
if (distribution.isTradable()) {
distribution.getTrades().forEach(tradeType -> {
addInTag(getTradeKey(tradeType), reference);
});
}
}
else {
if (distribution.isTradable()) {
addInTag(EnchantmentTags.TRADEABLE, reference);
}
else removeFromTag(EnchantmentTags.TRADEABLE, reference);
}
if (enchantment.isCurse()) {

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.2.0</version>
<version>4.2.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -34,7 +34,7 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>API</artifactId>
<version>4.2.0</version>
<version>4.2.1</version>
</dependency>
</dependencies>

View File

@ -7,7 +7,7 @@
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>ExcellentEnchants</artifactId>
<packaging>pom</packaging>
<version>4.2.0</version>
<version>4.2.1</version>
<modules>
<module>API</module>
<module>Core</module>