This commit is contained in:
nulli0n 2024-08-12 21:36:20 +05:00
parent 9faac63acf
commit fe6d37f3de
192 changed files with 4562 additions and 9043 deletions

14
.gitignore vendored
View File

@ -5,17 +5,7 @@
/Core/pom.xml.versionsBackup
/NMS/target/
/NMS/pom.xml.versionsBackup
/V1_18_R2/target/
/V1_18_R2/pom.xml.versionsBackup
/V1_19_R3/target/
/V1_19_R3/pom.xml.versionsBackup
/V1_20_R1/target/
/V1_20_R1/pom.xml.versionsBackup
/V1_20_R2/target/
/V1_20_R2/pom.xml.versionsBackup
/V1_20_R3/target/
/V1_20_R3/pom.xml.versionsBackup
/API/target/
/API/pom.xml.versionsBackup
/MC_1_20_6/target/
/MC_1_20_6/pom.xml.versionsBackup
/MC_1_21/target/
/MC_1_21/pom.xml.versionsBackup

View File

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

View File

@ -0,0 +1,14 @@
package su.nightexpress.excellentenchants.api;
public class ConfigBridge {
private static int enchantsTickInterval;
public static int getEnchantsTickInterval() {
return enchantsTickInterval;
}
public static void setEnchantsTickInterval(int enchantsTickInterval) {
ConfigBridge.enchantsTickInterval = enchantsTickInterval;
}
}

View File

@ -1,8 +0,0 @@
package su.nightexpress.excellentenchants.api;
@Deprecated
public enum DistributionMode {
VANILLA,
CUSTOM
}

View File

@ -1,24 +0,0 @@
package su.nightexpress.excellentenchants.api;
import org.jetbrains.annotations.NotNull;
@Deprecated
public enum DistributionWay {
ENCHANTING("Enchanting_Table"),
VILLAGER("Villagers"),
LOOT_GENERATION("Loot_Generation"),
FISHING("Fishing"),
MOB_EQUIPMENT("Mob_Equipment");
private final String pathName;
DistributionWay(@NotNull String pathName) {
this.pathName = pathName;
}
@NotNull
public String getPathName() {
return pathName;
}
}

View File

@ -1,21 +0,0 @@
package su.nightexpress.excellentenchants.api;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
public class EnchantingBridge {
private static ItemStack enchantingItem;
public static ItemStack getEnchantingItem() {
return enchantingItem;
}
public static void setEnchantingItem(@Nullable ItemStack itemStack) {
enchantingItem = itemStack;
}
public static void clear() {
enchantingItem = null;
}
}

View File

@ -0,0 +1,6 @@
package su.nightexpress.excellentenchants.api;
public class EnchantmentID {
public static final String FLAME_WALKER = "flame_walker";
}

View File

@ -0,0 +1,26 @@
package su.nightexpress.excellentenchants.api.enchantment;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.Modifier;
public interface Charges {
boolean isEnabled();
boolean isCustomFuel();
int getMaxAmount(int level);
int getConsumeAmount(int level);
int getRechargeAmount(int level);
@NotNull ItemStack getFuel();
@NotNull Modifier getMaxAmount();
@NotNull Modifier getConsumeAmount();
@NotNull Modifier getRechargeAmount();
}

View File

@ -26,8 +26,15 @@ public class Cost {
@NotNull
public static Cost read(@NotNull FileConfig config, @NotNull String path) {
int base = ConfigValue.create(path + ".Base", 0).read(config);
int perLevel = ConfigValue.create(path + ".Per_Level", 0).read(config);
int base = ConfigValue.create(path + ".Base",
0,
"The cost for a level I enchantment."
).read(config);
int perLevel = ConfigValue.create(path + ".Per_Level",
0,
"The amount of levels added to the Base for each level above level I"
).read(config);
return new Cost(base, perLevel);
}

View File

@ -0,0 +1,90 @@
package su.nightexpress.excellentenchants.api.enchantment;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.meta.MetaHolder;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.placeholder.PlaceholderMap;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.List;
public interface CustomEnchantment extends MetaHolder {
default void clear() {
}
@NotNull PlaceholderMap getPlaceholders(int level);
@NotNull FileConfig getConfig();
@NotNull Enchantment getBukkitEnchantment();
@NotNull Definition getDefinition();
@NotNull Distribution getDistribution();
@NotNull Charges getCharges();
boolean load();
boolean checkServerRequirements();
boolean isAvailableToUse(@NotNull LivingEntity entity);
boolean isAvailableToUse(@NotNull World world);
default boolean isSupportedItem(@NotNull ItemStack itemStack) {
return this.getDefinition().getSupportedItems().is(itemStack);
}
default boolean isPrimaryItem(@NotNull ItemStack itemStack) {
return this.getDefinition().getPrimaryItems().is(itemStack);
}
@NotNull String getId();
@NotNull String getDisplayName();
@NotNull String getFormattedName();
@NotNull List<String> getDescription();
@NotNull List<String> getDescription(int level);
@NotNull List<String> getDescription(int level, int charges);
boolean isCurse();
boolean isHiddenFromList();
boolean hasVisualEffects();
boolean hasCharges();
boolean isChargesFuel(@NotNull ItemStack item);
int getCharges(@NotNull ItemStack item);
int getCharges(@NotNull ItemMeta meta);
void setCharges(@NotNull ItemStack item, int level, int amount);
boolean isFullOfCharges(@NotNull ItemStack item);
boolean isOutOfCharges(@NotNull ItemStack item);
void restoreCharges(@NotNull ItemStack item, int level);
void fuelCharges(@NotNull ItemStack item, int level);
void consumeCharges(@NotNull ItemStack item, int level);
@Deprecated
void consumeChargesNoUpdate(@NotNull ItemStack item, int level);
}

View File

@ -0,0 +1,37 @@
package su.nightexpress.excellentenchants.api.enchantment;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Set;
public interface Definition {
boolean hasConflicts();
@NotNull String getDisplayName();
@NotNull List<String> getDescription();
/**
* Items on which this enchantment can be applied using an anvil or using the /enchant command.
*/
@NotNull ItemsCategory getSupportedItems();
/**
* Items for which this enchantment appears in an enchanting table.
*/
@NotNull ItemsCategory getPrimaryItems();
@NotNull Set<String> getConflicts();
@NotNull Rarity getRarity();
int getMaxLevel();
@NotNull Cost getMinCost();
@NotNull Cost getMaxCost();
int getAnvilCost();
}

View File

@ -0,0 +1,22 @@
package su.nightexpress.excellentenchants.api.enchantment;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public interface Distribution {
boolean isTreasure();
boolean isDiscoverable();
boolean isTradable();
@NotNull Set<TradeType> getTrades();
boolean isOnMobSpawnEquipment();
boolean isOnRandomLoot();
boolean isOnTradedEquipment();
}

View File

@ -1,201 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.distribution.DistributionOptions;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.placeholder.PlaceholderMap;
import java.util.List;
import java.util.Set;
public interface EnchantmentData {
default void clear() {
}
@NotNull PlaceholderMap getPlaceholders(int level);
@NotNull FileConfig getConfig();
boolean load();
boolean checkServerRequirements();
boolean isAvailableToUse(@NotNull LivingEntity entity);
boolean isAvailableToUse(@NotNull World world);
boolean checkEnchantLimit(@NotNull ItemStack item);
default boolean isSupportedItem(@NotNull ItemStack itemStack) {
return this.getSupportedItems().is(itemStack);
}
default boolean isPrimaryItem(@NotNull ItemStack itemStack) {
return this.getPrimaryItems().is(itemStack);
}
/**
* Items on which this enchantment can be applied using an anvil or using the /enchant command.
*/
@NotNull ItemsCategory getSupportedItems();
/**
* Items for which this enchantment appears in an enchanting table.
*/
@NotNull default ItemsCategory getPrimaryItems() {
return this.getSupportedItems();
}
@NotNull DistributionOptions getDistributionOptions();
@NotNull Rarity getRarity();
void setRarity(@NotNull Rarity rarity);
@NotNull String getId();
@NotNull String getName();
@Deprecated
@NotNull
default String getNameFormatted(int level) {
return this.getNameFormatted(level, -1);
}
@Deprecated
@NotNull String getNameFormatted(int level, int charges);
@NotNull List<String> getDescription();
@NotNull List<String> getDescriptionFormatted();
@NotNull List<String> getDescriptionReplaced(int level);
@NotNull List<String> getDescriptionReplaced(int level, int charges);
@NotNull Enchantment getEnchantment();
void setEnchantment(@NotNull Enchantment enchantment);
default boolean hasConflicts() {
return !this.getConflicts().isEmpty();
}
@NotNull Set<String> getConflicts();
int getMaxLevel();
int getMinCost(int level);
int getMaxCost(int level);
default boolean isCurse() {
return false;
}
boolean isTreasure();
boolean hasVisualEffects();
boolean isChargesEnabled();
boolean isChargesCustomFuel();
int getChargesMax(int level);
int getChargesConsumeAmount(int level);
int getChargesRechargeAmount(int level);
@NotNull ItemStack getChargesFuel();
boolean isChargesFuel(@NotNull ItemStack item);
default int getCharges(@NotNull ItemStack item) {
ItemMeta meta = item.getItemMeta();
return meta == null ? 0 : this.getCharges(meta);
}
int getCharges(@NotNull ItemMeta meta);
void setCharges(@NotNull ItemStack item, int level, int amount);
boolean isFullOfCharges(@NotNull ItemStack item);
boolean isOutOfCharges(@NotNull ItemStack item);
void restoreCharges(@NotNull ItemStack item, int level);
void fuelCharges(@NotNull ItemStack item, int level);
void consumeCharges(@NotNull ItemStack item, int level);
void consumeChargesNoUpdate(@NotNull ItemStack item, int level);
void setDisplayName(@NotNull String displayName);
default void setDescription(@NotNull String... description) {
this.setDescription(Lists.newList(description));
}
void setDescription(@NotNull List<String> description);
boolean isHiddenFromList();
void setHiddenFromList(boolean hiddenFromList);
void setTreasure(boolean treasure);
void setMaxLevel(int levelMax);
@NotNull Cost getMinCost();
void setMinCost(@NotNull Cost minCost);
@NotNull Cost getMaxCost();
void setMaxCost(@NotNull Cost maxCost);
int getAnvilCost();
void setAnvilCost(int anvilCost);
default void setConflicts(@NotNull String... conflicts) {
this.setConflicts(Lists.newSet(conflicts));
}
void setConflicts(@NotNull Set<String> conflicts);
void setVisualEffects(boolean visualEffects);
void setChargesEnabled(boolean chargesEnabled);
void setChargesCustomFuel(boolean chargesCustomFuel);
@NotNull Modifier getChargesMax();
void setChargesMax(@NotNull Modifier chargesMax);
void setChargesFuel(@Nullable ItemStack chargesFuel);
@NotNull Modifier getChargesConsumeAmount();
void setChargesConsumeAmount(@NotNull Modifier chargesConsumeAmount);
@NotNull Modifier getChargesRechargeAmount();
void setChargesRechargeAmount(@NotNull Modifier chargesRechargeAmount);
}

View File

@ -1,54 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.nightcore.util.ItemUtil;
import java.util.function.Predicate;
@Deprecated
public enum ItemCategory {
HELMET(ItemUtil::isHelmet),
CHESTPLATE(ItemUtil::isChestplate),
LEGGINGS(ItemUtil::isLeggings),
BOOTS(ItemUtil::isBoots),
ELYTRA(item -> item.getType() == Material.ELYTRA),
SWORD(ItemUtil::isSword),
TRIDENT(ItemUtil::isTrident),
AXE(ItemUtil::isAxe),
BOW(item -> item.getType() == Material.BOW),
CROSSBOW(item -> item.getType() == Material.CROSSBOW),
HOE(ItemUtil::isHoe),
PICKAXE(ItemUtil::isPickaxe),
SHOVEL(ItemUtil::isShovel),
FISHING_ROD(ItemUtil::isFishingRod),
SHIELD(itemStack -> itemStack.getType() == Material.SHIELD),
//@Deprecated WEAPON(item -> SWORD.isIncluded(item) || TRIDENT.isIncluded(item)),
TOOL(ItemUtil::isTool),
//@Deprecated ARMOR(ItemUtil::isArmor),
//UNIVERSAL(item -> WEAPON.isIncluded(item) || TOOL.isIncluded(item) || ARMOR.isIncluded(item)),
;
private Predicate<ItemStack> predicate;
ItemCategory(@NotNull Predicate<ItemStack> predicate) {
this.setPredicate(predicate);
}
@NotNull
public Predicate<ItemStack> getPredicate() {
return predicate;
}
public void setPredicate(@NotNull Predicate<ItemStack> predicate) {
this.predicate = predicate;
}
public boolean isIncluded(@NotNull ItemStack item) {
return this.getPredicate().test(item);
}
}

View File

@ -2,7 +2,6 @@ package su.nightexpress.excellentenchants.api.enchantment;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
@ -19,13 +18,13 @@ public class ItemsCategory {
private final Supplier<Set<Material>> supplier;
private final EquipmentSlot[] slots;
private final EnchantmentTarget target;
// private final EnchantmentTarget target;
private final String localized;
public ItemsCategory(@NotNull Supplier<Set<Material>> supplier, EquipmentSlot[] slots, @Nullable EnchantmentTarget target, @Nullable String localized) {
public ItemsCategory(@NotNull Supplier<Set<Material>> supplier, EquipmentSlot[] slots/*, @Nullable EnchantmentTarget target*/, @Nullable String localized) {
this.supplier = supplier;
this.slots = slots;
this.target = target;
// this.target = target;
this.localized = localized;
}
@ -63,47 +62,22 @@ public class ItemsCategory {
return slots;
}
/**
* Only for compatibility reasons with versions < 1.21
*/
public EnchantmentTarget getTarget() {
return target;
}
// /**
// * Only for compatibility reasons with versions < 1.21
// */
// public EnchantmentTarget getTarget() {
// return target;
// }
public String getLocalized() {
return localized;
}
/*@NotNull
public static ItemsCategory create(@NotNull Set<Material> materials, EquipmentSlot... slots) {
return new ItemsCategory(() -> materials);
}
@NotNull
public static ItemsCategory create(Material... materials) {
return create(Stream.of(materials).collect(Collectors.toSet()));
}
@SafeVarargs
@NotNull
public static ItemsCategory create(Tag<Material>... tags) {
return create(Stream.of(tags).flatMap(tag -> tag.getValues().stream()).collect(Collectors.toSet()));
}*/
// @NotNull
// @Deprecated
// public static ItemsCategory fusion(ItemsCategory... categories) {
// Set<Supplier<Set<Material>>> suppliers = Stream.of(categories).map(category -> category.supplier).collect(Collectors.toSet());
// Supplier<Set<Material>> result = () -> suppliers.stream().flatMap(supplier -> supplier.get().stream()).collect(Collectors.toSet());
//
// return new ItemsCategory(result, categories[0].getSlots(), categories[0].target, categories[0].localized);
// }
public static class Builder {
private Supplier<Set<Material>> supplier;
private EquipmentSlot[] slots;
private EnchantmentTarget target;
// private EnchantmentTarget target;
private String localized;
public Builder() {
@ -113,7 +87,7 @@ public class ItemsCategory {
@NotNull
public ItemsCategory build() {
return new ItemsCategory(this.supplier, this.slots, this.target, this.localized);
return new ItemsCategory(this.supplier, this.slots, /*this.target,*/ this.localized);
}
@NotNull
@ -128,11 +102,12 @@ public class ItemsCategory {
return this;
}
@NotNull
public Builder target(EnchantmentTarget target) {
this.target = target;
return this;
}
// @NotNull
// @Deprecated
// public Builder target(EnchantmentTarget target) {
// this.target = target;
// return this;
// }
@NotNull
public Builder localized(@NotNull LangString localized) {

View File

@ -1,41 +1,17 @@
package su.nightexpress.excellentenchants.api.enchantment;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.nightcore.util.random.Rnd;
import su.nightexpress.nightcore.config.FileConfig;
import java.util.HashMap;
import java.util.Map;
public interface Rarity {
@Deprecated
public enum Rarity {
void write(@NotNull FileConfig config, @NotNull String path);
COMMON(10),
UNCOMMON(5),
RARE(2),
VERY_RARE(1);
@NotNull String getId();
private int weight;
@NotNull String getName();
Rarity(int weight) {
this.weight = weight;
}
@NotNull String getNameFormat();
public int getWeight() {
return this.weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@NotNull
public static Rarity getByWeight() {
Map<Rarity, Double> map = new HashMap<>();
for (Rarity rarity : Rarity.values()) {
map.put(rarity, (double) rarity.getWeight());
}
return Rnd.getByWeight(map);
}
int getWeight();
}

View File

@ -0,0 +1,19 @@
package su.nightexpress.excellentenchants.api.enchantment;
public enum TradeType {
DESERT_COMMON,
DESERT_SPECIAL,
PLAINS_COMMON,
PLAINS_SPECIAL,
SAVANNA_COMMON,
SAVANNA_SPECIAL,
JUNGLE_COMMON,
JUNGLE_SPECIAL,
SNOW_COMMON,
SNOW_SPECIAL,
SWAMP_COMMON,
SWAMP_SPECIAL,
TAIGA_COMMON,
TAIGA_SPECIAL
;
}

View File

@ -0,0 +1,24 @@
package su.nightexpress.excellentenchants.api.enchantment.bridge;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.nightcore.util.Pair;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public interface FlameWalker {
Map<Location, Pair<Long, Integer>> MAGMA_BLOCKS = new ConcurrentHashMap<>();
static void addBlock(@NotNull Block block, double seconds) {
MAGMA_BLOCKS.put(block.getLocation(), Pair.of(System.currentTimeMillis() + (long) seconds * 1000L, Rnd.get(1000)));
}
@NotNull Modifier getRadius();
double getBlockDecayTime(int level);
}

View File

@ -1,14 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.data;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
public interface ArrowData {
@NotNull ArrowSettings getArrowSettings();
@NotNull
default UniParticle getProjectileTrail() {
return this.getArrowSettings().getProjectileTrail();
}
}

View File

@ -1,9 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.data;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
public interface ArrowSettings {
@NotNull UniParticle getProjectileTrail();
}

View File

@ -1,21 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.data;
import org.jetbrains.annotations.NotNull;
public interface ChanceData {
@NotNull ChanceSettings getChanceSettings();
/*@NotNull
default UnaryOperator<String> replacePlaceholders(int level) {
return this.getChanceImplementation().replacePlaceholders(level);
}*/
default double getTriggerChance(int level) {
return this.getChanceSettings().getTriggerChance(level);
}
default boolean checkTriggerChance(int level) {
return getChanceSettings().checkTriggerChance(level);
}
}

View File

@ -1,8 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.data;
public interface ChanceSettings {
double getTriggerChance(int level);
boolean checkTriggerChance(int level);
}

View File

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

View File

@ -1,12 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.data;
public interface PeriodicSettings {
long getInterval();
long getNextTriggerTime();
boolean isTriggerTime();
void updateTriggerTime();
}

View File

@ -1,35 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.data;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
public interface PotionData {
@NotNull PotionSettings getPotionSettings();
default boolean isPermanent() {
return this.getPotionSettings().isPermanent();
}
default PotionEffectType getEffectType() {
return this.getPotionSettings().getEffectType();
}
default int getEffectAmplifier(int level) {
return this.getPotionSettings().getEffectAmplifier(level);
}
default int getEffectDuration(int level) {
return this.getPotionSettings().getEffectDuration(level);
}
default PotionEffect createEffect(int level) {
return this.getPotionSettings().createEffect(level);
}
default boolean addEffect(@NotNull LivingEntity target, int level) {
return this.getPotionSettings().addEffect(target, level);
}
}

View File

@ -1,21 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.data;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
public interface PotionSettings {
boolean isPermanent();
PotionEffectType getEffectType();
int getEffectAmplifier(int level);
int getEffectDuration(int level);
PotionEffect createEffect(int level);
boolean addEffect(@NotNull LivingEntity target, int level);
}

View File

@ -1,10 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.distribution;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.nightcore.config.FileConfig;
@Deprecated
public interface DistributionOptions {
void load(@NotNull FileConfig config);
}

View File

@ -1,12 +0,0 @@
package su.nightexpress.excellentenchants.api.enchantment.distribution;
public interface VanillaOptions extends DistributionOptions {
boolean isDiscoverable();
void setDiscoverable(boolean discoverable);
boolean isTradeable();
void setTradeable(boolean tradeable);
}

View File

@ -1,29 +1,26 @@
package su.nightexpress.excellentenchants.enchantment.data;
package su.nightexpress.excellentenchants.api.enchantment.meta;
import org.bukkit.Particle;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowSettings;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
public class ArrowSettingsImpl implements ArrowSettings {
public class ArrowEffects {
//private final EnchantmentData enchantmentData;
private final UniParticle trailParticle;
private ArrowSettingsImpl(@NotNull UniParticle trailParticle) {
//this.enchantmentData = enchantmentData;
private ArrowEffects(@NotNull UniParticle trailParticle) {
this.trailParticle = trailParticle;
}
@NotNull
public static ArrowSettingsImpl create(@NotNull FileConfig config) {
return create(config, UniParticle.of(Particle.REDSTONE));
public static ArrowEffects create(@NotNull FileConfig config) {
return create(config, UniParticle.of(Particle.CLOUD));
}
@NotNull
public static ArrowSettingsImpl create(@NotNull FileConfig config, @NotNull UniParticle particle) {
public static ArrowEffects create(@NotNull FileConfig config, @NotNull UniParticle particle) {
UniParticle effect = ConfigValue.create("Settings.VisualEffects.Trail",
(cfg, path, def) -> UniParticle.read(cfg, path),
(cfg, path, particle1) -> particle1.write(cfg, path),
@ -31,10 +28,9 @@ public class ArrowSettingsImpl implements ArrowSettings {
"Sets projectile particle trail effect."
).read(config);
return new ArrowSettingsImpl(effect);
return new ArrowEffects(effect);
}
@Override
@NotNull
public UniParticle getProjectileTrail() {
return this.trailParticle;

View File

@ -0,0 +1,12 @@
package su.nightexpress.excellentenchants.api.enchantment.meta;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
public interface ArrowMeta extends MetaHolder {
@NotNull
default UniParticle getProjectileTrail() {
return this.getMeta().getArrowEffects().getProjectileTrail();
}
}

View File

@ -0,0 +1,12 @@
package su.nightexpress.excellentenchants.api.enchantment.meta;
public interface ChanceMeta extends MetaHolder {
default double getTriggerChance(int level) {
return this.getMeta().getProbability().getTriggerChance(level);
}
default boolean checkTriggerChance(int level) {
return this.getMeta().getProbability().checkTriggerChance(level);
}
}

View File

@ -0,0 +1,45 @@
package su.nightexpress.excellentenchants.api.enchantment.meta;
public class EnchantMeta {
private Probability probability;
private PotionEffects potionEffects;
private ArrowEffects arrowEffects;
private Period period;
public EnchantMeta() {
}
public Probability getProbability() {
return probability;
}
public void setProbability(Probability probability) {
this.probability = probability;
}
public PotionEffects getPotionEffects() {
return potionEffects;
}
public void setPotionEffects(PotionEffects potionEffects) {
this.potionEffects = potionEffects;
}
public ArrowEffects getArrowEffects() {
return arrowEffects;
}
public void setArrowEffects(ArrowEffects arrowEffects) {
this.arrowEffects = arrowEffects;
}
public Period getPeriod() {
return period;
}
public void setPeriod(Period period) {
this.period = period;
}
}

View File

@ -0,0 +1,8 @@
package su.nightexpress.excellentenchants.api.enchantment.meta;
import org.jetbrains.annotations.NotNull;
public interface MetaHolder {
@NotNull EnchantMeta getMeta();
}

View File

@ -0,0 +1,48 @@
package su.nightexpress.excellentenchants.api.enchantment.meta;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.ConfigBridge;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
public class Period {
private final long interval;
private long waitTicks;
public Period(long interval) {
this.interval = interval;
this.updateTriggerTime();
}
@NotNull
public static Period create(@NotNull FileConfig config) {
long baseTick = ConfigBridge.getEnchantsTickInterval();
long interval = ConfigValue.create("Settings.Trigger-Interval",
baseTick,
"Sets how often (in ticks) this enchantment will be triggered.",
"20 ticks = 1 second."
).read(config);
return new Period(interval);
}
public long getInterval() {
return this.interval;
}
public void consumeTicks() {
this.waitTicks -= ConfigBridge.getEnchantsTickInterval();
}
public boolean isTriggerTime() {
return this.waitTicks <= 0;
}
public void updateTriggerTime() {
if (this.waitTicks <= 0) {
this.waitTicks = this.getInterval();
}
}
}

View File

@ -0,0 +1,20 @@
package su.nightexpress.excellentenchants.api.enchantment.meta;
public interface PeriodMeta extends MetaHolder {
default long getInterval() {
return this.getMeta().getPeriod().getInterval();
}
default void consumeTicks() {
this.getMeta().getPeriod().consumeTicks();
}
default boolean isTriggerTime() {
return this.getMeta().getPeriod().isTriggerTime();
}
default void updateTriggerTime() {
this.getMeta().getPeriod().updateTriggerTime();
}
}

View File

@ -1,37 +1,36 @@
package su.nightexpress.excellentenchants.enchantment.data;
package su.nightexpress.excellentenchants.api.enchantment.meta;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.ConfigBridge;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
import su.nightexpress.nightcore.config.FileConfig;
public class PotionSettingsImpl implements PotionSettings {
public class PotionEffects {
private final PotionEffectType effectType;
private final Modifier duration;
private final Modifier amplifier;
private final boolean isPermanent;
private final boolean particles;
private final boolean permanent;
private final boolean particles;
private PotionSettingsImpl(@NotNull PotionEffectType effectType,
boolean isPermanent,
boolean particles,
@NotNull Modifier duration,
@NotNull Modifier amplifier) {
private PotionEffects(@NotNull PotionEffectType effectType,
boolean permanent,
boolean particles,
@NotNull Modifier duration,
@NotNull Modifier amplifier) {
this.effectType = effectType;
this.duration = duration;
this.amplifier = amplifier;
this.isPermanent = isPermanent;
this.permanent = permanent;
this.particles = particles;
}
@NotNull
public static PotionSettingsImpl create(@NotNull EnchantmentData data, @NotNull FileConfig config, @NotNull PotionEffectType type, boolean isPermanent) {
public static PotionEffects create(@NotNull CustomEnchantment data, @NotNull FileConfig config, @NotNull PotionEffectType type, boolean isPermanent) {
return create(data, config, type, isPermanent,
Modifier.multiply(5, 1, 1),
Modifier.add(0, 1, 1, 5)
@ -39,12 +38,12 @@ public class PotionSettingsImpl implements PotionSettings {
}
@NotNull
public static PotionSettingsImpl create(@NotNull EnchantmentData data,
@NotNull FileConfig config,
@NotNull PotionEffectType type,
boolean isPermanent,
@NotNull Modifier duration,
@NotNull Modifier amplifier) {
public static PotionEffects create(@NotNull CustomEnchantment data,
@NotNull FileConfig config,
@NotNull PotionEffectType type,
boolean isPermanent,
@NotNull Modifier duration,
@NotNull Modifier amplifier) {
Modifier durationScale = Modifier.read(config, "Settings.Potion_Effect.Duration", duration,
"Potion effect duration (in seconds). This setting is useless for 'permanent' effects.");
@ -52,24 +51,21 @@ public class PotionSettingsImpl implements PotionSettings {
Modifier amplifierScale = Modifier.read(config, "Settings.Potion_Effect.Level", amplifier,
"Potion effect level.");
return new PotionSettingsImpl(type, isPermanent, data.hasVisualEffects(), durationScale, amplifierScale);
return new PotionEffects(type, isPermanent, data.hasVisualEffects(), durationScale, amplifierScale);
}
@Override
public boolean isPermanent() {
return this.isPermanent;
return this.permanent;
}
@Override
@NotNull
public PotionEffectType getEffectType() {
return this.effectType;
}
@Override
public int getEffectDuration(int level) {
if (this.isPermanent()) {
int duration = Config.CORE_PASSIVE_ENCHANTS_TRIGGER_INTERVAL.get().intValue() * 2;
int duration = ConfigBridge.getEnchantsTickInterval() * 2;
if (this.getEffectType().getKey().equals(PotionEffectType.NIGHT_VISION.getKey()) && duration < 600) {
duration += 30 * 20;
}
@ -78,12 +74,10 @@ public class PotionSettingsImpl implements PotionSettings {
return (int) (this.duration.getValue(level) * 20);
}
@Override
public int getEffectAmplifier(int level) {
return (int) this.amplifier.getValue(level);
}
@Override
@NotNull
public PotionEffect createEffect(int level) {
int duration = this.getEffectDuration(level);
@ -92,7 +86,6 @@ public class PotionSettingsImpl implements PotionSettings {
return new PotionEffect(this.getEffectType(), duration, amplifier, false, this.particles);
}
@Override
public boolean addEffect(@NotNull LivingEntity target, int level) {
target.addPotionEffect(this.createEffect(level));
return true;

View File

@ -0,0 +1,33 @@
package su.nightexpress.excellentenchants.api.enchantment.meta;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
public interface PotionMeta extends MetaHolder {
default boolean isPermanent() {
return this.getMeta().getPotionEffects().isPermanent();
}
default PotionEffectType getEffectType() {
return this.getMeta().getPotionEffects().getEffectType();
}
default int getEffectAmplifier(int level) {
return this.getMeta().getPotionEffects().getEffectAmplifier(level);
}
default int getEffectDuration(int level) {
return this.getMeta().getPotionEffects().getEffectDuration(level);
}
default PotionEffect createEffect(int level) {
return this.getMeta().getPotionEffects().createEffect(level);
}
default boolean addEffect(@NotNull LivingEntity target, int level) {
return this.getMeta().getPotionEffects().addEffect(target, level);
}
}

View File

@ -1,38 +1,37 @@
package su.nightexpress.excellentenchants.enchantment.data;
package su.nightexpress.excellentenchants.api.enchantment.meta;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.random.Rnd;
public class ChanceSettingsImpl implements ChanceSettings {
public class Probability {
private final Modifier triggerChance;
private ChanceSettingsImpl(@NotNull Modifier triggerChance) {
private Probability(@NotNull Modifier triggerChance) {
this.triggerChance = triggerChance;
}
@NotNull
public static ChanceSettingsImpl create(@NotNull FileConfig config) {
public static Probability create(@NotNull FileConfig config) {
return create(config, Modifier.add(100, 0, 1, 100));
}
@NotNull
public static ChanceSettingsImpl create(@NotNull FileConfig config, @NotNull Modifier def) {
Modifier chanceMod = Modifier.read(config, "Settings.Trigger_Chance", def,
"A chance that this enchantment will be triggered.");
public static Probability create(@NotNull FileConfig config, @NotNull Modifier def) {
Modifier chanceMod = Modifier.read(config, "Settings.Trigger_Chance",
def,
"A chance that this enchantment will be triggered."
);
return new ChanceSettingsImpl(chanceMod);
return new Probability(chanceMod);
}
@Override
public double getTriggerChance(int level) {
return this.triggerChance.getValue(level);
}
@Override
public boolean checkTriggerChance(int level) {
return Rnd.chance(this.getTriggerChance(level));
}

View File

@ -5,9 +5,9 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface BlockBreakEnchant extends EnchantmentData {
public interface BlockBreakEnchant extends CustomEnchantment {
boolean onBreak(@NotNull BlockBreakEvent event, @NotNull LivingEntity player, @NotNull ItemStack item, int level);

View File

@ -5,9 +5,9 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface BlockDropEnchant extends EnchantmentData {
public interface BlockDropEnchant extends CustomEnchantment {
boolean onDrop(@NotNull BlockDropItemEvent event, @NotNull LivingEntity player, @NotNull ItemStack item, int level);

View File

@ -8,9 +8,9 @@ import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface BowEnchant extends EnchantmentData {
public interface BowEnchant extends CustomEnchantment {
boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level);

View File

@ -5,9 +5,9 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface CombatEnchant extends EnchantmentData {
public interface CombatEnchant extends CustomEnchantment {
boolean onAttack(@NotNull EntityDamageByEntityEvent event,
@NotNull LivingEntity damager, @NotNull LivingEntity victim,

View File

@ -5,9 +5,9 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface DamageEnchant extends EnchantmentData {
public interface DamageEnchant extends CustomEnchantment {
boolean onDamage(@NotNull EntityDamageEvent event, @NotNull LivingEntity entity, @NotNull ItemStack item, int level);

View File

@ -7,9 +7,9 @@ import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityResurrectEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface DeathEnchant extends EnchantmentData {
public interface DeathEnchant extends CustomEnchantment {
boolean onDeath(@NotNull EntityDeathEvent event, @NotNull LivingEntity entity, ItemStack item, int level);

View File

@ -4,9 +4,9 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface FishingEnchant extends EnchantmentData {
public interface FishingEnchant extends CustomEnchantment {
boolean onFishing(@NotNull PlayerFishEvent event, @NotNull ItemStack item, int level);

View File

@ -1,7 +1,7 @@
package su.nightexpress.excellentenchants.api.enchantment.type;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface GenericEnchant extends EnchantmentData {
public interface GenericEnchant extends CustomEnchantment {
}

View File

@ -5,9 +5,9 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
public interface InteractEnchant extends EnchantmentData {
public interface InteractEnchant extends CustomEnchantment {
boolean onInteract(@NotNull PlayerInteractEvent event, @NotNull LivingEntity entity, @NotNull ItemStack item, int level);

View File

@ -3,10 +3,10 @@ package su.nightexpress.excellentenchants.api.enchantment.type;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicData;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.meta.PeriodMeta;
public interface PassiveEnchant extends EnchantmentData, PeriodicData {
public interface PassiveEnchant extends CustomEnchantment, PeriodMeta {
boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level);
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.1.0</version>
<version>4.2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -18,92 +18,81 @@
</properties>
<repositories>
<repository>
<id>md_5-releases</id>
<url>https://repo.md-5.net/content/repositories/releases/</url>
</repository>
<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>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20.4-R0.1-SNAPSHOT</version>
<version>1.21.1-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.lumine</groupId>
<artifactId>Mythic-Dist</artifactId>
<version>5.6.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.1.0</version>
<version>5.3.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>API</artifactId>
<version>4.1.0</version>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>4.1.0</version>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>MC_1_21</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>MC_1_20_6</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R3</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R2</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R1</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R3</artifactId>
<version>4.1.0</version>
<version>4.2.0</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,31 @@
package su.nightexpress.excellentenchants;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
import su.nightexpress.excellentenchants.rarity.RarityManager;
public class EnchantsAPI {
private static EnchantsPlugin plugin;
static void load(@NotNull EnchantsPlugin plugin) {
EnchantsAPI.plugin = plugin;
}
@NotNull
private static EnchantsPlugin plugin() {
if (plugin == null) throw new IllegalStateException("API is not initialized!");
return plugin;
}
@NotNull
public static EnchantManager getEnchantManager() {
return plugin().getEnchantManager();
}
@NotNull
public static RarityManager getRarityManager() {
return plugin().getRarityManager();
}
}

View File

@ -4,35 +4,29 @@ import org.bukkit.entity.Item;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.DistributionWay;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.command.*;
import su.nightexpress.excellentenchants.api.ConfigBridge;
import su.nightexpress.excellentenchants.command.BaseCommands;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.config.Keys;
import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.excellentenchants.config.Perms;
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
import su.nightexpress.excellentenchants.enchantment.EnchantPopulator;
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.excellentenchants.hook.HookPlugin;
import su.nightexpress.excellentenchants.hook.impl.PlaceholderHook;
import su.nightexpress.excellentenchants.hook.impl.ProtocolLibHook;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import su.nightexpress.excellentenchants.nms.v1_19_R3.V1_19_R3;
import su.nightexpress.excellentenchants.nms.v1_20_R1.V1_20_R1;
import su.nightexpress.excellentenchants.nms.v1_20_R2.V1_20_R2;
import su.nightexpress.excellentenchants.nms.v1_20_R3.V1_20_R3;
import su.nightexpress.excellentenchants.rarity.RarityManager;
import su.nightexpress.excellentenchants.registry.EnchantRegistry;
import su.nightexpress.nightcore.NightPlugin;
import su.nightexpress.nightcore.command.api.NightPluginCommand;
import su.nightexpress.nightcore.command.base.ReloadSubCommand;
import su.nightexpress.nightcore.command.experimental.ImprovedCommands;
import su.nightexpress.nightcore.config.PluginDetails;
import su.nightexpress.nightcore.util.Plugins;
import su.nightexpress.nightcore.util.Version;
public class EnchantsPlugin extends NightPlugin {
public class EnchantsPlugin extends NightPlugin implements ImprovedCommands {
private EnchantRegistry registry;
private RarityManager rarityManager;
private EnchantManager enchantManager;
private EnchantNMS enchantNMS;
@ -40,13 +34,12 @@ public class EnchantsPlugin extends NightPlugin {
public void onLoad() {
super.onLoad();
this.registry = new EnchantRegistry(this);
EnchantUtils.hook(this);
}
@Override
@NotNull
protected PluginDetails getDefaultDetails() {
return PluginDetails.create("Enchants", new String[]{"excellentenchants", "eenchants"})
return PluginDetails.create("Enchants", new String[]{"eenchants", "excellentenchants"})
.setConfigClass(Config.class)
.setLangClass(Lang.class)
.setPermissionsClass(Perms.class);
@ -54,98 +47,73 @@ public class EnchantsPlugin extends NightPlugin {
@Override
public void enable() {
if (!this.setNMS()) {
if (!this.loadInternals()) {
this.error("Unsupported server version!");
this.getPluginManager().disablePlugin(this);
return;
}
//this.getLangManager().loadEnum(ItemCategory.class);
//this.getLangManager().loadEnum(EnchantmentTarget.class);
this.getLangManager().loadEnum(DistributionWay.class);
this.getLangManager().loadEnum(Rarity.class);
this.loadAPI();
this.loadCommands();
Keys.loadKeys(this);
Config.loadRarityWeights(this.getConfig());
this.registerCommands();
this.rarityManager = new RarityManager(this);
this.rarityManager.setup();
this.registry.setup();
this.enchantManager = new EnchantManager(this);
this.enchantManager.setup();
if (Plugins.isInstalled(HookPlugin.PROTOCOL_LIB)) {
ProtocolLibHook.setup(this);
}
else {
this.warn(HookPlugin.PROTOCOL_LIB + " is not installed. Enchantment descriptions won't be displayed.");
this.loadHooks();
}
@Override
public void disable() {
if (Plugins.hasPlaceholderAPI()) {
PlaceholderHook.shutdown();
}
/*if (Config.ENCHANTMENTS_DISPLAY_MODE.get() == 2) {
if (this.enchantManager != null) this.enchantManager.shutdown();
if (this.rarityManager != null) this.rarityManager.shutdown();
this.registry.shutdown();
}
private boolean loadInternals() {
if (Version.getCurrent() == Version.MC_1_21) {
this.enchantNMS = new Internal_1_21(this);
return true;
}
return false;
}
private void loadCommands() {
BaseCommands.load(this);
}
private void loadAPI() {
EnchantsAPI.load(this);
Keys.loadKeys(this);
ConfigBridge.setEnchantsTickInterval(Config.CORE_PASSIVE_ENCHANTS_TRIGGER_INTERVAL.get().intValue());
}
private void loadHooks() {
if (Config.isDescriptionEnabled()) {
if (Plugins.isInstalled(HookPlugin.PROTOCOL_LIB)) {
ProtocolLibHook.setup(this);
}
else {
this.warn(HookPlugin.PROTOCOL_LIB + " is not installed. Display mode is set to Plain lore.");
Config.ENCHANTMENTS_DISPLAY_MODE.set(1);
this.warn(HookPlugin.PROTOCOL_LIB + " is not installed. Enchantment descriptions won't display.");
}
}*/
}
if (Plugins.hasPlaceholderAPI()) {
PlaceholderHook.setup(this);
}
}
@Override
public void disable() {
if (this.enchantManager != null) {
this.enchantManager.shutdown();
this.enchantManager = null;
}
if (Plugins.hasPlaceholderAPI()) {
PlaceholderHook.shutdown();
}
this.registry.shutdown();
}
private boolean setNMS() {
this.enchantNMS = switch (Version.getCurrent()) {
case V1_19_R3 -> new V1_19_R3();
case V1_20_R1 -> new V1_20_R1();
case V1_20_R2 -> new V1_20_R2();
case V1_20_R3 -> new V1_20_R3();
case MC_1_20_6 -> new Internal1_20_6();
case MC_1_21 -> new Internal_1_21(this);
default -> null;
};
return this.enchantNMS != null;
}
private void registerCommands() {
NightPluginCommand mainCommand = this.getBaseCommand();
mainCommand.addChildren(new BookCommand(this));
mainCommand.addChildren(new EnchantCommand(this));
mainCommand.addChildren(new ListCommand(this));
mainCommand.addChildren(new RarityBookCommand(this));
mainCommand.addChildren(new ReloadSubCommand(this, Perms.COMMAND_RELOAD));
if (Config.ENCHANTMENTS_CHARGES_ENABLED.get()) {
mainCommand.addChildren(new GetFuelCommand(this));
}
}
@NotNull
public EnchantPopulator createPopulator(@NotNull ItemStack item, @NotNull DistributionWay distributionWay) {
return new EnchantPopulator(this, item, distributionWay);
}
public void populateResource(@NotNull BlockDropItemEvent event, @NotNull ItemStack itemStack) {
/*if (Plugins.isSpigot()) {
this.warn("Adding items to BlockDropItemEvent is not supported in Spigot, please use Paper or its forks for this feature.");
return;
}*/
Item item = this.getEnchantNMS().popResource(event.getBlock(), itemStack);
event.getItems().add(item);
}
@ -155,6 +123,11 @@ public class EnchantsPlugin extends NightPlugin {
return registry;
}
@NotNull
public RarityManager getRarityManager() {
return rarityManager;
}
@NotNull
public EnchantManager getEnchantManager() {
return this.enchantManager;

View File

@ -1,23 +1,28 @@
package su.nightexpress.excellentenchants;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PeriodMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
import su.nightexpress.excellentenchants.util.EnchantPlaceholders;
import su.nightexpress.nightcore.language.LangAssets;
import su.nightexpress.nightcore.util.ItemUtil;
import su.nightexpress.nightcore.util.NumberUtil;
public class Placeholders extends su.nightexpress.nightcore.util.Placeholders {
public static final String URL_WIKI = "https://nightexpress.gitbook.io/excellentenchants";
public static final String URL_PLACEHOLDERS = "https://nightexpress.gitbook.io/excellentenchants/utility/placeholders";
public static final String URL_CHRAGES = "https://nightexpress.gitbook.io/excellentenchants/features/charges";
public static final String VANILLA_DISTRIBUTION_NAME = "Vanilla Distribution Mode";
public static final String CUSTOM_DISTRIBUTION_NAME = "Custom Distribution Mode";
public static final String VANILLA_DISTRIBUTION_HEADER = "=".repeat(15) + " " + VANILLA_DISTRIBUTION_NAME + " " + "=".repeat(15);
public static final String CUSTOM_DISTRIBUTION_HEADER = "=".repeat(15) + " " + CUSTOM_DISTRIBUTION_NAME + " " + "=".repeat(15);
public static final String WIKI_URL = "https://nightexpress.gitbook.io/excellentenchants/";
public static final String WIKI_PLACEHOLDERS = WIKI_URL + "utility/placeholders";
public static final String WIKI_CHRAGES = WIKI_URL + "features/charges";
public static final String GENERIC_TYPE = "%type%";
public static final String GENERIC_NAME = "%name%";
public static final String GENERIC_ITEM = "%item%";
public static final String GENERIC_LEVEL = "%level%";
public static final String GENERIC_AMOUNT = "%amount%";
public static final String GENERIC_MODIFIER = "%modifier%";
public static final String GENERIC_CHARGES = "%charges%";
public static final String GENERIC_MODIFIER = "%modifier%";
public static final String GENERIC_DESCRIPTION = "%description%";
public static final String GENERIC_ENCHANT = "%enchant%";
public static final String GENERIC_RADIUS = "%radius%";
@ -34,24 +39,54 @@ public class Placeholders extends su.nightexpress.nightcore.util.Placeholders {
public static final String ENCHANTMENT_POTION_TYPE = "%enchantment_potion_type%";
public static final String ENCHANTMENT_ID = "%enchantment_id%";
public static final String ENCHANTMENT_NAME = "%enchantment_name%";
public static final String ENCHANTMENT_NAME_FORMATTED = "%enchantment_name_formatted%";
public static final String ENCHANTMENT_DESCRIPTION = "%enchantment_description%";
public static final String ENCHANTMENT_DESCRIPTION_FORMATTED = "%enchantment_description_formatted%";
//public static final String ENCHANTMENT_DESCRIPTION_FORMATTED = "%enchantment_description_formatted%";
public static final String ENCHANTMENT_DESCRIPTION_REPLACED = "%enchantment_description_replaced%";
public static final String ENCHANTMENT_LEVEL = "%enchantment_level%";
public static final String ENCHANTMENT_LEVEL_MIN = "%enchantment_level_min%";
public static final String ENCHANTMENT_LEVEL_MAX = "%enchantment_level_max%";
public static final String ENCHANTMENT_RARITY = "%enchantment_rarity%";
public static final String ENCHANTMENT_FIT_ITEM_TYPES = "%enchantment_fit_item_types%";
public static final String ENCHANTMENT_OBTAIN_CHANCE_ENCHANTING = "%enchantment_obtain_chance_enchanting%";
public static final String ENCHANTMENT_OBTAIN_CHANCE_VILLAGER = "%enchantment_obtain_chance_villager%";
public static final String ENCHANTMENT_OBTAIN_CHANCE_LOOT_GENERATION = "%enchantment_obtain_chance_loot_generation%";
public static final String ENCHANTMENT_OBTAIN_CHANCE_FISHING = "%enchantment_obtain_chance_fishing%";
public static final String ENCHANTMENT_OBTAIN_CHANCE_MOB_SPAWNING = "%enchantment_obtain_chance_mob_spawning%";
public static final String ENCHANTMENT_CHARGES = "%enchantment_charges%";
public static final String ENCHANTMENT_CHARGES_MAX_AMOUNT = "%enchantment_charges_max_amount%";
public static final String ENCHANTMENT_CHARGES_CONSUME_AMOUNT = "%enchantment_charges_consume_amount%";
public static final String ENCHANTMENT_CHARGES_RECHARGE_AMOUNT = "%enchantment_charges_recharge_amount%";
public static final String ENCHANTMENT_CHARGES_FUEL_ITEM = "%enchantment_charges_fuel_item%";
public static EnchantPlaceholders forEnchant(@NotNull GameEnchantment enchantment) {
EnchantPlaceholders placeholders = new EnchantPlaceholders();
placeholders
.add(ENCHANTMENT_ID, enchantment::getId)
.add(ENCHANTMENT_NAME, enchantment::getDisplayName)
.add(ENCHANTMENT_DESCRIPTION, () -> String.join("\n", enchantment.getDescription()))
//.add(ENCHANTMENT_DESCRIPTION_FORMATTED, () -> String.join("\n", enchantment.getDescriptionFormatted()))
.add(ENCHANTMENT_DESCRIPTION_REPLACED, level -> String.join("\n", enchantment.getDescription(level)))
.add(ENCHANTMENT_LEVEL, NumberUtil::toRoman)
.add(ENCHANTMENT_LEVEL_MIN, () -> String.valueOf(1))
.add(ENCHANTMENT_LEVEL_MAX, () -> String.valueOf(enchantment.getDefinition().getMaxLevel()))
.add(ENCHANTMENT_RARITY, () -> enchantment.getDefinition().getRarity().getName())
.add(ENCHANTMENT_FIT_ITEM_TYPES, () -> enchantment.getDefinition().getSupportedItems().getLocalized())
.add(ENCHANTMENT_CHARGES_MAX_AMOUNT, level -> NumberUtil.format(enchantment.getCharges().getMaxAmount(level)))
.add(ENCHANTMENT_CHARGES_CONSUME_AMOUNT, level -> NumberUtil.format(enchantment.getCharges().getConsumeAmount(level)))
.add(ENCHANTMENT_CHARGES_RECHARGE_AMOUNT, level -> NumberUtil.format(enchantment.getCharges().getRechargeAmount(level)))
.add(ENCHANTMENT_CHARGES_FUEL_ITEM, () -> ItemUtil.getItemName(enchantment.getCharges().getFuel()));
if (enchantment instanceof ChanceMeta chanceMeta) {
placeholders.add(ENCHANTMENT_CHANCE, level -> NumberUtil.format(chanceMeta.getTriggerChance(level)));
}
if (enchantment instanceof PeriodMeta periodMeta) {
placeholders.add(ENCHANTMENT_INTERVAL, () -> NumberUtil.format(periodMeta.getInterval() / 20D));
}
if (enchantment instanceof PotionMeta potionMeta) {
placeholders.add(ENCHANTMENT_POTION_LEVEL, level -> NumberUtil.toRoman(potionMeta.getEffectAmplifier(level)));
placeholders.add(ENCHANTMENT_POTION_DURATION, level -> NumberUtil.format(potionMeta.getEffectDuration(level) / 20D));
placeholders.add(ENCHANTMENT_POTION_TYPE, () -> LangAssets.get(potionMeta.getEffectType()));
}
return placeholders;
}
}

View File

@ -0,0 +1,209 @@
package su.nightexpress.excellentenchants.command;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.excellentenchants.config.Perms;
import su.nightexpress.excellentenchants.registry.EnchantRegistry;
import su.nightexpress.excellentenchants.util.EnchantUtils;
import su.nightexpress.nightcore.command.experimental.CommandContext;
import su.nightexpress.nightcore.command.experimental.argument.ArgumentTypes;
import su.nightexpress.nightcore.command.experimental.argument.ParsedArguments;
import su.nightexpress.nightcore.command.experimental.impl.ReloadCommand;
import su.nightexpress.nightcore.command.experimental.node.ChainedNode;
import su.nightexpress.nightcore.command.experimental.node.DirectNode;
import su.nightexpress.nightcore.util.*;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.Set;
public class BaseCommands {
public static void load(@NotNull EnchantsPlugin plugin) {
ChainedNode rootNode = plugin.getRootNode();
ReloadCommand.inject(plugin, rootNode, Perms.COMMAND_RELOAD);
rootNode.addChildren(DirectNode.builder(plugin, "book")
.description(Lang.COMMAND_BOOK_DESC)
.permission(Perms.COMMAND_BOOK)
.withArgument(CommandArguments.enchantArgument(CommandArguments.ENCHANT).required())
.withArgument(CommandArguments.levelArgument(CommandArguments.LEVEL))
.withArgument(ArgumentTypes.player(CommandArguments.PLAYER))
.executes((context, arguments) -> giveBook(plugin, context, arguments))
);
rootNode.addChildren(DirectNode.builder(plugin, "enchant")
.description(Lang.COMMAND_ENCHANT_DESC)
.permission(Perms.COMMAND_ENCHANT)
.withArgument(CommandArguments.enchantArgument(CommandArguments.ENCHANT).required())
.withArgument(CommandArguments.levelArgument(CommandArguments.LEVEL).required())
.withArgument(ArgumentTypes.player(CommandArguments.PLAYER))
.withArgument(CommandArguments.slotArgument(CommandArguments.SLOT))
.executes((context, arguments) -> enchantItem(plugin, context, arguments))
);
rootNode.addChildren(DirectNode.builder(plugin, "list")
.playerOnly()
.description(Lang.COMMAND_LIST_DESC)
.permission(Perms.COMMAND_LIST)
.withArgument(ArgumentTypes.player(CommandArguments.PLAYER).permission(Perms.COMMAND_LIST_OTHERS))
.executes((context, arguments) -> openList(plugin, context, arguments))
);
rootNode.addChildren(DirectNode.builder(plugin, "raritybook")
.description(Lang.COMMAND_RARITY_BOOK_DESC)
.permission(Perms.COMMAND_RARITY_BOOK)
.withArgument(CommandArguments.rarityArgument(plugin, CommandArguments.RARITY).required())
.withArgument(CommandArguments.levelArgument(CommandArguments.LEVEL))
.withArgument(ArgumentTypes.player(CommandArguments.PLAYER))
.executes((context, arguments) -> giveRarityBook(plugin, context, arguments))
);
if (Config.isChargesEnabled()) {
rootNode.addChildren(DirectNode.builder(plugin, "getfuel")
.playerOnly()
.description(Lang.COMMAND_GET_FUEL_DESC)
.permission(Perms.COMMAND_GET_FUEL)
.withArgument(CommandArguments.customEnchantArgument(CommandArguments.ENCHANT).required()
.withSamples(context -> EnchantRegistry.getRegistered().stream().filter(CustomEnchantment::hasCharges).map(CustomEnchantment::getId).toList())
)
.withArgument(ArgumentTypes.integerAbs(CommandArguments.AMOUNT).withSamples(context -> Lists.newList("1", "8", "16", "32", "64")))
.executes((context, arguments) -> giveFuel(plugin, context, arguments))
);
}
}
private static int getLevel(@NotNull Enchantment enchantment, @NotNull ParsedArguments arguments) {
int level = arguments.getIntArgument(CommandArguments.LEVEL, -1);
if (level < 1) {
level = EnchantUtils.randomLevel(enchantment);
}
return level;
}
public static boolean giveBook(@NotNull EnchantsPlugin plugin, @NotNull CommandContext context, @NotNull ParsedArguments arguments) {
Player player = CommandUtil.getPlayerOrSender(context, arguments, CommandArguments.PLAYER);
if (player == null) return false;
Enchantment enchantment = arguments.getEnchantmentArgument(CommandArguments.ENCHANT);
int level = getLevel(enchantment, arguments);
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
EnchantUtils.add(item, enchantment, level, true);
Players.addItem(player, item);
Lang.COMMAND_BOOK_DONE.getMessage()
.replace(Placeholders.GENERIC_ENCHANT, EnchantUtils.getLocalized(enchantment))
.replace(Placeholders.forPlayer(player))
.send(context.getSender());
return true;
}
public static boolean enchantItem(@NotNull EnchantsPlugin plugin, @NotNull CommandContext context, @NotNull ParsedArguments arguments) {
Player player = CommandUtil.getPlayerOrSender(context, arguments, CommandArguments.PLAYER);
if (player == null) return false;
EquipmentSlot slot = arguments.getArgument(CommandArguments.SLOT, EquipmentSlot.class, EquipmentSlot.HAND);
ItemStack item = player.getInventory().getItem(slot);
if (item == null || item.getType().isAir()) {
Lang.COMMAND_ENCHANT_ERROR_NO_ITEM.getMessage().send(context.getSender());
return false;
}
Enchantment enchantment = arguments.getEnchantmentArgument(CommandArguments.ENCHANT);
int level = getLevel(enchantment, arguments);
if (level > 0) {
EnchantUtils.add(item, enchantment, level, true);
}
else EnchantUtils.remove(item, enchantment);
//player.getInventory().setItem(slot, item);
(context.getSender() == player ? Lang.COMMAND_ENCHANT_DONE_SELF : Lang.COMMAND_ENCHANT_DONE_OTHERS).getMessage()
.replace(Placeholders.forPlayer(player))
.replace(Placeholders.GENERIC_ITEM, ItemUtil.getItemName(item))
.replace(Placeholders.GENERIC_ENCHANT, EnchantUtils.getLocalized(enchantment))
.replace(Placeholders.GENERIC_LEVEL, NumberUtil.toRoman(level))
.send(context.getSender());
return true;
}
public static boolean giveFuel(@NotNull EnchantsPlugin plugin, @NotNull CommandContext context, @NotNull ParsedArguments arguments) {
Player player = context.getPlayerOrThrow();
CustomEnchantment enchantment = arguments.getArgument(CommandArguments.ENCHANT, CustomEnchantment.class);
int amount = arguments.getIntArgument(CommandArguments.AMOUNT, 1);
if (!enchantment.hasCharges()) {
Lang.COMMAND_GET_FUEL_ERROR_NO_CHARGES.getMessage()
.replace(Placeholders.GENERIC_NAME, enchantment.getDisplayName())
.send(context.getSender());
return false;
}
ItemStack fuel = enchantment.getCharges().getFuel();
fuel.setAmount(amount);
Players.addItem(player, fuel);
Lang.COMMAND_GET_FUEL_DONE.getMessage()
.replace(Placeholders.GENERIC_AMOUNT, NumberUtil.format(amount))
.replace(Placeholders.GENERIC_NAME, ItemUtil.getItemName(fuel))
.send(context.getSender());
return true;
}
public static boolean openList(@NotNull EnchantsPlugin plugin, @NotNull CommandContext context, @NotNull ParsedArguments arguments) {
Player player = CommandUtil.getPlayerOrSender(context, arguments, CommandArguments.PLAYER);
if (player == null) return false;
plugin.getEnchantManager().openEnchantsMenu(player);
if (player != context.getSender()) {
Lang.COMMAND_LIST_DONE_OTHERS.getMessage().replace(Placeholders.forPlayer(player)).send(context.getSender());
}
return true;
}
public static boolean giveRarityBook(@NotNull EnchantsPlugin plugin, @NotNull CommandContext context, @NotNull ParsedArguments arguments) {
Player player = CommandUtil.getPlayerOrSender(context, arguments, CommandArguments.PLAYER);
if (player == null) return false;
Rarity rarity = arguments.getArgument(CommandArguments.RARITY, Rarity.class);
Set<CustomEnchantment> enchants = EnchantRegistry.getByRarity(rarity);
CustomEnchantment customEnchantment = enchants.isEmpty() ? null : Rnd.get(enchants);
if (customEnchantment == null) {
Lang.COMMAND_RARITY_BOOK_ERROR_EMPTY.getMessage().send(context.getSender());
return false;
}
Enchantment enchantment = customEnchantment.getBukkitEnchantment();
int level = getLevel(enchantment, arguments);
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
EnchantUtils.add(item, enchantment, level, true);
Players.addItem(player, item);
Lang.COMMAND_RARITY_BOOK_DONE.getMessage()
.replace(Placeholders.GENERIC_NAME, rarity.getName())
.replace(Placeholders.forPlayer(player))
.send(context.getSender());
return true;
}
}

View File

@ -1,80 +0,0 @@
package su.nightexpress.excellentenchants.command;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.config.Perms;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.nightcore.command.CommandResult;
import su.nightexpress.nightcore.command.impl.AbstractCommand;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Players;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.Arrays;
import java.util.List;
public class BookCommand extends AbstractCommand<EnchantsPlugin> {
public BookCommand(@NotNull EnchantsPlugin plugin) {
super(plugin, new String[]{"book"}, Perms.COMMAND_BOOK);
this.setDescription(Lang.COMMAND_BOOK_DESC);
this.setUsage(Lang.COMMAND_BOOK_USAGE);
}
@Override
@NotNull
public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (arg == 1) {
return Players.playerNames(player);
}
if (arg == 2) {
return BukkitThing.getEnchantments().stream().map(enchantment -> enchantment.getKey().getKey()).toList();
}
if (arg == 3) {
return Arrays.asList("-1", "1", "5", "10");
}
return super.getTab(player, arg, args);
}
@Override
protected void onExecute(@NotNull CommandSender sender, @NotNull CommandResult result) {
if (result.length() < 4) {
this.errorUsage(sender);
return;
}
Player player = Players.getPlayer(result.getArg(1));
if (player == null) {
this.errorPlayer(sender);
return;
}
Enchantment enchantment = BukkitThing.getEnchantment(result.getArg(2));
if (enchantment == null) {
Lang.ERROR_INVALID_ENCHANT.getMessage().send(sender);
return;
}
int level = result.getInt(3, -1);
if (level < 1) {
level = Rnd.get(enchantment.getStartLevel(), enchantment.getMaxLevel());
}
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
EnchantUtils.add(item, enchantment, level, true);
//EnchantUtils.updateDisplay(item);
Players.addItem(player, item);
Lang.COMMAND_BOOK_DONE.getMessage()
.replace(Placeholders.GENERIC_ENCHANT, EnchantUtils.getLocalized(enchantment))
.replace(Placeholders.forPlayer(player))
.send(sender);
}
}

View File

@ -0,0 +1,67 @@
package su.nightexpress.excellentenchants.command;
import org.bukkit.Registry;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.EquipmentSlot;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.excellentenchants.registry.EnchantRegistry;
import su.nightexpress.nightcore.command.experimental.argument.ArgumentTypes;
import su.nightexpress.nightcore.command.experimental.argument.CommandArgument;
import su.nightexpress.nightcore.command.experimental.builder.ArgumentBuilder;
import su.nightexpress.nightcore.util.*;
import java.util.Arrays;
public class CommandArguments {
public static final String PLAYER = "player";
public static final String AMOUNT = "amount";
public static final String LEVEL = "level";
public static final String ENCHANT = "enchant";
public static final String SLOT = "slot";
public static final String RARITY = "rarity";
@NotNull
public static ArgumentBuilder<Enchantment> enchantArgument(@NotNull String name) {
return ArgumentTypes.enchantment(name).withSamples(context -> BukkitThing.getNames(Registry.ENCHANTMENT));
}
@NotNull
public static ArgumentBuilder<CustomEnchantment> customEnchantArgument(@NotNull String name) {
return CommandArgument.builder(name, (string, context) -> EnchantRegistry.getById(string))
.localized(Lang.COMMAND_ARGUMENT_NAME_ENCHANTMENT)
.customFailure(Lang.ERROR_COMMAND_INVALID_ENCHANTMENT_ARGUMENT)
.withSamples(context -> EnchantRegistry.getRegisteredNames())
;
}
@NotNull
public static ArgumentBuilder<Integer> levelArgument(@NotNull String name) {
return ArgumentTypes.integer(CommandArguments.LEVEL)
.localized(Lang.COMMAND_ARGUMENT_NAME_LEVEL)
.withSamples(context -> Lists.newList("-1", "1", "3", "5", "10"));
}
@NotNull
public static ArgumentBuilder<Rarity> rarityArgument(@NotNull EnchantsPlugin plugin, @NotNull String name) {
return CommandArgument.builder(name, (string, context) -> plugin.getRarityManager().getRarity(string))
.localized(Lang.COMMAND_ARGUMENT_NAME_RARITY)
.customFailure(Lang.ERROR_COMMAND_INVALID_RARITY_ARGUMENT)
.withSamples(context -> plugin.getRarityManager().getRarityNames());
}
@NotNull
public static ArgumentBuilder<EquipmentSlot> slotArgument(@NotNull String name) {
return CommandArgument.builder(name, (str, context) -> {
EquipmentSlot slot = StringUtil.getEnum(str, EquipmentSlot.class).orElse(null);
return slot == EquipmentSlot.BODY ? null : slot;
})
.localized(Lang.COMMAND_ARGUMENT_NAME_SLOT)
.customFailure(Lang.ERROR_COMMAND_INVALID_SLOT_ARGUMENT)
.withSamples(context -> Arrays.stream(EntityUtil.EQUIPMENT_SLOTS).map(Enum::name).map(String::toLowerCase).toList());
}
}

View File

@ -1,95 +0,0 @@
package su.nightexpress.excellentenchants.command;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.excellentenchants.config.Perms;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.nightcore.command.CommandResult;
import su.nightexpress.nightcore.command.impl.AbstractCommand;
import su.nightexpress.nightcore.util.*;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.Arrays;
import java.util.List;
public class EnchantCommand extends AbstractCommand<EnchantsPlugin> {
public EnchantCommand(@NotNull EnchantsPlugin plugin) {
super(plugin, new String[]{"enchant"}, Perms.COMMAND_ENCHANT);
this.setDescription(Lang.COMMAND_ENCHANT_DESC);
this.setUsage(Lang.COMMAND_ENCHANT_USAGE);
}
@Override
@NotNull
public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (arg == 1) {
return BukkitThing.getEnchantments().stream().map(enchantment -> enchantment.getKey().getKey()).toList();
}
if (arg == 2) {
return Arrays.asList("-1", "1", "5", "10");
}
if (arg == 3) {
return Players.playerNames(player);
}
if (arg == 4) {
return Lists.getEnums(EquipmentSlot.class);
}
return super.getTab(player, arg, args);
}
@Override
protected void onExecute(@NotNull CommandSender sender, @NotNull CommandResult result) {
if (result.length() < 3) {
this.errorUsage(sender);
return;
}
Enchantment enchantment = BukkitThing.getEnchantment(result.getArg(1));
if (enchantment == null) {
Lang.ERROR_INVALID_ENCHANT.getMessage().send(sender);
return;
}
Player player = Players.getPlayer(result.getArg(3, sender.getName()));
if (player == null) {
this.errorPlayer(sender);
return;
}
EquipmentSlot slot = StringUtil.getEnum(result.getArg(4, ""), EquipmentSlot.class).orElse(EquipmentSlot.HAND);
ItemStack item = player.getInventory().getItem(slot);
if (item == null || item.getType().isAir()) {
Lang.COMMAND_ENCHANT_ERROR_NO_ITEM.getMessage().send(sender);
return;
}
int level = result.getInt(2, -1);
if (level < 0) {
level = Rnd.get(enchantment.getStartLevel(), enchantment.getMaxLevel());
}
if (level > 0) {
EnchantUtils.add(item, enchantment, level, true);
}
else EnchantUtils.remove(item, enchantment);
//EnchantUtils.updateDisplay(item);
player.getInventory().setItem(slot, item);
(sender == player ? Lang.COMMAND_ENCHANT_DONE_SELF : Lang.COMMAND_ENCHANT_DONE_OTHERS).getMessage()
.replace(Placeholders.forPlayer(player))
.replace(Placeholders.GENERIC_ITEM, ItemUtil.getItemName(item))
.replace(Placeholders.GENERIC_ENCHANT, EnchantUtils.getLocalized(enchantment))
.replace(Placeholders.GENERIC_LEVEL, NumberUtil.toRoman(level))
.send(sender);
}
}

View File

@ -1,69 +0,0 @@
package su.nightexpress.excellentenchants.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.excellentenchants.config.Perms;
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
import su.nightexpress.nightcore.command.CommandResult;
import su.nightexpress.nightcore.command.impl.AbstractCommand;
import su.nightexpress.nightcore.util.ItemUtil;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.NumberUtil;
import su.nightexpress.nightcore.util.Players;
import java.util.List;
public class GetFuelCommand extends AbstractCommand<EnchantsPlugin> {
public GetFuelCommand(@NotNull EnchantsPlugin plugin) {
super(plugin, new String[]{"getfuel"}, Perms.COMMAND_GET_FUEL);
this.setDescription(Lang.COMMAND_GET_FUEL_DESC);
this.setUsage(Lang.COMMAND_GET_FUEL_USAGE);
this.setPlayerOnly(true);
}
@Override
@NotNull
public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (arg == 1) {
return EnchantRegistry.getRegistered().stream().filter(EnchantmentData::isChargesEnabled).map(EnchantmentData::getId).toList();
}
if (arg == 2) {
return Lists.newList("1", "8", "16", "32", "64");
}
return super.getTab(player, arg, args);
}
@Override
protected void onExecute(@NotNull CommandSender sender, @NotNull CommandResult result) {
if (result.length() < 2) {
this.errorUsage(sender);
return;
}
EnchantmentData data = EnchantRegistry.getById(result.getArg(1));
if (data == null) {
Lang.ERROR_INVALID_ENCHANT.getMessage().send(sender);
return;
}
int amount = result.getInt(2, 1);
ItemStack fuel = data.getChargesFuel();
fuel.setAmount(amount);
Player player = (Player) sender;
Players.addItem(player, fuel);
Lang.COMMAND_GET_FUEL_DONE.getMessage()
.replace(Placeholders.GENERIC_AMOUNT, NumberUtil.format(amount))
.replace(Placeholders.GENERIC_NAME, ItemUtil.getItemName(fuel))
.send(sender);
}
}

View File

@ -1,52 +0,0 @@
package su.nightexpress.excellentenchants.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.config.Perms;
import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.nightcore.command.CommandResult;
import su.nightexpress.nightcore.command.impl.AbstractCommand;
import su.nightexpress.nightcore.util.Players;
import java.util.List;
public class ListCommand extends AbstractCommand<EnchantsPlugin> {
public ListCommand(@NotNull EnchantsPlugin plugin) {
super(plugin, new String[]{"list"}, Perms.COMMAND_LIST);
this.setDescription(Lang.COMMAND_LIST_DESC);
this.setDescription(Lang.COMMAND_LIST_USAGE);
}
@Override
@NotNull
public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (arg == 1 && player.hasPermission(Perms.COMMAND_LIST_OTHERS)) {
return Players.playerNames(player);
}
return super.getTab(player, arg, args);
}
@Override
protected void onExecute(@NotNull CommandSender sender, @NotNull CommandResult result) {
if (result.length() >= 2 && !sender.hasPermission(Perms.COMMAND_LIST_OTHERS)) {
this.errorPermission(sender);
return;
}
Player player = Players.getPlayer(result.getArg(1, sender.getName()));
if (player == null) {
this.errorPlayer(sender);
return;
}
plugin.getEnchantManager().openEnchantsMenu(player);
if (player != sender) {
Lang.COMMAND_LIST_DONE_OTHERS.getMessage().replace(Placeholders.forPlayer(player)).send(sender);
}
}
}

View File

@ -1,91 +0,0 @@
package su.nightexpress.excellentenchants.command;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.config.Perms;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.config.Lang;
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.nightcore.command.CommandResult;
import su.nightexpress.nightcore.command.impl.AbstractCommand;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.Players;
import su.nightexpress.nightcore.util.StringUtil;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public class RarityBookCommand extends AbstractCommand<EnchantsPlugin> {
public RarityBookCommand(@NotNull EnchantsPlugin plugin) {
super(plugin, new String[]{"raritybook"}, Perms.COMMAND_RARITY_BOOK);
this.setDescription(Lang.COMMAND_RARITY_BOOK_DESC);
this.setUsage(Lang.COMMAND_RARITY_BOOK_USAGE);
}
@Override
@NotNull
public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (arg == 1) {
return Players.playerNames(player);
}
if (arg == 2) {
return Lists.getEnums(Rarity.class);
}
if (arg == 3) {
return Arrays.asList("-1", "1", "5", "10");
}
return super.getTab(player, arg, args);
}
@Override
protected void onExecute(@NotNull CommandSender sender, @NotNull CommandResult result) {
if (result.length() < 4) {
this.errorUsage(sender);
return;
}
Player player = Players.getPlayer(result.getArg(1));
if (player == null) {
this.errorPlayer(sender);
return;
}
Rarity rarity = StringUtil.getEnum(result.getArg(2), Rarity.class).orElse(null);
if (rarity == null) {
Lang.ERROR_INVALID_RARITY.getMessage().send(sender);
return;
}
Set<EnchantmentData> enchants = EnchantRegistry.getByRarity(rarity);
EnchantmentData enchantmentData = enchants.isEmpty() ? null : Rnd.get(enchants);
if (enchantmentData == null) {
Lang.ERROR_INVALID_ENCHANT.getMessage().send(sender);
return;
}
int level = result.getInt(3, -1);
if (level < 1) {
level = Rnd.get(1, enchantmentData.getMaxLevel());
}
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
EnchantUtils.add(item, enchantmentData.getEnchantment(), level, true);
//EnchantUtils.updateDisplay(item);
Players.addItem(player, item);
Lang.COMMAND_RARITY_BOOK_DONE.getMessage()
.replace(Placeholders.GENERIC_NAME, plugin.getLangManager().getEnum(rarity))
.replace(Placeholders.forPlayer(player))
.send(sender);
}
}

View File

@ -2,16 +2,10 @@ package su.nightexpress.excellentenchants.config;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.DistributionMode;
import su.nightexpress.excellentenchants.api.DistributionWay;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.hook.HookPlugin;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.NumberUtil;
import su.nightexpress.nightcore.util.StringUtil;
import su.nightexpress.nightcore.util.wrapper.UniInt;
import java.util.*;
import java.util.stream.Collectors;
@ -21,7 +15,7 @@ import static su.nightexpress.nightcore.util.text.tag.Tags.*;
public class Config {
public static final String DIR_MENU = "/menu/";
public static final String DIR_MENU = "/menu/";
public static final String DIR_ENCHANTS = "/enchants/";
public static final ConfigValue<Long> CORE_PROJECTILE_PARTICLE_INTERVAL = ConfigValue.create("Core.Projectile_Particles_Tick_Interval",
@ -54,7 +48,8 @@ public class Config {
public static final ConfigValue<Integer> CORE_ITEM_ENCHANT_LIMIT = ConfigValue.create("Core.Item_Enchantments_Limit",
3,
"Sets max. amount of custom enchantments per item.",
"[Default is 3]");
"[Default is 3]"
);
public static final ConfigValue<Boolean> CORE_SWORD_ENCHANTS_TO_AXES = ConfigValue.create("Core.Sword_Enchants_To_Axes",
true,
@ -79,11 +74,11 @@ public class Config {
public static final ConfigValue<Set<String>> ENCHANTMENTS_DISABLED_LIST = ConfigValue.forSet("Enchantments.Disabled.List",
String::toLowerCase,
FileConfig::set,
Set.of("example_name", "custom_sharpness"),
Lists.newSet("example_name", "custom_sharpness"),
"Put here CUSTOM enchantment names that you want to disable and remove completely.",
"Enchantment names are equal to their config file names in '" + DIR_ENCHANTS + "' folder.",
"[*] You MUST REBOOT your server for disabled enchantments to have effect.",
"[*] Once enchantment is disabled, it will be removed from all items in the world on next load!"
"Enchantment names are equal to their config file names in the '" + DIR_ENCHANTS + "' directory.",
"[*] Reboot required when changed!",
"[**] Disabled enchantments will be removed from all items forever!"
);
public static final ConfigValue<Map<String, Set<String>>> ENCHANTMENTS_DISABLED_IN_WORLDS = ConfigValue.forMap("Enchantments.Disabled.ByWorld",
@ -91,117 +86,44 @@ public class Config {
(cfg, path, worldName) -> cfg.getStringSet(path + "." + worldName).stream().map(String::toLowerCase).collect(Collectors.toSet()),
(cfg, path, map) -> map.forEach((world, enchants) -> cfg.set(path + "." + world, enchants)),
() -> Map.of(
"your_world_name", Set.of("enchantment_name", "ice_aspect"),
"another_world", Set.of("another_enchantment", "ice_aspect")
"your_world_name", Lists.newSet("enchantment_name", "ice_aspect"),
"another_world", Lists.newSet("another_enchantment", "ice_aspect")
),
"Put here CUSTOM enchantment names that you want to disable in specific worlds.",
"To disable all enchantments for a world, use '" + WILDCARD + "' instead of enchantment names.",
"Enchantment names are equal to their config file names in '" + DIR_ENCHANTS + "' folder.",
VANILLA_DISTRIBUTION_HEADER,
"Enchantments will have no effect, but will appear in the world.",
CUSTOM_DISTRIBUTION_HEADER,
"Enchantments will have no effect and won't appear in the world."
"Enchantment names are equal to their config file names in the '" + DIR_ENCHANTS + "' directory.",
"[*] This setting only disables enchantment effects, not the enchantment distribution there!"
);
public static final ConfigValue<DistributionMode> DISTRIBUTION_MODE = ConfigValue.create("Enchantments.Distribution.Mode",
DistributionMode.class, DistributionMode.VANILLA,
"Sets in a which way new enchantments will be distributed to the worlds.",
"Allowed values: " + StringUtil.inlineEnum(DistributionMode.class, ", "),
"=".repeat(15) + " ! WARNING ! " + "=".repeat(15),
"You MUST REBOOT your server when changing this. Otherwise result is unpredictable.",
VANILLA_DISTRIBUTION_HEADER,
"[+] Very simple to use, almost no need to configure anything.",
"[+] Handled by the server, automatically supports all possible ways to get enchantments.",
"[+] Very accurate generation, repsects all vanilla game mechanics.",
"[-] Customization is almost non-existent.",
CUSTOM_DISTRIBUTION_HEADER,
"[+] Very flexible and customizable.",
"[+] Possibility for new ways to generate / obtain enchantments.",
"[-] Might be difficult to configure and balance everything.",
"[-] Enchantment generation is not such accurate as vanilla does."
);
public static final ConfigValue<Boolean> DISTRIBUTION_SINGLE_ENCHANT_IN_VILLAGER_BOOKS = ConfigValue.create("Enchantments.Distribution.Custom.Single_Enchant_In_Villager_Books",
true,
"When enabled, enchanted books in villager trades will have no more than 1 enchantment (vanilla or custom one).");
private static final ConfigValue<Map<DistributionWay, DistributionWaySettings>> DISTRIBUTION_WAY_SETTINGS = ConfigValue.forMap("Enchantments.Distribution.Custom.Ways",
id -> StringUtil.getEnum(id, DistributionWay.class).orElse(null),
(cfg, path, def) -> DistributionWaySettings.read(cfg, path + "." + def),
(cfg, path, map) -> map.forEach((type, settings) -> settings.write(cfg, path + "." + type.name())),
() -> Map.of(
DistributionWay.ENCHANTING, new DistributionWaySettings(true, 5, 75, UniInt.of(0, 2)),
DistributionWay.FISHING, new DistributionWaySettings(true, 4, 45, UniInt.of(0, 2)),
DistributionWay.LOOT_GENERATION, new DistributionWaySettings(true, 4, 80, UniInt.of(0, 2)),
DistributionWay.MOB_EQUIPMENT, new DistributionWaySettings(true, 4, 35, UniInt.of(0, 2)),
DistributionWay.VILLAGER, new DistributionWaySettings(true, 4, 60, UniInt.of(0, 2))
),
"Settings for the different ways of obtaining enchantments."
);
@Deprecated
public static final ConfigValue<Integer> ENCHANTMENTS_DISPLAY_MODE = ConfigValue.create("Enchantments.Display.Mode",
1,
"Sets how enchantment names and descriptions will be handled on items.",
"=".repeat(15) + " AVAILABLE VALUES " + "=".repeat(15),
"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 " + HookPlugin.PROTOCOL_LIB + " to be installed.",
"",
"Plain mode is faster, but may not reflect all changes immediately.",
"Packet mode is slower, but instantly reflect all changes. In creative mode, there is a chance for lore duplication."
);
@Deprecated
public static final ConfigValue<Boolean> ENCHANTMENTS_DISPLAY_NAME_HIDE_1ST_LEVEL = ConfigValue.create("Enchantments.Display.Name.Hide_1st_Level",
true,
"Hides enchantment level component from name format for level 1 enchantments.");
public static final ConfigValue<Map<Rarity, String>> ENCHANTMENTS_DISPLAY_NAME_RARITY_FORMAT = ConfigValue.forMap("Enchantments.Display.Name.Rarity",
(id) -> StringUtil.getEnum(id, Rarity.class).orElse(null),
(cfg, path, id) -> cfg.getString(path + "." + id, GENERIC_NAME),
(cfg, path, map) -> map.forEach((rarity, format) -> cfg.set(path + "." + rarity.name(), format)),
() -> Map.of(
Rarity.COMMON, WHITE.enclose(GENERIC_NAME),
Rarity.UNCOMMON, LIGHT_GREEN.enclose(GENERIC_NAME),
Rarity.RARE, LIGHT_CYAN.enclose(GENERIC_NAME),
Rarity.VERY_RARE, LIGHT_ORANGE.enclose(GENERIC_NAME)
),
"Sets enchantment name format depends on enchantment rarity.");
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_NAME_CURSE_FORMAT = ConfigValue.create("Enchantments.Display.Name.Curse",
LIGHT_RED.enclose(GENERIC_NAME),
"Sets cursed enchantments name format.");
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_NAME_FORMAT = ConfigValue.create("Enchantments.Display.Name.Format",
ENCHANTMENT_NAME + ENCHANTMENT_LEVEL + ENCHANTMENT_CHARGES,
"Enchantment name format created from name components.");
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_NAME_COMPONENT_NAME = ConfigValue.create("Enchantments.Display.Name.Component.Name",
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_NAME_COMPONENT = ConfigValue.create("Enchantments.Display.Name.Component.Name",
GENERIC_VALUE,
"Enchantment name display component for name format.");
"Enchantment name display component for name format."
);
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_NAME_COMPONENT_LEVEL = ConfigValue.create("Enchantments.Display.Name.Component.Level",
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_LEVEL_COMPONENT = ConfigValue.create("Enchantments.Display.Name.Component.Level",
" " + GENERIC_VALUE,
"Enchantment level display component for name format.");
"Enchantment level display component for name format."
);
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_NAME_COMPONENT_CHARGES = ConfigValue.create("Enchantments.Display.Name.Component.Charges",
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_CHARGES_COMPONENT = ConfigValue.create("Enchantments.Display.Name.Component.Charges",
" " + GENERIC_VALUE,
"Enchantment charges display component for name format.");
"Enchantment charges display component for name format."
);
public static final ConfigValue<Boolean> ENCHANTMENTS_DISPLAY_DESCRIPTION_ENABLED = ConfigValue.create("Enchantments.Display.Description.Enabled",
true,
"When 'true', adds the enchantment description to item lore under enchantment names.",
"For Display-Mode = 2 description is not shown while you're in Creative gamemode.");
"When 'true', adds the enchantment description to item lore under enchantment names."
);
public static final ConfigValue<Boolean> ENCHANTMENTS_DISPLAY_DESCRIPTION_BOOKS_ONLY = ConfigValue.create("Enchantments.Display.Description.Books_Only",
false,
"Sets whether or not only enchanted books will have enchantment descriptions.");
"Sets whether or not only enchanted books will have enchantment descriptions."
);
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_DESCRIPTION_FORMAT = ConfigValue.create("Enchantments.Display.Description.Format",
LIGHT_GRAY.enclose("" + ENCHANTMENT_NAME + " " + ENCHANTMENT_CHARGES + ": " + GENERIC_DESCRIPTION),
"Sets enchantment description format.");
LIGHT_GRAY.enclose("" + GENERIC_NAME + GENERIC_CHARGES + ": " + GENERIC_DESCRIPTION),
"Sets enchantment description format."
).onRead(str -> str.replace(ENCHANTMENT_NAME, GENERIC_NAME).replace(ENCHANTMENT_CHARGES, GENERIC_CHARGES));
@ -210,7 +132,8 @@ public class Config {
false,
"Enables Enchantment Charges feature.",
"When enabled in the first time, make sure to check enchantments configs for new 'Charges' section.",
URL_CHRAGES);
WIKI_CHRAGES
);
public static final ConfigValue<TreeMap<Integer, String>> ENCHANTMENTS_CHARGES_FORMAT = ConfigValue.forTreeMap("Enchantments.Charges.Format",
raw -> NumberUtil.getInteger(raw, 0),
@ -226,38 +149,29 @@ public class Config {
},
"Enchantment charges format depends on amount of charges left (in percent).",
"If you don't want to display charges, leave only keys with negative values.",
"Use '" + GENERIC_AMOUNT + "' placeholder for charges amount.");
"Use '" + GENERIC_AMOUNT + "' placeholder for charges amount."
);
public static final ConfigValue<Boolean> ENCHANTMENTS_CHARGES_COMPARE_TYPE_ONLY = ConfigValue.create("Enchantments.Charges.Compare_Material_Only",
false,
"When enabled, only item material will be checked to determine if an item can be used as an enchantment fuel.",
"When disabled, it will compare the whole item meta including name, lore, model data etc.",
"[Default is false]");
"[Default is false]"
);
public static final ConfigValue<ItemStack> ENCHANTMENTS_CHARGES_FUEL_ITEM = ConfigValue.create("Enchantments.Charges.Fuel_Item",
new ItemStack(Material.LAPIS_LAZULI),
"Default item used to recharge item's enchantments on anvils.",
"If you want different item for certain enchantments, you can do it in that enchantment configs.",
"Item Options: " + WIKI_ITEMS_URL);
"Item Options: " + WIKI_ITEMS_URL
);
@NotNull
public static Optional<DistributionWaySettings> getDistributionWaySettings(@NotNull DistributionWay way) {
DistributionWaySettings settings = DISTRIBUTION_WAY_SETTINGS.get().get(way);
return settings == null || !settings.isEnabled() ? Optional.empty() : Optional.of(settings);
public static boolean isDescriptionEnabled() {
return ENCHANTMENTS_DISPLAY_DESCRIPTION_ENABLED.get();
}
public static void loadRarityWeights(@NotNull FileConfig config) {
for (Rarity rarity : Rarity.values()) {
int weight = ConfigValue.create("Enchantments.Distribution.Custom.Rarity_Weights." + rarity.name(), rarity.getWeight()).read(config);
rarity.setWeight(weight);
}
}
public static boolean isVanillaDistribution() {
return Config.DISTRIBUTION_MODE.get() == DistributionMode.VANILLA;
}
public static boolean isCustomDistribution() {
return Config.DISTRIBUTION_MODE.get() == DistributionMode.CUSTOM;
public static boolean isChargesEnabled() {
return ENCHANTMENTS_CHARGES_ENABLED.get();
}
}

View File

@ -1,61 +0,0 @@
package su.nightexpress.excellentenchants.config;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.wrapper.UniInt;
@Deprecated
public class DistributionWaySettings {
private final boolean enabled;
private final int maxEnchantments;
private final double generationChance;
private final UniInt amount;
public DistributionWaySettings(boolean enabled,
int maxEnchantments, double generationChance,
@NotNull UniInt amount) {
this.enabled = enabled;
this.maxEnchantments = maxEnchantments;
this.generationChance = generationChance;
this.amount = amount;
}
@NotNull
public static DistributionWaySettings read(@NotNull FileConfig cfg, @NotNull String path) {
boolean enabled = cfg.getBoolean(path + ".Enabled");
int maxEnchantments = cfg.getInt(path + ".Max_Enchantments", 4);
double generationChance = cfg.getDouble(path + ".Generation_Chance", 50D);
UniInt amount = UniInt.read(cfg, path + ".Amount");
return new DistributionWaySettings(enabled, maxEnchantments, generationChance, amount);
}
public void write(@NotNull FileConfig cfg, @NotNull String path) {
cfg.set(path + ".Enabled", this.isEnabled());
cfg.set(path + ".Max_Enchantments", this.getMaxEnchantments());
cfg.set(path + ".Generation_Chance", this.getGenerationChance());
this.amount.write(cfg, path + ".Amount");
}
public int rollAmount() {
return this.amount.roll();
}
public boolean isEnabled() {
return enabled;
}
public int getMaxEnchantments() {
return maxEnchantments;
}
public double getGenerationChance() {
return generationChance;
}
@NotNull
public UniInt getAmount() {
return amount;
}
}

View File

@ -6,15 +6,11 @@ import su.nightexpress.excellentenchants.EnchantsPlugin;
public class Keys {
@Deprecated
public static NamespacedKey loreSize;
public static NamespacedKey itemRecharged;
public static NamespacedKey entitySpawnReason;
public static void loadKeys(@NotNull EnchantsPlugin plugin) {
loreSize = new NamespacedKey(plugin, "lore_size");
itemRecharged = new NamespacedKey(plugin, "item.recharged");
entitySpawnReason = new NamespacedKey(plugin, "entity.spawn_reason");
}

View File

@ -9,67 +9,65 @@ import static su.nightexpress.nightcore.util.text.tag.Tags.*;
public class Lang extends CoreLang {
public static final LangString COMMAND_LIST_DESC = LangString.of("Command.List.Desc",
"List of all custom enchantments.");
public static final LangString COMMAND_ARGUMENT_NAME_LEVEL = LangString.of("Command.Argument.Name.Level", "level");
public static final LangString COMMAND_ARGUMENT_NAME_SLOT = LangString.of("Command.Argument.Name.Slot", "slot");
public static final LangString COMMAND_ARGUMENT_NAME_RARITY = LangString.of("Command.Argument.Name.Rarity", "rarity");
public static final LangString COMMAND_LIST_USAGE = LangString.of("Command.List.Usage",
"[player]");
public static final LangString COMMAND_LIST_DESC = LangString.of("Command.List.Desc", "List of custom enchantments.");
public static final LangString COMMAND_ENCHANT_DESC = LangString.of("Command.Enchant.Desc", "Enchant item in specific slot.");
public static final LangString COMMAND_BOOK_DESC = LangString.of("Command.Book.Desc", "Give a book with specific enchantment.");
public static final LangString COMMAND_RARITY_BOOK_DESC = LangString.of("Command.RarityBook.Desc", "Give a book with enchantment of specific rarity.");
public static final LangString COMMAND_GET_FUEL_DESC = LangString.of("Command.GetFuel.Desc", "Get enchantment fuel item.");
public static final LangText COMMAND_LIST_DONE_OTHERS = LangText.of("Command.List.DoneOthers",
LIGHT_GRAY.enclose("Opened enchantments GUI for " + LIGHT_YELLOW.enclose(PLAYER_NAME) + "."));
LIGHT_GRAY.enclose("Opened enchantments GUI for " + LIGHT_YELLOW.enclose(PLAYER_NAME) + ".")
);
public static final LangString COMMAND_GET_FUEL_DESC = LangString.of("Command.GetFuel.Desc",
"Get enchantment fuel item.");
public static final LangString COMMAND_GET_FUEL_USAGE = LangString.of("Command.GetFuel.Usage",
"<enchant> [amount]");
public static final LangText COMMAND_GET_FUEL_DONE = LangText.of("Command.GetFuel.Done",
LIGHT_GRAY.enclose("You got " + LIGHT_YELLOW.enclose("x" + GENERIC_AMOUNT + " " + GENERIC_NAME) + "."));
LIGHT_GRAY.enclose("You got " + LIGHT_YELLOW.enclose("x" + GENERIC_AMOUNT + " " + GENERIC_NAME) + ".")
);
public static final LangText COMMAND_GET_FUEL_ERROR_NO_CHARGES = LangText.of("Command.GetFuel.Error.NoCharges",
LIGHT_GRAY.enclose("Enchantment " + LIGHT_RED.enclose(GENERIC_NAME) + " don't have charges.")
);
public static final LangString COMMAND_ENCHANT_USAGE = LangString.of("Command.Enchant.Usage",
"<enchant> <level> [player] [slot]");
public static final LangString COMMAND_ENCHANT_DESC = LangString.of("Command.Enchant.Desc",
"Enchants the item in your hand.");
public static final LangText COMMAND_ENCHANT_DONE_SELF = LangText.of("Command.Enchant.Done.Self",
LIGHT_GRAY.enclose(LIGHT_YELLOW.enclose(GENERIC_ITEM) + " enchanted with " + LIGHT_YELLOW.enclose(GENERIC_ENCHANT + " " + GENERIC_LEVEL) + "!"));
LIGHT_GRAY.enclose(LIGHT_YELLOW.enclose(GENERIC_ITEM) + " enchanted with " + LIGHT_YELLOW.enclose(GENERIC_ENCHANT + " " + GENERIC_LEVEL) + "!")
);
public static final LangText COMMAND_ENCHANT_DONE_OTHERS = LangText.of("Command.Enchant.Done.Others",
LIGHT_GRAY.enclose(LIGHT_YELLOW.enclose(PLAYER_DISPLAY_NAME) + "'s " + LIGHT_YELLOW.enclose(GENERIC_ITEM) + " enchanted with " + LIGHT_YELLOW.enclose(GENERIC_ENCHANT + " " + GENERIC_LEVEL) + "!"));
LIGHT_GRAY.enclose(LIGHT_YELLOW.enclose(PLAYER_DISPLAY_NAME) + "'s " + LIGHT_YELLOW.enclose(GENERIC_ITEM) + " enchanted with " + LIGHT_YELLOW.enclose(GENERIC_ENCHANT + " " + GENERIC_LEVEL) + "!")
);
public static final LangText COMMAND_ENCHANT_ERROR_NO_ITEM = LangText.of("Command.Enchant.Error.NoItem",
RED.enclose("There is no item to enchant!"));
LIGHT_RED.enclose("There is no item to enchant!")
);
public static final LangString COMMAND_BOOK_USAGE = LangString.of("Command.Book.Usage",
"<player> <enchant> <level>");
public static final LangString COMMAND_BOOK_DESC = LangString.of("Command.Book.Desc",
"Gives custom enchanted book.");
public static final LangText COMMAND_BOOK_DONE = LangText.of("Command.Book.Done",
LIGHT_GRAY.enclose("Given " + LIGHT_YELLOW.enclose(GENERIC_ENCHANT) + " enchanted book to " + LIGHT_YELLOW.enclose(PLAYER_DISPLAY_NAME) + "."));
LIGHT_GRAY.enclose("Given " + LIGHT_YELLOW.enclose(GENERIC_ENCHANT) + " enchanted book to " + LIGHT_YELLOW.enclose(PLAYER_DISPLAY_NAME) + ".")
);
public static final LangString COMMAND_RARITY_BOOK_USAGE = LangString.of("Command.RarityBook.Usage",
"<player> <tier> <level>");
public static final LangString COMMAND_RARITY_BOOK_DESC = LangString.of("Command.RarityBook.Desc",
"Give an enchanted book with enchantment of specified rarity.");
public static final LangText COMMAND_RARITY_BOOK_DONE = LangText.of("Command.RarityBook.Done",
LIGHT_GRAY.enclose("Given " + LIGHT_YELLOW.enclose(GENERIC_NAME) + " enchanted book to " + LIGHT_YELLOW.enclose(PLAYER_DISPLAY_NAME) + "."));
LIGHT_GRAY.enclose("Given " + LIGHT_YELLOW.enclose(GENERIC_NAME) + " enchanted book to " + LIGHT_YELLOW.enclose(PLAYER_DISPLAY_NAME) + ".")
);
public static final LangText COMMAND_RARITY_BOOK_ERROR_EMPTY = LangText.of("Command.RarityBook.Error.Empty",
LIGHT_GRAY.enclose("There is no enchantments with the " + LIGHT_RED.enclose(GENERIC_NAME) + " rarity!")
);
public static final LangText ERROR_INVALID_ENCHANT = LangText.of("Error.InvalidEnchantment",
RED.enclose("Invalid enchantment."));
public static final LangText ERROR_INVALID_RARITY = LangText.of("Error.InvalidRarity",
RED.enclose("Invalid rarity!"));
public static final LangText ERROR_COMMAND_INVALID_RARITY_ARGUMENT = LangText.of("Error.Command.Argument.InvalidRarity",
LIGHT_GRAY.enclose(LIGHT_RED.enclose(GENERIC_VALUE) + " is not a valid rarity!")
);
public static final LangText ERROR_COMMAND_INVALID_SLOT_ARGUMENT = LangText.of("Error.Command.Argument.InvalidSlot",
LIGHT_GRAY.enclose(LIGHT_RED.enclose(GENERIC_VALUE) + " is not a valid slot!")
);
public static final LangString ITEM_CATEGORY_HELMET = LangString.of("ItemCategory.Helmet", "Helmet");
public static final LangString ITEM_CATEGORY_CHESTPLATE = LangString.of("ItemCategory.Chestplate", "Chestplate");
@ -96,6 +94,4 @@ public class Lang extends CoreLang {
public static final LangString ITEM_CATEGORY_TORSO = LangString.of("ItemCategory.Torso", "Chestplate/Elytra");
public static final LangString ITEM_CATEGORY_ALL_WEAPON = LangString.of("ItemCategory.AllWeapon", "All Weapon");
public static final LangString ITEM_CATEGORY_MINING_TOOLS = LangString.of("ItemCategory.MiningTools", "Mining Tools");
}

View File

@ -4,79 +4,58 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.ConfigBridge;
import su.nightexpress.excellentenchants.api.EnchantmentID;
import su.nightexpress.excellentenchants.api.enchantment.meta.PeriodMeta;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.enchantment.impl.armor.FlameWalkerEnchant;
import su.nightexpress.excellentenchants.enchantment.listener.EnchantAnvilListener;
import su.nightexpress.excellentenchants.enchantment.listener.EnchantGenericListener;
import su.nightexpress.excellentenchants.enchantment.listener.EnchantPopulationListener;
import su.nightexpress.excellentenchants.enchantment.listener.EnchantVanillaListener;
import su.nightexpress.excellentenchants.enchantment.menu.EnchantmentsListMenu;
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.excellentenchants.enchantment.listener.AnvilListener;
import su.nightexpress.excellentenchants.enchantment.listener.GenericListener;
import su.nightexpress.excellentenchants.enchantment.menu.EnchantsMenu;
import su.nightexpress.excellentenchants.registry.EnchantRegistry;
import su.nightexpress.excellentenchants.util.EnchantUtils;
import su.nightexpress.nightcore.manager.AbstractManager;
import su.nightexpress.nightcore.util.Pair;
import su.nightexpress.nightcore.util.Version;
import java.util.*;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
public class EnchantManager extends AbstractManager<EnchantsPlugin> {
private final Set<Pair<PassiveEnchant, EnchantmentData>> passiveEnchants;
private final Set<PassiveEnchant> passiveEnchants;
private EnchantmentsListMenu enchantmentsListMenu;
private EnchantsMenu enchantsMenu;
public EnchantManager(@NotNull EnchantsPlugin plugin) {
super(plugin);
this.passiveEnchants = new HashSet<>();
EnchantRegistry.getEnchantments(PassiveEnchant.class).forEach(passiveEnchant -> {
EnchantmentData enchantmentData = EnchantRegistry.getById(passiveEnchant.getId());
if (enchantmentData == null) return;
this.passiveEnchants.add(Pair.of(passiveEnchant, enchantmentData));
});
this.passiveEnchants = new HashSet<>(EnchantRegistry.getEnchantments(PassiveEnchant.class));
}
protected void onLoad() {
this.enchantmentsListMenu = new EnchantmentsListMenu(this.plugin);
this.enchantsMenu = new EnchantsMenu(this.plugin);
this.addListener(new EnchantGenericListener(this.plugin, this));
this.addListener(new EnchantAnvilListener(this.plugin));
if (Config.isCustomDistribution()) {
this.plugin.info("Using custom distribution system. Applying patches...");
this.addListener(new EnchantPopulationListener(this.plugin));
}
else if (Version.isBehind(Version.MC_1_21)) {
this.plugin.info("Using vanilla distribution. Applying enchanting table patches...");
this.addListener(new EnchantVanillaListener(this.plugin));
}
this.addListener(new GenericListener(this.plugin, this));
this.addListener(new AnvilListener(this.plugin));
this.addTask(this.plugin.createAsyncTask(this::displayProjectileTrails).setTicksInterval(Config.CORE_PROJECTILE_PARTICLE_INTERVAL.get()));
this.addTask(this.plugin.createTask(this::updatePassiveEnchantEffects).setTicksInterval(Config.CORE_PASSIVE_ENCHANTS_TRIGGER_INTERVAL.get()));
if (EnchantRegistry.isRegistered(FlameWalkerEnchant.ID)) {
if (!this.passiveEnchants.isEmpty()) {
this.addTask(this.plugin.createTask(this::updatePassiveEnchantEffects).setTicksInterval(ConfigBridge.getEnchantsTickInterval()));
}
if (EnchantRegistry.isRegistered(EnchantmentID.FLAME_WALKER)) {
this.addTask(this.plugin.createTask(FlameWalkerEnchant::tickBlocks).setSecondsInterval(1));
}
}
@Override
protected void onShutdown() {
if (this.enchantmentsListMenu != null) this.enchantmentsListMenu.clear();
/*if (EnchantRegistry.isRegistered(FlameWalkerEnchant.ID)) {
FlameWalkerEnchant.clear();
}*/
}
@NotNull
public EnchantmentsListMenu getEnchantmentsListMenu() {
return enchantmentsListMenu;
if (this.enchantsMenu != null) this.enchantsMenu.clear();
}
public void openEnchantsMenu(@NotNull Player player) {
this.enchantmentsListMenu.open(player);
this.enchantsMenu.open(player);
}
private void displayProjectileTrails() {
@ -91,17 +70,17 @@ public class EnchantManager extends AbstractManager<EnchantsPlugin> {
}
private void updatePassiveEnchantEffects() {
if (this.passiveEnchants.isEmpty()) return;
Set<PassiveEnchant> readyEnchants = this.passiveEnchants.stream()
.peek(PeriodMeta::consumeTicks)
.filter(PeriodMeta::isTriggerTime)
.collect(Collectors.toSet());
if (readyEnchants.isEmpty()) return;
Set<LivingEntity> entities = this.getPassiveEnchantEntities();
this.passiveEnchants.forEach(pair -> {
PassiveEnchant enchant = pair.getFirst();
EnchantmentData enchantmentData = pair.getSecond();
if (!enchant.isTriggerTime()) return;
readyEnchants.forEach(enchant -> {
for (LivingEntity entity : entities) {
EnchantUtils.getEquipped(entity, enchantmentData).forEach((item, level) -> {
EnchantUtils.getEquipped(entity, enchant).forEach((item, level) -> {
if (!enchant.isAvailableToUse(entity)) return;
if (enchant.isOutOfCharges(item)) return;
if (enchant.onTrigger(entity, item, level)) {

View File

@ -1,262 +0,0 @@
package su.nightexpress.excellentenchants.enchantment;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.DistributionWay;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.config.DistributionWaySettings;
import su.nightexpress.excellentenchants.enchantment.data.CustomDistribution;
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiFunction;
public class EnchantPopulator {
//private final ExcellentEnchants plugin;
private final DistributionWay distributionWay;
private final ItemStack item;
private final Map<Rarity, Set<EnchantmentData>> candidates;
private final Map<Enchantment, Integer> defaultPopulation;
private final Set<BiFunction<EnchantmentData, CustomDistribution, Boolean>> predicates;
private World world;
private BiFunction<EnchantmentData, CustomDistribution, Integer> levelGenerator;
public EnchantPopulator(@NotNull EnchantsPlugin plugin, @NotNull ItemStack item, @NotNull DistributionWay distributionWay) {
//this.plugin = plugin;
this.item = item;
this.distributionWay = distributionWay;
this.candidates = new HashMap<>();
this.defaultPopulation = new HashMap<>();
this.predicates = new HashSet<>();
this.withLevelGenerator((data, distribution) -> distribution.generateLevel(this.getDistributionWay()));
//this.fillDefaultCandidates();
}
@NotNull
public EnchantPopulator withWorld(@NotNull World world) {
this.world = world;
return this;
}
@NotNull
public EnchantPopulator withLevelGenerator(@NotNull BiFunction<EnchantmentData, CustomDistribution, Integer> levelGenerator) {
this.levelGenerator = levelGenerator;
return this;
}
@NotNull
public EnchantPopulator withCondition(@NotNull BiFunction<EnchantmentData, CustomDistribution, Boolean> predicate) {
this.predicates.add(predicate);
return this;
}
@NotNull
public EnchantPopulator withDefaultPopulation(@NotNull Map<Enchantment, Integer> population) {
this.defaultPopulation.putAll(population);
//this.getPopulation().putAll(population);
return this;
}
private void fillDefaultCandidates() {
for (Rarity rarity : Rarity.values()) {
Set<EnchantmentData> dataSet = EnchantRegistry.getEnchantments(rarity);
dataSet.removeIf(data -> {
CustomDistribution distribution = (CustomDistribution) data.getDistributionOptions();
// Check if can be distributed.
if (!distribution.isDistributable(this.getDistributionWay())) return true;
// Check for custom conditions.
if (!this.predicates.isEmpty() && !this.predicates.stream().allMatch(predicate -> predicate.apply(data, distribution))) return true;
// Enchanting books is always good.
if (this.getItem().getType() == Material.BOOK && this.getDistributionWay() == DistributionWay.ENCHANTING) return false;
// Check if item can be enchanted.
return !data.getEnchantment().canEnchantItem(this.getItem()) && !EnchantUtils.isEnchantedBook(this.getItem());
});
this.candidates.put(rarity, dataSet);
}
}
public boolean isEmpty() {
return this.getCandidates().isEmpty() || this.getCandidates().values().stream().allMatch(Set::isEmpty);
}
public boolean isEmpty(@NotNull Rarity rarity) {
return this.getCandidates(rarity).isEmpty();
}
public void purge(@NotNull Rarity rarity) {
this.getCandidates().remove(rarity);
}
public void purge(@NotNull Rarity tier, @NotNull EnchantmentData enchant) {
this.getCandidates(tier).remove(enchant);
this.getCandidates().keySet().removeIf(this::isEmpty);
}
@NotNull
public ItemStack getItem() {
return item;
}
@NotNull
public DistributionWay getDistributionWay() {
return distributionWay;
}
@Nullable
public World getWorld() {
return world;
}
@NotNull
public BiFunction<EnchantmentData, CustomDistribution, Integer> getLevelGenerator() {
return levelGenerator;
}
@NotNull
public Map<Rarity, Set<EnchantmentData>> getCandidates() {
return this.candidates;
}
@NotNull
public Set<EnchantmentData> getCandidates(@NotNull Rarity rarity) {
return this.candidates.getOrDefault(rarity, new HashSet<>());
}
@Nullable
public Rarity getRarityByWeight() {
Map<Rarity, Double> map = new HashMap<>();
for (Rarity rarity : this.getCandidates().keySet()) {
map.put(rarity, (double) rarity.getWeight());
}
return map.isEmpty() ? null : Rnd.getByWeight(map);
}
@Nullable
public EnchantmentData getEnchantmentByWeight(@NotNull Rarity rarity) {
Map<EnchantmentData, Double> map = new HashMap<>();
this.getCandidates(rarity).forEach(enchantmentData -> {
CustomDistribution distribution = (CustomDistribution) enchantmentData.getDistributionOptions();
map.put(enchantmentData, distribution.getWeight(this.getDistributionWay()));
});
return map.isEmpty() ? null : Rnd.getByWeight(map);
}
@NotNull
public Map<Enchantment, Integer> createPopulation() {
this.candidates.clear();
this.fillDefaultCandidates();
Map<Enchantment, Integer> population = new HashMap<>(this.defaultPopulation);
DistributionWaySettings settings = Config.getDistributionWaySettings(this.getDistributionWay()).orElse(null);
if (settings == null || !Rnd.chance(settings.getGenerationChance())) return population;
int enchantsLimit = settings.getMaxEnchantments();
int enchantsRolled = settings.rollAmount();
// Try to populate as many as possible.
while (!this.isEmpty() && enchantsRolled > 0) {
// Limit reached.
if (population.size() >= enchantsLimit) break;
Rarity rarity = this.getRarityByWeight();
if (rarity == null) break; // no tiers left.
EnchantmentData enchantmentData = this.getEnchantmentByWeight(rarity);
// Remove entire rarity if no enchants can be selected.
if (enchantmentData == null) {
this.purge(rarity);
continue;
}
if (!(enchantmentData.getDistributionOptions() instanceof CustomDistribution distribution)) {
this.purge(rarity, enchantmentData);
continue;
}
// Remove disabled world enchants.
if (this.world != null && !enchantmentData.isAvailableToUse(this.world)) {
this.purge(rarity, enchantmentData);
continue;
}
// Remove conflicting enchants.
if (population.keySet().stream().anyMatch(has -> has.conflictsWith(enchantmentData.getEnchantment()) || enchantmentData.getEnchantment().conflictsWith(has))) {
this.purge(rarity, enchantmentData);
continue;
}
// Level generation failed.
int level = this.getLevelGenerator().apply(enchantmentData, distribution);
if (level < 1) {
this.purge(rarity, enchantmentData);
continue;
}
// All good!
this.purge(rarity, enchantmentData);
population.put(enchantmentData.getEnchantment(), level);
enchantsRolled--;
}
return population;
}
public boolean populate() {
ItemStack item = this.getItem();
AtomicBoolean status = new AtomicBoolean(false);
Map<Enchantment, Integer> population = this.createPopulation();//this.getPopulation().isEmpty() ? this.createPopulation() : this.getPopulation();
boolean singleVillagerBook = this.getDistributionWay() == DistributionWay.VILLAGER
&& EnchantUtils.isEnchantedBook(item)
&& Config.DISTRIBUTION_SINGLE_ENCHANT_IN_VILLAGER_BOOKS.get();
if (singleVillagerBook) {
if (!population.isEmpty()) {
EnchantUtils.removeAll(item);
}
while (population.size() > 1) {
population.remove(Rnd.get(population.keySet()));
}
}
population.forEach((enchantment, level) -> {
if (EnchantUtils.add(item, enchantment, level, false)) {
status.set(true);
}
});
/*if (status.get()) {
EnchantUtils.updateDisplay(item);
}*/
return status.get();
}
}

View File

@ -1,742 +0,0 @@
package su.nightexpress.excellentenchants.enchantment.data;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
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.DistributionWay;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.Cost;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.distribution.DistributionOptions;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.enchantment.util.EnchantPlaceholders;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.language.LangAssets;
import su.nightexpress.nightcore.manager.AbstractFileData;
import su.nightexpress.nightcore.manager.SimpeListener;
import su.nightexpress.nightcore.util.ItemUtil;
import su.nightexpress.nightcore.util.NumberUtil;
import su.nightexpress.nightcore.util.PDCUtil;
import su.nightexpress.nightcore.util.StringUtil;
import su.nightexpress.nightcore.util.placeholder.PlaceholderMap;
import su.nightexpress.nightcore.util.random.Rnd;
import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static su.nightexpress.excellentenchants.Placeholders.*;
public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsPlugin> implements EnchantmentData {
protected Enchantment enchantment;
private Rarity rarity;
private String displayName;
private List<String> description;
private boolean hiddenFromList;
private boolean treasure;
private boolean visualEffects;
private int maxLevel;
private Cost minCost;
private Cost maxCost;
private int anvilCost;
private boolean chargesEnabled;
private boolean chargesCustomFuel;
private Modifier chargesMax;
private Modifier chargesConsumeAmount;
private Modifier chargesRechargeAmount;
private ItemStack chargesFuel;
private final DistributionOptions distributionOptions;
private final Set<String> conflicts;
private final NamespacedKey chargesKey;
private final EnchantPlaceholders placeholders;
public AbstractEnchantmentData(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(new ArrayList<>());
this.setRarity(Rarity.COMMON);
this.setMaxLevel(3);
this.conflicts = new HashSet<>();
this.chargesKey = new NamespacedKey(plugin, this.getId() + ".charges");
this.placeholders = new EnchantPlaceholders();
if (!Config.isVanillaDistribution()) {
this.distributionOptions = new CustomDistribution(this);
}
else {
this.distributionOptions = new VanillaDistribution();
}
}
public void registerListeners() {
if (this instanceof SimpeListener listener) {
this.plugin.getPluginManager().registerEvents(listener, plugin);
}
}
@Override
public boolean checkServerRequirements() {
return true;
}
@Override
protected boolean onLoad(@NotNull FileConfig cfg) {
this.setRarity(ConfigValue.create("Settings.Rarity", Rarity.class, this.rarity,
"The rarity is an attribute of an enchantment.",
"It affects the chance of getting an enchantment from enchanting or loots as well as the combination cost in anvil.",
"[*] Only for versions BELOW 1.20.6!"
).read(cfg));
// TODO Custom rarity class for 1.21
this.setDisplayName(ConfigValue.create("Settings.Name",
StringUtil.capitalizeUnderscored(this.getId()),
"Enchantment name."
).read(cfg));
this.setDescription(ConfigValue.create("Settings.Description",
this.getDescription(),
"Enchantment description.",
"You can use 'Enchantment' placeholders: " + URL_PLACEHOLDERS
).read(cfg));
this.setMaxLevel(ConfigValue.create("Settings.Level.Max",
this.getMaxLevel(),
"Max. enchantment level."
).read(cfg));
this.setHiddenFromList(ConfigValue.create("Settings.Hide_From_List",
false,
"Sets whether or not this enchantment will be hidden from Enchants GUI."
).read(cfg));
this.setConflicts(ConfigValue.create("Settings.Conflicts",
this.getConflicts(),
"Makes this enchantment exclusive for ones in the list.",
"Conflicting enchantments can not be combined on anvils and obtained together on the same item."
).read(cfg));
this.setVisualEffects(ConfigValue.create("Settings.VisualEffects.Enabled",
true,
"Enables enchantment visual effects (mostly particles)."
).read(cfg));
this.setTreasure(ConfigValue.create("Distribution.Treasure",
false,
"Sets whether this enchantment is a treasure enchantment.",
"Treasure enchantments can only be received via looting, trading, or fishing."
).read(cfg));
//int costAdjust = Math.max(7, 42 - this.getMaxLevel() * 7);
int costBase = Config.isVanillaDistribution() ? 45 : 30;
int costStart = Rnd.get(5) + 1;
int costMod = Rnd.get(10) + 1;
int costPerLevel = (int) ((double) costBase / (double) this.getMaxLevel());
this.setMinCost(Cost.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Cost.Min",
new Cost(costStart, costPerLevel),
VANILLA_DISTRIBUTION_HEADER,
"Sets min. **modified** level cost for this enchantment to be selected in enchanting table.",
"Explanation: https://minecraft.wiki/w/Enchanting_mechanics#How_enchantments_are_chosen",
"Vanilla costs: https://minecraft.wiki/w/Enchanting/Levels",
CUSTOM_DISTRIBUTION_HEADER,
"Sets min. **plain** level cost for this enchantment to be selected in enchanting table."
)
);
this.setMaxCost(Cost.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Cost.Max",
new Cost(costStart * costMod, costPerLevel),
VANILLA_DISTRIBUTION_HEADER,
"Sets max. **modified** level cost for this enchantment to be selected in enchanting table.",
"Explanation: https://minecraft.wiki/w/Enchanting_mechanics#How_enchantments_are_chosen",
"Vanilla costs: https://minecraft.wiki/w/Enchanting/Levels",
CUSTOM_DISTRIBUTION_HEADER,
"Sets max. **plain** level cost for this enchantment to be selected in enchanting table.")
);
// TODO Check what actually does
this.setAnvilCost(ConfigValue.create("Anvil.Cost",
Rnd.get(8) + 1,
"The cost when applying this enchantment using an anvil. Halved when adding to a book, multiplied by the level of the enchantment.",
"[*] Works for 1.20.6+ only!"
).read(cfg));
this.distributionOptions.load(cfg);
if (Config.ENCHANTMENTS_CHARGES_ENABLED.get() && !this.isCurse()) {
this.setChargesEnabled(ConfigValue.create("Charges.Enabled",
false,
"When 'true' enables the Charges system for this enchantment.",
"[*] Enchantments in enchanting table are generated with maximum charges."
).read(cfg));
this.setChargesCustomFuel(ConfigValue.create("Charges.Custom_Fuel",
false,
"When 'true' uses different (non-default) fuel item (from the 'Fuel_Item' setting) to recharge."
).read(cfg));
this.setChargesMax(Modifier.read(cfg, "Charges.Maximum",
Modifier.add(100, 25, 1),
"Maximum amount of charges for the enchantment."
));
this.setChargesConsumeAmount(Modifier.read(cfg, "Charges.Consume_Amount",
Modifier.add(1, 0, 0),
"How many charges will be consumed when enchantment is triggered?"
));
this.setChargesRechargeAmount(Modifier.read(cfg, "Charges.Recharge_Amount",
Modifier.add(25, 5, 1),
"How many charges will be restored when using 'Fuel Item' in anvil?"
));
this.setChargesFuel(ConfigValue.create("Charges.Fuel_Item",
new ItemStack(Material.LAPIS_LAZULI),
"An item, that will be used to restore enchantment charges on anvils.",
WIKI_ITEMS_URL
).read(cfg));
}
this.placeholders
.add(ENCHANTMENT_ID, this::getId)
.add(ENCHANTMENT_NAME, this::getName)
.add(ENCHANTMENT_NAME_FORMATTED, this::getNameFormatted)
.add(ENCHANTMENT_DESCRIPTION, () -> String.join("\n", this.getDescription()))
.add(ENCHANTMENT_DESCRIPTION_FORMATTED, () -> String.join("\n", this.getDescriptionFormatted()))
.add(ENCHANTMENT_DESCRIPTION_REPLACED, level -> String.join("\n", this.getDescriptionReplaced(level)))
.add(ENCHANTMENT_LEVEL, NumberUtil::toRoman)
.add(ENCHANTMENT_LEVEL_MIN, () -> String.valueOf(1))
.add(ENCHANTMENT_LEVEL_MAX, () -> String.valueOf(this.getMaxLevel()))
.add(ENCHANTMENT_RARITY, () -> plugin.getLangManager().getEnum(this.getRarity()))
.add(ENCHANTMENT_FIT_ITEM_TYPES, () -> this.getSupportedItems().getLocalized())
.add(ENCHANTMENT_CHARGES_MAX_AMOUNT, level -> NumberUtil.format(this.getChargesMax(level)))
.add(ENCHANTMENT_CHARGES_CONSUME_AMOUNT, level -> NumberUtil.format(this.getChargesConsumeAmount(level)))
.add(ENCHANTMENT_CHARGES_RECHARGE_AMOUNT, level -> NumberUtil.format(this.getChargesRechargeAmount(level)))
.add(ENCHANTMENT_CHARGES_FUEL_ITEM, () -> ItemUtil.getItemName(this.getChargesFuel()));
if (this instanceof ChanceData chanceData) {
this.placeholders.add(ENCHANTMENT_CHANCE, level -> NumberUtil.format(chanceData.getTriggerChance(level)));
}
if (this instanceof PeriodicData periodicData) {
this.placeholders.add(ENCHANTMENT_INTERVAL, () -> NumberUtil.format(periodicData.getInterval() / 20D));
}
if (this instanceof PotionData potionData) {
this.placeholders.add(ENCHANTMENT_POTION_LEVEL, level -> NumberUtil.toRoman(potionData.getEffectAmplifier(level)));
this.placeholders.add(ENCHANTMENT_POTION_DURATION, level -> NumberUtil.format(potionData.getEffectDuration(level) / 20D));
this.placeholders.add(ENCHANTMENT_POTION_TYPE, () -> LangAssets.get(potionData.getEffectType()));
}
if (this.getDistributionOptions() instanceof CustomDistribution distribution) {
this.placeholders.add(ENCHANTMENT_OBTAIN_CHANCE_ENCHANTING, () -> NumberUtil.format(distribution.getWeight(DistributionWay.ENCHANTING)));
this.placeholders.add(ENCHANTMENT_OBTAIN_CHANCE_VILLAGER, () -> NumberUtil.format(distribution.getWeight(DistributionWay.VILLAGER)));
this.placeholders.add(ENCHANTMENT_OBTAIN_CHANCE_LOOT_GENERATION, () -> NumberUtil.format(distribution.getWeight(DistributionWay.LOOT_GENERATION)));
this.placeholders.add(ENCHANTMENT_OBTAIN_CHANCE_FISHING, () -> NumberUtil.format(distribution.getWeight(DistributionWay.FISHING)));
this.placeholders.add(ENCHANTMENT_OBTAIN_CHANCE_MOB_SPAWNING, () -> NumberUtil.format(distribution.getWeight(DistributionWay.MOB_EQUIPMENT)));
}
this.loadAdditional(cfg);
this.registerListeners();
return true;
}
protected abstract void loadAdditional(@NotNull FileConfig config);
@Override
protected void onSave(@NotNull FileConfig cfg) {
}
@NotNull
private String logPrefix() {
return "[" + this.getId() + "] ";
}
protected void info(@NotNull String text) {
this.plugin.info(this.logPrefix() + text);
}
protected void warn(@NotNull String text) {
this.plugin.warn(this.logPrefix() + text);
}
protected void error(@NotNull String text) {
this.plugin.error(this.logPrefix() + text);
}
@NotNull
public PlaceholderMap getPlaceholders(int level) {
return this.placeholders.toMap(level);
}
public void addPlaceholder(@NotNull String key, @NotNull Function<Integer, String> replacer) {
this.placeholders.add(key, replacer);
}
// @Override
// @NotNull
// public ItemCategory[] getItemCategories() {
// return new ItemCategory[0];
// }
/*@Override
public EquipmentSlot[] getSlots() {
return switch (this.getCategory()) {
case BOW, CROSSBOW, TRIDENT, FISHING_ROD, WEAPON, TOOL -> new EquipmentSlot[]{EquipmentSlot.HAND};
case ARMOR_HEAD -> new EquipmentSlot[]{EquipmentSlot.HEAD};
case ARMOR_TORSO -> new EquipmentSlot[]{EquipmentSlot.CHEST};
case ARMOR_LEGS -> new EquipmentSlot[]{EquipmentSlot.LEGS};
case ARMOR_FEET -> new EquipmentSlot[]{EquipmentSlot.FEET};
case ARMOR, WEARABLE -> new EquipmentSlot[]{EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
case BREAKABLE -> new EquipmentSlot[]{EquipmentSlot.HAND, EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
case VANISHABLE -> EnchantUtils.EQUIPMENT_SLOTS;
default -> throw new IllegalStateException("Unexpected value: " + this.getCategory());
};
}*/
@Override
public boolean isAvailableToUse(@NotNull World world) {
Set<String> disabled = Config.ENCHANTMENTS_DISABLED_IN_WORLDS.get().getOrDefault(world.getName().toLowerCase(), Collections.emptySet());
return disabled.isEmpty() || (!disabled.contains(this.getId()) && !disabled.contains(WILDCARD));
}
@Override
public boolean isAvailableToUse(@NotNull LivingEntity entity) {
return this.isAvailableToUse(entity.getWorld());
}
@Override
public boolean checkEnchantLimit(@NotNull ItemStack item) {
// Allow to re-enchant item with the same enchantment.
if (EnchantUtils.contains(item, this.getEnchantment())) {
return true;
}
return !EnchantUtils.hasMaximumEnchants(item);
}
/*@Override
public final boolean checkEnchantCategory(@NotNull ItemStack item) {
EnchantmentTarget category = this.getCategory();
if (category == EnchantmentTarget.WEAPON && ItemUtil.isAxe(item)) {
return Config.CORE_SWORD_ENCHANTS_TO_AXES.get();
}
if (category == EnchantmentTarget.BOW && item.getType() == Material.CROSSBOW) {
return Config.CORE_BOW_ENCHANTS_TO_CROSSBOW.get();
}
if ((category == EnchantmentTarget.ARMOR || category == EnchantmentTarget.ARMOR_TORSO) && item.getType() == Material.ELYTRA) {
return Config.CORE_CHESTPLATE_ENCHANTS_TO_ELYTRA.get();
}
return false;
}
@Override
public boolean checkItemCategory(@NotNull ItemStack item) {
return !this.hasItemCategory() || Stream.of(this.getItemCategories()).anyMatch(itemCategory -> itemCategory.isIncluded(item));
}*/
public int generateLevel() {
return Rnd.get(1, this.getMaxLevel());
}
@Override
@NotNull
public String getNameFormatted(int level, int charges) {
String rarityFormat = this.isCurse() ? Config.ENCHANTMENTS_DISPLAY_NAME_CURSE_FORMAT.get() : Config.ENCHANTMENTS_DISPLAY_NAME_RARITY_FORMAT.get()
.getOrDefault(this.getRarity(), GENERIC_NAME);
String nameFormat = this.formatComponents(Config.ENCHANTMENTS_DISPLAY_NAME_FORMAT.get(), level, charges);
return rarityFormat.replace(GENERIC_NAME, nameFormat);
}
@Override
@NotNull
public List<String> getDescriptionFormatted() {
return new ArrayList<>(this.getDescription().stream()
.map(line -> Config.ENCHANTMENTS_DISPLAY_DESCRIPTION_FORMAT.get().replace(GENERIC_DESCRIPTION, line))
.toList());
}
@Override
@NotNull
public List<String> getDescriptionReplaced(int level) {
return this.getDescriptionReplaced(level, 0);
}
@Override
@NotNull
public List<String> getDescriptionReplaced(int level, int charges) {
List<String> description = new ArrayList<>(this.getDescriptionFormatted());
description.replaceAll(line -> this.getPlaceholders(level).replacer().apply(this.formatComponents(line, level, charges)));
return description;
}
@NotNull
private String formatComponents(@NotNull String string, int level, int charges) {
String chargesFormat = "";
boolean showLevel = this.getMaxLevel() > 1;
boolean showCharges = this.isChargesEnabled() && charges >= 0;
if (showCharges) {
int chargesMax = this.getChargesMax(level);
int percent = (int) Math.ceil((double) charges / (double) chargesMax * 100D);
Map.Entry<Integer, String> entry = Config.ENCHANTMENTS_CHARGES_FORMAT.get().floorEntry(percent);
if (entry != null) {
chargesFormat = entry.getValue().replace(GENERIC_AMOUNT, String.valueOf(charges));
}
}
String compName = Config.ENCHANTMENTS_DISPLAY_NAME_COMPONENT_NAME.get().replace(GENERIC_VALUE, this.getName());
String compLevel = showLevel ? Config.ENCHANTMENTS_DISPLAY_NAME_COMPONENT_LEVEL.get().replace(GENERIC_VALUE, NumberUtil.toRoman(level)) : "";
String compChrages = showCharges ? Config.ENCHANTMENTS_DISPLAY_NAME_COMPONENT_CHARGES.get().replace(GENERIC_VALUE, chargesFormat) : "";
return string
.replace(ENCHANTMENT_NAME, compName)
.replace(ENCHANTMENT_LEVEL, compLevel)
.replace(ENCHANTMENT_CHARGES, compChrages);
}
@Override
public int getMinCost(int level) {
return this.getMinCost().calculate(level);
}
@Override
public int getMaxCost(int level) {
return this.getMaxCost().calculate(level);
}
/*@Override
public int getAnvilMergeCost(int level) {
return this.getAnvilMergeCost().getIntValue(level);
}*/
@Override
public int getChargesMax(int level) {
return this.isChargesEnabled() ? this.getChargesMax().getIntValue(level) : 0;
}
@Override
public int getChargesConsumeAmount(int level) {
return this.isChargesEnabled() ? this.getChargesConsumeAmount().getIntValue(level) : 0;
}
@Override
public int getChargesRechargeAmount(int level) {
return this.isChargesEnabled() ? this.getChargesRechargeAmount().getIntValue(level) : 0;
}
@Override
public boolean isChargesFuel(@NotNull ItemStack item) {
if (Config.ENCHANTMENTS_CHARGES_COMPARE_TYPE_ONLY.get()) {
return item.getType() == this.getChargesFuel().getType();
}
return item.isSimilar(this.getChargesFuel());
}
@Override
public boolean isOutOfCharges(@NotNull ItemStack item) {
return this.getCharges(item) == 0;
}
@Override
public boolean isFullOfCharges(@NotNull ItemStack item) {
if (!this.isChargesEnabled()) return true;
int level = EnchantUtils.getLevel(item, this.getEnchantment());
int max = this.getChargesMax(level);
return this.getCharges(item) == max;
}
@Override
public int getCharges(@NotNull ItemMeta meta) {
return this.isChargesEnabled() ? PDCUtil.getInt(meta, this.chargesKey).orElse(0) : -1;
}
@Override
public void setCharges(@NotNull ItemStack item, int level, int amount) {
if (!this.isChargesEnabled()) return;
int max = this.getChargesMax(level);
int set = Math.min(Math.abs(amount), max);
PDCUtil.set(item, this.chargesKey, set);
}
@Override
public void restoreCharges(@NotNull ItemStack item, int level) {
this.setCharges(item, level, Integer.MAX_VALUE);
}
@Override
public void fuelCharges(@NotNull ItemStack item, int level) {
int recharge = this.getChargesRechargeAmount(level);
int has = this.getCharges(item);
int set = has + recharge;
this.setCharges(item, level, set);
}
@Override
public void consumeChargesNoUpdate(@NotNull ItemStack item, int level) {
if (!this.isChargesEnabled()) return;
int charges = this.getCharges(item);
int consumeAmount = this.getChargesConsumeAmount(level);
this.setCharges(item, level, charges < consumeAmount ? 0 : Math.max(0, charges - consumeAmount));
}
@Override
public void consumeCharges(@NotNull ItemStack item, int level) {
if (!this.isChargesEnabled()) return;
this.consumeChargesNoUpdate(item, level);
//EnchantUtils.updateDisplay(item);
}
@Override
@NotNull
public Enchantment getEnchantment() {
return this.enchantment;
}
@Override
public void setEnchantment(@NotNull Enchantment enchantment) {
this.enchantment = enchantment;
}
@NotNull
@Override
public Rarity getRarity() {
return rarity;
}
@Override
public void setRarity(@NotNull Rarity rarity) {
this.rarity = rarity;
}
@NotNull
@Override
public DistributionOptions getDistributionOptions() {
return distributionOptions;
}
@NotNull
public String getName() {
return displayName;
}
@Override
public void setDisplayName(@NotNull String displayName) {
this.displayName = displayName;
}
@Override
@NotNull
public List<String> getDescription() {
return description;
}
@Override
public void setDescription(@NotNull List<String> description) {
this.description = description;
}
@Override
public boolean isHiddenFromList() {
return hiddenFromList;
}
@Override
public void setHiddenFromList(boolean hiddenFromList) {
this.hiddenFromList = hiddenFromList;
}
@Override
public boolean isTreasure() {
return this.treasure;
}
@Override
public void setTreasure(boolean treasure) {
this.treasure = treasure;
}
@Override
public void setMaxLevel(int levelMax) {
this.maxLevel = Math.max(1, levelMax);
}
@Override
public int getMaxLevel() {
return maxLevel;
}
@Override
@NotNull
public Cost getMinCost() {
return this.minCost;
}
@Override
public void setMinCost(@NotNull Cost minCost) {
this.minCost = minCost;
}
@Override
@NotNull
public Cost getMaxCost() {
return this.maxCost;
}
@Override
public void setMaxCost(@NotNull Cost maxCost) {
this.maxCost = maxCost;
}
@Override
public int getAnvilCost() {
return anvilCost;
}
@Override
public void setAnvilCost(int anvilCost) {
this.anvilCost = anvilCost;
}
/*@Override
@NotNull
public Modifier getAnvilMergeCost() {
return this.anvilMergeCost;
}
@Override
public void setAnvilMergeCost(@NotNull Modifier anvilMergeCost) {
this.anvilMergeCost = anvilMergeCost;
}
@Override
public int getMaxMergeLevel() {
return this.maxMergeLevel;
}
@Override
public void setMaxMergeLevel(int maxMergeLevel) {
this.maxMergeLevel = Math.min(this.getMaxLevel(), maxMergeLevel);
}*/
@Override
@NotNull
public Set<String> getConflicts() {
return this.conflicts;
}
@Override
public void setConflicts(@NotNull Set<String> conflicts) {
this.conflicts.clear();
this.conflicts.addAll(conflicts.stream().map(String::toLowerCase).collect(Collectors.toSet()));
}
@Override
public boolean hasVisualEffects() {
return visualEffects;
}
@Override
public void setVisualEffects(boolean visualEffects) {
this.visualEffects = visualEffects;
}
@Override
public boolean isChargesEnabled() {
return chargesEnabled;
}
@Override
public void setChargesEnabled(boolean chargesEnabled) {
this.chargesEnabled = chargesEnabled;
}
@Override
public boolean isChargesCustomFuel() {
return chargesCustomFuel;
}
@Override
public void setChargesCustomFuel(boolean chargesCustomFuel) {
this.chargesCustomFuel = chargesCustomFuel;
}
@Override
@NotNull
public Modifier getChargesMax() {
return chargesMax;
}
@Override
public void setChargesMax(@NotNull Modifier chargesMax) {
this.chargesMax = chargesMax;
}
@NotNull
public ItemStack getChargesFuel() {
ItemStack fuelHas = this.chargesFuel;
if (!this.isChargesCustomFuel() || fuelHas == null || fuelHas.getType().isAir()) {
return new ItemStack(Config.ENCHANTMENTS_CHARGES_FUEL_ITEM.get());
}
return new ItemStack(fuelHas);
}
@Override
public void setChargesFuel(@Nullable ItemStack chargesFuel) {
this.chargesFuel = chargesFuel;
}
@Override
@NotNull
public Modifier getChargesConsumeAmount() {
return chargesConsumeAmount;
}
@Override
public void setChargesConsumeAmount(@NotNull Modifier chargesConsumeAmount) {
this.chargesConsumeAmount = chargesConsumeAmount;
}
@Override
@NotNull
public Modifier getChargesRechargeAmount() {
return chargesRechargeAmount;
}
@Override
public void setChargesRechargeAmount(@NotNull Modifier chargesRechargeAmount) {
this.chargesRechargeAmount = chargesRechargeAmount;
}
}

View File

@ -1,154 +0,0 @@
package su.nightexpress.excellentenchants.enchantment.data;
import org.bukkit.loot.LootTable;
import org.bukkit.loot.LootTables;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.distribution.DistributionOptions;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.DistributionWay;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.StringUtil;
import su.nightexpress.nightcore.util.random.Rnd;
import su.nightexpress.nightcore.util.wrapper.UniInt;
import java.util.*;
public class CustomDistribution implements DistributionOptions {
private final EnchantmentData enchantmentData;
private final Map<DistributionWay, Double> weightMap;
private final Map<DistributionWay, UniInt> levelRangeMap;
private final Set<LootTables> lootTables;
public CustomDistribution(@NotNull EnchantmentData enchantmentData) {
this.enchantmentData = enchantmentData;
this.weightMap = new HashMap<>();
this.levelRangeMap = new HashMap<>();
this.lootTables = new HashSet<>();
}
public void load(@NotNull FileConfig config) {
for (DistributionWay distributionWay : DistributionWay.values()) {
String pathName = distributionWay.getPathName();
double obtainChance = ConfigValue.create("Distribution." + pathName + ".Weight", 50D,
"Determines how often this enchantment will appear in " + pathName + ".",
"Greater value = Greater chance.").read(config);
this.weightMap.put(distributionWay, obtainChance);
int levelMin = ConfigValue.create("Distribution." + pathName + ".Level.Min", -1,
"Minimal level when obtained via " + pathName,
"Can not be less than enchantment min. level. Set -1 to use enchantment min. level.").read(config);
int levelMax = ConfigValue.create("Distribution." + pathName + ".Level.Max", -1,
"Maximal level when obtained via " + pathName,
"Can not be greater than enchantment max. level. Set -1 to use enchantment max. level.").read(config);
this.levelRangeMap.put(distributionWay, UniInt.of(levelMin, levelMax));
}
boolean isWhitelist = ConfigValue.create("Distribution." + DistributionWay.LOOT_GENERATION.getPathName() + ".LootTables.Whitelist",
false,
"When 'true', uses only loot tables listed below.",
"When 'false', uses ALL loot tables except ones listed below.",
"[Default is false]"
).read(config);
Set<LootTables> tables = ConfigValue.forSet("Distribution." + DistributionWay.LOOT_GENERATION.getPathName() + ".LootTables.List",
id -> StringUtil.getEnum(id, LootTables.class).orElse(null),
(cfg, path, set) -> cfg.set(path, set.stream().map(Enum::name).toList()),
Set.of(
LootTables.DESERT_PYRAMID
),
"Depends on Whitelist mode, this enchantment will appear on items generated by certain Loot Tables only.",
"=".repeat(15) + " EXAMPLES " + "=".repeat(15),
"==> Set 'Whitelist' on 'true' and add '" + LootTables.DESERT_PYRAMID.name() + "' to the list to make this enchantment appear on items generated inside Desert Pyramid chests only.",
"==> Set 'Whitelist' on 'false' and add '" + LootTables.DESERT_PYRAMID.name() + "' to the list to make this enchantment appear on items generated inside any structure's chests except Deset Pyramids.",
"",
"[*] Keep in mind, that Loot Generation is only applicable to items in chests. Listing here loot tables of mobs, fishing and other sources is useless.",
"Available loot table names: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/loot/LootTables.html"
).read(config);
if (isWhitelist) {
this.lootTables.addAll(tables);
}
else {
this.lootTables.addAll(Arrays.asList(LootTables.values()));
this.lootTables.removeAll(tables);
}
}
@NotNull
public Map<DistributionWay, Double> getWeightMap() {
return weightMap;
}
@NotNull
public Map<DistributionWay, UniInt> getLevelRangeMap() {
return levelRangeMap;
}
@NotNull
public Set<LootTables> getLootTables() {
return lootTables;
}
public boolean isDistributable(@NotNull DistributionWay distributionWay) {
if (distributionWay == DistributionWay.ENCHANTING && (this.enchantmentData.isTreasure() || this.enchantmentData.isCurse())) return false;
return this.getWeight(distributionWay) > 0D;
}
public boolean isGoodLootTable(@NotNull LootTable table) {
return this.getLootTables().stream().anyMatch(tables -> tables.getLootTable() == table);
}
public double getWeight(@NotNull DistributionWay distributionWay) {
return this.getWeightMap().getOrDefault(distributionWay, 0D);
}
public int getMinLevel(@NotNull DistributionWay distributionWay) {
return this.getLevelRangeMap().getOrDefault(distributionWay, UniInt.of(-1, -1)).getMinValue();
}
public int getMaxLevel(@NotNull DistributionWay distributionWay) {
return this.getLevelRangeMap().getOrDefault(distributionWay, UniInt.of(-1, -1)).getMaxValue();
}
public int generateLevel(@NotNull DistributionWay distributionWay) {
int levelCapMin = this.getMinLevel(distributionWay);
int levelCapMax = this.getMaxLevel(distributionWay);
if (levelCapMin < 1) levelCapMin = 1;
if (levelCapMax <= 0 || levelCapMax > this.enchantmentData.getMaxLevel()) levelCapMax = this.enchantmentData.getMaxLevel();
return Rnd.get(levelCapMin, levelCapMax);
}
public int getLevelByEnchantCost(int xpLevel) {
int get = 0;
for (int level = this.enchantmentData.getMaxLevel(); level > 0; level--) {
if (xpLevel >= this.enchantmentData.getMinCost(level) && xpLevel <= this.enchantmentData.getMaxCost(level)) {
get = level;
break;
}
}
return get != 0 ? this.fineLevel(get, DistributionWay.ENCHANTING) : 0;
}
public int fineLevel(int level, @NotNull DistributionWay distributionWay) {
int levelCapMin = this.getMinLevel(distributionWay);
int levelCapMax = this.getMaxLevel(distributionWay);
if (levelCapMin > 0 && level < levelCapMin) level = levelCapMin;
if (levelCapMax > 0 && level > levelCapMax) level = levelCapMax;
return level;
}
}

View File

@ -1,55 +0,0 @@
package su.nightexpress.excellentenchants.enchantment.data;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicSettings;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.nightcore.config.FileConfig;
public class PeriodSettingsImpl implements PeriodicSettings {
private final Modifier triggerInterval;
private long nextTriggerTime;
public PeriodSettingsImpl(@NotNull Modifier triggerInterval) {
this.triggerInterval = triggerInterval;
this.updateTriggerTime();
}
@NotNull
public static PeriodSettingsImpl create(@NotNull FileConfig config) {
long baseTick = Config.CORE_PASSIVE_ENCHANTS_TRIGGER_INTERVAL.get();
return create(config, Modifier.add(baseTick, 0, 1));
}
@NotNull
public static PeriodSettingsImpl create(@NotNull FileConfig config, @NotNull Modifier def) {
Modifier intervalMod = Modifier.read(config, "Settings.Trigger_Interval", def,
"Sets how often (in ticks) this enchantment will be triggered.",
"20 ticks = 1 second.");
return new PeriodSettingsImpl(intervalMod);
}
@Override
public long getInterval() {
return (long) this.triggerInterval.getValue(1);
}
@Override
public long getNextTriggerTime() {
return nextTriggerTime;
}
@Override
public boolean isTriggerTime() {
return System.currentTimeMillis() >= this.getNextTriggerTime();
}
@Override
public void updateTriggerTime() {
this.nextTriggerTime = System.currentTimeMillis() + this.getInterval() * 50L - 100L;
}
}

View File

@ -1,43 +0,0 @@
package su.nightexpress.excellentenchants.enchantment.data;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.distribution.VanillaOptions;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
public class VanillaDistribution implements VanillaOptions {
private boolean discoverable;
private boolean tradeable;
@Override
public void load(@NotNull FileConfig config) {
this.setTradeable(ConfigValue.create("Distribution.Tradeable",
true,
"Sets whether or not this enchantment can be populated in villager trades.").read(config));
this.setDiscoverable(ConfigValue.create("Distribution.Discoverable",
true,
"Sets whether or not this enchantment can be populated in enchanting table.").read(config));
}
@Override
public boolean isTradeable() {
return this.tradeable;
}
@Override
public void setTradeable(boolean tradeable) {
this.tradeable = tradeable;
}
@Override
public boolean isDiscoverable() {
return discoverable;
}
@Override
public void setDiscoverable(boolean discoverable) {
this.discoverable = discoverable;
}
}

View File

@ -0,0 +1,114 @@
package su.nightexpress.excellentenchants.enchantment.impl;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.Charges;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import static su.nightexpress.nightcore.util.Placeholders.WIKI_ITEMS_URL;
public class EnchantCharges implements Charges {
private boolean enabled;
private boolean customFuel;
private Modifier maxAmount;
private Modifier consumeAmount;
private Modifier rechargeAmount;
private ItemStack fuel;
public EnchantCharges() {
}
public void load(@NotNull FileConfig config) {
this.enabled = ConfigValue.create("Charges.Enabled",
false,
"When 'true' enables the Charges system for this enchantment.",
"[*] Enchantments in enchanting table are generated with maximum charges."
).read(config);
if (!this.enabled) return;
this.customFuel = ConfigValue.create("Charges.Custom_Fuel",
false,
"When 'true' uses different (non-default) fuel item (from the 'Fuel_Item' setting) to recharge."
).read(config);
this.maxAmount = Modifier.read(config, "Charges.Maximum",
Modifier.add(100, 25, 1),
"Maximum amount of charges for the enchantment."
);
this.consumeAmount = Modifier.read(config, "Charges.Consume_Amount",
Modifier.add(1, 0, 0),
"How many charges will be consumed when enchantment is triggered?"
);
this.rechargeAmount = Modifier.read(config, "Charges.Recharge_Amount",
Modifier.add(25, 5, 1),
"How many charges will be restored when using 'Fuel Item' in anvil?"
);
this.fuel = ConfigValue.create("Charges.Fuel_Item",
new ItemStack(Material.LAPIS_LAZULI),
"An item, that will be used to restore enchantment charges on anvils.",
WIKI_ITEMS_URL
).read(config);
}
@Override
public int getMaxAmount(int level) {
return this.isEnabled() ? this.getMaxAmount().getIntValue(level) : 0;
}
@Override
public int getConsumeAmount(int level) {
return this.isEnabled() ? this.getConsumeAmount().getIntValue(level) : 0;
}
@Override
public int getRechargeAmount(int level) {
return this.isEnabled() ? this.getRechargeAmount().getIntValue(level) : 0;
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isCustomFuel() {
return customFuel;
}
@Override
@NotNull
public Modifier getMaxAmount() {
return maxAmount;
}
@NotNull
public ItemStack getFuel() {
ItemStack fuelHas = this.fuel;
if (!this.isCustomFuel() || fuelHas == null || fuelHas.getType().isAir()) {
return new ItemStack(Config.ENCHANTMENTS_CHARGES_FUEL_ITEM.get());
}
return new ItemStack(fuelHas);
}
@Override
@NotNull
public Modifier getConsumeAmount() {
return consumeAmount;
}
@Override
@NotNull
public Modifier getRechargeAmount() {
return rechargeAmount;
}
}

View File

@ -0,0 +1,226 @@
package su.nightexpress.excellentenchants.enchantment.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.EnchantsAPI;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.Cost;
import su.nightexpress.excellentenchants.api.enchantment.Definition;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.util.EnchantUtils;
import su.nightexpress.excellentenchants.rarity.EnchantRarity;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.StringUtil;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.List;
import java.util.Set;
public class EnchantDefinition implements Definition {
private final String rarityId;
private final ItemsCategory supportedItems;
private final ItemsCategory primaryItems;
private List<String> description;
private String displayName;
private Rarity rarity;
private Set<String> conflicts;
private int maxLevel;
private Cost minCost;
private Cost maxCost;
private int anvilCost;
public EnchantDefinition(@NotNull List<String> description,
@NotNull String rarityId,
int maxLevel,
@NotNull ItemsCategory supportedItems,
@Nullable ItemsCategory primaryItems,
@Nullable Set<String> conflicts) {
this.rarityId = rarityId;
this.description = description;
this.maxLevel = maxLevel;
this.supportedItems = supportedItems;
this.primaryItems = primaryItems;
this.conflicts = conflicts;
}
@NotNull
public static EnchantDefinition create(@NotNull List<String> description,
@NotNull String rarityId,
int maxLevel,
@NotNull ItemsCategory supportedItems,
@Nullable ItemsCategory primaryItems,
@Nullable Set<String> conflicts) {
return new EnchantDefinition(description, rarityId, maxLevel, supportedItems, primaryItems, conflicts);
}
@NotNull
public static EnchantDefinition create(@NotNull String description,
@NotNull String rarityId,
int maxLevel,
@NotNull ItemsCategory supportedItems,
@Nullable ItemsCategory primaryItems) {
return create(Lists.newList(description), rarityId, maxLevel, supportedItems, primaryItems, null);
}
@NotNull
public static EnchantDefinition create(@NotNull String description,
@NotNull String rarityId,
int maxLevel,
@NotNull ItemsCategory supportedItems) {
return create(description, rarityId, maxLevel, supportedItems, (ItemsCategory) null);
}
@NotNull
public static EnchantDefinition create(@NotNull String description,
@NotNull String rarityId,
int maxLevel,
@NotNull ItemsCategory supportedItems,
@NotNull Set<String> conflicts) {
return create(Lists.newList(description), rarityId, maxLevel, supportedItems, null, conflicts);
}
public void load(@NotNull GameEnchantment enchantment, @NotNull FileConfig config) {
String rarityId = ConfigValue.create("Settings.Rarity",
this.rarityId,
"Rarity affects the chance of getting an enchantment from enchanting or loots depending on rarity weight value.",
"You can create and edit rarities in the config.yml"
).read(config);
Rarity rarity = EnchantsAPI.getRarityManager().getRarity(rarityId);
if (rarity == null) {
enchantment.error("Invalid rarity '" + rarityId + "' for the '" + enchantment.getId() + "' enchantment! Replaced with dummy one.");
rarity = EnchantRarity.DUMMY;
}
this.rarity = rarity;
this.displayName = ConfigValue.create("Settings.Name",
StringUtil.capitalizeUnderscored(enchantment.getId()),
"Enchantment display name."
).read(config);
this.description = ConfigValue.create("Settings.Description",
this.description,
"Enchantment description.",
"You can use 'Enchantment' placeholders: " + Placeholders.WIKI_PLACEHOLDERS
).read(config);
this.setMaxLevel(ConfigValue.create("Settings.Level.Max",
this.maxLevel,
"The maximum level of this enchantment.",
"Value between 1 and 255 (inclusive).",
"[*] Reboot required when changed."
).read(config));
this.conflicts = ConfigValue.create("Settings.Conflicts",
this.conflicts,
"Enchantments that are incompatible with this enchantment.",
"[*] Reboot required when changed."
).read(config);
int costCap = Rnd.get(45, 65) + 1;
int costPerLevel = (int) ((double) costCap / (double) this.maxLevel);
int minCost = Rnd.nextInt(5) + 1;
int maxCost = this.maxLevel == 1 ? costPerLevel : Rnd.get(3, 7) + minCost;
// int costBase = 45;
// int costStart = Rnd.get(5) + 1;
// int costMod = Rnd.get(10) + 1;
// int costPerLevel = (int) ((double) costBase / (double) this.getMaxLevel());
this.minCost = Cost.read(config, "Settings.Cost.Min",
new Cost(minCost, costPerLevel),
"The minimum possible cost of this enchantment in levels.",
"Explanation: https://minecraft.wiki/w/Enchanting_mechanics#How_enchantments_are_chosen",
"Vanilla costs: https://minecraft.wiki/w/Enchanting/Levels",
"[*] Reboot required when changed."
);
this.maxCost = Cost.read(config, "Settings.Cost.Max",
new Cost(maxCost, costPerLevel),
"The maximum possible cost of this enchantment in levels.",
"Explanation: https://minecraft.wiki/w/Enchanting_mechanics#How_enchantments_are_chosen",
"Vanilla costs: https://minecraft.wiki/w/Enchanting/Levels",
"[*] Reboot required when changed."
);
this.anvilCost = ConfigValue.create("Settings.Cost.Anvil",
Rnd.get(8) + 1,
"The base cost when applying this enchantment to another item using an anvil. Halved when adding using a book, multiplied by the level of the enchantment.",
"[*] Reboot required when changed."
).read(config);
}
private void setMaxLevel(int levelMax) {
this.maxLevel = Math.clamp(levelMax, 1, EnchantUtils.LEVEL_CAP);
}
@Override
public boolean hasConflicts() {
return this.conflicts != null && !this.conflicts.isEmpty();
}
@NotNull
@Override
public ItemsCategory getSupportedItems() {
return this.supportedItems;
}
@NotNull
@Override
public ItemsCategory getPrimaryItems() {
return this.primaryItems == null ? this.supportedItems : this.primaryItems;
}
@NotNull
@Override
public Set<String> getConflicts() {
return conflicts;
}
@NotNull
@Override
public String getDisplayName() {
return displayName;
}
@NotNull
@Override
public List<String> getDescription() {
return description;
}
@NotNull
@Override
public Rarity getRarity() {
return rarity;
}
@Override
public int getMaxLevel() {
return maxLevel;
}
@NotNull
@Override
public Cost getMinCost() {
return minCost;
}
@NotNull
@Override
public Cost getMaxCost() {
return maxCost;
}
@Override
public int getAnvilCost() {
return anvilCost;
}
}

View File

@ -0,0 +1,170 @@
package su.nightexpress.excellentenchants.enchantment.impl;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.Distribution;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.StringUtil;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class EnchantDistribution implements Distribution {
private Set<TradeType> tradeTypes;
private boolean treasure;
private boolean discoverable;
private boolean tradable;
private boolean onMobSpawnEquipment;
private boolean onRandomLoot;
private boolean onTradedEquipment;
public EnchantDistribution(@NotNull Set<TradeType> tradeTypes,
boolean treasure,
boolean discoverable,
boolean tradable,
boolean onMobSpawnEquipment,
boolean onRandomLoot,
boolean onTradedEquipment) {
this.tradeTypes = tradeTypes;
this.treasure = treasure;
this.discoverable = discoverable;
this.tradable = tradable;
this.onMobSpawnEquipment = onMobSpawnEquipment;
this.onRandomLoot = onRandomLoot;
this.onTradedEquipment = onTradedEquipment;
}
@NotNull
public static EnchantDistribution defaults() {
return new EnchantDistribution(
new HashSet<>(Arrays.asList(TradeType.values())),
false,
true,
true,
true,
true,
true
);
}
@NotNull
public static EnchantDistribution regular(@NotNull TradeType... tradeTypes) {
return new EnchantDistribution(
new HashSet<>(Arrays.asList(tradeTypes)),
false,
true,
true,
true,
true,
true
);
}
@NotNull
public static EnchantDistribution treasure(@NotNull TradeType... tradeTypes) {
return new EnchantDistribution(
new HashSet<>(Arrays.asList(tradeTypes)),
true,
false,
true,
false,
true,
false
);
}
public void load(@NotNull FileConfig config) {
this.treasure = ConfigValue.create("Distribution.Treasure",
this.treasure,
"Sets whether this enchantment is a treasure enchantment.",
"Treasure enchantments are those that can't be obtained using an enchantment table, and won't be generated on randomly enchanted equipment sold by villagers or worn by mobs.",
"Treasure enchantments can only be received via looting, trading, or fishing.",
"If a treasure enchantment is tradable, it will have double the price (before capping to 64 emeralds) compared to a non-treasure enchantment of the same level.",
"[*] Reboot required when changed."
).read(config);
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."
).read(config);
this.tradeTypes = ConfigValue.forSet("Distribution.TradeTypes",
name -> StringUtil.getEnum(name, TradeType.class).orElse(null),
(cfg, path, set) -> cfg.set(path, set.stream().map(Enum::name).toList()),
() -> new HashSet<>(this.tradeTypes),
"Sets in which village biomes this enchantment can be found in villager trades.",
"Allowed values: [" + StringUtil.inlineEnum(TradeType.class, ", ") + "]",
"https://minecraft.wiki/w/Villager_Trade_Rebalance#Trading",
"[*] Reboot required when changed.",
"[**] Has no effect if 'Tradeable' is set on 'false' and Villager Trade Rebalance is disabled."
).read(config);
this.onMobSpawnEquipment = ConfigValue.create("Distribution.On_Mob_Spawn_Equipment",
this.onMobSpawnEquipment,
"Sets whether or not this enchantment can be found on spawned mobs' equipment.",
"[*] Reboot required when changed.",
"[**] Has no effect if 'Treasure' is set on 'true'."
).read(config);
this.onTradedEquipment = ConfigValue.create("Distribution.On_Traded_Equipment",
this.onTradedEquipment,
"Sets whether or not this enchantment can be found on equipment sold by villagers.",
"[*] Reboot required when changed.",
"[**] Has no effect if 'Treasure' is set on 'true'."
).read(config);
this.onRandomLoot = ConfigValue.create("Distribution.On_Random_Loot",
this.onRandomLoot,
"Sets whether or not this enchantment can be found on naturally generated equipment from loot tables.",
"[*] Reboot required when changed."
).read(config);
this.discoverable = ConfigValue.create("Distribution.Discoverable",
this.discoverable,
"Sets whether or not this enchantment can be generated in enchanting table.",
"[*] Reboot required when changed.",
"[**] Has no effect if 'Treasure' is set on 'true'."
).read(config);
}
@Override
public boolean isTreasure() {
return this.treasure;
}
@Override
public boolean isTradable() {
return this.tradable;
}
@Override
@NotNull
public Set<TradeType> getTrades() {
return this.tradeTypes;
}
@Override
public boolean isDiscoverable() {
return discoverable;
}
@Override
public boolean isOnMobSpawnEquipment() {
return onMobSpawnEquipment;
}
@Override
public boolean isOnRandomLoot() {
return onRandomLoot;
}
@Override
public boolean isOnTradedEquipment() {
return onTradedEquipment;
}
}

View File

@ -0,0 +1,315 @@
package su.nightexpress.excellentenchants.enchantment.impl;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
import su.nightexpress.excellentenchants.api.enchantment.meta.EnchantMeta;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.util.EnchantPlaceholders;
import su.nightexpress.excellentenchants.util.EnchantUtils;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.manager.AbstractFileData;
import su.nightexpress.nightcore.manager.SimpeListener;
import su.nightexpress.nightcore.util.PDCUtil;
import su.nightexpress.nightcore.util.placeholder.PlaceholderMap;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
public abstract class GameEnchantment extends AbstractFileData<EnchantsPlugin> implements CustomEnchantment {
protected final EnchantMeta meta;
protected final EnchantDefinition definition;
protected final EnchantDistribution distribution;
protected final EnchantCharges charges;
private final NamespacedKey chargesKey;
private final EnchantPlaceholders placeholders;
private final String logPrefix;
private Enchantment enchantment;
private boolean hiddenFromList;
private boolean visualEffects;
public GameEnchantment(@NotNull EnchantsPlugin plugin, @NotNull File file, @NotNull EnchantDefinition definition) {
this(plugin, file, definition, EnchantDistribution.defaults());
}
public GameEnchantment(@NotNull EnchantsPlugin plugin, @NotNull File file, @NotNull EnchantDefinition definition, @NotNull EnchantDistribution distribution) {
super(plugin, file);
this.meta = new EnchantMeta();
this.definition = definition;
this.distribution = distribution;
this.charges = new EnchantCharges();
this.chargesKey = new NamespacedKey(plugin, this.getId() + "_charges");
this.placeholders = Placeholders.forEnchant(this);
this.logPrefix = "[" + this.getId() + "] ";
}
public void registerListeners() {
if (this instanceof SimpeListener listener) {
this.plugin.getPluginManager().registerEvents(listener, plugin);
}
}
@Override
public boolean checkServerRequirements() {
return true;
}
@Override
protected boolean onLoad(@NotNull FileConfig config) {
this.loadMain(config);
this.loadSettings(config);
this.loadAdditional(config);
this.registerListeners();
return true;
}
private void loadMain(@NotNull FileConfig config) {
this.definition.load(this, config);
this.distribution.load(config);
if (Config.isChargesEnabled() && !this.isCurse()) {
this.charges.load(config);
}
}
private void loadSettings(@NotNull FileConfig config) {
this.hiddenFromList = ConfigValue.create("Settings.Hide_From_List",
false,
"Sets whether or not this enchantment will be hidden from Enchants GUI."
).read(config);
this.visualEffects = ConfigValue.create("Settings.VisualEffects.Enabled",
true,
"Enables enchantment visual effects (mostly particles)."
).read(config);
}
protected abstract void loadAdditional(@NotNull FileConfig config);
@Override
protected void onSave(@NotNull FileConfig config) {
}
public void onRegister(@NotNull Enchantment enchantment) {
if (this.enchantment != null) return;
this.enchantment = enchantment;
}
protected void info(@NotNull String text) {
this.plugin.info(this.logPrefix + text);
}
protected void warn(@NotNull String text) {
this.plugin.warn(this.logPrefix + text);
}
protected void error(@NotNull String text) {
this.plugin.error(this.logPrefix + text);
}
@NotNull
public PlaceholderMap getPlaceholders(int level) {
return this.placeholders.toMap(level);
}
public void addPlaceholder(@NotNull String key, @NotNull Function<Integer, String> replacer) {
this.placeholders.add(key, replacer);
}
@Override
@NotNull
public Enchantment getBukkitEnchantment() {
return this.enchantment;
}
@Override
@NotNull
public EnchantMeta getMeta() {
return this.meta;
}
@NotNull
@Override
public EnchantDefinition getDefinition() {
return definition;
}
@NotNull
@Override
public EnchantDistribution getDistribution() {
return distribution;
}
@NotNull
@Override
public EnchantCharges getCharges() {
return this.charges;
}
@Override
public boolean isAvailableToUse(@NotNull World world) {
Set<String> disabled = Config.ENCHANTMENTS_DISABLED_IN_WORLDS.get().getOrDefault(world.getName().toLowerCase(), Collections.emptySet());
return disabled.isEmpty() || (!disabled.contains(this.getId()) && !disabled.contains(Placeholders.WILDCARD));
}
@Override
public boolean isAvailableToUse(@NotNull LivingEntity entity) {
return this.isAvailableToUse(entity.getWorld());
}
@NotNull
public String getDisplayName() {
return this.definition.getDisplayName();
}
@Override
@NotNull
public String getFormattedName() {
return this.isCurse() ? this.getDisplayName() : this.getPlaceholders(1).replacer().apply(this.definition.getRarity().getNameFormat());
}
@Override
@NotNull
public List<String> getDescription() {
return this.definition.getDescription();
}
@Override
@NotNull
public List<String> getDescription(int level) {
return this.getDescription(level, 0);
}
@Override
@NotNull
public List<String> getDescription(int level, int charges) {
List<String> description = new ArrayList<>(this.getDescription());
String lineFormat = Config.ENCHANTMENTS_DISPLAY_DESCRIPTION_FORMAT.get();
description.replaceAll(line -> {
line = lineFormat.replace(Placeholders.GENERIC_DESCRIPTION, line);
line = EnchantUtils.replaceComponents(this, line, level, charges);
line = this.getPlaceholders(level).replacer().apply(line);
return line;
});
return description;
}
@Override
public boolean isHiddenFromList() {
return this.hiddenFromList;
}
@Override
public boolean hasVisualEffects() {
return this.visualEffects;
}
@Override
public boolean isCurse() {
return false;
}
@Override
public boolean hasCharges() {
return this.charges != null && this.charges.isEnabled();
}
@Override
public boolean isChargesFuel(@NotNull ItemStack item) {
if (!this.hasCharges()) return false;
if (Config.ENCHANTMENTS_CHARGES_COMPARE_TYPE_ONLY.get()) {
return item.getType() == this.charges.getFuel().getType();
}
return item.isSimilar(this.charges.getFuel());
}
@Override
public boolean isOutOfCharges(@NotNull ItemStack item) {
return this.hasCharges() && this.getCharges(item) == 0;
}
@Override
public boolean isFullOfCharges(@NotNull ItemStack item) {
if (!this.hasCharges()) return false;
int level = EnchantUtils.getLevel(item, this.getBukkitEnchantment());
int max = this.charges.getMaxAmount(level);
return this.getCharges(item) == max;
}
@Override
public int getCharges(@NotNull ItemStack item) {
ItemMeta meta = item.getItemMeta();
return meta == null ? 0 : this.getCharges(meta);
}
@Override
public int getCharges(@NotNull ItemMeta meta) {
return this.hasCharges() ? PDCUtil.getInt(meta, this.chargesKey).orElse(0) : -1;
}
@Override
public void setCharges(@NotNull ItemStack item, int level, int amount) {
if (!this.hasCharges()) return;
int max = this.charges.getMaxAmount(level);
int set = Math.min(Math.abs(amount), max);
PDCUtil.set(item, this.chargesKey, set);
}
@Override
public void restoreCharges(@NotNull ItemStack item, int level) {
this.setCharges(item, level, Integer.MAX_VALUE);
}
@Override
public void fuelCharges(@NotNull ItemStack item, int level) {
if (!this.hasCharges()) return;
int recharge = this.charges.getRechargeAmount(level);
int has = this.getCharges(item);
int set = has + recharge;
this.setCharges(item, level, set);
}
@Override
public void consumeChargesNoUpdate(@NotNull ItemStack item, int level) {
if (!this.hasCharges()) return;
int charges = this.getCharges(item);
int consumeAmount = this.charges.getConsumeAmount(level);
this.setCharges(item, level, charges < consumeAmount ? 0 : Math.max(0, charges - consumeAmount));
}
@Override
public void consumeCharges(@NotNull ItemStack item, int level) {
if (!this.hasCharges()) return;
this.consumeChargesNoUpdate(item, level);
}
}

View File

@ -8,71 +8,51 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
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.nightcore.config.FileConfig;
import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class ColdSteelEnchant extends AbstractEnchantmentData implements ChanceData, PotionData, CombatEnchant {
public class ColdSteelEnchant extends GameEnchantment implements ChanceMeta, PotionMeta, CombatEnchant {
public static final String ID = "cold_steel";
private ChanceSettingsImpl chanceSettings;
private PotionSettingsImpl potionSettings;
public ColdSteelEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to apply " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.) on attacker.");
this.setRarity(Rarity.COMMON);
this.setMaxLevel(3);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SNOW_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to apply " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.) on attacker.",
EnchantRarity.RARE,
3,
ItemCategories.TORSO
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(8, 2, 1));
this.meta.setProbability(Probability.create(config, Modifier.add(8, 2, 1)));
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.SLOW_DIGGING, false,
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.MINING_FATIGUE, false,
Modifier.add(4, 1, 1, 300),
Modifier.add(0, 1,1, 5)
);
));
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.TORSO;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_TORSO;
// }
@NotNull
@Override
public EventPriority getProtectPriority() {

View File

@ -9,17 +9,17 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
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.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
@ -27,54 +27,34 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class DarknessCloakEnchant extends AbstractEnchantmentData implements ChanceData, PotionData, CombatEnchant {
public class DarknessCloakEnchant extends GameEnchantment implements ChanceMeta, PotionMeta, CombatEnchant {
public static final String ID = "darkness_cloak";
private ChanceSettingsImpl chanceSettings;
private PotionSettingsImpl potionSettings;
public DarknessCloakEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to apply " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.) on attacker.");
this.setMaxLevel(3);
this.setRarity(Rarity.COMMON);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SWAMP_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to apply " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.) on attacker.",
EnchantRarity.COMMON,
3,
ItemCategories.TORSO
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(11, 3, 1));
this.meta.setProbability(Probability.create(config, Modifier.add(11, 3, 1)));
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.DARKNESS, false,
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.DARKNESS, false,
Modifier.add(5, 1, 1, 300),
Modifier.add(0, 1, 1, 10)
);
));
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.TORSO;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_TORSO;
// }
@NotNull
@Override
public EventPriority getProtectPriority() {

View File

@ -8,53 +8,66 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.type.GenericEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
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.excellentenchants.util.EnchantUtils;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.manager.SimpeListener;
import su.nightexpress.nightcore.util.EntityUtil;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.NumberUtil;
import java.io.File;
import java.util.Set;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_AMOUNT;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_MAX;
import static su.nightexpress.excellentenchants.Placeholders.*;
import static org.bukkit.event.entity.EntityDamageEvent.DamageCause;
public class ElementalProtectionEnchant extends AbstractEnchantmentData implements SimpeListener, GenericEnchant {
public class ElementalProtectionEnchant extends GameEnchantment implements SimpeListener, GenericEnchant {
public static final String ID = "elemental_protection";
private static final Set<EntityDamageEvent.DamageCause> DAMAGE_CAUSES = Set.of(
EntityDamageEvent.DamageCause.POISON, EntityDamageEvent.DamageCause.WITHER,
EntityDamageEvent.DamageCause.MAGIC, EntityDamageEvent.DamageCause.FREEZE,
EntityDamageEvent.DamageCause.LIGHTNING);
private static final Set<DamageCause> DAMAGE_CAUSES = Lists.newSet(
DamageCause.POISON, DamageCause.WITHER,
DamageCause.MAGIC, DamageCause.FREEZE,
DamageCause.LIGHTNING
);
private Modifier protectionAmount;
private double protectionCapacity;
private boolean protectionAsModifier;
public ElementalProtectionEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription("Reduces Poison, Magic, Wither, Lightning, Freeze damage by " + GENERIC_AMOUNT + "%.");
this.setMaxLevel(5);
this.setRarity(Rarity.COMMON);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SWAMP_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Reduces Poison, Magic, Wither, Lightning, Freeze damage by " + GENERIC_AMOUNT + "%.",
EnchantRarity.COMMON,
5,
ItemCategories.ARMOR
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.protectionAmount = Modifier.read(config, "Settings.Protection.Amount",
Modifier.add(0, 5, 1, 100),
"Protection amount given by enchantment.");
Modifier.add(0, 4, 1, 100),
"Protection amount given by enchantment."
);
this.protectionCapacity = ConfigValue.create("Settings.Protection.Capacity",
100D,
"Maximal possible protection value from all armor pieces together.").read(config);
"Maximal possible protection value from all armor pieces together."
).read(config);
this.protectionAsModifier = ConfigValue.create("Settings.Protection.As_Modifier",
true,
@ -65,18 +78,6 @@ public class ElementalProtectionEnchant extends AbstractEnchantmentData implemen
this.addPlaceholder(GENERIC_MAX, level -> NumberUtil.format(this.getProtectionCapacity()));
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.ARMOR;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR;
// }
public double getProtectionAmount(int level) {
return this.protectionAmount.getValue(level);
}
@ -95,13 +96,11 @@ public class ElementalProtectionEnchant extends AbstractEnchantmentData implemen
if (!(event.getEntity() instanceof LivingEntity entity)) return;
if (!this.isAvailableToUse(entity)) return;
// TODO Work as percent to ignore damage
double protectionAmount = 0D;
for (ItemStack armor : EntityUtil.getEquippedArmor(entity).values()) {
if (armor == null || armor.getType().isAir()) continue;
int level = EnchantUtils.getLevel(armor, this.getEnchantment());
int level = EnchantUtils.getLevel(armor, this.getBukkitEnchantment());
if (level <= 0) continue;
protectionAmount += this.getProtectionAmount(level);

View File

@ -9,14 +9,15 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
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.FileConfig;
import su.nightexpress.nightcore.util.NumberUtil;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
@ -27,23 +28,29 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_DURATION;
public class FireShieldEnchant extends AbstractEnchantmentData implements ChanceData, CombatEnchant {
public class FireShieldEnchant extends GameEnchantment implements ChanceMeta, CombatEnchant {
public static final String ID = "fire_shield";
private Modifier fireDuration;
private ChanceSettingsImpl chanceSettings;
private Modifier fireDuration;
public FireShieldEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to ignite attackers for " + GENERIC_DURATION + "s.");
this.setMaxLevel(3);
this.setRarity(Rarity.UNCOMMON);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.DESERT_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to ignite attackers for " + GENERIC_DURATION + "s.",
EnchantRarity.RARE,
3,
ItemCategories.ARMOR
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3, 2, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(3, 2, 1, 100)));
this.fireDuration = Modifier.read(config, "Settings.Fire.Duration",
Modifier.multiply(2, 1, 1, 600),
@ -54,24 +61,6 @@ public class FireShieldEnchant extends AbstractEnchantmentData implements Chance
this.addPlaceholder(GENERIC_DURATION, level -> NumberUtil.format(this.getFireDuration(level)));
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.ARMOR;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR;
// }
@NotNull
@Override
public EventPriority getProtectPriority() {

View File

@ -19,69 +19,88 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.type.GenericEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
import su.nightexpress.excellentenchants.api.enchantment.bridge.FlameWalker;
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.Pair;
import su.nightexpress.nightcore.util.random.Rnd;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
public class FlameWalkerEnchant extends AbstractEnchantmentData implements GenericEnchant, SimpeListener {
public class FlameWalkerEnchant extends GameEnchantment implements GenericEnchant, FlameWalker, SimpeListener {
public static final String ID = "flame_walker";
private static final BlockFace[] FACES = {BlockFace.SOUTH, BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST};
private static final Map<Location, Pair<Long, Integer>> BLOCKS_TO_DESTROY = new ConcurrentHashMap<>();
private static final BlockFace[] FACES = {BlockFace.SOUTH, BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST};
private Modifier radius;
private Modifier blockDecayTime;
public FlameWalkerEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription("Ability to walk on lava, ignore magma block damage.");
this.setMaxLevel(3);
this.setRarity(Rarity.RARE);
this.setConflicts(Enchantment.FROST_WALKER.getKey().getKey());
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.DESERT_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
Lists.newList("Ability to walk on lava, ignore magma block damage."),
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOOTS,
null,
Lists.newSet(BukkitThing.toString(Enchantment.FROST_WALKER))
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.radius = Modifier.read(config, "Settings.Radius",
Modifier.add(3.0, 1.0, 1, 16),
"Sets max radius."
);
this.blockDecayTime = Modifier.read(config, "Settings.Block_Decay",
Modifier.add(8, 1, 1, 120),
"Sets up to how long (in seconds) blocks will stay before turn back to lava.");
"Sets up to how long (in seconds) blocks will stay before turn back into lava."
);
}
@NotNull
@Override
public Modifier getRadius() {
return radius;
}
@Override
public double getBlockDecayTime(int level) {
return this.blockDecayTime.getValue(level);
}
@Override
public void clear() {
BLOCKS_TO_DESTROY.keySet().forEach(location -> location.getBlock().setType(Material.LAVA));
BLOCKS_TO_DESTROY.clear();
}
public static void addBlock(@NotNull Block block, double seconds) {
BLOCKS_TO_DESTROY.put(block.getLocation(), Pair.of(System.currentTimeMillis() + (long) seconds * 1000L, Rnd.get(1000)));
MAGMA_BLOCKS.keySet().forEach(location -> location.getBlock().setType(Material.LAVA));
MAGMA_BLOCKS.clear();
}
public static boolean isBlock(@NotNull Block block) {
return BLOCKS_TO_DESTROY.containsKey(block.getLocation());
return MAGMA_BLOCKS.containsKey(block.getLocation());
}
public static void tickBlocks() {
long now = System.currentTimeMillis();
BLOCKS_TO_DESTROY.keySet().removeIf(location -> location.getBlock().isLiquid() || location.getBlock().getType() != Material.MAGMA_BLOCK);
BLOCKS_TO_DESTROY.forEach((location, pair) -> {
MAGMA_BLOCKS.keySet().removeIf(location -> location.getBlock().isLiquid() || location.getBlock().getType() != Material.MAGMA_BLOCK);
MAGMA_BLOCKS.forEach((location, pair) -> {
Block block = location.getBlock();
long time = pair.getFirst();
if (now >= time) {
@ -106,22 +125,6 @@ public class FlameWalkerEnchant extends AbstractEnchantmentData implements Gener
});
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOOTS;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_FEET;
// }
public double getBlockDecayTime(int level) {
return this.blockDecayTime.getValue(level);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
@ -135,22 +138,37 @@ public class FlameWalkerEnchant extends AbstractEnchantmentData implements Gener
ItemStack boots = player.getInventory().getBoots();
if (boots == null || boots.getType().isAir()) return;
int level = EnchantUtils.getLevel(boots, this.getEnchantment());
int level = EnchantUtils.getLevel(boots, this.getBukkitEnchantment());
if (level <= 0) return;
Block bTo = to.getBlock().getRelative(BlockFace.DOWN);
boolean hasLava = Stream.of(FACES).anyMatch(face -> bTo.getRelative(face).getType() == Material.LAVA);
if (!hasLava) return;
Set<Block> blocks = plugin.getEnchantNMS().handleFlameWalker(player, player.getLocation(), level);
blocks.forEach(block -> {
addBlock(block, Rnd.getDouble(this.getBlockDecayTime(level)) + 1);
});
if (!blocks.isEmpty()) {
if (plugin.getEnchantNMS().handleFlameWalker(this, player, level)) {
this.consumeCharges(boots, level);
}
}
@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;
EntityEquipment equipment = livingEntity.getEquipment();
if (equipment == null) return;
ItemStack boots = equipment.getBoots();
if (boots == null || boots.getType().isAir()) return;
int level = EnchantUtils.getLevel(boots, this.getBukkitEnchantment());
if (level <= 0) return;
event.setCancelled(true);
this.consumeCharges(boots, level);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onFlameWalkerBlock(BlockBreakEvent event) {
if (isBlock(event.getBlock())) {
@ -179,23 +197,4 @@ public class FlameWalkerEnchant extends AbstractEnchantmentData implements Gener
return false;
});
}
@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;
EntityEquipment equipment = livingEntity.getEquipment();
if (equipment == null) return;
ItemStack boots = equipment.getBoots();
if (boots == null || boots.getType().isAir()) return;
int level = EnchantUtils.getLevel(boots, this.getEnchantment());
if (level <= 0) return;
event.setCancelled(true);
this.consumeCharges(boots, level);
}
}

View File

@ -8,71 +8,51 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
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.nightcore.config.FileConfig;
import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class HardenedEnchant extends AbstractEnchantmentData implements ChanceData, PotionData, CombatEnchant {
public class HardenedEnchant extends GameEnchantment implements ChanceMeta, PotionMeta, CombatEnchant {
public static final String ID = "hardened";
private ChanceSettingsImpl chanceSettings;
private PotionSettingsImpl potionSettings;
public HardenedEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to get " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.) when damaged.");
this.setMaxLevel(3);
this.setRarity(Rarity.UNCOMMON);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.PLAINS_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to get " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.) when damaged.",
EnchantRarity.RARE,
3,
ItemCategories.TORSO
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(2, 2, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(2, 2, 1, 100)));
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.DAMAGE_RESISTANCE, false,
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.RESISTANCE, false,
Modifier.add(2, 1, 1, 300),
Modifier.add(0, 1, 1.5, 5)
);
));
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.TORSO;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_TORSO;
// }
@NotNull
@Override
public EventPriority getProtectPriority() {

View File

@ -11,17 +11,17 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
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.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
import su.nightexpress.nightcore.util.wrapper.UniSound;
@ -30,41 +30,33 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class IceShieldEnchant extends AbstractEnchantmentData implements ChanceData, PotionData, CombatEnchant {
public class IceShieldEnchant extends GameEnchantment implements ChanceMeta, PotionMeta, CombatEnchant {
public static final String ID = "ice_shield";
private ChanceSettingsImpl chanceSettings;
private PotionSettingsImpl potionSettings;
public IceShieldEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to freeze and apply " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.) on attacker.");
this.setMaxLevel(3);
this.setRarity(Rarity.COMMON);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SNOW_COMMON));
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(4, 4, 1, 100));
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.SLOW, false,
Modifier.add(2, 2, 1, 300),
Modifier.add(0, 1, 1, 5)
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to freeze and apply " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.) on attacker.",
EnchantRarity.COMMON,
3,
ItemCategories.TORSO
);
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.TORSO;
}
protected void loadAdditional(@NotNull FileConfig config) {
this.meta.setProbability(Probability.create(config, Modifier.add(4, 4, 1, 100)));
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_TORSO;
// }
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.SLOWNESS, false,
Modifier.add(2, 2, 1, 300),
Modifier.add(0, 1, 1, 5)
));
}
@NotNull
@Override
@ -72,18 +64,6 @@ public class IceShieldEnchant extends AbstractEnchantmentData implements ChanceD
return EventPriority.HIGHEST;
}
@Override
@NotNull
public ChanceSettings getChanceSettings() {
return this.chanceSettings;
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@Override
public boolean onAttack(@NotNull EntityDamageByEntityEvent event, @NotNull LivingEntity damager, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
return false;

View File

@ -5,16 +5,16 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.Period;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
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.nightcore.config.FileConfig;
import java.io.File;
@ -22,50 +22,30 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_POTION_LEVEL;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_POTION_TYPE;
public class JumpingEnchant extends AbstractEnchantmentData implements PotionData, PassiveEnchant {
public class JumpingEnchant extends GameEnchantment implements PotionMeta, PassiveEnchant {
public static final String ID = "bunny_hop";
private PotionSettingsImpl potionSettings;
private PeriodSettingsImpl periodSettings;
public JumpingEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setMaxLevel(3);
this.setRarity(Rarity.COMMON);
this.setDescription("Grants permanent " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " effect.");
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.PLAINS_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Grants permanent " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " effect.",
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOOTS
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.JUMP, true);
this.periodSettings = PeriodSettingsImpl.create(config);
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.JUMP_BOOST, true));
this.meta.setPeriod(Period.create(config));
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@NotNull
@Override
public PeriodicSettings getPeriodSettings() {
return periodSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOOTS;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_FEET;
// }
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
return this.addEffect(entity, level);

View File

@ -14,14 +14,15 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.type.DeathEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
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;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.manager.SimpeListener;
@ -31,26 +32,32 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
public class KamikadzeEnchant extends AbstractEnchantmentData implements ChanceData, DeathEnchant, SimpeListener {
public class KamikadzeEnchant extends GameEnchantment implements ChanceMeta, DeathEnchant, SimpeListener {
public static final String ID = "self_destruction";
private Modifier explosionSize;
private boolean applyOnResurrect;
private ChanceSettingsImpl chanceSettings;
private Modifier explosionSize;
private boolean applyOnResurrect;
private Entity exploder;
public KamikadzeEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to create an explosion on death.");
this.setMaxLevel(3);
this.setRarity(Rarity.UNCOMMON);
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.JUNGLE_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to create an explosion on death.",
EnchantRarity.RARE,
3,
ItemCategories.TORSO
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(0, 5, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(0, 5, 1, 100)));
this.applyOnResurrect = ConfigValue.create("Settings.Apply_On_Resurrect",
true,
@ -63,24 +70,6 @@ public class KamikadzeEnchant extends AbstractEnchantmentData implements ChanceD
);
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.TORSO;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_TORSO;
// }
public boolean isApplyOnResurrect() {
return this.applyOnResurrect;
}
@ -99,7 +88,7 @@ public class KamikadzeEnchant extends AbstractEnchantmentData implements ChanceD
this.exploder = null;
if (exploded && this.hasVisualEffects()) {
UniParticle.of(Particle.SMOKE_NORMAL).play(entity.getEyeLocation(), 0.5, 0.1, 60);
UniParticle.of(Particle.SMOKE).play(entity.getEyeLocation(), 0.5, 0.1, 60);
UniParticle.of(Particle.LAVA).play(entity.getEyeLocation(), 1.25, 0.1, 100);
}

View File

@ -5,16 +5,16 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Period;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
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.nightcore.config.FileConfig;
import java.io.File;
@ -22,50 +22,30 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_POTION_LEVEL;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_POTION_TYPE;
public class NightVisionEnchant extends AbstractEnchantmentData implements PotionData, PassiveEnchant {
public class NightVisionEnchant extends GameEnchantment implements PotionMeta, PassiveEnchant {
public static final String ID = "night_vision";
private PotionSettingsImpl potionSettings;
private PeriodSettingsImpl periodSettings;
public NightVisionEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription("Grants permanent " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " effect.");
this.setMaxLevel(1);
this.setRarity(Rarity.VERY_RARE);
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.SWAMP_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Grants permanent " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " effect.",
EnchantRarity.MYTHIC,
1,
ItemCategories.HELMET
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.NIGHT_VISION, true);
this.periodSettings = PeriodSettingsImpl.create(config);
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.NIGHT_VISION, true));
this.meta.setPeriod(Period.create(config));
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@NotNull
@Override
public PeriodicSettings getPeriodSettings() {
return periodSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.HELMET;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_HEAD;
// }
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
return this.addEffect(entity, level);

View File

@ -7,16 +7,16 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicSettings;
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.meta.Period;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
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.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.EntityUtil;
import su.nightexpress.nightcore.util.NumberUtil;
@ -26,7 +26,7 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class RegrowthEnchant extends AbstractEnchantmentData implements ChanceData, PassiveEnchant {
public class RegrowthEnchant extends GameEnchantment implements ChanceMeta, PassiveEnchant {
public static final String ID = "regrowth";
@ -34,21 +34,24 @@ public class RegrowthEnchant extends AbstractEnchantmentData implements ChanceDa
private Modifier maxHealth;
private Modifier healAmount;
private ChanceSettingsImpl chanceSettings;
private PeriodSettingsImpl periodSettings;
public RegrowthEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription("Restores " + GENERIC_AMOUNT + "❤ every few seconds.");
this.setMaxLevel(5);
this.setRarity(Rarity.VERY_RARE);
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.TAIGA_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Restores " + GENERIC_AMOUNT + "❤ every few seconds.",
EnchantRarity.MYTHIC,
5,
ItemCategories.TORSO
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(100, 0, 1, 100));
this.periodSettings = PeriodSettingsImpl.create(config);
this.meta.setProbability(Probability.create(config, Modifier.add(100, 0, 1, 100)));
this.meta.setPeriod(Period.create(config));
this.minHealth = Modifier.read(config, "Settings.Heal.Min_Health",
Modifier.add(0.5, 0, 0),
@ -70,30 +73,6 @@ public class RegrowthEnchant extends AbstractEnchantmentData implements ChanceDa
this.addPlaceholder(GENERIC_MAX, level -> NumberUtil.format(this.getMaxHealthToHeal(level)));
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@NotNull
@Override
public PeriodicSettings getPeriodSettings() {
return periodSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.TORSO;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_TORSO;
// }
public double getHealAmount(int level) {
return this.healAmount.getValue(level);
}

View File

@ -6,13 +6,14 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
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.excellentenchants.api.enchantment.meta.Period;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.NumberUtil;
@ -21,25 +22,30 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_AMOUNT;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_MAX;
public class SaturationEnchant extends AbstractEnchantmentData implements PassiveEnchant {
public class SaturationEnchant extends GameEnchantment implements PassiveEnchant {
public static final String ID = "saturation";
private Modifier feedAmount;
private Modifier maxFoodLevel;
private PeriodSettingsImpl periodSettings;
public SaturationEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription("Restores " + GENERIC_AMOUNT + " food points every few seconds.");
this.setMaxLevel(3);
this.setRarity(Rarity.RARE);
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.SAVANNA_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Restores " + GENERIC_AMOUNT + " food points every few seconds.",
EnchantRarity.LEGENDARY,
3,
ItemCategories.HELMET
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.periodSettings = PeriodSettingsImpl.create(config);
this.meta.setPeriod(Period.create(config));
this.feedAmount = Modifier.read(config, "Settings.Saturation.Amount",
Modifier.add(0, 1, 1, 10),
@ -53,24 +59,6 @@ public class SaturationEnchant extends AbstractEnchantmentData implements Passiv
this.addPlaceholder(GENERIC_MAX, level -> NumberUtil.format(this.getMaxFoodLevel(level)));
}
@NotNull
@Override
public PeriodicSettings getPeriodSettings() {
return periodSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.HELMET;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_HEAD;
// }
public final int getFeedAmount(int level) {
return (int) this.feedAmount.getValue(level);
}

View File

@ -5,16 +5,16 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Period;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
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.nightcore.config.FileConfig;
import java.io.File;
@ -22,50 +22,30 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_POTION_LEVEL;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_POTION_TYPE;
public class SpeedyEnchant extends AbstractEnchantmentData implements PotionData, PassiveEnchant {
public class SpeedyEnchant extends GameEnchantment implements PotionMeta, PassiveEnchant {
public static final String ID = "sonic";
private PotionSettingsImpl potionSettings;
private PeriodSettingsImpl periodSettings;
public SpeedyEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription("Grants permanent " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " effect.");
this.setMaxLevel(3);
this.setRarity(Rarity.UNCOMMON);
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.SAVANNA_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Grants permanent " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " effect.",
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOOTS
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.SPEED, true);
this.periodSettings = PeriodSettingsImpl.create(config);
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.SPEED, true));
this.meta.setPeriod(Period.create(config));
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@NotNull
@Override
public PeriodicSettings getPeriodSettings() {
return periodSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOOTS;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_FEET;
// }
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
return this.addEffect(entity, level);

View File

@ -7,14 +7,15 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
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.FileConfig;
import su.nightexpress.nightcore.util.NumberUtil;
@ -23,23 +24,29 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_AMOUNT;
public class StoppingForceEnchant extends AbstractEnchantmentData implements ChanceData, CombatEnchant {
public class StoppingForceEnchant extends GameEnchantment implements ChanceMeta, CombatEnchant {
public static final String ID = "stopping_force";
private ChanceSettingsImpl chanceSettings;
private Modifier knockbackModifier;
private Modifier knockbackModifier;
public StoppingForceEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to get only " + GENERIC_AMOUNT + "% of knockback in combat.");
this.setMaxLevel(3);
this.setRarity(Rarity.UNCOMMON);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.DESERT_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to get only " + GENERIC_AMOUNT + "% of knockback in combat.",
EnchantRarity.RARE,
3,
ItemCategories.LEGGINGS
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(100, 0, 0, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(100, 0, 0, 100)));
this.knockbackModifier = Modifier.read(config, "Settings.Knockback_Modifier",
Modifier.add(0.9, -0.2, 1),
@ -52,30 +59,12 @@ public class StoppingForceEnchant extends AbstractEnchantmentData implements Cha
return this.knockbackModifier.getValue(level);
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_LEGS;
// }
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.LEGGINGS;
}
@NotNull
@Override
public EventPriority getProtectPriority() {
return EventPriority.HIGHEST;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return this.chanceSettings;
}
@Override
public boolean onAttack(@NotNull EntityDamageByEntityEvent event, @NotNull LivingEntity damager, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
return false;

View File

@ -12,15 +12,16 @@ import org.bukkit.loot.LootTables;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.type.GenericEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
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.excellentenchants.util.EnchantUtils;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.manager.SimpeListener;
@ -35,26 +36,31 @@ import java.util.Set;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
public class TreasureHunterEnchant extends AbstractEnchantmentData implements ChanceData, GenericEnchant, SimpeListener {
public class TreasureHunterEnchant extends GameEnchantment implements ChanceMeta, GenericEnchant, SimpeListener {
public static final String ID = "treasure_hunter";
private ChanceSettingsImpl chanceSettings;
private final Set<LootTables> lootTables;
public TreasureHunterEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to get more items in loot chests.");
this.setMaxLevel(4);
this.setRarity(Rarity.RARE);
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.JUNGLE_COMMON));
this.lootTables = new HashSet<>();
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to get more items in loot chests.",
EnchantRarity.LEGENDARY,
4,
ItemCategories.HELMET
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(2.5, 2.5, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(2.5, 2.5, 1, 100)));
boolean isWhitelist = ConfigValue.create("Settings.LootTables.Whitelist",
false,
@ -88,24 +94,6 @@ public class TreasureHunterEnchant extends AbstractEnchantmentData implements Ch
this.lootTables.clear();
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.HELMET;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_HEAD;
// }
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onLootExplore(LootGenerateEvent event) {
if (this.lootTables.isEmpty()) return;
@ -116,7 +104,7 @@ public class TreasureHunterEnchant extends AbstractEnchantmentData implements Ch
ItemStack helmet = player.getInventory().getHelmet();
if (helmet == null || helmet.getType().isAir()) return;
int level = EnchantUtils.getLevel(helmet, this.getEnchantment());
int level = EnchantUtils.getLevel(helmet, this.getBukkitEnchantment());
if (level < 1) return;
if (!this.checkTriggerChance(level)) return;

View File

@ -5,16 +5,16 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
import su.nightexpress.excellentenchants.api.enchantment.data.PotionSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.Period;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
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.nightcore.config.FileConfig;
import java.io.File;
@ -22,50 +22,30 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_POTION_LEVEL;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_POTION_TYPE;
public class WaterBreathingEnchant extends AbstractEnchantmentData implements PotionData, PassiveEnchant {
public class WaterBreathingEnchant extends GameEnchantment implements PotionMeta, PassiveEnchant {
public static final String ID = "aquaman";
private PotionSettingsImpl potionSettings;
private PeriodSettingsImpl periodSettings;
public WaterBreathingEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setMaxLevel(1);
this.setRarity(Rarity.UNCOMMON);
this.setDescription("Grants permanent " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " effect.");
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.JUNGLE_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Grants permanent " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " effect.",
EnchantRarity.MYTHIC,
1,
ItemCategories.HELMET
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.WATER_BREATHING, true);
this.periodSettings = PeriodSettingsImpl.create(config);
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.WATER_BREATHING, true));
this.meta.setPeriod(Period.create(config));
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@NotNull
@Override
public PeriodicSettings getPeriodSettings() {
return periodSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.HELMET;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.ARMOR_HEAD;
// }
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
return this.addEffect(entity, level);

View File

@ -12,15 +12,18 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
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.FileConfig;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.NumberUtil;
import java.io.File;
@ -28,33 +31,40 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_TIME;
public class BomberEnchant extends AbstractEnchantmentData implements ChanceData, BowEnchant {
public class BomberEnchant extends GameEnchantment implements ChanceMeta, BowEnchant {
public static final String ID = "bomber";
private Modifier fuseTicks;
private ChanceSettingsImpl chanceSettings;
private Modifier fuseTicks;
public BomberEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to launch TNT that explodes in " + GENERIC_TIME + "s.");
this.setMaxLevel(3);
this.setRarity(Rarity.RARE);
this.setConflicts(
EnderBowEnchant.ID, GhastEnchant.ID,
ExplosiveArrowsEnchant.ID, PoisonedArrowsEnchant.ID, ConfusingArrowsEnchant.ID,
WitheredArrowsEnchant.ID, ElectrifiedArrowsEnchant.ID, DragonfireArrowsEnchant.ID,
DarknessArrowsEnchant.ID,
HoverEnchant.ID, FlareEnchant.ID,
Enchantment.ARROW_FIRE.getKey().getKey(),
Enchantment.ARROW_KNOCKBACK.getKey().getKey(),
Enchantment.ARROW_DAMAGE.getKey().getKey()
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.DESERT_SPECIAL));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
Lists.newList(ENCHANTMENT_CHANCE + "% chance to launch TNT that explodes in " + GENERIC_TIME + "s."),
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOWS,
null,
Lists.newSet(
EnderBowEnchant.ID, GhastEnchant.ID,
ExplosiveArrowsEnchant.ID, PoisonedArrowsEnchant.ID, ConfusingArrowsEnchant.ID,
WitheredArrowsEnchant.ID, ElectrifiedArrowsEnchant.ID, DragonfireArrowsEnchant.ID,
DarknessArrowsEnchant.ID,
HoverEnchant.ID, FlareEnchant.ID,
BukkitThing.toString(Enchantment.FLAME),
BukkitThing.toString(Enchantment.PUNCH),
BukkitThing.toString(Enchantment.POWER)
)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3.5, 1.5, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(3.5, 1.5, 1, 100)));
this.fuseTicks = Modifier.read(config, "Settings.Fuse_Ticks",
Modifier.add(110, -10, 1),
@ -63,28 +73,10 @@ public class BomberEnchant extends AbstractEnchantmentData implements ChanceData
this.addPlaceholder(GENERIC_TIME, level -> NumberUtil.format((double) this.getFuseTicks(level) / 20D));
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
public int getFuseTicks(int level) {
return (int) this.fuseTicks.getValue(level);
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
@NotNull
@Override
public EventPriority getShootPriority() {

View File

@ -1,5 +1,6 @@
package su.nightexpress.excellentenchants.enchantment.impl.bow;
import org.bukkit.Color;
import org.bukkit.Particle;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.Arrow;
@ -13,76 +14,55 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.*;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.*;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.data.*;
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.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class ConfusingArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, PotionData, BowEnchant {
public class ConfusingArrowsEnchant extends GameEnchantment implements ChanceMeta, ArrowMeta, PotionMeta, BowEnchant {
public static final String ID = "confusing_arrows";
private ArrowSettingsImpl arrowSettings;
private ChanceSettingsImpl chanceSettings;
private PotionSettingsImpl potionSettings;
public ConfusingArrowsEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.)");
this.setMaxLevel(3);
this.setRarity(Rarity.COMMON);
this.setConflicts(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SWAMP_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.)",
EnchantRarity.COMMON,
3,
ItemCategories.BOWS,
Lists.newSet(
EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID
)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.SPELL_MOB));
this.meta.setArrowEffects(ArrowEffects.create(config, UniParticle.of(Particle.ENTITY_EFFECT, Color.fromRGB(200, 100, 100))));
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(10, 5, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(10, 5, 1, 100)));
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.CONFUSION, false,
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.NAUSEA, false,
Modifier.add(3, 3, 1, 300),
Modifier.add(0, 1, 1, 10)
);
));
}
@NotNull
@Override
public ArrowSettings getArrowSettings() {
return arrowSettings;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
@Override
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
if (!(event.getProjectile() instanceof Arrow arrow)) return false;

View File

@ -13,76 +13,58 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.*;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ArrowMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.ArrowEffects;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.data.*;
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.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class DarknessArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, PotionData, BowEnchant {
public class DarknessArrowsEnchant extends GameEnchantment implements ChanceMeta, ArrowMeta, PotionMeta, BowEnchant {
public static final String ID = "darkness_arrows";
private ArrowSettingsImpl arrowSettings;
private ChanceSettingsImpl chanceSettings;
private PotionSettingsImpl potionSettings;
public DarknessArrowsEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.)");
this.setMaxLevel(3);
this.setRarity(Rarity.COMMON);
this.setConflicts(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SNOW_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.)",
EnchantRarity.COMMON,
3,
ItemCategories.BOWS,
Lists.newSet(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.ASH));
this.meta.setArrowEffects(ArrowEffects.create(config, UniParticle.of(Particle.ASH)));
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(8, 4, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(8, 4, 1, 100)));
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.DARKNESS, false,
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.DARKNESS, false,
Modifier.add(3.5, 1.5, 1, 300),
Modifier.add(0, 1, 1, 5)
);
));
}
@NotNull
@Override
public ArrowSettings getArrowSettings() {
return arrowSettings;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
@Override
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
if (!(event.getProjectile() instanceof Arrow arrow)) return false;

View File

@ -20,19 +20,20 @@ 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.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowData;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
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.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ArrowSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
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.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;
@ -41,29 +42,33 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class DragonfireArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, BowEnchant {
public class DragonfireArrowsEnchant extends GameEnchantment implements ChanceMeta, ArrowMeta, BowEnchant {
public static final String ID = "dragonfire_arrows";
private Modifier fireDuration;
private Modifier fireRadius;
private ArrowSettingsImpl arrowSettings;
private ChanceSettingsImpl chanceSettings;
public DragonfireArrowsEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to launch an dragonfire arrow (R=" + GENERIC_RADIUS + ", " + GENERIC_DURATION + "s).");
this.setMaxLevel(3);
this.setRarity(Rarity.RARE);
this.setConflicts(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SAVANNA_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to launch an dragonfire arrow (R=" + GENERIC_RADIUS + ", " + GENERIC_DURATION + "s).",
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOWS,
Lists.newSet(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.DRAGON_BREATH));
this.meta.setArrowEffects(ArrowEffects.create(config, UniParticle.of(Particle.DRAGON_BREATH)));
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3, 3, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(3, 3, 1, 100)));
this.fireDuration = Modifier.read(config, "Settings.Fire.Duration",
Modifier.multiply(100, 1, 1, 60 * 20),
@ -77,30 +82,6 @@ public class DragonfireArrowsEnchant extends AbstractEnchantmentData implements
this.addPlaceholder(GENERIC_RADIUS, level -> NumberUtil.format(this.getFireRadius(level)));
}
@NotNull
@Override
public ArrowSettings getArrowSettings() {
return arrowSettings;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
public int getFireDuration(int level) {
return (int) this.fireDuration.getValue(level);
}
@ -140,7 +121,7 @@ public class DragonfireArrowsEnchant extends AbstractEnchantmentData implements
ItemStack item = new ItemStack(Material.LINGERING_POTION);
ItemUtil.editMeta(item, meta -> {
if (meta instanceof PotionMeta potionMeta) {
potionMeta.addCustomEffect(new PotionEffect(PotionEffectType.HARM, 20, 0), true);
potionMeta.addCustomEffect(new PotionEffect(PotionEffectType.INSTANT_DAMAGE, 20, 0), true);
}
});
@ -155,7 +136,7 @@ public class DragonfireArrowsEnchant extends AbstractEnchantmentData implements
cloud.setRadius((float) this.getFireRadius(level));
cloud.setDuration(this.getFireDuration(level));
cloud.setRadiusPerTick((7.0F - cloud.getRadius()) / (float) cloud.getDuration());
cloud.addCustomEffect(new PotionEffect(PotionEffectType.HARM, 1, 1), true);
cloud.addCustomEffect(new PotionEffect(PotionEffectType.INSTANT_DAMAGE, 1, 1), true);
LingeringPotionSplashEvent splashEvent;

View File

@ -13,19 +13,20 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowData;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
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.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ArrowSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
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.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.LocationUtil;
import su.nightexpress.nightcore.util.NumberUtil;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
@ -35,28 +36,33 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_DAMAGE;
public class ElectrifiedArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, BowEnchant {
public class ElectrifiedArrowsEnchant extends GameEnchantment implements ChanceMeta, ArrowMeta, BowEnchant {
public static final String ID = "electrified_arrows";
private ArrowSettingsImpl arrowSettings;
private ChanceSettingsImpl chanceSettings;
private Modifier damageModifier;
private boolean thunderstormOnly;
private Modifier damageModifier;
private boolean thunderstormOnly;
public ElectrifiedArrowsEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance for an arrow to strike lightning with " + GENERIC_DAMAGE + "❤ extra damage.");
this.setMaxLevel(3);
this.setRarity(Rarity.UNCOMMON);
this.setConflicts(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.PLAINS_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance for an arrow to strike lightning with " + GENERIC_DAMAGE + "❤ extra damage.",
EnchantRarity.RARE,
3,
ItemCategories.BOWS,
Lists.newSet(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.FIREWORKS_SPARK));
this.meta.setArrowEffects(ArrowEffects.create(config, UniParticle.of(Particle.ELECTRIC_SPARK)));
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(0, 5, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(0, 5, 1, 100)));
this.thunderstormOnly = ConfigValue.create("Settings.During_Thunderstorm_Only",
false,
@ -71,18 +77,6 @@ public class ElectrifiedArrowsEnchant extends AbstractEnchantmentData implements
this.addPlaceholder(GENERIC_DAMAGE, level -> NumberUtil.format(this.getDamage(level)));
}
@NotNull
@Override
public ArrowSettings getArrowSettings() {
return arrowSettings;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
public boolean isDuringThunderstormOnly() {
return thunderstormOnly;
}
@ -91,26 +85,14 @@ public class ElectrifiedArrowsEnchant extends AbstractEnchantmentData implements
return this.damageModifier.getValue(level);
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
//
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
private void summonLightning(@NotNull Block block) {
Location location = block.getLocation();
block.getWorld().strikeLightningEffect(location);
if (this.hasVisualEffects()) {
Location center = LocationUtil.getCenter(location.add(0, 1, 0), false);
Location center = LocationUtil.setCenter2D(location.add(0, 1, 0));
UniParticle.blockCrack(block.getType()).play(center, 0.5, 0.1, 100);
UniParticle.of(Particle.FIREWORKS_SPARK).play(center, 0.75, 0.05, 120);
UniParticle.of(Particle.ELECTRIC_SPARK).play(center, 0.75, 0.05, 120);
}
}

View File

@ -11,65 +11,54 @@ import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
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.FileConfig;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Lists;
import java.io.File;
public class EnderBowEnchant extends AbstractEnchantmentData implements ChanceData, BowEnchant {
public class EnderBowEnchant extends GameEnchantment implements ChanceMeta, BowEnchant {
public static final String ID = "ender_bow";
private ChanceSettingsImpl chanceSettings;
public EnderBowEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription("Shoots ender pearls instead of arrows.");
this.setMaxLevel(1);
this.setRarity(Rarity.VERY_RARE);
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.PLAINS_SPECIAL));
}
this.setConflicts(
BomberEnchant.ID, GhastEnchant.ID,
ExplosiveArrowsEnchant.ID, PoisonedArrowsEnchant.ID, ConfusingArrowsEnchant.ID,
WitheredArrowsEnchant.ID, ElectrifiedArrowsEnchant.ID, DragonfireArrowsEnchant.ID,
DarknessArrowsEnchant.ID, VampiricArrowsEnchant.ID,
HoverEnchant.ID, FlareEnchant.ID,
Enchantment.ARROW_FIRE.getKey().getKey(),
Enchantment.ARROW_KNOCKBACK.getKey().getKey(),
Enchantment.ARROW_DAMAGE.getKey().getKey()
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Shoots ender pearls instead of arrows.",
EnchantRarity.MYTHIC,
1,
ItemCategories.BOWS,
Lists.newSet(
BomberEnchant.ID, GhastEnchant.ID,
ExplosiveArrowsEnchant.ID, PoisonedArrowsEnchant.ID, ConfusingArrowsEnchant.ID,
WitheredArrowsEnchant.ID, ElectrifiedArrowsEnchant.ID, DragonfireArrowsEnchant.ID,
DarknessArrowsEnchant.ID, VampiricArrowsEnchant.ID,
HoverEnchant.ID, FlareEnchant.ID,
BukkitThing.toString(Enchantment.FLAME),
BukkitThing.toString(Enchantment.PUNCH),
BukkitThing.toString(Enchantment.POWER)
)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config);
this.meta.setProbability(Probability.create(config));
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
@NotNull
@Override
public EventPriority getShootPriority() {

View File

@ -13,20 +13,21 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowData;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
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.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ArrowSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
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.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.manager.SimpeListener;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.NumberUtil;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
@ -35,7 +36,7 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_RADIUS;
public class ExplosiveArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, BowEnchant, SimpeListener {
public class ExplosiveArrowsEnchant extends GameEnchantment implements ChanceMeta, ArrowMeta, BowEnchant, SimpeListener {
public static final String ID = "explosive_arrows";
@ -44,24 +45,28 @@ public class ExplosiveArrowsEnchant extends AbstractEnchantmentData implements C
private boolean explosionDamageBlocks;
private Modifier explosionSize;
private ArrowSettingsImpl arrowSettings;
private ChanceSettingsImpl chanceSettings;
private Entity lastExploder;
public ExplosiveArrowsEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to launch an explosive arrow.");
this.setMaxLevel(3);
this.setRarity(Rarity.RARE);
this.setConflicts(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.TAIGA_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to launch an explosive arrow.",
EnchantRarity.LEGENDARY,
3,
ItemCategories.BOWS,
Lists.newSet(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.SMOKE_NORMAL));
this.meta.setArrowEffects(ArrowEffects.create(config, UniParticle.of(Particle.SMOKE)));
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3, 2, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(3, 2, 1, 100)));
this.explosionFireSpread = ConfigValue.create("Settings.Explosion.Fire_Spread",
true,
@ -82,30 +87,6 @@ public class ExplosiveArrowsEnchant extends AbstractEnchantmentData implements C
this.addPlaceholder(GENERIC_RADIUS, level -> NumberUtil.format(this.getExplosionSize(level)));
}
@NotNull
@Override
public ArrowSettings getArrowSettings() {
return arrowSettings;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
public final double getExplosionSize(int level) {
return this.explosionSize.getValue(level);
}

View File

@ -18,17 +18,17 @@ import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowData;
import su.nightexpress.excellentenchants.api.enchantment.data.ArrowSettings;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
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.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ArrowSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
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.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
@ -36,57 +36,36 @@ import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.ENCHANTMENT_CHANCE;
public class FlareEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, BowEnchant {
public class FlareEnchant extends GameEnchantment implements ChanceMeta, ArrowMeta, BowEnchant {
public static final String ID = "flare";
private ChanceSettingsImpl chanceSettings;
private ArrowSettingsImpl arrowSettings;
public FlareEnchant(@NotNull EnchantsPlugin plugin, File file) {
super(plugin, file);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SNOW_COMMON));
}
this.setDescription(ENCHANTMENT_CHANCE + "% chance to create a torch where arrow lands.");
this.setMaxLevel(1);
this.setRarity(Rarity.RARE);
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to create a torch where arrow lands.",
EnchantRarity.LEGENDARY,
1,
ItemCategories.BOWS
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config);
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.FIREWORKS_SPARK));
this.meta.setProbability(Probability.create(config));
this.meta.setArrowEffects(ArrowEffects.create(config, UniParticle.of(Particle.ELECTRIC_SPARK)));
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
@NotNull
@Override
public EventPriority getHitPriority() {
return EventPriority.HIGHEST;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return this.chanceSettings;
}
@NotNull
@Override
public ArrowSettings getArrowSettings() {
return this.arrowSettings;
}
@Override
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
if (!(event.getProjectile() instanceof Arrow)) return false;

View File

@ -13,49 +13,57 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceSettings;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
import su.nightexpress.excellentenchants.enchantment.data.ItemCategories;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
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.excellentenchants.util.EnchantUtils;
import su.nightexpress.nightcore.config.ConfigValue;
import su.nightexpress.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Lists;
import java.io.File;
public class GhastEnchant extends AbstractEnchantmentData implements ChanceData, BowEnchant {
public class GhastEnchant extends GameEnchantment implements ChanceMeta, BowEnchant {
public static final String ID = "ghast";
private boolean fireSpread;
private Modifier yield;
private ChanceSettingsImpl chanceSettings;
private boolean fireSpread;
private Modifier yield;
public GhastEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription("Shoots fireballs instead of arrows.");
this.setMaxLevel(1);
this.setRarity(Rarity.UNCOMMON);
super(plugin, file, definition(), EnchantDistribution.treasure(TradeType.SWAMP_COMMON));
}
this.setConflicts(
EnderBowEnchant.ID, BomberEnchant.ID,
ExplosiveArrowsEnchant.ID, PoisonedArrowsEnchant.ID, ConfusingArrowsEnchant.ID,
WitheredArrowsEnchant.ID, ElectrifiedArrowsEnchant.ID, DragonfireArrowsEnchant.ID,
DarknessArrowsEnchant.ID, VampiricArrowsEnchant.ID,
HoverEnchant.ID, FlareEnchant.ID,
Enchantment.ARROW_FIRE.getKey().getKey(),
Enchantment.ARROW_KNOCKBACK.getKey().getKey(),
Enchantment.ARROW_DAMAGE.getKey().getKey()
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
"Shoots fireballs instead of arrows.",
EnchantRarity.RARE,
1,
ItemCategories.BOWS,
Lists.newSet(
EnderBowEnchant.ID, BomberEnchant.ID,
ExplosiveArrowsEnchant.ID, PoisonedArrowsEnchant.ID, ConfusingArrowsEnchant.ID,
WitheredArrowsEnchant.ID, ElectrifiedArrowsEnchant.ID, DragonfireArrowsEnchant.ID,
DarknessArrowsEnchant.ID, VampiricArrowsEnchant.ID,
HoverEnchant.ID, FlareEnchant.ID,
BukkitThing.toString(Enchantment.FLAME),
BukkitThing.toString(Enchantment.PUNCH),
BukkitThing.toString(Enchantment.POWER)
)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.chanceSettings = ChanceSettingsImpl.create(config);
this.meta.setProbability(Probability.create(config));
this.fireSpread = ConfigValue.create("Settings.Fire_Spread",
true,
@ -66,12 +74,6 @@ public class GhastEnchant extends AbstractEnchantmentData implements ChanceData,
"Fireball explosion size/radius. The more value = the bigger the explosion.");
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
public boolean isFireSpread() {
return fireSpread;
}
@ -80,18 +82,6 @@ public class GhastEnchant extends AbstractEnchantmentData implements ChanceData,
return (float) this.yield.getValue(level);
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @Override
// @NotNull
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
@NotNull
@Override
public EventPriority getShootPriority() {

View File

@ -13,76 +13,53 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.*;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.*;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.data.*;
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.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class HoverEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, PotionData, BowEnchant {
public class HoverEnchant extends GameEnchantment implements ChanceMeta, ArrowMeta, PotionMeta, BowEnchant {
public static final String ID = "hover";
private ArrowSettingsImpl arrowSettings;
private ChanceSettingsImpl chanceSettings;
private PotionSettingsImpl potionSettings;
public HoverEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.)");
this.setMaxLevel(3);
this.setRarity(Rarity.COMMON);
this.setConflicts(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.DESERT_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.)",
EnchantRarity.COMMON,
3,
ItemCategories.BOWS,
Lists.newSet(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.BUBBLE_POP));
this.meta.setArrowEffects(ArrowEffects.create(config, UniParticle.of(Particle.BUBBLE_POP)));
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3, 3, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(3, 3, 1, 100)));
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.LEVITATION, false,
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.LEVITATION, false,
Modifier.add(2, 1, 1, 15),
Modifier.add(0, 1, 1, 5)
);
));
}
@NotNull
@Override
public ArrowSettings getArrowSettings() {
return arrowSettings;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@NotNull
@Override
public PotionSettingsImpl getPotionSettings() {
return potionSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
@Override
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
if (!(event.getProjectile() instanceof Arrow arrow)) return false;

View File

@ -13,76 +13,58 @@ import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.Modifier;
import su.nightexpress.excellentenchants.api.enchantment.ItemsCategory;
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
import su.nightexpress.excellentenchants.api.enchantment.data.*;
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
import su.nightexpress.excellentenchants.api.enchantment.meta.ArrowMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
import su.nightexpress.excellentenchants.api.enchantment.meta.ArrowEffects;
import su.nightexpress.excellentenchants.api.enchantment.meta.Probability;
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionEffects;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.enchantment.data.*;
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.nightcore.config.FileConfig;
import su.nightexpress.nightcore.util.Lists;
import su.nightexpress.nightcore.util.wrapper.UniParticle;
import java.io.File;
import static su.nightexpress.excellentenchants.Placeholders.*;
public class PoisonedArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, PotionData, BowEnchant {
public class PoisonedArrowsEnchant extends GameEnchantment implements ChanceMeta, ArrowMeta, PotionMeta, BowEnchant {
public static final String ID = "poisoned_arrows";
private ArrowSettingsImpl arrowSettings;
private ChanceSettingsImpl chanceSettings;
private PotionSettingsImpl potionSettings;
public PoisonedArrowsEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
super(plugin, file);
this.setDescription(ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.)");
this.setMaxLevel(3);
this.setRarity(Rarity.COMMON);
this.setConflicts(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID);
super(plugin, file, definition(), EnchantDistribution.regular(TradeType.SWAMP_COMMON));
}
@NotNull
private static EnchantDefinition definition() {
return EnchantDefinition.create(
ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + ENCHANTMENT_POTION_TYPE + " " + ENCHANTMENT_POTION_LEVEL + " (" + ENCHANTMENT_POTION_DURATION + "s.)",
EnchantRarity.COMMON,
3,
ItemCategories.BOWS,
Lists.newSet(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID)
);
}
@Override
protected void loadAdditional(@NotNull FileConfig config) {
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.SLIME));
this.meta.setArrowEffects(ArrowEffects.create(config, UniParticle.of(Particle.ITEM_SLIME)));
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(7.5, 2.5, 1, 100));
this.meta.setProbability(Probability.create(config, Modifier.add(7.5, 2.5, 1, 100)));
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.POISON, false,
this.meta.setPotionEffects(PotionEffects.create(this, config, PotionEffectType.POISON, false,
Modifier.add(3, 1, 1, 300),
Modifier.add(0, 1, 1, 5)
);
));
}
@NotNull
@Override
public ArrowSettings getArrowSettings() {
return arrowSettings;
}
@NotNull
@Override
public ChanceSettings getChanceSettings() {
return chanceSettings;
}
@NotNull
@Override
public PotionSettings getPotionSettings() {
return potionSettings;
}
@Override
@NotNull
public ItemsCategory getSupportedItems() {
return ItemCategories.BOWS;
}
// @NotNull
// @Override
// public EnchantmentTarget getCategory() {
// return EnchantmentTarget.BOW;
// }
@Override
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
if (!(event.getProjectile() instanceof Arrow arrow)) return false;

Some files were not shown because too many files have changed in this diff Show More