mirror of
https://github.com/nulli0n/ExcellentEnchants-spigot.git
synced 2025-01-23 21:21:23 +01:00
v4.2.1
This commit is contained in:
parent
fe6d37f3de
commit
8623159ca6
@ -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>
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
20
Core/pom.xml
20
Core/pom.xml
@ -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>
|
||||
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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)));
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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
|
@ -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>
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user