This commit is contained in:
BuildTools 2023-10-24 17:25:21 +05:00
parent 0eed750aec
commit d5537829eb
41 changed files with 253 additions and 641 deletions

2
.gitignore vendored
View File

@ -5,8 +5,6 @@
/Core/pom.xml.versionsBackup
/NMS/target/
/NMS/pom.xml.versionsBackup
/V1_17_R1/target/
/V1_17_R1/pom.xml.versionsBackup
/V1_18_R2/target/
/V1_18_R2/pom.xml.versionsBackup
/V1_19_R3/target/

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>3.6.0</version>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -24,22 +24,18 @@
<repository>
<id>dmulloy2-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
<repository>
<id>lumine-repo</id>
<url>https://mvn.lumine.io/repository/maven-public/</url>
</repository>
<repository>
<id>lumine-snapshot</id>
<url>http://mvn.lumine.io/repository/maven-snapshots/</url>
</repository>
</repositories>
@ -64,7 +60,7 @@
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.0.0</version>
<version>5.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -76,32 +72,27 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_17_R1</artifactId>
<version>3.6.0</version>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_18_R2</artifactId>
<version>3.6.0</version>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R3</artifactId>
<version>3.6.0</version>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R1</artifactId>
<version>3.6.0</version>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R2</artifactId>
<version>3.6.0</version>
<version>3.6.2</version>
</dependency>
</dependencies>

View File

@ -23,7 +23,6 @@ import su.nightexpress.excellentenchants.hook.impl.PlaceholderHook;
import su.nightexpress.excellentenchants.hook.impl.ProtocolHook;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import su.nightexpress.excellentenchants.nms.V1_20_R2;
import su.nightexpress.excellentenchants.nms.v1_17_R1.V1_17_R1;
import su.nightexpress.excellentenchants.nms.v1_18_R2.V1_18_R2;
import su.nightexpress.excellentenchants.nms.v1_19_R3.V1_19_R3;
import su.nightexpress.excellentenchants.nms.v1_20_R1.V1_20_R1;
@ -50,7 +49,11 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
@Override
public void enable() {
this.setNMS();
if (!this.setNMS()) {
this.error("Unsupported server version!");
this.getPluginManager().disablePlugin(this);
return;
}
this.tierManager = new TierManager(this);
this.tierManager.setup();
@ -85,15 +88,15 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
this.registry.shutdown();
}
private void setNMS() {
private boolean setNMS() {
this.enchantNMS = switch (Version.getCurrent()) {
case V1_17_R1 -> new V1_17_R1();
case V1_18_R2 -> new V1_18_R2();
case V1_19_R3 -> new V1_19_R3();
case V1_20_R1 -> new V1_20_R1();
case V1_20_R2 -> new V1_20_R2();
default -> null;
};
return this.enchantManager != null;
}
@Override

View File

@ -8,14 +8,14 @@ public class Perms {
private static final String PREFIX = "excellentenchants.";
private static final String PREFIX_COMMAND = PREFIX + "command.";
public static final JPermission PLUGIN = new JPermission(PREFIX + Placeholders.WILDCARD, "Access to all the plugin functions.");
public static final JPermission PLUGIN = new JPermission(PREFIX + Placeholders.WILDCARD, "Access to all the plugin functions.");
public static final JPermission COMMAND = new JPermission(PREFIX_COMMAND + Placeholders.WILDCARD, "Access to all the plugin commands.");
public static final JPermission COMMAND_BOOK = new JPermission(PREFIX_COMMAND + "book", "Allows to use '/eenchants book' command.");
public static final JPermission COMMAND_ENCHANT = new JPermission(PREFIX_COMMAND + "enchant", "Allows to use '/eenchants enchant' command.");
public static final JPermission COMMAND_LIST = new JPermission(PREFIX_COMMAND + "list", "Allows to use '/eenchants list' command.", PermissionDefault.TRUE);
public static final JPermission COMMAND_TIERBOOK = new JPermission(PREFIX_COMMAND + "tierbook", "Allows to use '/eenchants tierbook' command.");
public static final JPermission COMMAND_RELOAD = new JPermission(PREFIX_COMMAND + "reload", "Allows to use '/eenchants reload' command.");
public static final JPermission COMMAND_RELOAD = new JPermission(PREFIX_COMMAND + "reload", "Allows to use '/eenchants reload' command.");
static {
PLUGIN.addChildren(COMMAND);

View File

@ -13,6 +13,7 @@ public class Placeholders extends su.nexmedia.engine.utils.Placeholders {
public static final String GENERIC_ENCHANT = "%enchant%";
public static final String ENCHANTMENT_CHANCE = "%enchantment_trigger_chance%";
public static final String ENCHANTMENT_INTERVAL = "%enchantment_trigger_interval%";
public static final String ENCHANTMENT_POTION_LEVEL = "%enchantment_potion_level%";
public static final String ENCHANTMENT_POTION_DURATION = "%enchantment_potion_duration%";
public static final String ENCHANTMENT_POTION_TYPE = "%enchantment_potion_type%";

View File

@ -0,0 +1,24 @@
package su.nightexpress.excellentenchants.api.enchantment.meta;
import org.jetbrains.annotations.NotNull;
public interface Periodic {
@NotNull Periodic getPeriodImplementation();
default long getInterval(int level) {
return this.getPeriodImplementation().getInterval(level);
}
default long getNextTriggerTime() {
return this.getPeriodImplementation().getNextTriggerTime();
}
default boolean isTriggerTime() {
return this.getPeriodImplementation().isTriggerTime();
}
default void updateTriggerTime(int level) {
this.getPeriodImplementation().updateTriggerTime(level);
}
}

View File

@ -4,8 +4,9 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.meta.Periodic;
public interface PassiveEnchant extends IEnchantment {
public interface PassiveEnchant extends IEnchantment, Periodic {
boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level);
}

View File

@ -19,13 +19,18 @@ import java.util.stream.Stream;
public class Config {
public static final JOption<Long> TASKS_ARROW_TRAIL_TICKS_INTERVAL = JOption.create("Tasks.Arrow_Trail.Tick_Interval",
public static final JOption<Long> TASKS_ARROW_TRAIL_TICKS_INTERVAL = JOption.create("Tasks.Arrow_Trail.Tick_Interval",
1L,
"Sets how often (in ticks) arrow trail particle effects will be spawned behind the arrow."
);
public static final JOption<Long> TASKS_PASSIVE_POTION_EFFECTS_APPLY_INTERVAL = JOption.create("Tasks.Passive_Potion_Effects.Apply_Interval",
public static final JOption<Long> TASKS_PASSIVE_ENCHANTS_TRIGGER_INTERVAL = JOption.create("Tasks.Passive_Enchants.Trigger_Interval",
100L,
"Sets how often (in ticks) the plugin will apply permanent potion effects from enchanted items to an entity who wear them."
"Sets how often (in ticks) the plugin will attempt to trigger passive enchantment effects on all alive entities.",
"For best results it's recommened to keep this value smaller, but at the same rate as enchantment 'Trigger_Interval' settings.",
"Examples:",
"--- Global: 100 ticks; Regrowth: 100 ticks; Saturation: 100 ticks;",
"--- Global: 50 ticks, Regrowth: 100 ticks; Saturation: 150 ticks;"
);
public static final JOption<Boolean> ENCHANTMENTS_CHARGES_ENABLED = JOption.create("Enchantments.Charges.Enabled",
@ -86,7 +91,8 @@ public class Config {
"To disable all enchantments for a world, use '" + Placeholders.WILDCARD + "' instead of enchantment names.")
.setWriter((cfg, path, map) -> map.forEach((world, enchants) -> cfg.set(path + "." + world, enchants)));
public static final JOption<Integer> ENCHANTMENTS_DISPLAY_MODE = JOption.create("Enchantments.Display.Mode", 1,
public static final JOption<Integer> ENCHANTMENTS_DISPLAY_MODE = JOption.create("Enchantments.Display.Mode",
1,
"Sets how enchantment names and descriptions will be handled on items.",
"1 = Plain modification of item's lore (lore changes are real and persistent).",
"2 = Packet modification of item's lore (no real changes are made to the items). Requires ProtocolLib.",

View File

@ -2,9 +2,9 @@ package su.nightexpress.excellentenchants.config;
import su.nexmedia.engine.api.lang.LangKey;
import su.nexmedia.engine.lang.EngineLang;
import su.nightexpress.excellentenchants.Placeholders;
import static su.nexmedia.engine.utils.Colors.RED;
import static su.nexmedia.engine.utils.Colors.*;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class Lang extends EngineLang {
@ -12,18 +12,18 @@ public class Lang extends EngineLang {
public static final LangKey COMMAND_ENCHANT_USAGE = LangKey.of("Command.Enchant.Usage", "<enchant> <level>");
public static final LangKey COMMAND_ENCHANT_DESC = LangKey.of("Command.Enchant.Desc", "Enchants the item in your hand.");
public static final LangKey COMMAND_ENCHANT_DONE = LangKey.of("Command.Enchant.Done", "&aSuccessfully enchanted!");
public static final LangKey COMMAND_ENCHANT_DONE = LangKey.of("Command.Enchant.Done", LIGHT_YELLOW + "Successfully enchanted!");
public static final LangKey COMMAND_ENCHANT_ERROR_NO_ITEM = LangKey.of("Command.Enchant.Error.NoItem", RED + "You must hold an item to enchant it!");
public static final LangKey COMMAND_BOOK_USAGE = LangKey.of("Command.Book.Usage", "<player> <enchant> <level>");
public static final LangKey COMMAND_BOOK_DESC = LangKey.of("Command.Book.Desc", "Gives custom enchanted book.");
public static final LangKey COMMAND_BOOK_DONE = LangKey.of("Command.Book.Done", "Given &6" + Placeholders.GENERIC_ENCHANT + "&7 enchanted book to &6" + Placeholders.PLAYER_DISPLAY_NAME + "&7.");
public static final LangKey COMMAND_BOOK_DONE = LangKey.of("Command.Book.Done", LIGHT_YELLOW + "Given " + ORANGE + GENERIC_ENCHANT + LIGHT_YELLOW + " enchanted book to " + ORANGE + PLAYER_DISPLAY_NAME + LIGHT_YELLOW + ".");
public static final LangKey COMMAND_TIER_BOOK_USAGE = LangKey.of("Command.TierBook.Usage", "<player> <tier> <level>");
public static final LangKey COMMAND_TIER_BOOK_DESC = LangKey.of("Command.TierBook.Desc", "Gives an enchanted book.");
public static final LangKey COMMAND_TIER_BOOK_ERROR = LangKey.of("Command.TierBook.Error", "&cInvalid tier!");
public static final LangKey COMMAND_TIER_BOOK_DONE = LangKey.of("Command.TierBook.Done", "Given &6" + Placeholders.TIER_NAME + "&7 enchanted book to &6" + Placeholders.PLAYER_DISPLAY_NAME + "&7.");
public static final LangKey COMMAND_TIER_BOOK_ERROR = LangKey.of("Command.TierBook.Error", RED + "Invalid tier!");
public static final LangKey COMMAND_TIER_BOOK_DONE = LangKey.of("Command.TierBook.Done", LIGHT_YELLOW + "Given " + ORANGE + TIER_NAME + LIGHT_YELLOW + " enchanted book to " + ORANGE + PLAYER_DISPLAY_NAME + LIGHT_YELLOW + ".");
public static final LangKey ERROR_NO_ENCHANT = LangKey.of("Error.NoEnchant", "&cInvalid enchantment.");
public static final LangKey ERROR_NO_ENCHANT = LangKey.of("Error.NoEnchant", RED + "Invalid enchantment.");
}

View File

@ -7,7 +7,7 @@ import su.nightexpress.excellentenchants.enchantment.listener.EnchantAnvilListen
import su.nightexpress.excellentenchants.enchantment.listener.EnchantGenericListener;
import su.nightexpress.excellentenchants.enchantment.menu.EnchantmentsListMenu;
import su.nightexpress.excellentenchants.enchantment.task.ArrowTrailsTask;
import su.nightexpress.excellentenchants.enchantment.task.PotionEffectsTask;
import su.nightexpress.excellentenchants.enchantment.task.PassiveEnchantsTask;
public class EnchantManager extends AbstractManager<ExcellentEnchants> {
@ -15,8 +15,8 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
private EnchantmentsListMenu enchantmentsListMenu;
private ArrowTrailsTask arrowTrailsTask;
private PotionEffectsTask potionEffectsTask;
private ArrowTrailsTask arrowTrailsTask;
private PassiveEnchantsTask passiveEnchantsTask;
public EnchantManager(@NotNull ExcellentEnchants plugin) {
super(plugin);
@ -25,15 +25,14 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
@Override
protected void onLoad() {
this.enchantmentsListMenu = new EnchantmentsListMenu(this.plugin);
//this.addListener(new EnchantHandlerListener(this));
this.addListener(new EnchantGenericListener(this));
this.addListener(new EnchantAnvilListener(this.plugin));
this.arrowTrailsTask = new ArrowTrailsTask(this.plugin);
this.arrowTrailsTask.start();
this.potionEffectsTask = new PotionEffectsTask(this.plugin);
this.potionEffectsTask.start();
this.passiveEnchantsTask = new PassiveEnchantsTask(this.plugin);
this.passiveEnchantsTask.start();
}
@Override
@ -46,9 +45,9 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
this.arrowTrailsTask.stop();
this.arrowTrailsTask = null;
}
if (this.potionEffectsTask != null) {
this.potionEffectsTask.stop();
this.potionEffectsTask = null;
if (this.passiveEnchantsTask != null) {
this.passiveEnchantsTask.stop();
this.passiveEnchantsTask = null;
}
}

View File

@ -19,6 +19,7 @@ import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.meta.Periodic;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
@ -83,6 +84,9 @@ public abstract class ExcellentEnchant extends Enchantment implements IEnchantme
if (this instanceof Chanced chanced) {
map.add(Placeholders.ENCHANTMENT_CHANCE, () -> NumberUtil.format(chanced.getTriggerChance(level)));
}
if (this instanceof Periodic periodic) {
map.add(Placeholders.ENCHANTMENT_INTERVAL, () -> NumberUtil.format(periodic.getInterval(level) / 20D));
}
if (this instanceof Potioned potioned) {
map.add(Placeholders.ENCHANTMENT_POTION_LEVEL, () -> NumberUtil.toRoman(potioned.getEffectAmplifier(level)));
map.add(Placeholders.ENCHANTMENT_POTION_DURATION, () -> NumberUtil.format(potioned.getEffectDuration(level) / 20D));

View File

@ -10,6 +10,7 @@ import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
public class AquamanEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
@ -17,6 +18,7 @@ public class AquamanEnchant extends ExcellentEnchant implements Potioned, Passiv
public static final String ID = "aquaman";
private PotionImplementation potionImplementation;
private PeriodImplementation periodImplementation;
public AquamanEnchant(@NotNull ExcellentEnchants plugin) {
super(plugin, ID);
@ -29,6 +31,7 @@ public class AquamanEnchant extends ExcellentEnchant implements Potioned, Passiv
public void loadSettings() {
super.loadSettings();
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.WATER_BREATHING, true);
this.periodImplementation = PeriodImplementation.create(this, "100");
}
@NotNull
@ -37,6 +40,12 @@ public class AquamanEnchant extends ExcellentEnchant implements Potioned, Passiv
return potionImplementation;
}
@NotNull
@Override
public PeriodImplementation getPeriodImplementation() {
return periodImplementation;
}
@Override
@NotNull
public EnchantmentTarget getItemTarget() {

View File

@ -10,6 +10,7 @@ import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
public class JumpingEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
@ -17,6 +18,7 @@ public class JumpingEnchant extends ExcellentEnchant implements Potioned, Passiv
public static final String ID = "bunny_hop";
private PotionImplementation potionImplementation;
private PeriodImplementation periodImplementation;
public JumpingEnchant(@NotNull ExcellentEnchants plugin) {
super(plugin, ID);
@ -29,6 +31,7 @@ public class JumpingEnchant extends ExcellentEnchant implements Potioned, Passiv
public void loadSettings() {
super.loadSettings();
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.JUMP, true);
this.periodImplementation = PeriodImplementation.create(this, "100");
}
@NotNull
@ -37,6 +40,12 @@ public class JumpingEnchant extends ExcellentEnchant implements Potioned, Passiv
return potionImplementation;
}
@NotNull
@Override
public PeriodImplementation getPeriodImplementation() {
return periodImplementation;
}
@Override
@NotNull
public EnchantmentTarget getItemTarget() {

View File

@ -10,6 +10,7 @@ import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
public class NightVisionEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
@ -17,6 +18,7 @@ public class NightVisionEnchant extends ExcellentEnchant implements Potioned, Pa
public static final String ID = "night_vision";
private PotionImplementation potionImplementation;
private PeriodImplementation periodImplementation;
public NightVisionEnchant(@NotNull ExcellentEnchants plugin) {
super(plugin, ID);
@ -29,6 +31,7 @@ public class NightVisionEnchant extends ExcellentEnchant implements Potioned, Pa
public void loadSettings() {
super.loadSettings();
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.NIGHT_VISION, true);
this.periodImplementation = PeriodImplementation.create(this, "100");
}
@NotNull
@ -37,6 +40,12 @@ public class NightVisionEnchant extends ExcellentEnchant implements Potioned, Pa
return potionImplementation;
}
@NotNull
@Override
public PeriodImplementation getPeriodImplementation() {
return periodImplementation;
}
@Override
@NotNull
public EnchantmentTarget getItemTarget() {

View File

@ -6,41 +6,36 @@ import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.utils.EntityUtil;
import su.nexmedia.engine.utils.NumberUtil;
import su.nexmedia.engine.utils.values.UniParticle;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.Cleanable;
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
import su.nightexpress.excellentenchants.enchantment.task.AbstractEnchantmentTask;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
public class RegrowthEnchant extends ExcellentEnchant implements Chanced, PassiveEnchant, Cleanable {
public class RegrowthEnchant extends ExcellentEnchant implements Chanced, PassiveEnchant {
public static final String ID = "regrowth";
private static final String PLACEHOLDER_HEAL_AMOUNT = "%enchantment_heal_amount%";
private static final String PLACEHOLDER_HEAL_MIN_HEALTH = "%enchantment_heal_min_health%";
private static final String PLACEHOLDER_HEAL_MAX_HEALTH = "%enchantment_heal_max_health%";
private static final String PLACEHOLDER_HEAL_INTERVAL = "%enchantment_heal_interval%";
private long healInterval;
private EnchantScaler healMinHealth;
private EnchantScaler healMaxHealth;
private EnchantScaler healAmount;
private ChanceImplementation chanceImplementation;
private Task task;
private PeriodImplementation periodImplementation;
public RegrowthEnchant(@NotNull ExcellentEnchants plugin) {
super(plugin, ID);
this.getDefaults().setDescription("Restores " + PLACEHOLDER_HEAL_AMOUNT + " hearts every " + PLACEHOLDER_HEAL_INTERVAL + "s.");
this.getDefaults().setDescription("Restores " + PLACEHOLDER_HEAL_AMOUNT + " hearts every " + Placeholders.ENCHANTMENT_INTERVAL + "s.");
this.getDefaults().setLevelMax(5);
this.getDefaults().setTier(0.7);
}
@ -50,8 +45,9 @@ public class RegrowthEnchant extends ExcellentEnchant implements Chanced, Passiv
super.loadSettings();
this.chanceImplementation = ChanceImplementation.create(this,
"20.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5");
this.healInterval = JOption.create("Settings.Heal.Interval", 100,
"How often (in ticks) enchantment will have effect? 1 second = 20 ticks.").read(cfg);
this.periodImplementation = PeriodImplementation.create(this, "100");
this.healMinHealth = EnchantScaler.read(this, "Settings.Heal.Min_Health", "0.5",
"Minimal entity health for the enchantment to have effect.");
this.healMaxHealth = EnchantScaler.read(this, "Settings.Heal.Max_Health", "20.0",
@ -62,22 +58,6 @@ public class RegrowthEnchant extends ExcellentEnchant implements Chanced, Passiv
this.addPlaceholder(PLACEHOLDER_HEAL_AMOUNT, level -> NumberUtil.format(this.getHealAmount(level)));
this.addPlaceholder(PLACEHOLDER_HEAL_MIN_HEALTH, level -> NumberUtil.format(this.getHealMaxHealth(level)));
this.addPlaceholder(PLACEHOLDER_HEAL_MAX_HEALTH, level -> NumberUtil.format(this.getHealMaxHealth(level)));
this.addPlaceholder(PLACEHOLDER_HEAL_INTERVAL, level -> NumberUtil.format((double) this.healInterval / 20D));
this.task = new Task(plugin);
this.task.start();
}
@Override
public void clear() {
this.stopTask();
}
private void stopTask() {
if (this.task != null) {
this.task.stop();
this.task = null;
}
}
@NotNull
@ -86,6 +66,12 @@ public class RegrowthEnchant extends ExcellentEnchant implements Chanced, Passiv
return chanceImplementation;
}
@NotNull
@Override
public PeriodImplementation getPeriodImplementation() {
return periodImplementation;
}
@NotNull
@Override
public EnchantmentTarget getItemTarget() {
@ -104,10 +90,6 @@ public class RegrowthEnchant extends ExcellentEnchant implements Chanced, Passiv
return this.healMaxHealth.getValue(level);
}
public long getHealInterval() {
return this.healInterval;
}
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
if (!this.checkTriggerChance(level)) return false;
@ -125,25 +107,4 @@ public class RegrowthEnchant extends ExcellentEnchant implements Chanced, Passiv
}
return true;
}
class Task extends AbstractEnchantmentTask {
public Task(@NotNull ExcellentEnchants plugin) {
super(plugin, healInterval, false);
}
@Override
public void action() {
for (LivingEntity entity : this.getEntities()) {
EnchantUtils.getEquipped(entity, RegrowthEnchant.class).forEach((item, enchants) -> {
enchants.forEach((enchant, level) -> {
if (enchant.isOutOfCharges(item)) return;
if (enchant.onTrigger(entity, item, level)) {
enchant.consumeCharges(item, level);
}
});
});
}
}
}
}

View File

@ -5,34 +5,29 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.utils.NumberUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.Cleanable;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.task.AbstractEnchantmentTask;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
public class SaturationEnchant extends ExcellentEnchant implements PassiveEnchant, Cleanable {
public class SaturationEnchant extends ExcellentEnchant implements PassiveEnchant {
public static final String ID = "saturation";
private static final String PLACEHOLDER_SATURATION_AMOUNT = "%enchantment_saturation_amount%";
private static final String PLACEHOLDER_SATURATION_INTERVAL = "%enchantment_saturation_interval%";
private static final String PLACEHOLDER_SATURATION_MAX_FOOD_LEVEL = "%enchantment_saturation_max_food_level%";
private long saturationInterval;
private EnchantScaler saturationAmount;
private EnchantScaler saturationMaxFoodLevel;
private Task task;
private PeriodImplementation periodImplementation;
public SaturationEnchant(@NotNull ExcellentEnchants plugin) {
super(plugin, ID);
this.getDefaults().setDescription("Restores " + PLACEHOLDER_SATURATION_AMOUNT + " food points every " + PLACEHOLDER_SATURATION_INTERVAL + "s.");
this.getDefaults().setDescription("Restores " + PLACEHOLDER_SATURATION_AMOUNT + " food points every " + Placeholders.ENCHANTMENT_INTERVAL + "s.");
this.getDefaults().setLevelMax(3);
this.getDefaults().setTier(0.5);
}
@ -40,31 +35,21 @@ public class SaturationEnchant extends ExcellentEnchant implements PassiveEnchan
@Override
public void loadSettings() {
super.loadSettings();
this.saturationInterval = JOption.create("Settings.Saturation.Interval", 100,
"How often (in ticks) enchantment will have effect? 1 second = 20 ticks.").read(cfg);
this.periodImplementation = PeriodImplementation.create(this, "100");
this.saturationAmount = EnchantScaler.read(this, "Settings.Saturation.Amount", Placeholders.ENCHANTMENT_LEVEL,
"Amount of food points to restore.");
this.saturationMaxFoodLevel = EnchantScaler.read(this, "Settings.Saturation.Max_Food_Level", "20",
"Maximal player's food level for the enchantment to stop feeding them.");
this.addPlaceholder(PLACEHOLDER_SATURATION_AMOUNT, level -> NumberUtil.format(this.getSaturationAmount(level)));
this.addPlaceholder(PLACEHOLDER_SATURATION_INTERVAL, level -> NumberUtil.format((double) this.saturationInterval / 20D));
this.addPlaceholder(PLACEHOLDER_SATURATION_MAX_FOOD_LEVEL, level -> NumberUtil.format(this.getMaxFoodLevel(level)));
this.task = new Task(plugin);
this.task.start();
}
@NotNull
@Override
public void clear() {
this.stopTask();
}
private void stopTask() {
if (this.task != null) {
this.task.stop();
this.task = null;
}
public PeriodImplementation getPeriodImplementation() {
return periodImplementation;
}
@Override
@ -81,10 +66,6 @@ public class SaturationEnchant extends ExcellentEnchant implements PassiveEnchan
return (int) this.saturationMaxFoodLevel.getValue(level);
}
public long getSaturationInterval() {
return saturationInterval;
}
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
if (!(entity instanceof Player player)) return false;
@ -94,25 +75,4 @@ public class SaturationEnchant extends ExcellentEnchant implements PassiveEnchan
player.setFoodLevel(Math.min(20, player.getFoodLevel() + amount));
return true;
}
class Task extends AbstractEnchantmentTask {
public Task(@NotNull ExcellentEnchants plugin) {
super(plugin, saturationInterval, false);
}
@Override
public void action() {
for (LivingEntity entity : this.getEntities()) {
EnchantUtils.getEquipped(entity, SaturationEnchant.class).forEach((item, enchants) -> {
enchants.forEach((enchant, level) -> {
if (enchant.isOutOfCharges(item)) return;
if (enchant.onTrigger(entity, item, level)) {
enchant.consumeCharges(item, level);
}
});
});
}
}
}
}

View File

@ -10,6 +10,7 @@ import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
public class SpeedyEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
@ -17,6 +18,7 @@ public class SpeedyEnchant extends ExcellentEnchant implements Potioned, Passive
public static final String ID = "sonic";
private PotionImplementation potionImplementation;
private PeriodImplementation periodImplementation;
public SpeedyEnchant(@NotNull ExcellentEnchants plugin) {
super(plugin, ID);
@ -29,6 +31,7 @@ public class SpeedyEnchant extends ExcellentEnchant implements Potioned, Passive
public void loadSettings() {
super.loadSettings();
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.SPEED, true);
this.periodImplementation = PeriodImplementation.create(this, "100");
}
@NotNull
@ -37,6 +40,12 @@ public class SpeedyEnchant extends ExcellentEnchant implements Potioned, Passive
return potionImplementation;
}
@NotNull
@Override
public PeriodImplementation getPeriodImplementation() {
return periodImplementation;
}
@Override
@NotNull
public EnchantmentTarget getItemTarget() {

View File

@ -104,6 +104,8 @@ public class VampiricArrowsEnchant extends ExcellentEnchant implements BowEnchan
@Override
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
if (shooter.isDead() || shooter.getHealth() <= 0D) return false;
double healAmount = this.getHealAmount(level);
if (healAmount <= 0D) return false;

View File

@ -0,0 +1,55 @@
package su.nightexpress.excellentenchants.enchantment.impl.meta;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.meta.Periodic;
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
public class PeriodImplementation implements Periodic {
private final EnchantScaler triggerInterval;
private long nextTriggerTime;
public PeriodImplementation(@NotNull ExcellentEnchant enchant, @NotNull EnchantScaler triggerInterval) {
this.triggerInterval = triggerInterval;
}
@NotNull
public static PeriodImplementation create(@NotNull ExcellentEnchant enchant) {
return create(enchant, "100");
}
@NotNull
public static PeriodImplementation create(@NotNull ExcellentEnchant enchant, @NotNull String def) {
return new PeriodImplementation(enchant, EnchantScaler.read(enchant, "Settings.Trigger_Interval", def,
"Sets how often (in ticks) this enchantment will be triggered.",
"20 ticks = 1 second."));
}
@NotNull
@Override
public Periodic getPeriodImplementation() {
return this;
}
@Override
public long getInterval(int level) {
return (long) this.triggerInterval.getValue(level);
}
@Override
public long getNextTriggerTime() {
return nextTriggerTime;
}
@Override
public boolean isTriggerTime() {
return System.currentTimeMillis() >= this.getNextTriggerTime();
}
@Override
public void updateTriggerTime(int level) {
this.nextTriggerTime = System.currentTimeMillis() + this.getInterval(level) / 20L * 1000L;
}
}

View File

@ -64,7 +64,7 @@ public final class PotionImplementation implements Potioned {
public int getEffectDuration(int level) {
if (this.isPermanent()) {
int duration = Config.TASKS_PASSIVE_POTION_EFFECTS_APPLY_INTERVAL.get().intValue() + 30;
int duration = Config.TASKS_PASSIVE_ENCHANTS_TRIGGER_INTERVAL.get().intValue() + 30;
if (this.getEffectType().getName().equalsIgnoreCase(PotionEffectType.NIGHT_VISION.getName())) {
duration += 30 * 20;
}

View File

@ -10,6 +10,7 @@ import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
public class HasteEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
@ -17,6 +18,7 @@ public class HasteEnchant extends ExcellentEnchant implements Potioned, PassiveE
public static final String ID = "haste";
private PotionImplementation potionImplementation;
private PeriodImplementation periodImplementation;
public HasteEnchant(@NotNull ExcellentEnchants plugin) {
super(plugin, ID);
@ -29,6 +31,7 @@ public class HasteEnchant extends ExcellentEnchant implements Potioned, PassiveE
public void loadSettings() {
super.loadSettings();
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.FAST_DIGGING, true);
this.periodImplementation = PeriodImplementation.create(this, "100");
}
@NotNull
@ -37,6 +40,12 @@ public class HasteEnchant extends ExcellentEnchant implements Potioned, PassiveE
return potionImplementation;
}
@NotNull
@Override
public PeriodImplementation getPeriodImplementation() {
return periodImplementation;
}
@Override
@NotNull
public EnchantmentTarget getItemTarget() {

View File

@ -64,7 +64,7 @@ public class SoulboundEnchant extends ExcellentEnchant implements GenericEnchant
world.dropItemNaturally(location, save);
}
else {
this.consumeCharges(save, EnchantUtils.getLevel(save, this));
this.consumeChargesNoUpdate(save, EnchantUtils.getLevel(save, this));
player.getInventory().addItem(save);
}
});

View File

@ -218,7 +218,7 @@ public class EnchantDecapitator extends ExcellentEnchant implements Chanced, Dea
String texture = this.headTextures.get(entity.getType());
if (texture == null) return false;
entityName = this.headName.replace(Placeholders.GENERIC_TYPE, plugin.getLangManager().getEnum(entity.getType()));
entityName = this.headName.replace(Placeholders.GENERIC_TYPE, LangManager.getEntityType(entity.getType()));
ItemUtil.setSkullTexture(item, texture);
meta = (SkullMeta) item.getItemMeta();
}

View File

@ -12,6 +12,7 @@ import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.api.manager.EventListener;
import su.nexmedia.engine.utils.PDCUtil;
import su.nexmedia.engine.utils.StringUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
@ -25,7 +26,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
public class EnchantThrifty extends ExcellentEnchant implements Chanced, DeathEnchant {
public class EnchantThrifty extends ExcellentEnchant implements Chanced, DeathEnchant, EventListener {
public static final String ID = "thrifty";
@ -98,9 +99,9 @@ public class EnchantThrifty extends ExcellentEnchant implements Chanced, DeathEn
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onCreatureSpawn(CreatureSpawnEvent e) {
if (!this.ignoredSpawnReasons.contains(e.getSpawnReason())) return;
public void onCreatureSpawn(CreatureSpawnEvent event) {
if (!this.ignoredSpawnReasons.contains(event.getSpawnReason())) return;
PDCUtil.set(e.getEntity(), this.keyEntityIgnored, true);
PDCUtil.set(event.getEntity(), this.keyEntityIgnored, true);
}
}

View File

@ -71,7 +71,7 @@ public class SwiperEnchant extends ExcellentEnchant implements CombatEnchant, Ch
int levelHas = player.getLevel();
int xpHas = player.getTotalExperience();
xpHas = Math.max(0, xpHas - amount);
xpHas = Math.max(0, xpHas + amount);
player.setExp(0F);
player.setTotalExperience(0);
player.setLevel(0);

View File

@ -1,251 +0,0 @@
package su.nightexpress.excellentenchants.enchantment.listener;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.manager.AbstractListener;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
public class EnchantHandlerListener extends AbstractListener<ExcellentEnchants> {
public EnchantHandlerListener(@NotNull EnchantManager enchantManager) {
super(enchantManager.plugin());
}
// ---------------------------------------------------------------
// Combat Attacking Enchants
// ---------------------------------------------------------------
/*@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEnchantCombatMelee(EntityDamageEvent event) {
if (event.getCause() == DamageCause.THORNS) return;
if (!(event.getEntity() instanceof LivingEntity victim)) return;
if (event instanceof EntityDamageByEntityEvent ede) {
if (ede.getDamager() instanceof Projectile projectile && this.getSourceWeapon(projectile) != null) {
this.handleCombatBowEnchants(ede, projectile, victim);
return;
}
if (!(ede.getDamager() instanceof LivingEntity damager) || damager == victim) return;
this.handleCombatWeaponEnchants(ede, damager, victim);
this.handleCombatArmorEnchants(ede, damager, victim);
}
else {
this.handleArmorEnchants(event, victim);
}
}
private void handleCombatWeaponEnchants(@NotNull EntityDamageByEntityEvent e,
@NotNull LivingEntity damager, @NotNull LivingEntity victim) {
EntityEquipment equipment = damager.getEquipment();
if (equipment == null) return;
ItemStack weapon = equipment.getItemInMainHand();
if (weapon.getType().isAir() || weapon.getType() == Material.ENCHANTED_BOOK) return;
EnchantUtils.getExcellents(weapon, CombatEnchant.class).forEach((combatEnchant, level) -> {
if (combatEnchant.isOutOfCharges(weapon)) return;
if (combatEnchant.onAttack(e, damager, victim, weapon, level)) {
combatEnchant.consumeChargesNoUpdate(weapon, level);
}
});
EnchantUtils.updateChargesDisplay(weapon);
}
private void handleCombatArmorEnchants(@NotNull EntityDamageByEntityEvent e,
@NotNull LivingEntity damager, @NotNull LivingEntity victim) {
EntityEquipment equipDamager = damager.getEquipment();
if (equipDamager == null) return;
ItemStack weaponDamager = equipDamager.getItemInMainHand();
for (ItemStack armor : EntityUtil.getEquippedArmor(victim).values()) {
if (armor == null || armor.getType().isAir()) continue;
EnchantUtils.getExcellents(armor, CombatEnchant.class).forEach((combatEnchant, level) -> {
if (combatEnchant.isOutOfCharges(armor)) return;
if (combatEnchant.onProtect(e, damager, victim, weaponDamager, level)) {
combatEnchant.consumeChargesNoUpdate(armor, level);
}
});
EnchantUtils.updateChargesDisplay(armor);
}
}
private void handleArmorEnchants(@NotNull EntityDamageEvent e, @NotNull LivingEntity entity) {
EnchantUtils.getEquipped(entity, DamageEnchant.class).forEach((item, enchants) -> {
enchants.forEach((enchant, level) -> {
if (enchant.isOutOfCharges(item)) return;
if (enchant.onDamage(e, entity, item, level)) {
enchant.consumeChargesNoUpdate(item, level);
}
});
EnchantUtils.updateChargesDisplay(item);
});
}
private void handleCombatBowEnchants(@NotNull EntityDamageByEntityEvent e, @NotNull Projectile projectile,
@NotNull LivingEntity victim) {
if (!(projectile.getShooter() instanceof LivingEntity shooter)) return;
ItemStack bow = this.getSourceWeapon(projectile);
if (bow == null || bow.getType().isAir() || bow.getType() == Material.ENCHANTED_BOOK) return;
EnchantUtils.getExcellents(bow, BowEnchant.class).forEach((bowEnchant, level) -> {
bowEnchant.onDamage(e, projectile, shooter, victim, bow, level);
});
}
// ---------------------------------------------------------------
// Bow Shooting Enchants
// ---------------------------------------------------------------
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEnchantBowShoot(EntityShootBowEvent event) {
LivingEntity shooter = event.getEntity();
if (shooter.getEquipment() == null) return;
ItemStack bow = event.getBow();
if (bow == null || bow.getType().isAir() || bow.getType() == Material.ENCHANTED_BOOK) return;
EnchantUtils.getExcellents(bow, BowEnchant.class).forEach((bowEnchant, level) -> {
if (bowEnchant.isOutOfCharges(bow)) return;
if (bowEnchant.onShoot(event, shooter, bow, level)) {
if (bowEnchant instanceof Arrowed arrowed && event.getProjectile() instanceof Projectile projectile) {
arrowed.addData(projectile);
arrowed.addTrail(projectile);
}
bowEnchant.consumeChargesNoUpdate(bow, level);
}
});
EnchantUtils.updateChargesDisplay(bow);
if (event.getProjectile() instanceof Projectile projectile) {
this.setSourceWeapon(projectile, bow);
}
}
// ---------------------------------------------------------------
// Bow Hit Land Enchants
// ---------------------------------------------------------------
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEnchantBowHit(ProjectileHitEvent event) {
Projectile projectile = event.getEntity();
ItemStack bow = this.getSourceWeapon(projectile);
if (bow == null || bow.getType().isAir() || bow.getType() == Material.ENCHANTED_BOOK) return;
EnchantUtils.getExcellents(bow, BowEnchant.class).forEach((bowEnchant, level) -> {
bowEnchant.onHit(event, null, projectile, bow, level);
});
// Prevent to apply enchants multiple times on hits.
this.plugin.runTask(task -> this.removeSourceWeapon(projectile));
}
// ---------------------------------------------------------------
// Interaction Related Enchants
// ---------------------------------------------------------------
@EventHandler(priority = EventPriority.HIGHEST)
public void onEnchantInteract(PlayerInteractEvent event) {
if (event.useInteractedBlock() == Result.DENY) return;
if (event.useItemInHand() == Result.DENY) return;
ItemStack item = event.getItem();
if (item == null || item.getType().isAir() || item.getType() == Material.ENCHANTED_BOOK) return;
Player player = event.getPlayer();
EnchantUtils.getExcellents(item, InteractEnchant.class).forEach((interEnchant, level) -> {
if (interEnchant.isOutOfCharges(item)) return;
if (interEnchant.onInteract(event, player, item, level)) {
interEnchant.consumeChargesNoUpdate(item, level);
}
});
EnchantUtils.updateChargesDisplay(item);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onEnchantFishing(PlayerFishEvent event) {
Player player = event.getPlayer();
ItemStack item = EnchantUtils.getFishingRod(player);
if (item == null) return;
EnchantUtils.getExcellents(item, FishingEnchant.class).forEach((enchant, level) -> {
if (event.isCancelled()) return; // Check if event was cancelled by some enchantment.
if (enchant.isOutOfCharges(item)) return;
if (enchant.onFishing(event, item, level)) {
enchant.consumeChargesNoUpdate(item, level);
}
});
EnchantUtils.updateChargesDisplay(item);
}
// ---------------------------------------------------------------
// Death Related Enchants
// ---------------------------------------------------------------
@EventHandler(priority = EventPriority.HIGHEST)
public void onEnchantDeath(EntityDeathEvent event) {
LivingEntity entity = event.getEntity();
EnchantUtils.getEquipped(entity, DeathEnchant.class).forEach((item, enchants) -> {
enchants.forEach(((deathEnchant, level) -> {
if (deathEnchant.isOutOfCharges(item)) return;
if (deathEnchant.onDeath(event, entity, item, level)) {
deathEnchant.consumeChargesNoUpdate(item, level);
}
}));
if (Config.ENCHANTMENTS_CHARGES_ENABLED.get()) {
EnchantUtils.updateChargesDisplay(item);
}
});
Player killer = entity.getKiller();
if (killer == null) return;
ItemStack weapon = killer.getInventory().getItemInMainHand();
if (weapon.getType().isAir() || weapon.getType() == Material.ENCHANTED_BOOK) return;
EnchantUtils.getExcellents(weapon, DeathEnchant.class).forEach((deathEnchant, level) -> {
if (deathEnchant.isOutOfCharges(weapon)) return;
if (deathEnchant.onKill(event, entity, killer, level)) {
deathEnchant.consumeChargesNoUpdate(weapon, level);
}
});
EnchantUtils.updateChargesDisplay(weapon);
}
// Handle BlockBreak enchantments.
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEnchantBlockBreak(BlockBreakEvent event) {
Player player = event.getPlayer();
if (player.getGameMode() == GameMode.CREATIVE) return;
ItemStack tool = player.getInventory().getItemInMainHand();
if (tool.getType().isAir() || tool.getType() == Material.ENCHANTED_BOOK) return;
EnchantUtils.getExcellents(tool, BlockBreakEnchant.class).forEach((blockEnchant, level) -> {
if (blockEnchant.isOutOfCharges(tool)) return;
if (blockEnchant.onBreak(event, player, tool, level)) {
blockEnchant.consumeChargesNoUpdate(tool, level);
}
});
EnchantUtils.updateChargesDisplay(tool);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEnchantBlockDropItem(BlockDropItemEvent event) {
Player player = event.getPlayer();
if (player.getGameMode() == GameMode.CREATIVE) return;
ItemStack tool = player.getInventory().getItemInMainHand();
if (tool.getType().isAir() || tool.getType() == Material.ENCHANTED_BOOK) return;
EnchantUtils.getExcellents(tool, BlockDropEnchant.class).forEach((enchant, level) -> {
if (enchant.isOutOfCharges(tool)) return;
if (enchant.onDrop(event, player, tool, level)) {
enchant.consumeChargesNoUpdate(tool, level);
}
});
EnchantUtils.updateChargesDisplay(tool);
}*/
}

View File

@ -14,6 +14,7 @@ import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nexmedia.engine.Version;
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
import su.nightexpress.excellentenchants.api.enchantment.type.*;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
@ -314,6 +315,8 @@ public class DataGathers {
@NotNull
@Override
public EquipmentSlot[] getEnchantSlots(@NotNull PlayerFishEvent event) {
if (Version.isBehind(Version.V1_19_R3)) return new EquipmentSlot[] {EquipmentSlot.HAND};
return event.getHand() == null ? new EquipmentSlot[] {EquipmentSlot.HAND} : new EquipmentSlot[]{event.getHand()};
}

View File

@ -1,7 +1,7 @@
package su.nightexpress.excellentenchants.enchantment.registry.wrapper;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@ -40,6 +40,8 @@ public class WrappedEvent<E extends Event, T extends IEnchantment> implements Li
LivingEntity entity = this.dataGather.getEntity(event);
if (entity == null) return;
Player player = entity instanceof Player p1 ? p1 : null;
this.dataGather.getEnchants(event, this.enchantClass, entity).forEach((item, enchants) -> {
enchants.forEach(((enchant, level) -> {
if (!this.dataGather.checkPriority(enchant, this.priority)) return;
@ -49,8 +51,8 @@ public class WrappedEvent<E extends Event, T extends IEnchantment> implements Li
enchant.consumeChargesNoUpdate(item, level);
}
}));
if (Config.ENCHANTMENTS_CHARGES_ENABLED.get()) {
EnchantUtils.updateChargesDisplay(item);
if (this.priority == EventPriority.MONITOR && Config.ENCHANTMENTS_CHARGES_ENABLED.get() && player != null) {
EnchantUtils.updateDisplay(item);
}
});
}

View File

@ -5,19 +5,27 @@ import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.server.AbstractTask;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public abstract class AbstractEnchantmentTask extends AbstractTask<ExcellentEnchants> {
public class PassiveEnchantsTask extends AbstractTask<ExcellentEnchants> {
public AbstractEnchantmentTask(@NotNull ExcellentEnchants plugin, long interval, boolean async) {
super(plugin, interval, async);
public PassiveEnchantsTask(@NotNull ExcellentEnchants plugin) {
super(plugin, Config.TASKS_PASSIVE_ENCHANTS_TRIGGER_INTERVAL.get(), false);
}
@Override
public void action() {
for (LivingEntity entity : this.getEntities()) {
EnchantUtils.triggerPassiveEnchants(entity);
}
}
@NotNull
protected Collection<? extends LivingEntity> getEntities() {
private Collection<? extends LivingEntity> getEntities() {
Set<LivingEntity> list = new HashSet<>(plugin.getServer().getOnlinePlayers());
if (Config.ENCHANTMENTS_ENTITY_PASSIVE_FOR_MOBS.get()) {
@ -25,7 +33,7 @@ public abstract class AbstractEnchantmentTask extends AbstractTask<ExcellentEnch
list.addAll(world.getEntitiesByClass(LivingEntity.class));
});
}
list.removeIf(e -> e.isDead() || !e.isValid());
list.removeIf(entity -> entity.isDead() || !entity.isValid());
return list;
}
}

View File

@ -1,21 +0,0 @@
package su.nightexpress.excellentenchants.enchantment.task;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
public class PotionEffectsTask extends AbstractEnchantmentTask {
public PotionEffectsTask(@NotNull ExcellentEnchants plugin) {
super(plugin, Config.TASKS_PASSIVE_POTION_EFFECTS_APPLY_INTERVAL.get(), false);
}
@Override
public void action() {
for (LivingEntity entity : this.getEntities()) {
EnchantUtils.updateEquippedEffects(entity);
}
}
}

View File

@ -24,7 +24,6 @@ import su.nexmedia.engine.utils.ItemUtil;
import su.nexmedia.engine.utils.PDCUtil;
import su.nightexpress.excellentenchants.ExcellentEnchantsAPI;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
@ -356,18 +355,22 @@ public class EnchantUtils {
return map;
}
public static void updateEquippedEffects(@NotNull LivingEntity entity) {
public static void triggerPassiveEnchants(@NotNull LivingEntity entity) {
Player player = entity instanceof Player p1 ? p1 : null;
getEquipped(entity, PassiveEnchant.class).forEach((item, enchants) -> {
enchants.forEach((enchant, level) -> {
if (!enchant.isAvailableToUse(entity)) return;
if (enchant instanceof Potioned potioned) {
if (enchant.isOutOfCharges(item)) return;
if (enchant.onTrigger(entity, item, level)) {
enchant.consumeChargesNoUpdate(item, level);
}
if (!enchant.isTriggerTime()) return;
if (enchant.isOutOfCharges(item)) return;
if (enchant.onTrigger(entity, item, level)) {
enchant.consumeChargesNoUpdate(item, level);
enchant.updateTriggerTime(level);
}
});
EnchantUtils.updateChargesDisplay(item);
if (Config.ENCHANTMENTS_CHARGES_ENABLED.get() && player != null) {
EnchantUtils.updateDisplay(item);
}
});
}

View File

@ -50,6 +50,11 @@ public class PlaceholderHook {
return ExcellentEnchantsAPI.PLUGIN.getDescription().getVersion();
}
@Override
public boolean persist() {
return true;
}
@Override
@Nullable
public String onPlaceholderRequest(Player player, @NotNull String params) {

View File

@ -5,5 +5,5 @@ author: NightExpress
desciption: Vanilla-like enchants for your server.
depend: [ NexEngine ]
softdepend: [ ProtocolLib, NoCheatPlus, PlaceholderAPI, MythicMobs ]
api-version: 1.17
api-version: 1.18
load: STARTUP

View File

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

View File

@ -1,71 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>3.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>V1_17_R1</artifactId>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.17.1-R0.1-SNAPSHOT</version>
<classifier>remapped-mojang</classifier>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>3.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>net.md-5</groupId>
<artifactId>specialsource-maven-plugin</artifactId>
<version>1.2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>remap</goal>
</goals>
<id>remap-obf</id>
<configuration>
<srgIn>org.spigotmc:minecraft-server:1.17.1-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
<reverse>true</reverse>
<remappedDependencies>org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT:jar:remapped-mojang</remappedDependencies>
<remappedArtifactAttached>true</remappedArtifactAttached>
<remappedClassifierName>remapped-obf</remappedClassifierName>
</configuration>
</execution>
<execution>
<phase>package</phase>
<goals>
<goal>remap</goal>
</goals>
<id>remap-spigot</id>
<configuration>
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
<srgIn>org.spigotmc:minecraft-server:1.17.1-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
<remappedDependencies>org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,116 +0,0 @@
package su.nightexpress.excellentenchants.nms.v1_17_R1;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.projectile.FishingHook;
import net.minecraft.world.item.SpawnEggItem;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftFishHook;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import java.util.HashSet;
import java.util.Set;
public class V1_17_R1 implements EnchantNMS {
@Override
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;
Entity entity = craftPlayer.getHandle();
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
craftPlayer.getHandle().connection.send(packet);
}
@Override
public void retrieveHook(@NotNull FishHook hook, @NotNull ItemStack item) {
CraftFishHook craftFishHook = (CraftFishHook) hook;
FishingHook handle = craftFishHook.getHandle();
handle.retrieve(CraftItemStack.asNMSCopy(item));
}
@Override
@Nullable
public ItemStack getSpawnEgg(@NotNull LivingEntity entity) {
CraftLivingEntity craftLivingEntity = (CraftLivingEntity) entity;
net.minecraft.world.entity.LivingEntity livingEntity = craftLivingEntity.getHandle();
SpawnEggItem eggItem = SpawnEggItem.byId(livingEntity.getType());
if (eggItem == null) return null;
return CraftItemStack.asBukkitCopy(eggItem.getDefaultInstance());
}
@Override
@NotNull
public Set<Block> handleFlameWalker(@NotNull LivingEntity bukkitEntity, @NotNull Location location, int level) {
Entity entity = ((CraftLivingEntity) bukkitEntity).getHandle();
BlockPos pos = new BlockPos(location.getX(), location.getY(), location.getZ());
ServerLevel world = ((CraftWorld) bukkitEntity.getWorld()).getHandle();
float radius = Math.min(16F, 2F + level);
BlockState bStone = Blocks.MAGMA_BLOCK.defaultBlockState();
BlockPos.MutableBlockPos posAbove = new BlockPos.MutableBlockPos();
Set<Block> blocks = new HashSet<>();
for (BlockPos posNear : BlockPos.betweenClosed(pos.b(-radius, -1.0, -radius), pos.b(radius, -1.0, radius))) {
if (!posNear.closerThan(entity.position(), radius)) continue;
posAbove.set(posNear.getX(), posNear.getY() + 1, posNear.getZ());
BlockState bLavaAbove = world.getBlockState(posAbove);
BlockState bLava = world.getBlockState(posNear);
if (!bLavaAbove.isAir()) continue;
if (!bLava.getBlock().equals(Blocks.LAVA)) continue;
if (bLava.getValue(LiquidBlock.LEVEL) != 0) continue;
if (!bStone.canSurvive(world, posNear)) continue;
if (!world.isUnobstructed(bStone, posNear, CollisionContext.empty())) continue;
if (!CraftEventFactory.handleBlockFormEvent(world, posNear, bStone, entity)) continue;
//world.scheduleTick(posNear, Blocks.STONE, Rnd.get(60, 120));
Location bukkitLoc = new Location(world.getWorld(), posNear.getX(), posNear.getY(), posNear.getZ());
blocks.add(bukkitLoc.getBlock());
}
return blocks;
}
@NotNull
public Item popResource(@NotNull Block block, @NotNull ItemStack item) {
Level world = ((CraftWorld)block.getWorld()).getHandle();
BlockPos pos = ((CraftBlock)block).getPosition();
net.minecraft.world.item.ItemStack itemstack = CraftItemStack.asNMSCopy(item);
float yMod = EntityType.ITEM.getHeight() / 2.0F;
double x = (pos.getX() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D);
double y = (pos.getY() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D) - yMod;
double z = (pos.getZ() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D);
ItemEntity itemEntity = new ItemEntity(world, x, y, z, itemstack);
itemEntity.setDefaultPickUpDelay();
return (Item) itemEntity.getBukkitEntity();
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -7,11 +7,10 @@
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>ExcellentEnchants</artifactId>
<packaging>pom</packaging>
<version>3.6.0</version>
<version>3.6.2</version>
<modules>
<module>Core</module>
<module>NMS</module>
<module>V1_17_R1</module>
<module>V1_18_R2</module>
<module>V1_19_R3</module>
<module>V1_20_R1</module>