v4.0.0 beta
This commit is contained in:
parent
1d508bb581
commit
13a40b39fc
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>3.6.5</version>
|
||||
<version>4.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
package su.nightexpress.excellentenchants.api;
|
||||
|
||||
public enum DistributionMode {
|
||||
|
||||
VANILLA,
|
||||
CUSTOM
|
||||
}
|
@ -1,18 +1,18 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
package su.nightexpress.excellentenchants.api;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum ObtainType {
|
||||
public enum DistributionWay {
|
||||
|
||||
ENCHANTING("Enchanting_Table"),
|
||||
VILLAGER("Villagers"),
|
||||
LOOT_GENERATION("Loot_Generation"),
|
||||
FISHING("Fishing"),
|
||||
MOB_SPAWNING("Mob_Spawning");
|
||||
MOB_EQUIPMENT("Mob_Equipment");
|
||||
|
||||
private final String pathName;
|
||||
|
||||
ObtainType(@NotNull String pathName) {
|
||||
DistributionWay(@NotNull String pathName) {
|
||||
this.pathName = pathName;
|
||||
}
|
||||
|
@ -0,0 +1,148 @@
|
||||
package su.nightexpress.excellentenchants.api;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.StringUtil;
|
||||
|
||||
public class Modifier {
|
||||
|
||||
private double base;
|
||||
private double perLevel;
|
||||
private double step;
|
||||
private double cap;
|
||||
private ModifierAction action;
|
||||
|
||||
public Modifier(double base, double perLevel, double step, double cap, @NotNull ModifierAction action) {
|
||||
this.setBase(base);
|
||||
this.setPerLevel(perLevel);
|
||||
this.setStep(step);
|
||||
this.setCap(cap);
|
||||
this.setAction(action);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Modifier add(double base, double perLevel, double step) {
|
||||
return add(base, perLevel, step, -1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Modifier multiply(double base, double perLevel, double step) {
|
||||
return multiply(base, perLevel, step, -1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Modifier add(double base, double perLevel, double step, double cap) {
|
||||
return new Modifier(base, perLevel, step, cap, ModifierAction.ADD);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Modifier multiply(double base, double perLevel, double step, double cap) {
|
||||
return new Modifier(base, perLevel, step, cap, ModifierAction.MULTIPLY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Modifier read(@NotNull FileConfig cfg, @NotNull String path, @NotNull Modifier def, String ... comments) {
|
||||
return new ConfigValue<>(path,
|
||||
(cfg2, path2, def2) -> Modifier.read(cfg2, path2),
|
||||
(cfg2, path2, mod) -> mod.write(cfg2, path2),
|
||||
def,
|
||||
comments
|
||||
).read(cfg);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Modifier read(@NotNull FileConfig cfg, @NotNull String path) {
|
||||
double base = ConfigValue.create(path + ".Base", 0D,
|
||||
"Start modifier value."
|
||||
).read(cfg);
|
||||
|
||||
double perLevel = ConfigValue.create(path + ".Per_Level", 0D,
|
||||
"Additional value calculated by enchantment level step (see below). Formula: <per_level> * <step>"
|
||||
).read(cfg);
|
||||
|
||||
double step = ConfigValue.create(path + ".Step" , 1D,
|
||||
"Defines level step for 'Per_Level' value calculation. Formula: <enchant_level> / <step>"
|
||||
).read(cfg);
|
||||
|
||||
double cap = ConfigValue.create(path + ".Cap", -1,
|
||||
"Sets a limit for the final (base & per level calculations) value.",
|
||||
"Set '-1' for no limit."
|
||||
).read(cfg);
|
||||
|
||||
ModifierAction action = ConfigValue.create(path + ".Action", ModifierAction.class, ModifierAction.ADD,
|
||||
"Sets action performed between 'Base' and final 'Per_Level' values.",
|
||||
"Available types: " + StringUtil.inlineEnum(ModifierAction.class, ", ")
|
||||
).read(cfg);
|
||||
|
||||
return new Modifier(base, perLevel, step, cap, action);
|
||||
}
|
||||
|
||||
public void write(@NotNull FileConfig cfg, @NotNull String path) {
|
||||
cfg.set(path + ".Base", this.getBase());
|
||||
cfg.set(path + ".Per_Level", this.getPerLevel());
|
||||
cfg.set(path + ".Step", this.getStep());
|
||||
cfg.set(path + ".Cap", this.getCap());
|
||||
cfg.set(path + ".Action", this.getAction().name());
|
||||
}
|
||||
|
||||
public double getValue(int level) {
|
||||
if (/*level == 1 || */this.perLevel == 0D) return this.capValue(this.getBase());
|
||||
|
||||
//level -= 1;
|
||||
|
||||
double step = this.getStep() == 0D ? 1D : Math.floor((double) level / this.getStep());
|
||||
double result = this.action.math(this.getBase(), this.getPerLevel() * step);
|
||||
|
||||
return this.capValue(result);
|
||||
}
|
||||
|
||||
public double capValue(double result) {
|
||||
return this.cap > 0 ? Math.min(result, this.cap) : result;
|
||||
}
|
||||
|
||||
public int getIntValue(int level) {
|
||||
return (int) this.getValue(level);
|
||||
}
|
||||
|
||||
public double getBase() {
|
||||
return this.base;
|
||||
}
|
||||
|
||||
public void setBase(double base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public double getPerLevel() {
|
||||
return this.perLevel;
|
||||
}
|
||||
|
||||
public void setPerLevel(double perLevel) {
|
||||
this.perLevel = perLevel;
|
||||
}
|
||||
|
||||
public double getStep() {
|
||||
return step;
|
||||
}
|
||||
|
||||
public void setStep(double step) {
|
||||
this.step = step;
|
||||
}
|
||||
|
||||
public double getCap() {
|
||||
return cap;
|
||||
}
|
||||
|
||||
public void setCap(double cap) {
|
||||
this.cap = cap;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ModifierAction getAction() {
|
||||
return this.action;
|
||||
}
|
||||
|
||||
public void setAction(@NotNull ModifierAction action) {
|
||||
this.action = action;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.util;
|
||||
package su.nightexpress.excellentenchants.api;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -0,0 +1,193 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
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 {
|
||||
|
||||
@NotNull PlaceholderMap getPlaceholders(int level);
|
||||
|
||||
@NotNull FileConfig getConfig();
|
||||
|
||||
boolean load();
|
||||
|
||||
boolean checkServerRequirements();
|
||||
|
||||
boolean isAvailableToUse(@NotNull LivingEntity entity);
|
||||
|
||||
boolean isAvailableToUse(@NotNull World world);
|
||||
|
||||
boolean checkEnchantCategory(@NotNull ItemStack item);
|
||||
|
||||
boolean checkItemCategory(@NotNull ItemStack item);
|
||||
|
||||
@NotNull DistributionOptions getDistributionOptions();
|
||||
|
||||
@NotNull Rarity getRarity();
|
||||
|
||||
void setRarity(@NotNull Rarity rarity);
|
||||
|
||||
@NotNull String getId();
|
||||
|
||||
@NotNull String getName();
|
||||
|
||||
@NotNull
|
||||
default String getNameFormatted(int level) {
|
||||
return this.getNameFormatted(level, -1);
|
||||
}
|
||||
|
||||
@NotNull String getNameFormatted(int level, int charges);
|
||||
|
||||
@NotNull List<String> getDescription();
|
||||
|
||||
@NotNull List<String> getDescriptionFormatted();
|
||||
|
||||
@NotNull List<String> getDescriptionReplaced(int level);
|
||||
|
||||
@NotNull EnchantmentTarget getCategory();
|
||||
|
||||
@NotNull Enchantment getEnchantment();
|
||||
|
||||
void setEnchantment(@NotNull Enchantment enchantment);
|
||||
|
||||
ItemCategory[] getItemCategories();
|
||||
|
||||
EquipmentSlot[] getSlots();
|
||||
|
||||
default boolean hasConflicts() {
|
||||
return !this.getConflicts().isEmpty();
|
||||
}
|
||||
|
||||
@NotNull Set<String> getConflicts();
|
||||
|
||||
int getMinLevel();
|
||||
|
||||
int getMaxLevel();
|
||||
|
||||
//int getMaxMergeLevel();
|
||||
|
||||
//int getAnvilMergeCost(int level);
|
||||
|
||||
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 setStartLevel(int levelMin);
|
||||
|
||||
void setMaxLevel(int levelMax);
|
||||
|
||||
//void setMaxMergeLevel(int maxMergeLevel);
|
||||
|
||||
@NotNull Modifier getMinCost();
|
||||
|
||||
void setMinCost(@NotNull Modifier minCost);
|
||||
|
||||
@NotNull Modifier getMaxCost();
|
||||
|
||||
void setMaxCost(@NotNull Modifier maxCost);
|
||||
|
||||
//@NotNull Modifier getAnvilMergeCost();
|
||||
|
||||
//void setAnvilMergeCost(@NotNull Modifier anvilMergeCost);
|
||||
|
||||
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);
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.config.JYML;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface IEnchantment extends Keyed {
|
||||
|
||||
boolean isAvailableToUse(@NotNull LivingEntity entity);
|
||||
|
||||
@NotNull JYML getConfig();
|
||||
|
||||
@NotNull String getId();
|
||||
|
||||
@NotNull String getDisplayName();
|
||||
|
||||
@NotNull String getNameFormatted(int level);
|
||||
|
||||
@NotNull String getNameFormatted(int level, int charges);
|
||||
|
||||
@NotNull List<String> getDescription();
|
||||
|
||||
@NotNull List<String> getDescription(int level);
|
||||
|
||||
@NotNull Set<String> getConflicts();
|
||||
|
||||
@NotNull ITier getTier();
|
||||
|
||||
@NotNull EnchantmentTarget getCategory();
|
||||
|
||||
ItemCategory[] getFitItemTypes();
|
||||
|
||||
int getMaxLevel();
|
||||
|
||||
int getStartLevel();
|
||||
|
||||
int getLevelByEnchantCost(int expLevel);
|
||||
|
||||
double getObtainChance(@NotNull ObtainType obtainType);
|
||||
|
||||
int getObtainLevelMin(@NotNull ObtainType obtainType);
|
||||
|
||||
int getObtainLevelMax(@NotNull ObtainType obtainType);
|
||||
|
||||
int generateLevel(@NotNull ObtainType obtainType);
|
||||
|
||||
int getAnvilMergeCost(int level);
|
||||
|
||||
//@Deprecated
|
||||
//boolean conflictsWith(@NotNull Enchantment enchantment);
|
||||
|
||||
boolean checkEnchantCategory(@NotNull ItemStack item);
|
||||
|
||||
boolean checkItemCategory(@NotNull ItemStack item);
|
||||
|
||||
boolean isCurse();
|
||||
|
||||
boolean isTreasure();
|
||||
|
||||
boolean isTradeable();
|
||||
|
||||
boolean isDiscoverable();
|
||||
|
||||
boolean isChargesEnabled();
|
||||
|
||||
int getChargesMax(int level);
|
||||
|
||||
int getChargesConsumeAmount(int level);
|
||||
|
||||
int getChargesRechargeAmount(int level);
|
||||
|
||||
@NotNull ItemStack getChargesFuel();
|
||||
|
||||
boolean isChargesFuel(@NotNull ItemStack item);
|
||||
|
||||
int getCharges(@NotNull ItemStack item);
|
||||
|
||||
boolean isFullOfCharges(@NotNull ItemStack item);
|
||||
|
||||
boolean isOutOfCharges(@NotNull ItemStack item);
|
||||
|
||||
void consumeCharges(@NotNull ItemStack item, int level);
|
||||
|
||||
void consumeChargesNoUpdate(@NotNull ItemStack item, int level);
|
||||
|
||||
EquipmentSlot[] getSlots();
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.placeholder.Placeholder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ITier extends Placeholder {
|
||||
|
||||
@NotNull String getId();
|
||||
|
||||
int getPriority();
|
||||
|
||||
@NotNull String getName();
|
||||
|
||||
@NotNull String getColor();
|
||||
|
||||
@NotNull Map<ObtainType, Double> getChance();
|
||||
|
||||
double getChance(@NotNull ObtainType obtainType);
|
||||
}
|
@ -3,7 +3,7 @@ package su.nightexpress.excellentenchants.api.enchantment;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.ItemUtil;
|
||||
import su.nightexpress.nightcore.util.ItemUtil;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@ -24,6 +24,7 @@ public enum ItemCategory {
|
||||
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),
|
||||
@ -46,83 +47,7 @@ public enum ItemCategory {
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void patchPredicate(@NotNull Predicate<ItemStack> extra) {
|
||||
//this.setPredicate(item -> this.getPredicate().test(item) || (extra.test(item)));
|
||||
}
|
||||
|
||||
/*public EquipmentSlot[] getSlots() {
|
||||
return switch (this) {
|
||||
case BOW, CROSSBOW, TRIDENT, FISHING_ROD, WEAPON, TOOL, HOE, PICKAXE, AXE, SWORD, SHOVEL ->
|
||||
new EquipmentSlot[]{EquipmentSlot.HAND};
|
||||
case HELMET -> new EquipmentSlot[]{EquipmentSlot.HEAD};
|
||||
case CHESTPLATE, ELYTRA -> new EquipmentSlot[]{EquipmentSlot.CHEST};
|
||||
case LEGGINGS -> new EquipmentSlot[]{EquipmentSlot.LEGS};
|
||||
case BOOTS -> new EquipmentSlot[]{EquipmentSlot.FEET};
|
||||
case ARMOR -> new EquipmentSlot[]{EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
|
||||
case UNIVERSAL -> new EquipmentSlot[]{EquipmentSlot.HAND, EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantmentTarget getEnchantmentTarget() {
|
||||
return switch (this) {
|
||||
case ARMOR -> EnchantmentTarget.ARMOR;
|
||||
case BOOTS -> EnchantmentTarget.ARMOR_FEET;
|
||||
case LEGGINGS -> EnchantmentTarget.ARMOR_LEGS;
|
||||
case CHESTPLATE, ELYTRA -> EnchantmentTarget.ARMOR_TORSO;
|
||||
case HELMET -> EnchantmentTarget.ARMOR_HEAD;
|
||||
case WEAPON, SWORD -> EnchantmentTarget.WEAPON;
|
||||
case TOOL, AXE, HOE, SHOVEL, PICKAXE -> EnchantmentTarget.TOOL;
|
||||
case BOW -> EnchantmentTarget.BOW;
|
||||
case FISHING_ROD -> EnchantmentTarget.FISHING_ROD;
|
||||
case TRIDENT -> EnchantmentTarget.TRIDENT;
|
||||
case CROSSBOW -> EnchantmentTarget.CROSSBOW;
|
||||
case UNIVERSAL -> EnchantmentTarget.WEARABLE;
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FitItemType getByEnchantmentTarget(@NotNull EnchantmentTarget target) {
|
||||
return switch (target) {
|
||||
case ARMOR -> ARMOR;
|
||||
case ARMOR_FEET -> BOOTS;
|
||||
case ARMOR_LEGS -> LEGGINGS;
|
||||
case ARMOR_TORSO -> CHESTPLATE;
|
||||
case ARMOR_HEAD -> HELMET;
|
||||
case WEAPON -> WEAPON;
|
||||
case TOOL -> TOOL;
|
||||
case BOW -> BOW;
|
||||
case FISHING_ROD -> FISHING_ROD;
|
||||
case TRIDENT -> TRIDENT;
|
||||
case CROSSBOW -> CROSSBOW;
|
||||
case BREAKABLE, WEARABLE -> UNIVERSAL;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + target);
|
||||
};
|
||||
}*/
|
||||
|
||||
public boolean isIncluded(@NotNull ItemStack item) {
|
||||
return this.getPredicate().test(item);
|
||||
|
||||
/*return switch (this) {
|
||||
case UNIVERSAL -> ARMOR.isIncluded(item) || WEAPON.isIncluded(item) || TOOL.isIncluded(item) || BOW.isIncluded(item) || FISHING_ROD.isIncluded(item) || ELYTRA.isIncluded(item);
|
||||
case HELMET -> ItemUtil.isHelmet(item);
|
||||
case CHESTPLATE -> ItemUtil.isChestplate(item) || (Config.ENCHANTMENTS_ITEM_CHESTPLATE_ENCHANTS_TO_ELYTRA.get() && ELYTRA.isIncluded(item));
|
||||
case LEGGINGS -> ItemUtil.isLeggings(item);
|
||||
case BOOTS -> ItemUtil.isBoots(item);
|
||||
case ELYTRA -> item.getType() == Material.ELYTRA;
|
||||
case WEAPON -> SWORD.isIncluded(item) || ItemUtil.isTrident(item);
|
||||
case TOOL -> ItemUtil.isTool(item);
|
||||
case ARMOR -> ItemUtil.isArmor(item);
|
||||
case SWORD -> ItemUtil.isSword(item) || (Config.ENCHANTMENTS_ITEM_SWORD_ENCHANTS_TO_AXES.get() && AXE.isIncluded(item));
|
||||
case TRIDENT -> ItemUtil.isTrident(item);
|
||||
case AXE -> ItemUtil.isAxe(item);
|
||||
case BOW -> item.getType() == Material.BOW || (Config.ENCHANTMENTS_ITEM_BOW_ENCHANTS_TO_CROSSBOW.get() && CROSSBOW.isIncluded(item));
|
||||
case CROSSBOW -> item.getType() == Material.CROSSBOW;
|
||||
case HOE -> ItemUtil.isHoe(item);
|
||||
case PICKAXE -> ItemUtil.isPickaxe(item);
|
||||
case SHOVEL -> ItemUtil.isShovel(item);
|
||||
case FISHING_ROD -> item.getType() == Material.FISHING_ROD;
|
||||
};*/
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,11 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum Rarity {
|
||||
|
||||
COMMON(10),
|
||||
@ -7,7 +13,7 @@ public enum Rarity {
|
||||
RARE(2),
|
||||
VERY_RARE(1);
|
||||
|
||||
private final int weight;
|
||||
private int weight;
|
||||
|
||||
Rarity(int weight) {
|
||||
this.weight = weight;
|
||||
@ -16,4 +22,19 @@ public enum Rarity {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
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();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
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();
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.meta;
|
||||
package su.nightexpress.excellentenchants.api.enchantment.data;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface Chanced {
|
||||
public interface ChanceData {
|
||||
|
||||
@NotNull Chanced getChanceImplementation();
|
||||
@NotNull ChanceSettings getChanceSettings();
|
||||
|
||||
/*@NotNull
|
||||
default UnaryOperator<String> replacePlaceholders(int level) {
|
||||
@ -12,10 +12,10 @@ public interface Chanced {
|
||||
}*/
|
||||
|
||||
default double getTriggerChance(int level) {
|
||||
return this.getChanceImplementation().getTriggerChance(level);
|
||||
return this.getChanceSettings().getTriggerChance(level);
|
||||
}
|
||||
|
||||
default boolean checkTriggerChance(int level) {
|
||||
return getChanceImplementation().checkTriggerChance(level);
|
||||
return getChanceSettings().checkTriggerChance(level);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.data;
|
||||
|
||||
public interface ChanceSettings {
|
||||
|
||||
double getTriggerChance(int level);
|
||||
|
||||
boolean checkTriggerChance(int level);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
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();
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.data;
|
||||
|
||||
public interface PeriodicSettings {
|
||||
|
||||
long getInterval();
|
||||
|
||||
long getNextTriggerTime();
|
||||
|
||||
boolean isTriggerTime();
|
||||
|
||||
void updateTriggerTime();
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
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);
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.distribution;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public interface DistributionOptions {
|
||||
|
||||
void load(@NotNull FileConfig config);
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.distribution;
|
||||
|
||||
public interface VanillaOptions extends DistributionOptions {
|
||||
|
||||
boolean isDiscoverable();
|
||||
|
||||
void setDiscoverable(boolean discoverable);
|
||||
|
||||
boolean isTradeable();
|
||||
|
||||
void setTradeable(boolean tradeable);
|
||||
}
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface BlockBreakEnchant extends IEnchantment {
|
||||
public interface BlockBreakEnchant extends EnchantmentData {
|
||||
|
||||
boolean onBreak(@NotNull BlockBreakEvent event, @NotNull LivingEntity player, @NotNull ItemStack item, int level);
|
||||
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface BlockDropEnchant extends IEnchantment {
|
||||
public interface BlockDropEnchant extends EnchantmentData {
|
||||
|
||||
boolean onDrop(@NotNull BlockDropItemEvent event, @NotNull LivingEntity player, @NotNull ItemStack item, int level);
|
||||
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface BowEnchant extends IEnchantment {
|
||||
public interface BowEnchant extends EnchantmentData {
|
||||
|
||||
boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level);
|
||||
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface CombatEnchant extends IEnchantment {
|
||||
public interface CombatEnchant extends EnchantmentData {
|
||||
|
||||
boolean onAttack(@NotNull EntityDamageByEntityEvent event,
|
||||
@NotNull LivingEntity damager, @NotNull LivingEntity victim,
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface DamageEnchant extends IEnchantment {
|
||||
public interface DamageEnchant extends EnchantmentData {
|
||||
|
||||
boolean onDamage(@NotNull EntityDamageEvent event, @NotNull LivingEntity entity, @NotNull ItemStack item, int level);
|
||||
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface DeathEnchant extends IEnchantment {
|
||||
public interface DeathEnchant extends EnchantmentData {
|
||||
|
||||
boolean onDeath(@NotNull EntityDeathEvent event, @NotNull LivingEntity entity, ItemStack item, int level);
|
||||
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface FishingEnchant extends IEnchantment {
|
||||
public interface FishingEnchant extends EnchantmentData {
|
||||
|
||||
boolean onFishing(@NotNull PlayerFishEvent event, @NotNull ItemStack item, int level);
|
||||
|
@ -0,0 +1,7 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.type;
|
||||
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface GenericEnchant extends EnchantmentData {
|
||||
|
||||
}
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
|
||||
public interface InteractEnchant extends IEnchantment {
|
||||
public interface InteractEnchant extends EnchantmentData {
|
||||
|
||||
boolean onInteract(@NotNull PlayerInteractEvent event, @NotNull LivingEntity entity, @NotNull ItemStack item, int level);
|
||||
|
@ -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.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Periodic;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicData;
|
||||
|
||||
public interface PassiveEnchant extends IEnchantment, Periodic {
|
||||
public interface PassiveEnchant extends EnchantmentData, PeriodicData {
|
||||
|
||||
boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level);
|
||||
}
|
26
Core/pom.xml
26
Core/pom.xml
@ -5,15 +5,16 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>3.6.5</version>
|
||||
<version>4.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>Core</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
@ -54,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>io.lumine</groupId>
|
||||
<artifactId>Mythic-Dist</artifactId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.6.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -72,37 +73,32 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>3.6.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_18_R2</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_19_R3</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_20_R1</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_20_R2</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_20_R3</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
package su.nightexpress.excellentenchants;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
|
||||
import su.nightexpress.excellentenchants.tier.TierManager;
|
||||
|
||||
public class ExcellentEnchantsAPI {
|
||||
|
||||
public static final ExcellentEnchants PLUGIN = ExcellentEnchants.getPlugin(ExcellentEnchants.class);
|
||||
|
||||
@NotNull
|
||||
public static EnchantManager getEnchantManager() {
|
||||
return PLUGIN.getEnchantManager();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TierManager getTierManager() {
|
||||
return PLUGIN.getTierManager();
|
||||
}
|
||||
}
|
@ -1,20 +1,19 @@
|
||||
package su.nightexpress.excellentenchants;
|
||||
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.event.block.BlockDropItemEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.NexPlugin;
|
||||
import su.nexmedia.engine.Version;
|
||||
import su.nexmedia.engine.api.command.GeneralCommand;
|
||||
import su.nexmedia.engine.command.list.ReloadSubCommand;
|
||||
import su.nexmedia.engine.utils.EngineUtils;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ItemCategory;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ObtainType;
|
||||
import su.nightexpress.excellentenchants.api.DistributionWay;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.command.BookCommand;
|
||||
import su.nightexpress.excellentenchants.command.EnchantCommand;
|
||||
import su.nightexpress.excellentenchants.command.ListCommand;
|
||||
import su.nightexpress.excellentenchants.command.TierbookCommand;
|
||||
import su.nightexpress.excellentenchants.command.RarityBookCommand;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.excellentenchants.config.Keys;
|
||||
import su.nightexpress.excellentenchants.config.Lang;
|
||||
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
|
||||
import su.nightexpress.excellentenchants.enchantment.EnchantPopulator;
|
||||
@ -23,38 +22,38 @@ import su.nightexpress.excellentenchants.hook.HookId;
|
||||
import su.nightexpress.excellentenchants.hook.impl.PlaceholderHook;
|
||||
import su.nightexpress.excellentenchants.hook.impl.ProtocolHook;
|
||||
import su.nightexpress.excellentenchants.nms.EnchantNMS;
|
||||
import su.nightexpress.excellentenchants.nms.v1_18_R2.V1_18_R2;
|
||||
import su.nightexpress.excellentenchants.nms.v1_19_R3.V1_19_R3;
|
||||
import su.nightexpress.excellentenchants.nms.v1_20_R1.V1_20_R1;
|
||||
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.tier.TierManager;
|
||||
import su.nightexpress.nightcore.NightPlugin;
|
||||
import su.nightexpress.nightcore.command.api.NightPluginCommand;
|
||||
import su.nightexpress.nightcore.command.base.ReloadSubCommand;
|
||||
import su.nightexpress.nightcore.config.PluginDetails;
|
||||
import su.nightexpress.nightcore.util.Plugins;
|
||||
import su.nightexpress.nightcore.util.Version;
|
||||
|
||||
public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
|
||||
|
||||
// TODO Config option to use minecraft internal enchanting population
|
||||
// TODO Custom name format for curse enchants
|
||||
// TODO Custom name format for treasure enchants
|
||||
public class ExcellentEnchantsPlugin extends NightPlugin {
|
||||
|
||||
private EnchantRegistry registry;
|
||||
private EnchantManager enchantManager;
|
||||
private EnchantNMS enchantNMS;
|
||||
private TierManager tierManager;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected ExcellentEnchants getSelf() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
|
||||
//this.updateFitItemTypes();
|
||||
this.registry = new EnchantRegistry(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected PluginDetails getDefaultDetails() {
|
||||
return PluginDetails.create("Enchants", new String[]{"excellentenchants", "eenchants"})
|
||||
.setConfigClass(Config.class)
|
||||
.setLangClass(Lang.class)
|
||||
.setPermissionsClass(Perms.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
if (!this.setNMS()) {
|
||||
@ -63,8 +62,15 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
|
||||
return;
|
||||
}
|
||||
|
||||
this.tierManager = new TierManager(this);
|
||||
this.tierManager.setup();
|
||||
Keys.loadKeys(this);
|
||||
Config.loadRarityWeights(this.getConfig());
|
||||
|
||||
this.getLangManager().loadEnum(ItemCategory.class);
|
||||
this.getLangManager().loadEnum(EnchantmentTarget.class);
|
||||
this.getLangManager().loadEnum(DistributionWay.class);
|
||||
this.getLangManager().loadEnum(Rarity.class);
|
||||
|
||||
this.registerCommands();
|
||||
|
||||
this.registry.setup();
|
||||
|
||||
@ -72,14 +78,18 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
|
||||
this.enchantManager.setup();
|
||||
|
||||
if (Config.ENCHANTMENTS_DISPLAY_MODE.get() == 2) {
|
||||
if (EngineUtils.hasPlugin(HookId.PROTOCOL_LIB)) {
|
||||
ProtocolHook.setup();
|
||||
if (Plugins.isInstalled(HookId.PROTOCOL_LIB)) {
|
||||
ProtocolHook.setup(this);
|
||||
}
|
||||
else {
|
||||
this.warn(HookId.PROTOCOL_LIB + " is not installed. Set display mode to Plain lore.");
|
||||
this.warn(HookId.PROTOCOL_LIB + " is not installed. Display mode is set to Plain lore.");
|
||||
Config.ENCHANTMENTS_DISPLAY_MODE.set(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (Plugins.hasPlaceholderAPI()) {
|
||||
PlaceholderHook.setup(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -88,19 +98,16 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
|
||||
this.enchantManager.shutdown();
|
||||
this.enchantManager = null;
|
||||
}
|
||||
if (this.tierManager != null) {
|
||||
this.tierManager.shutdown();
|
||||
this.tierManager = null;
|
||||
}
|
||||
if (EngineUtils.hasPlaceholderAPI()) {
|
||||
|
||||
if (Plugins.hasPlaceholderAPI()) {
|
||||
PlaceholderHook.shutdown();
|
||||
}
|
||||
|
||||
this.registry.shutdown();
|
||||
}
|
||||
|
||||
private boolean setNMS() {
|
||||
this.enchantNMS = switch (Version.getCurrent()) {
|
||||
case V1_18_R2 -> new V1_18_R2();
|
||||
case V1_19_R3 -> new V1_19_R3();
|
||||
case V1_20_R1 -> new V1_20_R1();
|
||||
case V1_20_R2 -> new V1_20_R2();
|
||||
@ -110,49 +117,27 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
|
||||
return this.enchantNMS != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadConfig() {
|
||||
this.getConfig().initializeOptions(Config.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadLang() {
|
||||
this.getLangManager().loadMissing(Lang.class);
|
||||
this.getLangManager().loadEnum(ItemCategory.class);
|
||||
this.getLangManager().loadEnum(EnchantmentTarget.class);
|
||||
this.getLangManager().loadEnum(ObtainType.class);
|
||||
this.getLang().saveChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCommands(@NotNull GeneralCommand<ExcellentEnchants> mainCommand) {
|
||||
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 TierbookCommand(this));
|
||||
mainCommand.addChildren(new ReloadSubCommand<>(this, Perms.COMMAND_RELOAD));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerHooks() {
|
||||
if (EngineUtils.hasPlaceholderAPI()) {
|
||||
PlaceholderHook.setup(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPermissions() {
|
||||
this.registerPermissions(Perms.class);
|
||||
mainCommand.addChildren(new RarityBookCommand(this));
|
||||
mainCommand.addChildren(new ReloadSubCommand(this, Perms.COMMAND_RELOAD));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantPopulator createPopulator(@NotNull ItemStack item, @NotNull ObtainType obtainType) {
|
||||
return new EnchantPopulator(this, item, obtainType);
|
||||
public EnchantPopulator createPopulator(@NotNull ItemStack item, @NotNull DistributionWay distributionWay) {
|
||||
return new EnchantPopulator(this, item, distributionWay);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TierManager getTierManager() {
|
||||
return tierManager;
|
||||
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);
|
||||
}
|
||||
|
||||
@NotNull
|
@ -1,25 +1,31 @@
|
||||
package su.nightexpress.excellentenchants;
|
||||
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import su.nexmedia.engine.api.server.JPermission;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniPermission;
|
||||
|
||||
public class Perms {
|
||||
|
||||
private static final String PREFIX = "excellentenchants.";
|
||||
private static final String PREFIX = "excellentenchants.";
|
||||
private static final String PREFIX_COMMAND = PREFIX + "command.";
|
||||
|
||||
public static final JPermission PLUGIN = new JPermission(PREFIX + Placeholders.WILDCARD, "Access to all the plugin functions.");
|
||||
public static final JPermission COMMAND = new JPermission(PREFIX_COMMAND + Placeholders.WILDCARD, "Access to all the plugin commands.");
|
||||
public static final UniPermission PLUGIN = new UniPermission(PREFIX + Placeholders.WILDCARD, "Access to all the plugin functions.");
|
||||
public static final UniPermission COMMAND = new UniPermission(PREFIX_COMMAND + Placeholders.WILDCARD, "Access to all the plugin commands.");
|
||||
|
||||
public static final JPermission COMMAND_BOOK = new JPermission(PREFIX_COMMAND + "book", "Allows to use '/eenchants book' command.");
|
||||
public static final JPermission COMMAND_ENCHANT = new JPermission(PREFIX_COMMAND + "enchant", "Allows to use '/eenchants enchant' command.");
|
||||
public static final JPermission COMMAND_LIST = new JPermission(PREFIX_COMMAND + "list", "Allows to use '/eenchants list' command.", PermissionDefault.TRUE);
|
||||
public static final JPermission COMMAND_TIERBOOK = new JPermission(PREFIX_COMMAND + "tierbook", "Allows to use '/eenchants tierbook' command.");
|
||||
public static final JPermission COMMAND_RELOAD = new JPermission(PREFIX_COMMAND + "reload", "Allows to use '/eenchants reload' command.");
|
||||
public static final UniPermission COMMAND_BOOK = new UniPermission(PREFIX_COMMAND + "book");
|
||||
public static final UniPermission COMMAND_ENCHANT = new UniPermission(PREFIX_COMMAND + "enchant");
|
||||
public static final UniPermission COMMAND_LIST = new UniPermission(PREFIX_COMMAND + "list", "Allows to use '/eenchants list' command.", PermissionDefault.TRUE);
|
||||
public static final UniPermission COMMAND_RARITY_BOOK = new UniPermission(PREFIX_COMMAND + "raritybook");
|
||||
public static final UniPermission COMMAND_RELOAD = new UniPermission(PREFIX_COMMAND + "reload");
|
||||
|
||||
static {
|
||||
PLUGIN.addChildren(COMMAND);
|
||||
|
||||
COMMAND.addChildren(COMMAND_BOOK, COMMAND_ENCHANT, COMMAND_LIST, COMMAND_RELOAD, COMMAND_TIERBOOK);
|
||||
COMMAND.addChildren(
|
||||
COMMAND_BOOK,
|
||||
COMMAND_ENCHANT,
|
||||
COMMAND_LIST,
|
||||
COMMAND_RELOAD,
|
||||
COMMAND_RARITY_BOOK
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,54 +1,56 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.151.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* su.nexmedia.engine.utils.Placeholders
|
||||
*/
|
||||
package su.nightexpress.excellentenchants;
|
||||
|
||||
public class Placeholders
|
||||
extends su.nexmedia.engine.utils.Placeholders {
|
||||
public static final String URL_WIKI = "https://github.com/nulli0n/ExcellentEnchants-spigot/wiki/";
|
||||
public class Placeholders extends su.nightexpress.nightcore.util.Placeholders {
|
||||
|
||||
public static final String URL_WIKI = "https://github.com/nulli0n/ExcellentEnchants-spigot/wiki/";
|
||||
public static final String URL_PLACEHOLDERS = "https://github.com/nulli0n/ExcellentEnchants-spigot/wiki/Internal-Placeholders";
|
||||
public static final String URL_ENGINE_SCALER = "https://github.com/nulli0n/NexEngine-spigot/wiki/Configuration-Tips#scalable-sections";
|
||||
public static final String URL_ENGINE_ITEMS = "https://github.com/nulli0n/NexEngine-spigot/wiki/Configuration-Tips#item-sections";
|
||||
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 URL_CHRAGES = "https://github.com/nulli0n/ExcellentEnchants-spigot/wiki/Charges-System";
|
||||
|
||||
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 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_DESCRIPTION = "%description%";
|
||||
public static final String GENERIC_ENCHANT = "%enchant%";
|
||||
public static final String ENCHANTMENT_CHANCE = "%enchantment_trigger_chance%";
|
||||
public static final String ENCHANTMENT_INTERVAL = "%enchantment_trigger_interval%";
|
||||
public static final String ENCHANTMENT_POTION_LEVEL = "%enchantment_potion_level%";
|
||||
public static final String ENCHANTMENT_POTION_DURATION = "%enchantment_potion_duration%";
|
||||
public static final String ENCHANTMENT_POTION_TYPE = "%enchantment_potion_type%";
|
||||
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_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_TIER = "%enchantment_tier%";
|
||||
public static final String ENCHANTMENT_TIER_COLOR = "%enchantment_tier_color%";
|
||||
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 GENERIC_ENCHANT = "%enchant%";
|
||||
public static final String GENERIC_RADIUS = "%radius%";
|
||||
public static final String GENERIC_DURATION = "%duration%";
|
||||
public static final String GENERIC_DAMAGE = "%damage%";
|
||||
public static final String GENERIC_MIN = "%min%";
|
||||
public static final String GENERIC_MAX = "%max%";
|
||||
public static final String GENERIC_TIME = "%time%";
|
||||
|
||||
public static final String ENCHANTMENT_CHANCE = "%enchantment_trigger_chance%";
|
||||
public static final String ENCHANTMENT_INTERVAL = "%enchantment_trigger_interval%";
|
||||
public static final String ENCHANTMENT_POTION_LEVEL = "%enchantment_potion_level%";
|
||||
public static final String ENCHANTMENT_POTION_DURATION = "%enchantment_potion_duration%";
|
||||
public static final String ENCHANTMENT_POTION_TYPE = "%enchantment_potion_type%";
|
||||
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_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_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 final String TIER_ID = "%tier_id%";
|
||||
public static final String TIER_NAME = "%tier_name%";
|
||||
public static final String TIER_OBTAIN_CHANCE_ENCHANTING = "%tier_obtain_chance_enchanting%";
|
||||
public static final String TIER_OBTAIN_CHANCE_VILLAGER = "%tier_obtain_chance_villager%";
|
||||
public static final String TIER_OBTAIN_CHANCE_LOOT_GENERATION = "%tier_obtain_chance_loot_generation%";
|
||||
public static final String TIER_OBTAIN_CHANCE_FISHING = "%tier_obtain_chance_fishing%";
|
||||
public static final String TIER_OBTAIN_CHANCE_MOB_SPAWNING = "%tier_obtain_chance_mob_spawning%";
|
||||
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%";
|
||||
}
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
|
||||
public interface Cleanable {
|
||||
|
||||
void clear();
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import su.nexmedia.engine.api.config.JYML;
|
||||
import su.nightexpress.excellentenchants.enchantment.type.ObtainType;
|
||||
import su.nightexpress.excellentenchants.tier.Tier;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface IEnchantment extends Keyed {
|
||||
|
||||
boolean isAvailableToUse(@NotNull LivingEntity entity);
|
||||
|
||||
@NotNull JYML getConfig();
|
||||
|
||||
@NotNull String getId();
|
||||
|
||||
@NotNull String getDisplayName();
|
||||
|
||||
@NotNull String getNameFormatted(int level);
|
||||
|
||||
@NotNull String getNameFormatted(int level, int charges);
|
||||
|
||||
@NotNull List<String> getDescription();
|
||||
|
||||
@NotNull List<String> getDescription(int level);
|
||||
|
||||
@NotNull Set<String> getConflicts();
|
||||
|
||||
@NotNull Tier getTier();
|
||||
|
||||
int getMaxLevel();
|
||||
|
||||
int getStartLevel();
|
||||
|
||||
int getLevelByEnchantCost(int expLevel);
|
||||
|
||||
double getObtainChance(@NotNull ObtainType obtainType);
|
||||
|
||||
int getObtainLevelMin(@NotNull ObtainType obtainType);
|
||||
|
||||
int getObtainLevelMax(@NotNull ObtainType obtainType);
|
||||
|
||||
int generateLevel(@NotNull ObtainType obtainType);
|
||||
|
||||
int getAnvilMergeCost(int level);
|
||||
|
||||
boolean conflictsWith(@NotNull Enchantment enchantment);
|
||||
|
||||
boolean canEnchantItem(@Nullable ItemStack item);
|
||||
|
||||
boolean isCursed();
|
||||
|
||||
boolean isTreasure();
|
||||
|
||||
boolean isChargesEnabled();
|
||||
|
||||
int getChargesMax(int level);
|
||||
|
||||
int getChargesConsumeAmount(int level);
|
||||
|
||||
int getChargesRechargeAmount(int level);
|
||||
|
||||
@NotNull ItemStack getChargesFuel();
|
||||
|
||||
boolean isChargesFuel(@NotNull ItemStack item);
|
||||
|
||||
int getCharges(@NotNull ItemStack item);
|
||||
|
||||
boolean isFullOfCharges(@NotNull ItemStack item);
|
||||
|
||||
boolean isOutOfCharges(@NotNull ItemStack item);
|
||||
|
||||
void consumeCharges(@NotNull ItemStack item, int level);
|
||||
|
||||
void consumeChargesNoUpdate(@NotNull ItemStack item, int level);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.meta;
|
||||
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface Arrowed {
|
||||
|
||||
@NotNull Arrowed getArrowImplementation();
|
||||
|
||||
@NotNull
|
||||
default Optional<UniParticle> getTrailParticle() {
|
||||
return this.getArrowImplementation().getTrailParticle();
|
||||
}
|
||||
|
||||
default void addTrail(@NotNull Projectile projectile) {
|
||||
this.getArrowImplementation().addTrail(projectile);
|
||||
}
|
||||
|
||||
default void addData(@NotNull Projectile projectile) {
|
||||
this.getArrowImplementation().addData(projectile);
|
||||
}
|
||||
|
||||
default boolean isOurProjectile(@NotNull Projectile projectile) {
|
||||
return this.getArrowImplementation().isOurProjectile(projectile);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.meta;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface Periodic {
|
||||
|
||||
@NotNull Periodic getPeriodImplementation();
|
||||
|
||||
default long getInterval() {
|
||||
return this.getPeriodImplementation().getInterval();
|
||||
}
|
||||
|
||||
default long getNextTriggerTime() {
|
||||
return this.getPeriodImplementation().getNextTriggerTime();
|
||||
}
|
||||
|
||||
default boolean isTriggerTime() {
|
||||
return this.getPeriodImplementation().isTriggerTime();
|
||||
}
|
||||
|
||||
default void updateTriggerTime() {
|
||||
this.getPeriodImplementation().updateTriggerTime();
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
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 Potioned {
|
||||
|
||||
@NotNull Potioned getPotionImplementation();
|
||||
|
||||
default boolean isPermanent() {
|
||||
return this.getPotionImplementation().isPermanent();
|
||||
}
|
||||
|
||||
default PotionEffectType getEffectType() {
|
||||
return this.getPotionImplementation().getEffectType();
|
||||
}
|
||||
|
||||
default int getEffectAmplifier(int level) {
|
||||
return this.getPotionImplementation().getEffectAmplifier(level);
|
||||
}
|
||||
|
||||
default int getEffectDuration(int level) {
|
||||
return this.getPotionImplementation().getEffectDuration(level);
|
||||
}
|
||||
|
||||
default PotionEffect createEffect(int level) {
|
||||
return this.getPotionImplementation().createEffect(level);
|
||||
}
|
||||
|
||||
default boolean addEffect(@NotNull LivingEntity target, int level) {
|
||||
return this.getPotionImplementation().addEffect(target, level);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.type;
|
||||
|
||||
import su.nightexpress.excellentenchants.api.enchantment.IEnchantment;
|
||||
|
||||
public interface GenericEnchant extends IEnchantment {
|
||||
|
||||
}
|
@ -1,42 +1,41 @@
|
||||
package su.nightexpress.excellentenchants.command;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
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.nexmedia.engine.api.command.AbstractCommand;
|
||||
import su.nexmedia.engine.api.command.CommandResult;
|
||||
import su.nexmedia.engine.utils.CollectionsUtil;
|
||||
import su.nexmedia.engine.utils.PlayerUtil;
|
||||
import su.nexmedia.engine.utils.random.Rnd;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.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<ExcellentEnchants> {
|
||||
public class BookCommand extends AbstractCommand<ExcellentEnchantsPlugin> {
|
||||
|
||||
public BookCommand(@NotNull ExcellentEnchants plugin) {
|
||||
public BookCommand(@NotNull ExcellentEnchantsPlugin plugin) {
|
||||
super(plugin, new String[]{"book"}, Perms.COMMAND_BOOK);
|
||||
this.setDescription(plugin.getMessage(Lang.COMMAND_BOOK_DESC));
|
||||
this.setUsage(plugin.getMessage(Lang.COMMAND_BOOK_USAGE));
|
||||
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 CollectionsUtil.playerNames(player);
|
||||
return Players.playerNames(player);
|
||||
}
|
||||
if (arg == 2) {
|
||||
return Arrays.stream(Enchantment.values()).map(e -> e.getKey().getKey()).toList();
|
||||
return BukkitThing.getEnchantments().stream().map(enchantment -> enchantment.getKey().getKey()).toList();
|
||||
}
|
||||
if (arg == 3) {
|
||||
return Arrays.asList("-1", "1", "5", "10");
|
||||
@ -47,19 +46,19 @@ public class BookCommand extends AbstractCommand<ExcellentEnchants> {
|
||||
@Override
|
||||
protected void onExecute(@NotNull CommandSender sender, @NotNull CommandResult result) {
|
||||
if (result.length() < 4) {
|
||||
this.printUsage(sender);
|
||||
this.errorUsage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = PlayerUtil.getPlayer(result.getArg(1));
|
||||
Player player = Players.getPlayer(result.getArg(1));
|
||||
if (player == null) {
|
||||
this.errorPlayer(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(result.getArg(2).toLowerCase()));
|
||||
Enchantment enchantment = BukkitThing.getEnchantment(result.getArg(2));
|
||||
if (enchantment == null) {
|
||||
plugin.getMessage(Lang.ERROR_NO_ENCHANT).send(sender);
|
||||
Lang.ERROR_NO_ENCHANT.getMessage().send(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -71,9 +70,9 @@ public class BookCommand extends AbstractCommand<ExcellentEnchants> {
|
||||
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
|
||||
EnchantUtils.add(item, enchantment, level, true);
|
||||
EnchantUtils.updateDisplay(item);
|
||||
PlayerUtil.addItem(player, item);
|
||||
Players.addItem(player, item);
|
||||
|
||||
plugin.getMessage(Lang.COMMAND_BOOK_DONE)
|
||||
Lang.COMMAND_BOOK_DONE.getMessage()
|
||||
.replace(Placeholders.GENERIC_ENCHANT, EnchantUtils.getLocalized(enchantment))
|
||||
.replace(Placeholders.forPlayer(player))
|
||||
.send(sender);
|
||||
|
@ -1,47 +1,46 @@
|
||||
package su.nightexpress.excellentenchants.command;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
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.nexmedia.engine.api.command.AbstractCommand;
|
||||
import su.nexmedia.engine.api.command.CommandResult;
|
||||
import su.nexmedia.engine.utils.*;
|
||||
import su.nexmedia.engine.utils.random.Rnd;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.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.*;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class EnchantCommand extends AbstractCommand<ExcellentEnchants> {
|
||||
public class EnchantCommand extends AbstractCommand<ExcellentEnchantsPlugin> {
|
||||
|
||||
public EnchantCommand(@NotNull ExcellentEnchants plugin) {
|
||||
public EnchantCommand(@NotNull ExcellentEnchantsPlugin plugin) {
|
||||
super(plugin, new String[]{"enchant"}, Perms.COMMAND_ENCHANT);
|
||||
this.setDescription(plugin.getMessage(Lang.COMMAND_ENCHANT_DESC));
|
||||
this.setUsage(plugin.getMessage(Lang.COMMAND_ENCHANT_USAGE));
|
||||
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 Arrays.stream(Enchantment.values()).map(e -> e.getKey().getKey()).toList();
|
||||
return BukkitThing.getEnchantments().stream().map(enchantment -> enchantment.getKey().getKey()).toList();
|
||||
}
|
||||
if (arg == 2) {
|
||||
return Arrays.asList("-1", "1", "5", "10");
|
||||
}
|
||||
if (arg == 3) {
|
||||
return CollectionsUtil.playerNames(player);
|
||||
return Players.playerNames(player);
|
||||
}
|
||||
if (arg == 4) {
|
||||
return CollectionsUtil.getEnumsList(EquipmentSlot.class);
|
||||
return Lists.getEnums(EquipmentSlot.class);
|
||||
}
|
||||
return super.getTab(player, arg, args);
|
||||
}
|
||||
@ -49,17 +48,17 @@ public class EnchantCommand extends AbstractCommand<ExcellentEnchants> {
|
||||
@Override
|
||||
protected void onExecute(@NotNull CommandSender sender, @NotNull CommandResult result) {
|
||||
if (result.length() < 3) {
|
||||
this.printUsage(sender);
|
||||
this.errorUsage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(result.getArg(1).toLowerCase()));
|
||||
Enchantment enchantment = BukkitThing.getEnchantment(result.getArg(1));
|
||||
if (enchantment == null) {
|
||||
plugin.getMessage(Lang.ERROR_NO_ENCHANT).send(sender);
|
||||
Lang.ERROR_NO_ENCHANT.getMessage().send(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = PlayerUtil.getPlayer(result.getArg(3, sender.getName()));
|
||||
Player player = Players.getPlayer(result.getArg(3, sender.getName()));
|
||||
if (player == null) {
|
||||
this.errorPlayer(sender);
|
||||
return;
|
||||
@ -69,7 +68,7 @@ public class EnchantCommand extends AbstractCommand<ExcellentEnchants> {
|
||||
|
||||
ItemStack item = player.getInventory().getItem(slot);
|
||||
if (item == null || item.getType().isAir()) {
|
||||
this.plugin.getMessage(Lang.COMMAND_ENCHANT_ERROR_NO_ITEM).send(sender);
|
||||
Lang.COMMAND_ENCHANT_ERROR_NO_ITEM.getMessage().send(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -86,7 +85,7 @@ public class EnchantCommand extends AbstractCommand<ExcellentEnchants> {
|
||||
EnchantUtils.updateDisplay(item);
|
||||
player.getInventory().setItem(slot, item);
|
||||
|
||||
plugin.getMessage(sender == player ? Lang.COMMAND_ENCHANT_DONE_SELF : Lang.COMMAND_ENCHANT_DONE_OTHERS)
|
||||
(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))
|
||||
|
@ -3,22 +3,22 @@ package su.nightexpress.excellentenchants.command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.command.AbstractCommand;
|
||||
import su.nexmedia.engine.api.command.CommandResult;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.Perms;
|
||||
import su.nightexpress.excellentenchants.config.Lang;
|
||||
import su.nightexpress.nightcore.command.CommandResult;
|
||||
import su.nightexpress.nightcore.command.impl.AbstractCommand;
|
||||
|
||||
public class ListCommand extends AbstractCommand<ExcellentEnchants> {
|
||||
public class ListCommand extends AbstractCommand<ExcellentEnchantsPlugin> {
|
||||
|
||||
public ListCommand(@NotNull ExcellentEnchants plugin) {
|
||||
public ListCommand(@NotNull ExcellentEnchantsPlugin plugin) {
|
||||
super(plugin, new String[]{"list"}, Perms.COMMAND_LIST);
|
||||
this.setDescription(plugin.getMessage(Lang.COMMAND_LIST_DESC));
|
||||
this.setDescription(Lang.COMMAND_LIST_DESC);
|
||||
this.setPlayerOnly(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onExecute(@NotNull CommandSender sender, @NotNull CommandResult result) {
|
||||
plugin.getEnchantManager().getEnchantsListGUI().open((Player) sender, 1);
|
||||
plugin.getEnchantManager().openEnchantsMenu((Player) sender);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,91 @@
|
||||
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.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.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<ExcellentEnchantsPlugin> {
|
||||
|
||||
public RarityBookCommand(@NotNull ExcellentEnchantsPlugin 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_NO_ENCHANT.getMessage().send(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
int level = result.getInt(3, -1);
|
||||
if (level < 1) {
|
||||
level = Rnd.get(enchantmentData.getMinLevel(), 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);
|
||||
}
|
||||
}
|
@ -1,90 +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.nexmedia.engine.api.command.AbstractCommand;
|
||||
import su.nexmedia.engine.api.command.CommandResult;
|
||||
import su.nexmedia.engine.utils.CollectionsUtil;
|
||||
import su.nexmedia.engine.utils.Placeholders;
|
||||
import su.nexmedia.engine.utils.PlayerUtil;
|
||||
import su.nexmedia.engine.utils.random.Rnd;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Perms;
|
||||
import su.nightexpress.excellentenchants.config.Lang;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
import su.nightexpress.excellentenchants.tier.Tier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TierbookCommand extends AbstractCommand<ExcellentEnchants> {
|
||||
|
||||
public TierbookCommand(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, new String[]{"tierbook"}, Perms.COMMAND_TIERBOOK);
|
||||
this.setDescription(plugin.getMessage(Lang.COMMAND_TIER_BOOK_DESC));
|
||||
this.setUsage(plugin.getMessage(Lang.COMMAND_TIER_BOOK_USAGE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
|
||||
if (arg == 1) {
|
||||
return CollectionsUtil.playerNames(player);
|
||||
}
|
||||
if (arg == 2) {
|
||||
return plugin.getTierManager().getTierIds();
|
||||
}
|
||||
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.printUsage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = PlayerUtil.getPlayer(result.getArg(1));
|
||||
if (player == null) {
|
||||
this.errorPlayer(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Tier tier = plugin.getTierManager().getTierById(result.getArg(2).toLowerCase());
|
||||
if (tier == null) {
|
||||
plugin.getMessage(Lang.COMMAND_TIER_BOOK_ERROR).send(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Set<ExcellentEnchant> enchants = EnchantRegistry.getOfTier(tier);
|
||||
ExcellentEnchant enchant = enchants.isEmpty() ? null : Rnd.get(enchants);
|
||||
if (enchant == null) {
|
||||
plugin.getMessage(Lang.ERROR_NO_ENCHANT).send(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
int level = result.getInt(3, -1);
|
||||
if (level < 1) {
|
||||
level = Rnd.get(enchant.getStartLevel(), enchant.getMaxLevel());
|
||||
}
|
||||
|
||||
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
|
||||
EnchantUtils.add(item, enchant.getBackend(), level, true);
|
||||
EnchantUtils.updateDisplay(item);
|
||||
PlayerUtil.addItem(player, item);
|
||||
|
||||
plugin.getMessage(Lang.COMMAND_TIER_BOOK_DONE)
|
||||
.replace(tier.replacePlaceholders())
|
||||
.replace(Placeholders.forPlayer(player))
|
||||
.send(sender);
|
||||
}
|
||||
}
|
@ -3,166 +3,255 @@ package su.nightexpress.excellentenchants.config;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.config.JOption;
|
||||
import su.nexmedia.engine.api.config.JYML;
|
||||
import su.nexmedia.engine.utils.Colorizer;
|
||||
import su.nexmedia.engine.utils.Colors2;
|
||||
import su.nexmedia.engine.utils.StringUtil;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ObtainType;
|
||||
import su.nightexpress.excellentenchants.tier.Tier;
|
||||
import su.nightexpress.excellentenchants.api.DistributionMode;
|
||||
import su.nightexpress.excellentenchants.api.DistributionWay;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.hook.HookId;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
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;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
import static su.nightexpress.nightcore.util.text.tag.Tags.*;
|
||||
|
||||
public class Config {
|
||||
|
||||
public static final String DIR_MENU = "/menu/";
|
||||
public static final String DIR_ENCHANTS = "/enchants/";
|
||||
|
||||
public static final JOption<Long> TASKS_ARROW_TRAIL_TICKS_INTERVAL = JOption.create("Tasks.Arrow_Trail.Tick_Interval",
|
||||
public static final ConfigValue<Long> CORE_PROJECTILE_PARTICLE_INTERVAL = ConfigValue.create("Core.Projectile_Particles_Tick_Interval",
|
||||
1L,
|
||||
"Sets how often (in ticks) arrow trail particle effects will be spawned behind the arrow."
|
||||
"Sets how often (in ticks) enchantment particle effects will be spawned behind projectiles.",
|
||||
"[Increase for performance; Decrease for better visuals]",
|
||||
"[20 ticks = 1 second]",
|
||||
"[Default is 1]"
|
||||
);
|
||||
|
||||
public static final JOption<Long> TASKS_PASSIVE_ENCHANTS_TRIGGER_INTERVAL = JOption.create("Tasks.Passive_Enchants.Trigger_Interval",
|
||||
public static final ConfigValue<Long> CORE_PASSIVE_ENCHANTS_TRIGGER_INTERVAL = ConfigValue.create("Core.Passive_Enchants_Trigger_Interval",
|
||||
100L,
|
||||
"Sets how often (in ticks) the plugin will attempt to trigger passive enchantment effects on all alive entities.",
|
||||
"For best results it's recommened to keep this value smaller, but at the same rate as enchantment 'Trigger_Interval' settings.",
|
||||
"Examples:",
|
||||
"--- Global: 100 ticks; Regrowth: 100 ticks; Saturation: 100 ticks;",
|
||||
"--- Global: 50 ticks, Regrowth: 100 ticks; Saturation: 150 ticks;"
|
||||
"Sets how often (in ticks) passive enchantment effects will trigger on all alive and loaded entities.",
|
||||
"For best results it's recommened to keep this value lower, but at the same rate as enchantment's 'Trigger_Interval' option.",
|
||||
"=".repeat(15) + " EXAMPLES " + "=".repeat(15),
|
||||
"==> Global (this): 100 ticks; Regrowth: 200 ticks; Saturation: 300 ticks;",
|
||||
"==> Global (this): 50 ticks, Regrowth: 100 ticks; Saturation: 150 ticks;",
|
||||
"[Increase for performance; Decrease for more smooth effect]",
|
||||
"[20 ticks = 1 second]",
|
||||
"[Default is 100]"
|
||||
);
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_INTERNAL_HANDLER = JOption.create("Enchantments.Internal_Distributor", false,
|
||||
"[EXPERIMENTAL - DO NOT TOUCH]",
|
||||
"Sets whether or not enchantment distribution will be handled by vanilla server mechanics.");
|
||||
public static final ConfigValue<Boolean> CORE_PASSIVE_ENCHANTS_FOR_MOBS = ConfigValue.create("Core.Apply_Passive_Enchants_To_Mobs",
|
||||
true,
|
||||
"Sets whether or not mobs can have passive enchantment effects (such as permanent potion effects, regeneration, etc.).",
|
||||
"[Enable for enhanced gameplay; Disable for performance]",
|
||||
"[Default is true]"
|
||||
);
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_CHARGES_ENABLED = JOption.create("Enchantments.Charges.Enabled",
|
||||
public static final ConfigValue<Boolean> CORE_SWORD_ENCHANTS_TO_AXES = ConfigValue.create("Core.Sword_Enchants_To_Axes",
|
||||
true,
|
||||
"Sets whether or not Sword enchantments can be applied on Axes.",
|
||||
"[Default is true]"
|
||||
);
|
||||
|
||||
public static final ConfigValue<Boolean> CORE_BOW_ENCHANTS_TO_CROSSBOW = ConfigValue.create("Core.Bow_Enchants_To_Crossbows",
|
||||
true,
|
||||
"Sets whether or not Bow enchantments can be applied on Crossbows.",
|
||||
"[Default is true]"
|
||||
);
|
||||
|
||||
public static final ConfigValue<Boolean> CORE_CHESTPLATE_ENCHANTS_TO_ELYTRA = ConfigValue.create("Core.Chestplate_Enchants_To_Elytra",
|
||||
false,
|
||||
"Enables the enchantment Charges feature.",
|
||||
Placeholders.URL_WIKI + "Charges-System");
|
||||
"Sets whether or not Chestplate enchantments can be applied on Elytras.",
|
||||
"[Default is false]"
|
||||
);
|
||||
|
||||
public static final JOption<TreeMap<Integer, String>> ENCHANTMENTS_CHARGES_FORMAT = new JOption<TreeMap<Integer, String>>("Enchantments.Charges.Format",
|
||||
(cfg, path, def) -> {
|
||||
TreeMap<Integer, String> map = new TreeMap<>();
|
||||
for (String raw : cfg.getSection(path)) {
|
||||
int percent = StringUtil.getInteger(raw, -1);
|
||||
if (percent < 0) continue;
|
||||
|
||||
String format = Colorizer.apply(cfg.getString(path + "." + raw, ""));
|
||||
if (format.isEmpty()) continue;
|
||||
|
||||
map.put(percent, format);
|
||||
}
|
||||
return map;
|
||||
},
|
||||
public static final ConfigValue<Set<String>> ENCHANTMENTS_DISABLED_LIST = ConfigValue.forSet("Enchantments.Disabled.List",
|
||||
String::toLowerCase,
|
||||
FileConfig::set,
|
||||
Set.of("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!"
|
||||
);
|
||||
|
||||
public static final ConfigValue<Map<String, Set<String>>> ENCHANTMENTS_DISABLED_IN_WORLDS = ConfigValue.forMap("Enchantments.Disabled.ByWorld",
|
||||
String::toLowerCase,
|
||||
(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")
|
||||
),
|
||||
"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."
|
||||
);
|
||||
|
||||
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."
|
||||
);
|
||||
|
||||
|
||||
|
||||
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 " + HookId.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."
|
||||
);
|
||||
|
||||
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",
|
||||
GENERIC_VALUE,
|
||||
"Enchantment name display component for name format.");
|
||||
|
||||
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_NAME_COMPONENT_LEVEL = ConfigValue.create("Enchantments.Display.Name.Component.Level",
|
||||
" " + GENERIC_VALUE,
|
||||
"Enchantment level display component for name format.");
|
||||
|
||||
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_NAME_COMPONENT_CHARGES = ConfigValue.create("Enchantments.Display.Name.Component.Charges",
|
||||
" " + GENERIC_VALUE,
|
||||
"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.");
|
||||
|
||||
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.");
|
||||
|
||||
public static final ConfigValue<String> ENCHANTMENTS_DISPLAY_DESCRIPTION_FORMAT = ConfigValue.create("Enchantments.Display.Description.Format",
|
||||
LIGHT_GRAY.enclose("• " + GENERIC_DESCRIPTION),
|
||||
"Sets enc" +
|
||||
"hantment description format.");
|
||||
|
||||
|
||||
|
||||
|
||||
public static final ConfigValue<Boolean> ENCHANTMENTS_CHARGES_ENABLED = ConfigValue.create("Enchantments.Charges.Enabled",
|
||||
false,
|
||||
"Enables Enchantment Charges feature.",
|
||||
"When enabled in the first time, make sure to check enchantments configs for new 'Charges' section.",
|
||||
URL_CHRAGES);
|
||||
|
||||
public static final ConfigValue<TreeMap<Integer, String>> ENCHANTMENTS_CHARGES_FORMAT = ConfigValue.forTreeMap("Enchantments.Charges.Format",
|
||||
raw -> NumberUtil.getInteger(raw, 0),
|
||||
(cfg, path, value) -> cfg.getString(path + "." + value, GENERIC_AMOUNT),
|
||||
(cfg, path, map) -> map.forEach((perc, str) -> cfg.set(path + "." + perc, str)),
|
||||
() -> {
|
||||
TreeMap<Integer, String> map = new TreeMap<>();
|
||||
map.put(0, "#ff9a9a(" + Placeholders.GENERIC_AMOUNT + "⚡)");
|
||||
map.put(25, "#ffc39a(" + Placeholders.GENERIC_AMOUNT + "⚡)");
|
||||
map.put(50, "#f6ff9a(" + Placeholders.GENERIC_AMOUNT + "⚡)");
|
||||
map.put(75, "#bcff9a(" + Placeholders.GENERIC_AMOUNT + "⚡)");
|
||||
map.put(0, LIGHT_RED.enclose("(" + GENERIC_AMOUNT + "⚡)"));
|
||||
map.put(25, LIGHT_ORANGE.enclose("(" + GENERIC_AMOUNT + "⚡)"));
|
||||
map.put(50, LIGHT_YELLOW.enclose("(" + GENERIC_AMOUNT + "⚡)"));
|
||||
map.put(75, LIGHT_GREEN.enclose("(" + GENERIC_AMOUNT + "⚡)"));
|
||||
return map;
|
||||
},
|
||||
"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 '" + Placeholders.GENERIC_AMOUNT + "' placeholder for amount of charges.")
|
||||
.setWriter((cfg, path, map) -> map.forEach((perc, str) -> cfg.set(path + "." + perc, str)));
|
||||
"Use '" + GENERIC_AMOUNT + "' placeholder for charges amount.");
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_CHARGES_COMPARE_TYPE_ONLY = JOption.create("Enchantments.Charges.Compare_Material_Only", false,
|
||||
"When enabled, only item material will be checked to determine if item can be used as an enchantment fuel.",
|
||||
"When disabled (default), it will compare the whole item meta including name, lore, model data etc.");
|
||||
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]");
|
||||
|
||||
public static final JOption<ItemStack> ENCHANTMENTS_CHARGES_FUEL_ITEM = JOption.create("Enchantments.Charges.Fuel_Item",
|
||||
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: " + Placeholders.URL_ENGINE_SCALER)
|
||||
.setWriter(JYML::setItem);
|
||||
|
||||
public static final JOption<Set<String>> ENCHANTMENTS_DISABLED = JOption.create("Enchantments.Disabled",
|
||||
Set.of("enchant_name", "other_enchant"),
|
||||
"A list of enchantments, that will be disabled and removed from the game (server).",
|
||||
"Enchantment names are the same as enchantment file name in /enchants/ folder. ! Must be in lower_case !",
|
||||
"Example: To disable 'Explosive Arrows' you need to add 'explosive_arrows' here.")
|
||||
.mapReader(set -> set.stream().map(String::toLowerCase).collect(Collectors.toSet()));
|
||||
|
||||
public static final JOption<Map<String, Set<String>>> ENCHANTMENTS_DISABLED_IN_WORLDS = new JOption<Map<String, Set<String>>>("Enchantments.Disabled_In_Worlds",
|
||||
(cfg, path, def) -> cfg.getSection(path).stream().collect(Collectors.toMap(k -> k, worldName -> cfg.getStringSet(path + "." + worldName))),
|
||||
() -> Map.of("your_world_name", Set.of("enchantment_name", "ice_aspect")),
|
||||
"Here you can disable certain enchantments in certain worlds.",
|
||||
"Enchantment names are the same as enchantment file name in /enchants/ folder. ! Must be in lower_case !",
|
||||
"To disable all enchantments for a world, use '" + Placeholders.WILDCARD + "' instead of enchantment names.")
|
||||
.setWriter((cfg, path, map) -> map.forEach((world, enchants) -> cfg.set(path + "." + world, enchants)));
|
||||
|
||||
public static final JOption<Integer> ENCHANTMENTS_DISPLAY_MODE = JOption.create("Enchantments.Display.Mode",
|
||||
1,
|
||||
"Sets how enchantment names and descriptions will be handled on items.",
|
||||
"1 = Plain modification of item's lore (lore changes are real and persistent).",
|
||||
"2 = Packet modification of item's lore (no real changes are made to the items). Requires ProtocolLib.",
|
||||
"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.");
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_DESCRIPTION_ENABLED = JOption.create("Enchantments.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.");
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_DESCRIPTION_BOOKS_ONLY = JOption.create("Enchantments.Description.Books_Only",
|
||||
false,
|
||||
"Sets whether or not only enchanted books will have enchantment descriptions.");
|
||||
|
||||
public static final JOption<String> ENCHANTMENTS_DESCRIPTION_FORMAT = JOption.create("Enchantments.Description.Format",
|
||||
"&8▸ " + Placeholders.GENERIC_DESCRIPTION,
|
||||
"Sets the global enchantment description format.").mapReader(Colorizer::apply);
|
||||
|
||||
public static final JOption<Integer> ENCHANTMENTS_ITEM_CUSTOM_MAX = JOption.create("Enchantments.Item.Max_Custom_Enchants", 3,
|
||||
"How many of custom enchantments the item can contain at the same time?");
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_ITEM_SWORD_ENCHANTS_TO_AXES = JOption.create("Enchantments.Item.Sword_Enchants_To_Axes", true,
|
||||
"Set this to 'true' to allow Sword enchantments for Axes.");
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_ITEM_BOW_ENCHANTS_TO_CROSSBOW = JOption.create("Enchantments.Item.Bow_Enchants_To_Crossbows", true,
|
||||
"Set this to 'true' to allow Bow enchantments for Crossbows.");
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_ITEM_CHESTPLATE_ENCHANTS_TO_ELYTRA = JOption.create("Enchantments.Item.Chestplate_Enchants_To_Elytra", false,
|
||||
"Set this to 'true' to allow Chestplate enchantments for Elytras.");
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_ENTITY_PASSIVE_FOR_MOBS = JOption.create("Enchantments.Entity.Apply_Passive_Enchants_To_Mobs", true,
|
||||
"When enabled, passive enchantments (permanent potion effects, regeneration, etc.) will be applied to mobs as well.",
|
||||
"Disable this if you're experiencing performance issues.");
|
||||
|
||||
public static final JOption<Boolean> ENCHANTMENTS_SINGLE_ENCHANT_IN_VILLAGER_BOOKS = JOption.create("Enchantments.Single_Enchant_In_Villager_Books", true,
|
||||
"Sets whether or not enchanted books in villager trades will have only 1 enchant, vanilla or custom one.");
|
||||
|
||||
private static final JOption<Map<ObtainType, ObtainSettings>> OBTAIN_SETTINGS = new JOption<Map<ObtainType, ObtainSettings>>("Enchantments.Obtaining",
|
||||
(cfg, path, def) -> Stream.of(ObtainType.values()).collect(Collectors.toMap(k -> k, v -> ObtainSettings.read(cfg, path + "." + v.getPathName()))),
|
||||
() -> Stream.of(ObtainType.values()).collect(Collectors.toMap(k -> k, v -> new ObtainSettings(true, 4, 80D, 0, 2))),
|
||||
"Settings for the different ways of obtaining enchantments.")
|
||||
.setWriter((cfg, path, map) -> map.forEach((type, settings) -> ObtainSettings.write(cfg, path + "." + type.getPathName(), settings)));
|
||||
"Item Options: " + WIKI_ITEMS_URL);
|
||||
|
||||
@NotNull
|
||||
public static Optional<ObtainSettings> getObtainSettings(@NotNull ObtainType obtainType) {
|
||||
ObtainSettings settings = OBTAIN_SETTINGS.get().get(obtainType);
|
||||
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);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<Tier> getDefaultTiers() {
|
||||
List<Tier> list = new ArrayList<>();
|
||||
list.add(new Tier("common", 1, "Common", Colors2.WHITE, getObtainWeight(50D)));
|
||||
list.add(new Tier("rare", 2, "Rare", Colors2.GREEN, getObtainWeight(25D)));
|
||||
list.add(new Tier("unique", 3, "Unique", Colors2.YELLOW, getObtainWeight(15D)));
|
||||
list.add(new Tier("legendary", 4, "Legendary", Colors2.ORANGE, getObtainWeight(5D)));
|
||||
return list;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<ObtainType, Double> getObtainWeight(double weight) {
|
||||
Map<ObtainType, Double> map = new HashMap<>();
|
||||
for (ObtainType obtainType : ObtainType.values()) {
|
||||
map.put(obtainType, weight);
|
||||
}
|
||||
return map;
|
||||
public static boolean isVanillaDistribution() {
|
||||
return Config.DISTRIBUTION_MODE.get() == DistributionMode.VANILLA;
|
||||
}
|
||||
|
||||
public static boolean isCustomDistribution() {
|
||||
return Config.DISTRIBUTION_MODE.get() == DistributionMode.CUSTOM;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
package su.nightexpress.excellentenchants.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniInt;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package su.nightexpress.excellentenchants.config;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
|
||||
public class Keys {
|
||||
|
||||
public static NamespacedKey loreSize;
|
||||
|
||||
public static NamespacedKey itemRecharged;
|
||||
|
||||
public static NamespacedKey entitySpawnReason;
|
||||
|
||||
public static void loadKeys(@NotNull ExcellentEnchantsPlugin plugin) {
|
||||
loreSize = new NamespacedKey(plugin, "lore_size");
|
||||
itemRecharged = new NamespacedKey(plugin, "item.recharged");
|
||||
entitySpawnReason = new NamespacedKey(plugin, "entity.spawn_reason");
|
||||
}
|
||||
}
|
@ -1,30 +1,54 @@
|
||||
package su.nightexpress.excellentenchants.config;
|
||||
|
||||
import su.nexmedia.engine.api.lang.LangKey;
|
||||
import su.nexmedia.engine.lang.EngineLang;
|
||||
import su.nightexpress.nightcore.core.CoreLang;
|
||||
import su.nightexpress.nightcore.language.entry.LangString;
|
||||
import su.nightexpress.nightcore.language.entry.LangText;
|
||||
|
||||
import static su.nexmedia.engine.utils.Colors2.*;
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
import static su.nightexpress.nightcore.util.text.tag.Tags.*;
|
||||
|
||||
public class Lang extends EngineLang {
|
||||
public class Lang extends CoreLang {
|
||||
|
||||
public static final LangKey COMMAND_LIST_DESC = LangKey.of("Command.List.Desc", "List of all custom enchantments.");
|
||||
public static final LangString COMMAND_LIST_DESC = LangString.of("Command.List.Desc",
|
||||
"List of all custom enchantments.");
|
||||
|
||||
public static final LangKey COMMAND_ENCHANT_USAGE = LangKey.of("Command.Enchant.Usage", "<enchant> <level> [player] [slot]");
|
||||
public static final LangKey COMMAND_ENCHANT_DESC = LangKey.of("Command.Enchant.Desc", "Enchants the item in your hand.");
|
||||
public static final LangKey COMMAND_ENCHANT_DONE_SELF = LangKey.of("Command.Enchant.Done.Self", LIGHT_ORANGE + GENERIC_ITEM + LIGHT_YELLOW + " enchanted with " + GENERIC_ENCHANT + " " + GENERIC_LEVEL + LIGHT_YELLOW + "!");
|
||||
public static final LangKey COMMAND_ENCHANT_DONE_OTHERS = LangKey.of("Command.Enchant.Done.Others", LIGHT_ORANGE + PLAYER_DISPLAY_NAME + LIGHT_YELLOW + "'s " + LIGHT_ORANGE + GENERIC_ITEM + LIGHT_YELLOW + " enchanted with " + GENERIC_ENCHANT + " " + GENERIC_LEVEL + LIGHT_YELLOW + "!");
|
||||
public static final LangKey COMMAND_ENCHANT_ERROR_NO_ITEM = LangKey.of("Command.Enchant.Error.NoItem", RED + "There is no item to enchant!");
|
||||
public static final LangString COMMAND_ENCHANT_USAGE = LangString.of("Command.Enchant.Usage",
|
||||
"<enchant> <level> [player] [slot]");
|
||||
|
||||
public static final LangKey COMMAND_BOOK_USAGE = LangKey.of("Command.Book.Usage", "<player> <enchant> <level>");
|
||||
public static final LangKey COMMAND_BOOK_DESC = LangKey.of("Command.Book.Desc", "Gives custom enchanted book.");
|
||||
public static final LangKey COMMAND_BOOK_DONE = LangKey.of("Command.Book.Done", LIGHT_YELLOW + "Given " + LIGHT_ORANGE + GENERIC_ENCHANT + LIGHT_YELLOW + " enchanted book to " + LIGHT_ORANGE + PLAYER_DISPLAY_NAME + LIGHT_YELLOW + ".");
|
||||
public static final LangString COMMAND_ENCHANT_DESC = LangString.of("Command.Enchant.Desc",
|
||||
"Enchants the item in your hand.");
|
||||
|
||||
public static final LangKey COMMAND_TIER_BOOK_USAGE = LangKey.of("Command.TierBook.Usage", "<player> <tier> <level>");
|
||||
public static final LangKey COMMAND_TIER_BOOK_DESC = LangKey.of("Command.TierBook.Desc", "Gives an enchanted book.");
|
||||
public static final LangKey COMMAND_TIER_BOOK_ERROR = LangKey.of("Command.TierBook.Error", RED + "Invalid tier!");
|
||||
public static final LangKey COMMAND_TIER_BOOK_DONE = LangKey.of("Command.TierBook.Done", LIGHT_YELLOW + "Given " + LIGHT_ORANGE + TIER_NAME + LIGHT_YELLOW + " enchanted book to " + LIGHT_ORANGE + PLAYER_DISPLAY_NAME + LIGHT_YELLOW + ".");
|
||||
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) + "!"));
|
||||
|
||||
public static final LangKey ERROR_NO_ENCHANT = LangKey.of("Error.NoEnchant", RED + "Invalid enchantment.");
|
||||
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) + "!"));
|
||||
|
||||
public static final LangText COMMAND_ENCHANT_ERROR_NO_ITEM = LangText.of("Command.Enchant.Error.NoItem",
|
||||
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) + "."));
|
||||
|
||||
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) + "."));
|
||||
|
||||
public static final LangText ERROR_NO_ENCHANT = LangText.of("Error.NoEnchant",
|
||||
RED.enclose("Invalid enchantment."));
|
||||
|
||||
public static final LangText ERROR_INVALID_RARITY = LangText.of("Error.InvalidRarity",
|
||||
RED.enclose("Invalid rarity!"));
|
||||
|
||||
}
|
||||
|
@ -1,67 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.config.JYML;
|
||||
|
||||
public class ObtainSettings {
|
||||
|
||||
private final boolean isEnabled;
|
||||
private final int enchantsTotalMax;
|
||||
private final double enchantsCustomGenerationChance;
|
||||
private final int enchantsCustomMin;
|
||||
private final int enchantsCustomMax;
|
||||
|
||||
public ObtainSettings(boolean isEnabled,
|
||||
int enchantsTotalMax, double enchantsCustomGenerationChance,
|
||||
int enchantsCustomMin, int enchantsCustomMax) {
|
||||
this.isEnabled = isEnabled;
|
||||
this.enchantsTotalMax = enchantsTotalMax;
|
||||
this.enchantsCustomGenerationChance = enchantsCustomGenerationChance;
|
||||
this.enchantsCustomMin = enchantsCustomMin;
|
||||
this.enchantsCustomMax = enchantsCustomMax;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ObtainSettings read(@NotNull JYML cfg, @NotNull String path) {
|
||||
boolean isEnabled = cfg.getBoolean(path + ".Enabled");
|
||||
int enchantsTotalMax = cfg.getInt(path + ".Enchantments.Total_Maximum", 4);
|
||||
double enchantsCustomGenerationChance = cfg.getDouble(path + ".Enchantments.Custom_Generation_Chance", 50D);
|
||||
int enchantsCustomMin = cfg.getInt(path + ".Enchantments.Custom_Minimum", 0);
|
||||
int enchantsCustomMax = cfg.getInt(path + ".Enchantments.Custom_Maximum", 2);
|
||||
|
||||
return new ObtainSettings(isEnabled, enchantsTotalMax, enchantsCustomGenerationChance, enchantsCustomMin, enchantsCustomMax);
|
||||
}
|
||||
|
||||
public static void write(@NotNull JYML cfg, @NotNull String path, @NotNull ObtainSettings settings) {
|
||||
cfg.set(path + ".Enabled", settings.isEnabled());
|
||||
cfg.set(path + ".Enchantments.Total_Maximum", settings.getEnchantsTotalMax());
|
||||
cfg.set(path + ".Enchantments.Custom_Generation_Chance", settings.getEnchantsCustomGenerationChance());
|
||||
cfg.set(path + ".Enchantments.Custom_Minimum", settings.getEnchantsCustomMin());
|
||||
cfg.set(path + ".Enchantments.Custom_Maximum", settings.getEnchantsCustomMax());
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
public int getEnchantsTotalMax() {
|
||||
return enchantsTotalMax;
|
||||
}
|
||||
|
||||
public double getEnchantsCustomGenerationChance() {
|
||||
return enchantsCustomGenerationChance;
|
||||
}
|
||||
|
||||
public int getEnchantsCustomMin() {
|
||||
return enchantsCustomMin;
|
||||
}
|
||||
|
||||
public int getEnchantsCustomMax() {
|
||||
return enchantsCustomMax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ObtainSettings{" + "enchantsTotalMax=" + enchantsTotalMax + ", enchantsCustomGenerationChance=" + enchantsCustomGenerationChance + ", enchantsCustomMin=" + enchantsCustomMin + ", enchantsCustomMax=" + enchantsCustomMax + '}';
|
||||
}
|
||||
}
|
@ -1,63 +1,123 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.151.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* org.jetbrains.annotations.NotNull
|
||||
* su.nexmedia.engine.NexPlugin
|
||||
* su.nexmedia.engine.api.manager.AbstractManager
|
||||
* su.nexmedia.engine.api.manager.EventListener
|
||||
*/
|
||||
package su.nightexpress.excellentenchants.enchantment;
|
||||
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.manager.AbstractManager;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
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.menu.EnchantmentsListMenu;
|
||||
import su.nightexpress.excellentenchants.enchantment.task.ArrowTrailsTask;
|
||||
import su.nightexpress.excellentenchants.enchantment.task.PassiveEnchantsTask;
|
||||
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
import su.nightexpress.nightcore.manager.AbstractManager;
|
||||
import su.nightexpress.nightcore.util.Pair;
|
||||
|
||||
public class EnchantManager
|
||||
extends AbstractManager<ExcellentEnchants> {
|
||||
import java.util.*;
|
||||
|
||||
public class EnchantManager extends AbstractManager<ExcellentEnchantsPlugin> {
|
||||
|
||||
private final Set<Pair<PassiveEnchant, EnchantmentData>> passiveEnchants;
|
||||
|
||||
public static final String DIR_ENCHANTS = "/enchants/";
|
||||
private EnchantmentsListMenu enchantmentsListMenu;
|
||||
private ArrowTrailsTask arrowTrailsTask;
|
||||
private PassiveEnchantsTask passiveEnchantsTask;
|
||||
|
||||
public EnchantManager(@NotNull ExcellentEnchants plugin) {
|
||||
public EnchantManager(@NotNull ExcellentEnchantsPlugin 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));
|
||||
});
|
||||
}
|
||||
|
||||
protected void onLoad() {
|
||||
this.enchantmentsListMenu = new EnchantmentsListMenu(this.plugin);
|
||||
this.addListener(new EnchantGenericListener(this));
|
||||
|
||||
this.addListener(new EnchantGenericListener(this.plugin, this));
|
||||
this.addListener(new EnchantAnvilListener(this.plugin));
|
||||
this.arrowTrailsTask = new ArrowTrailsTask(this.plugin);
|
||||
this.arrowTrailsTask.start();
|
||||
this.passiveEnchantsTask = new PassiveEnchantsTask(this.plugin);
|
||||
this.passiveEnchantsTask.start();
|
||||
|
||||
if (Config.isCustomDistribution()) {
|
||||
this.plugin.info("Using custom distribution system...");
|
||||
this.addListener(new EnchantPopulationListener(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)) {
|
||||
this.addTask(this.plugin.createTask(FlameWalkerEnchant::tickBlocks).setSecondsInterval(1));
|
||||
}
|
||||
}
|
||||
|
||||
protected void onShutdown() {
|
||||
if (this.enchantmentsListMenu != null) {
|
||||
this.enchantmentsListMenu.clear();
|
||||
this.enchantmentsListMenu = null;
|
||||
}
|
||||
if (this.arrowTrailsTask != null) {
|
||||
this.arrowTrailsTask.stop();
|
||||
this.arrowTrailsTask = null;
|
||||
}
|
||||
if (this.passiveEnchantsTask != null) {
|
||||
this.passiveEnchantsTask.stop();
|
||||
this.passiveEnchantsTask = null;
|
||||
if (this.enchantmentsListMenu != null) this.enchantmentsListMenu.clear();
|
||||
|
||||
if (EnchantRegistry.isRegistered(FlameWalkerEnchant.ID)) {
|
||||
FlameWalkerEnchant.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantmentsListMenu getEnchantsListGUI() {
|
||||
return this.enchantmentsListMenu;
|
||||
public EnchantmentsListMenu getEnchantmentsListMenu() {
|
||||
return enchantmentsListMenu;
|
||||
}
|
||||
|
||||
public void openEnchantsMenu(@NotNull Player player) {
|
||||
this.enchantmentsListMenu.open(player);
|
||||
}
|
||||
|
||||
private void displayProjectileTrails() {
|
||||
EnchantUtils.getEnchantedProjectiles().removeIf(enchantedProjectile -> {
|
||||
if (!enchantedProjectile.isValid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
enchantedProjectile.playParticles();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private void updatePassiveEnchantEffects() {
|
||||
if (this.passiveEnchants.isEmpty()) return;
|
||||
|
||||
Set<LivingEntity> entities = this.getPassiveEnchantEntities();
|
||||
|
||||
this.passiveEnchants.forEach(pair -> {
|
||||
PassiveEnchant enchant = pair.getFirst();
|
||||
EnchantmentData enchantmentData = pair.getSecond();
|
||||
if (!enchant.isTriggerTime()) return;
|
||||
|
||||
for (LivingEntity entity : entities) {
|
||||
EnchantUtils.getEquipped(entity, enchantmentData).forEach((item, level) -> {
|
||||
if (!enchant.isAvailableToUse(entity)) return;
|
||||
if (enchant.isOutOfCharges(item)) return;
|
||||
if (enchant.onTrigger(entity, item, level)) {
|
||||
enchant.consumeCharges(item, level);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enchant.updateTriggerTime();
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<LivingEntity> getPassiveEnchantEntities() {
|
||||
Set<LivingEntity> list = new HashSet<>(plugin.getServer().getOnlinePlayers());
|
||||
|
||||
if (Config.CORE_PASSIVE_ENCHANTS_FOR_MOBS.get()) {
|
||||
plugin.getServer().getWorlds().stream().filter(world -> !world.getPlayers().isEmpty()).forEach(world -> {
|
||||
list.addAll(world.getEntitiesByClass(LivingEntity.class));
|
||||
});
|
||||
}
|
||||
list.removeIf(entity -> entity.isDead() || !entity.isValid());
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,44 +6,47 @@ import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import su.nexmedia.engine.utils.random.Rnd;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
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.ObtainSettings;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.config.DistributionWaySettings;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.CustomDistribution;
|
||||
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ObtainType;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
import su.nightexpress.excellentenchants.tier.Tier;
|
||||
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.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class EnchantPopulator {
|
||||
|
||||
private final ExcellentEnchants plugin;
|
||||
private final ObtainType obtainType;
|
||||
private final ItemStack item;
|
||||
private final Map<Tier, Set<ExcellentEnchant>> candidates;
|
||||
private final Map<Enchantment, Integer> population;
|
||||
//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 Function<ExcellentEnchant, Integer> levelGenerator;
|
||||
private BiFunction<EnchantmentData, CustomDistribution, Integer> levelGenerator;
|
||||
|
||||
public EnchantPopulator(@NotNull ExcellentEnchants plugin, @NotNull ItemStack item, @NotNull ObtainType obtainType) {
|
||||
this.plugin = plugin;
|
||||
public EnchantPopulator(@NotNull ExcellentEnchantsPlugin plugin, @NotNull ItemStack item, @NotNull DistributionWay distributionWay) {
|
||||
//this.plugin = plugin;
|
||||
this.item = item;
|
||||
this.obtainType = obtainType;
|
||||
this.distributionWay = distributionWay;
|
||||
this.candidates = new HashMap<>();
|
||||
this.population = new HashMap<>();
|
||||
this.withLevelGenerator(enchant -> enchant.generateLevel(this.getObtainType()));
|
||||
this.defaultPopulation = new HashMap<>();
|
||||
this.predicates = new HashSet<>();
|
||||
this.withLevelGenerator((data, distribution) -> distribution.generateLevel(this.getDistributionWay()));
|
||||
|
||||
this.fillDefaultCandidates();
|
||||
//this.fillDefaultCandidates();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -53,42 +56,61 @@ public class EnchantPopulator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantPopulator withLevelGenerator(@NotNull Function<ExcellentEnchant, Integer> levelGenerator) {
|
||||
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.getPopulation().putAll(population);
|
||||
this.defaultPopulation.putAll(population);
|
||||
//this.getPopulation().putAll(population);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void fillDefaultCandidates() {
|
||||
this.plugin.getTierManager().getTiers().forEach(tier -> {
|
||||
Set<ExcellentEnchant> enchants = EnchantRegistry.getOfTier(tier);
|
||||
for (Rarity rarity : Rarity.values()) {
|
||||
Set<EnchantmentData> dataSet = EnchantRegistry.getEnchantments(rarity);
|
||||
|
||||
enchants.removeIf(enchant -> {
|
||||
return !enchant.isObtainable(this.getObtainType()) || (!enchant.getBackend().canEnchantItem(this.getItem()) && !EnchantUtils.isBook(this.getItem()));
|
||||
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(tier, enchants);
|
||||
});
|
||||
this.candidates.put(rarity, dataSet);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.getCandidates().isEmpty() || this.getCandidates().values().stream().allMatch(Set::isEmpty);
|
||||
}
|
||||
|
||||
public boolean isEmpty(@NotNull Tier tier) {
|
||||
return this.getCandidates(tier).isEmpty();
|
||||
public boolean isEmpty(@NotNull Rarity rarity) {
|
||||
return this.getCandidates(rarity).isEmpty();
|
||||
}
|
||||
|
||||
public void purge(@NotNull Tier tier) {
|
||||
this.getCandidates().remove(tier);
|
||||
public void purge(@NotNull Rarity rarity) {
|
||||
this.getCandidates().remove(rarity);
|
||||
}
|
||||
|
||||
public void purge(@NotNull Tier tier, @NotNull ExcellentEnchant enchant) {
|
||||
public void purge(@NotNull Rarity tier, @NotNull EnchantmentData enchant) {
|
||||
this.getCandidates(tier).remove(enchant);
|
||||
this.getCandidates().keySet().removeIf(this::isEmpty);
|
||||
}
|
||||
@ -99,8 +121,8 @@ public class EnchantPopulator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ObtainType getObtainType() {
|
||||
return obtainType;
|
||||
public DistributionWay getDistributionWay() {
|
||||
return distributionWay;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -109,89 +131,98 @@ public class EnchantPopulator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Function<ExcellentEnchant, Integer> getLevelGenerator() {
|
||||
public BiFunction<EnchantmentData, CustomDistribution, Integer> getLevelGenerator() {
|
||||
return levelGenerator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<Tier, Set<ExcellentEnchant>> getCandidates() {
|
||||
public Map<Rarity, Set<EnchantmentData>> getCandidates() {
|
||||
return this.candidates;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<ExcellentEnchant> getCandidates(@NotNull Tier tier) {
|
||||
return this.getCandidates().getOrDefault(tier, new HashSet<>());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<Enchantment, Integer> getPopulation() {
|
||||
return this.population;
|
||||
public Set<EnchantmentData> getCandidates(@NotNull Rarity rarity) {
|
||||
return this.candidates.getOrDefault(rarity, new HashSet<>());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tier getTierByChance() {
|
||||
Map<Tier, Double> map = this.getCandidates().keySet().stream()
|
||||
.filter(tier -> tier.getChance(this.getObtainType()) > 0D)
|
||||
.collect(Collectors.toMap(k -> k, v -> v.getChance(this.getObtainType()), (o, n) -> n, HashMap::new));
|
||||
if (map.isEmpty()) return null;
|
||||
public Rarity getRarityByWeight() {
|
||||
Map<Rarity, Double> map = new HashMap<>();
|
||||
|
||||
return Rnd.getByWeight(map);
|
||||
for (Rarity rarity : this.getCandidates().keySet()) {
|
||||
map.put(rarity, (double) rarity.getWeight());
|
||||
}
|
||||
|
||||
return map.isEmpty() ? null : Rnd.getByWeight(map);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ExcellentEnchant getEnchantByChance(@NotNull Tier tier) {
|
||||
Map<ExcellentEnchant, Double> map = this.getCandidates(tier).stream()
|
||||
.collect(Collectors.toMap(k -> k, v -> v.getObtainChance(this.getObtainType())));
|
||||
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() {
|
||||
Map<Enchantment, Integer> population = this.getPopulation();
|
||||
this.candidates.clear();
|
||||
this.fillDefaultCandidates();
|
||||
|
||||
ObtainSettings settings = Config.getObtainSettings(this.getObtainType()).orElse(null);
|
||||
if (settings == null || !Rnd.chance(settings.getEnchantsCustomGenerationChance())) return population;
|
||||
Map<Enchantment, Integer> population = new HashMap<>(this.defaultPopulation);
|
||||
|
||||
int enchantsLimit = settings.getEnchantsTotalMax();
|
||||
int enchantsRolled = Rnd.get(settings.getEnchantsCustomMin(), settings.getEnchantsCustomMax());
|
||||
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;
|
||||
|
||||
Tier tier = this.getTierByChance();
|
||||
if (tier == null) break; // no tiers left.
|
||||
Rarity rarity = this.getRarityByWeight();
|
||||
if (rarity == null) break; // no tiers left.
|
||||
|
||||
ExcellentEnchant enchant = this.getEnchantByChance(tier);
|
||||
// Remove entire tier if no enchants can be selected.
|
||||
if (enchant == null) {
|
||||
this.purge(tier);
|
||||
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 (world != null && enchant.isDisabledInWorld(world)) {
|
||||
this.purge(tier, enchant);
|
||||
if (this.world != null && !enchantmentData.isAvailableToUse(this.world)) {
|
||||
this.purge(rarity, enchantmentData);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove conflicting enchants.
|
||||
if (population.keySet().stream().anyMatch(has -> has.conflictsWith(enchant.getBackend()) || enchant.getBackend().conflictsWith(has))) {
|
||||
this.purge(tier, enchant);
|
||||
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(enchant);
|
||||
if (level < enchant.getStartLevel()) {
|
||||
this.purge(tier, enchant);
|
||||
int level = this.getLevelGenerator().apply(enchantmentData, distribution);
|
||||
if (level < enchantmentData.getMinLevel()) {
|
||||
this.purge(rarity, enchantmentData);
|
||||
continue;
|
||||
}
|
||||
|
||||
// All good!
|
||||
this.purge(tier, enchant);
|
||||
population.put(enchant.getBackend(), level);
|
||||
this.purge(rarity, enchantmentData);
|
||||
population.put(enchantmentData.getEnchantment(), level);
|
||||
enchantsRolled--;
|
||||
}
|
||||
|
||||
@ -201,16 +232,15 @@ public class EnchantPopulator {
|
||||
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();
|
||||
|
||||
var population = this.getPopulation().isEmpty() ? this.createPopulation() : this.getPopulation();
|
||||
|
||||
boolean singleVillagerBook = this.getObtainType() == ObtainType.VILLAGER
|
||||
&& item.getType() == Material.ENCHANTED_BOOK
|
||||
&& Config.ENCHANTMENTS_SINGLE_ENCHANT_IN_VILLAGER_BOOKS.get();
|
||||
boolean singleVillagerBook = this.getDistributionWay() == DistributionWay.VILLAGER
|
||||
&& EnchantUtils.isEnchantedBook(item)
|
||||
&& Config.DISTRIBUTION_SINGLE_ENCHANT_IN_VILLAGER_BOOKS.get();
|
||||
|
||||
if (singleVillagerBook) {
|
||||
if (!population.isEmpty()) {
|
||||
EnchantUtils.getAll(item).keySet().forEach(enchantment -> EnchantUtils.remove(item, enchantment));
|
||||
EnchantUtils.removeAll(item);
|
||||
}
|
||||
while (population.size() > 1) {
|
||||
population.remove(Rnd.get(population.keySet()));
|
||||
|
@ -1,361 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.config;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import su.nexmedia.engine.api.config.JOption;
|
||||
import su.nexmedia.engine.api.config.JYML;
|
||||
import su.nexmedia.engine.utils.Colorizer;
|
||||
import su.nexmedia.engine.utils.StringUtil;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsAPI;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ObtainType;
|
||||
import su.nightexpress.excellentenchants.tier.Tier;
|
||||
import su.nightexpress.excellentenchants.tier.TierManager;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class EnchantDefaults {
|
||||
|
||||
private final Map<ObtainType, Double> obtainChance;
|
||||
private final Map<ObtainType, int[]> obtainLevelCap;
|
||||
|
||||
private String displayName;
|
||||
private Tier tier;
|
||||
private List<String> description;
|
||||
private boolean hiddenFromList;
|
||||
private boolean isTreasure;
|
||||
private boolean tradeable;
|
||||
private boolean discoverable;
|
||||
private int levelMin;
|
||||
private int levelMax;
|
||||
private int maxMergeLevel;
|
||||
private EnchantScaler levelByEnchantCost;
|
||||
private EnchantScaler anvilMergeCost;
|
||||
private Set<String> conflicts;
|
||||
private boolean visualEffects;
|
||||
|
||||
private boolean chargesEnabled;
|
||||
private boolean chargesCustomFuel;
|
||||
private EnchantScaler chargesMax;
|
||||
private EnchantScaler chargesConsumeAmount;
|
||||
private EnchantScaler chargesRechargeAmount;
|
||||
private ItemStack chargesFuel;
|
||||
|
||||
public EnchantDefaults(@NotNull ExcellentEnchant enchant) {
|
||||
this.setDisplayName(StringUtil.capitalizeUnderscored(enchant.getId()));
|
||||
this.setTier(0.1);
|
||||
this.setDescription(new ArrayList<>());
|
||||
this.setHiddenFromList(false);
|
||||
this.setTreasure(false);
|
||||
this.setTradeable(true);
|
||||
this.setDiscoverable(true);
|
||||
this.setLevelMin(1);
|
||||
this.setLevelMax(3);
|
||||
this.setMaxMergeLevel(-1);
|
||||
this.setConflicts(new HashSet<>());
|
||||
this.setVisualEffects(true);
|
||||
this.obtainChance = new HashMap<>();
|
||||
this.obtainLevelCap = new HashMap<>();
|
||||
}
|
||||
|
||||
public void load(@NotNull ExcellentEnchant enchant) {
|
||||
ExcellentEnchants plugin = ExcellentEnchantsAPI.PLUGIN;
|
||||
JYML cfg = enchant.getConfig();
|
||||
|
||||
this.setDisplayName(JOption.create("Name", this.getDisplayName(),
|
||||
"Enchantment display name. It will be shown in item lore.").read(cfg));
|
||||
|
||||
Tier tier = plugin.getTierManager().getTierById(JOption.create("Tier", this.getTier().getId(),
|
||||
"Enchantment tier. Must be a valid tier identifier from the '" + TierManager.FILE_NAME + "'.").read(cfg));
|
||||
this.setTier(tier == null ? plugin.getTierManager().getMostCommon() : tier);
|
||||
//this.getTier().getEnchants().add(enchant);
|
||||
|
||||
this.setDescription(JOption.create("Description", this.getDescription(),
|
||||
"Enchantment description. It will be shown in item lore under enchantment name.",
|
||||
"You can use 'Enchantment' placeholders: " + Placeholders.URL_PLACEHOLDERS)
|
||||
.read(cfg));
|
||||
|
||||
this.setHiddenFromList(JOption.create("Hide_From_List", false,
|
||||
"Sets whether or not this enchantment will be hidden from Enchants GUI.").read(cfg));
|
||||
|
||||
this.setTreasure(JOption.create("Is_Treasure", this.isTreasure(),
|
||||
"Sets whether this enchantment is a treasure enchantment.",
|
||||
"Treasure enchantments can only be received via looting, trading, or fishing.").read(cfg));
|
||||
|
||||
if (Config.ENCHANTMENTS_INTERNAL_HANDLER.get()) {
|
||||
this.setTradeable(JOption.create("Tradeable", this.isTradeable(),
|
||||
"Sets whether or not this enchantment can be populated in villager trades.").read(cfg));
|
||||
|
||||
this.setDiscoverable(JOption.create("Discoverable", this.isTradeable(),
|
||||
"Sets whether or not this enchantment can be populated in enchanting table.").read(cfg));
|
||||
}
|
||||
else {
|
||||
this.setTradeable(false);
|
||||
this.setDiscoverable(false);
|
||||
}
|
||||
|
||||
this.setLevelMin(JOption.create("Level.Min", this.getLevelMin(),
|
||||
"Sets the minimal (start) enchantment level. Can not be less than 1.").read(cfg));
|
||||
|
||||
this.setLevelMax(JOption.create("Level.Max", this.getLevelMax(),
|
||||
"Sets the maximal enchantment level. Can not be less than min. level.",
|
||||
"Note: While you can 'bypass' this value by enchant commands, all level-dependant enchantment",
|
||||
"settings will have a limit up to this setting.").read(cfg));
|
||||
|
||||
this.setMaxMergeLevel(JOption.create("Anvil.Max_Merge_Level", this.getMaxMergeLevel(),
|
||||
"Sets max. enchantment level that can be obtained by combining 2 items with this enchantment.",
|
||||
"Set this to '-1' to remove merge limit and just use 'Max Level' instead."
|
||||
).read(cfg));
|
||||
|
||||
this.setLevelByEnchantCost(EnchantScaler.read(enchant, ObtainType.ENCHANTING.getPathName() + ".Level_By_Exp_Cost",
|
||||
(int)(30D / this.levelMax) + " * " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
"Sets how much XP levels must be used in enchanting table to obtain this enchantment.",
|
||||
"With a default formula '9 * %enchantment_level%' it will be [9, 18, 27] XP levels for [1, 2, 3] enchantment levels."));
|
||||
|
||||
this.setAnvilMergeCost(EnchantScaler.read(enchant, "Anvil.Merge_Cost", Placeholders.ENCHANTMENT_LEVEL,
|
||||
"Sets how much XP levels will be added to the anvil cost when combining custom enchantments."));
|
||||
|
||||
for (ObtainType obtainType : ObtainType.values()) {
|
||||
double obtainChance = JOption.create(obtainType.getPathName() + ".Chance", 50D,
|
||||
"Chance for this enchantment to be obtained via " + obtainType.getPathName()).read(cfg);
|
||||
this.getObtainChance().put(obtainType, obtainChance);
|
||||
|
||||
int levelMin = JOption.create(obtainType.getPathName() + ".Level.Min", -1,
|
||||
"Minimal level when obtained via " + obtainType.getPathName(),
|
||||
"Can not be less than enchantment min. level. Set -1 to use enchantment min. level.").read(cfg);
|
||||
int levelMax = JOption.create(obtainType.getPathName() + ".Level.Max", -1,
|
||||
"Maximal level when obtained via " + obtainType.getPathName(),
|
||||
"Can not be greater than enchantment max. level. Set -1 to use enchantment max. level.").read(cfg);
|
||||
this.getObtainLevelCap().put(obtainType, new int[]{levelMin, levelMax});
|
||||
}
|
||||
|
||||
|
||||
this.setConflicts(JOption.create("Conflicts", this.getConflicts(),
|
||||
"A list of conflicting enchantment names.",
|
||||
"Conflicting enchantments can not be combined on anvils and obtained together on the same item.").read(cfg));
|
||||
|
||||
this.setVisualEffects(JOption.create("Settings.Visual_Effects", this.isVisualEffects(),
|
||||
"Enables/Disables enchantment visual effects, such as particles.").read(cfg));
|
||||
|
||||
|
||||
if (Config.ENCHANTMENTS_CHARGES_ENABLED.get()) {
|
||||
this.setChargesEnabled(JOption.create("Settings.Charges.Enabled", this.isChargesEnabled(),
|
||||
"When 'true' enables the Charges system for this enchantment.",
|
||||
"When enchanted the first time on enchanting table, it will have maximum charges amount.").read(cfg));
|
||||
|
||||
this.setChargesCustomFuel(JOption.create("Settings.Charges.Custom_Fuel", this.isChargesCustomFuel(),
|
||||
"When 'true' uses different (non-default) fuel item (from the 'Fuel_Item' setting) to recharge.").read(cfg));
|
||||
|
||||
this.setChargesMax(EnchantScaler.read(enchant, "Settings.Charges.Maximum", "100",
|
||||
"Maximum amount of charges for the enchantment."));
|
||||
|
||||
this.setChargesConsumeAmount(EnchantScaler.read(enchant, "Settings.Charges.Consume_Amount", "1",
|
||||
"How many charges will be consumed when enchantment is triggered?"));
|
||||
|
||||
this.setChargesRechargeAmount(EnchantScaler.read(enchant, "Settings.Charges.Recharge_Amount", "25",
|
||||
"How many charges will be restored when using 'Fuel Item' in anvil?"));
|
||||
|
||||
this.setChargesFuel(JOption.create("Settings.Charges.Fuel_Item", new ItemStack(Material.LAPIS_LAZULI),
|
||||
"An item, that will be used to restore enchantment charges on anvils.",
|
||||
"Item Options:" + Placeholders.URL_ENGINE_ITEMS)
|
||||
.setWriter(JYML::setItem).read(cfg));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(@NotNull String displayName) {
|
||||
this.displayName = Colorizer.apply(displayName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Tier getTier() {
|
||||
return tier;
|
||||
}
|
||||
|
||||
public void setTier(double rarity) {
|
||||
this.setTier(ExcellentEnchantsAPI.getTierManager().getByRarityModifier(rarity));
|
||||
}
|
||||
|
||||
public void setTier(@NotNull Tier tier) {
|
||||
this.tier = tier;
|
||||
}
|
||||
|
||||
public void setDescription(@NotNull String... description) {
|
||||
this.setDescription(Arrays.asList(description));
|
||||
}
|
||||
|
||||
public void setDescription(@NotNull List<String> description) {
|
||||
this.description = Colorizer.apply(description);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public boolean isHiddenFromList() {
|
||||
return hiddenFromList;
|
||||
}
|
||||
|
||||
public void setHiddenFromList(boolean hiddenFromList) {
|
||||
this.hiddenFromList = hiddenFromList;
|
||||
}
|
||||
|
||||
public boolean isTreasure() {
|
||||
return isTreasure;
|
||||
}
|
||||
|
||||
public void setTreasure(boolean treasure) {
|
||||
isTreasure = treasure;
|
||||
}
|
||||
|
||||
public boolean isTradeable() {
|
||||
return tradeable;
|
||||
}
|
||||
|
||||
public void setTradeable(boolean tradeable) {
|
||||
this.tradeable = tradeable;
|
||||
}
|
||||
|
||||
public boolean isDiscoverable() {
|
||||
return discoverable;
|
||||
}
|
||||
|
||||
public void setDiscoverable(boolean discoverable) {
|
||||
this.discoverable = discoverable;
|
||||
}
|
||||
|
||||
public void setLevelMin(int levelMin) {
|
||||
this.levelMin = Math.max(1, levelMin);
|
||||
}
|
||||
|
||||
public int getLevelMin() {
|
||||
return levelMin;
|
||||
}
|
||||
|
||||
public void setLevelMax(int levelMax) {
|
||||
this.levelMax = Math.max(1, levelMax);
|
||||
}
|
||||
|
||||
public int getLevelMax() {
|
||||
return levelMax;
|
||||
}
|
||||
|
||||
public int getMaxMergeLevel() {
|
||||
return this.maxMergeLevel;
|
||||
}
|
||||
|
||||
public void setMaxMergeLevel(int maxMergeLevel) {
|
||||
this.maxMergeLevel = Math.min(this.getLevelMax(), maxMergeLevel);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantScaler getLevelByEnchantCost() {
|
||||
return levelByEnchantCost;
|
||||
}
|
||||
|
||||
public void setLevelByEnchantCost(@NotNull EnchantScaler levelByEnchantCost) {
|
||||
this.levelByEnchantCost = levelByEnchantCost;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantScaler getAnvilMergeCost() {
|
||||
return anvilMergeCost;
|
||||
}
|
||||
|
||||
public void setAnvilMergeCost(@NotNull EnchantScaler anvilMergeCost) {
|
||||
this.anvilMergeCost = anvilMergeCost;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<ObtainType, Double> getObtainChance() {
|
||||
return obtainChance;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<ObtainType, int[]> getObtainLevelCap() {
|
||||
return obtainLevelCap;
|
||||
}
|
||||
|
||||
public void setConflicts(@NotNull String... conflicts) {
|
||||
this.setConflicts(new HashSet<>(Arrays.asList(conflicts)));
|
||||
}
|
||||
|
||||
public void setConflicts(@NotNull Set<String> conflicts) {
|
||||
this.conflicts = conflicts;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<String> getConflicts() {
|
||||
return conflicts;
|
||||
}
|
||||
|
||||
public boolean isVisualEffects() {
|
||||
return visualEffects;
|
||||
}
|
||||
|
||||
public void setVisualEffects(boolean visualEffects) {
|
||||
this.visualEffects = visualEffects;
|
||||
}
|
||||
|
||||
public boolean isChargesEnabled() {
|
||||
return chargesEnabled;
|
||||
}
|
||||
|
||||
public void setChargesEnabled(boolean chargesEnabled) {
|
||||
this.chargesEnabled = chargesEnabled;
|
||||
}
|
||||
|
||||
public boolean isChargesCustomFuel() {
|
||||
return chargesCustomFuel;
|
||||
}
|
||||
|
||||
public void setChargesCustomFuel(boolean chargesCustomFuel) {
|
||||
this.chargesCustomFuel = chargesCustomFuel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantScaler getChargesMax() {
|
||||
return chargesMax;
|
||||
}
|
||||
|
||||
public void setChargesMax(@NotNull EnchantScaler chargesMax) {
|
||||
this.chargesMax = chargesMax;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemStack getChargesFuel() {
|
||||
return chargesFuel;
|
||||
}
|
||||
|
||||
public void setChargesFuel(@Nullable ItemStack chargesFuel) {
|
||||
this.chargesFuel = chargesFuel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantScaler getChargesConsumeAmount() {
|
||||
return chargesConsumeAmount;
|
||||
}
|
||||
|
||||
public void setChargesConsumeAmount(@NotNull EnchantScaler chargesConsumeAmount) {
|
||||
this.chargesConsumeAmount = chargesConsumeAmount;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantScaler getChargesRechargeAmount() {
|
||||
return chargesRechargeAmount;
|
||||
}
|
||||
|
||||
public void setChargesRechargeAmount(@NotNull EnchantScaler chargesRechargeAmount) {
|
||||
this.chargesRechargeAmount = chargesRechargeAmount;
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import su.nexmedia.engine.api.config.JYML;
|
||||
import su.nexmedia.engine.utils.Evaluator;
|
||||
import su.nexmedia.engine.utils.StringUtil;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class EnchantScaler {
|
||||
|
||||
public EnchantScaler(@NotNull ExcellentEnchant enchant, @NotNull String path) {
|
||||
this(enchant.getConfig(), path, Placeholders.ENCHANTMENT_LEVEL, enchant.getStartLevel(), enchant.getMaxLevel());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static EnchantScaler read(@NotNull ExcellentEnchant enchant, @NotNull String path, @NotNull String def, @Nullable String... comments) {
|
||||
enchant.getConfig().addMissing(path, def);
|
||||
if (comments != null) {
|
||||
List<String> list = new ArrayList<>(Arrays.asList(comments));
|
||||
list.add("You can use formulas/expressions here: " + Placeholders.URL_ENGINE_SCALER);
|
||||
list.add("Level placeholder: " + Placeholders.ENCHANTMENT_LEVEL);
|
||||
enchant.getConfig().setComments(path, list);
|
||||
}
|
||||
return new EnchantScaler(enchant, path);
|
||||
}
|
||||
|
||||
private final int levelMin;
|
||||
private final int levelMax;
|
||||
private final TreeMap<Integer, Double> values;
|
||||
|
||||
public EnchantScaler(@NotNull JYML cfg, @NotNull String path, @NotNull String levelPlaceholder, int levelMin, int levelMax) {
|
||||
this.levelMin = levelMin;
|
||||
this.levelMax = levelMax;
|
||||
this.values = new TreeMap<>();
|
||||
|
||||
// Load different values for each object level.
|
||||
Set<String> lvlKeys = cfg.getSection(path);
|
||||
if (!lvlKeys.isEmpty()) {
|
||||
for (String sLvl : lvlKeys) {
|
||||
int eLvl = StringUtil.getInteger(sLvl, 0);
|
||||
if (eLvl < this.getLevelMin() || eLvl > this.getLevelMax()) continue;
|
||||
|
||||
String formula = cfg.getString(path + "." + sLvl, "0").replace(levelPlaceholder, sLvl);
|
||||
values.put(eLvl, Evaluator.evaluate(formula));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the single formula for all object levels.
|
||||
for (int lvl = this.getLevelMin(); lvl < (this.getLevelMax() + 1); lvl++) {
|
||||
String sLvl = String.valueOf(lvl);
|
||||
String exChance = cfg.getString(path, "").replace(levelPlaceholder, sLvl);
|
||||
if (exChance.isEmpty()) continue;
|
||||
|
||||
values.put(lvl, Evaluator.evaluate(exChance));
|
||||
}
|
||||
}
|
||||
|
||||
public int getLevelMin() {
|
||||
return this.levelMin;
|
||||
}
|
||||
|
||||
public int getLevelMax() {
|
||||
return this.levelMax;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TreeMap<Integer, Double> getValues() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
public double getValue(int level) {
|
||||
Map.Entry<Integer, Double> en = this.values.floorEntry(level);
|
||||
return en != null ? en.getValue() : 0D;
|
||||
}
|
||||
}
|
@ -0,0 +1,738 @@
|
||||
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.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
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.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.DistributionWay;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.distribution.DistributionOptions;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ItemCategory;
|
||||
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.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 java.util.stream.Stream;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public abstract class AbstractEnchantmentData extends AbstractFileData<ExcellentEnchantsPlugin> 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 minLevel;
|
||||
private int maxLevel;
|
||||
//private int maxMergeLevel;
|
||||
|
||||
private Modifier minCost;
|
||||
private Modifier maxCost;
|
||||
//private Modifier anvilMergeCost;
|
||||
|
||||
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 ExcellentEnchantsPlugin plugin, @NotNull File file) {
|
||||
super(plugin, file);
|
||||
this.setDescription(new ArrayList<>());
|
||||
this.setRarity(Rarity.COMMON);
|
||||
this.setStartLevel(1);
|
||||
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."
|
||||
).read(cfg));
|
||||
|
||||
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.setStartLevel(ConfigValue.create("Settings.Level.Min",
|
||||
this.getMinLevel(),
|
||||
"Min. enchantment level."
|
||||
).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);
|
||||
double costBase = Config.isVanillaDistribution() ? 45D : 30D;
|
||||
double costAdjust = costBase / this.getMaxLevel();
|
||||
|
||||
this.setMinCost(Modifier.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Min_Cost",
|
||||
Modifier.add(1 - costAdjust, costAdjust, 1),
|
||||
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(Modifier.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Max_Cost",
|
||||
Modifier.add(12 - costAdjust, costAdjust, 1),
|
||||
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.")
|
||||
);
|
||||
|
||||
this.distributionOptions.load(cfg);
|
||||
|
||||
|
||||
|
||||
/*this.setAnvilMergeCost(Modifier.read(cfg, "Anvil.Merge.Cost",
|
||||
Modifier.add(1, 1, 1),
|
||||
"Sets XP cost to apply or transfer this enchantment using anvils."
|
||||
));
|
||||
|
||||
this.setMaxMergeLevel(ConfigValue.create("Anvil.Merge.Max_Level",
|
||||
-1,
|
||||
"Max. enchantment level that can be obtained by combining 2 items with this enchantment.",
|
||||
"Set to '-1' to remove limit and cap to max. enchantment level."
|
||||
).read(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(this.getMinLevel()))
|
||||
.add(ENCHANTMENT_LEVEL_MAX, () -> String.valueOf(this.getMaxLevel()))
|
||||
.add(ENCHANTMENT_RARITY, () -> plugin.getLangManager().getEnum(this.getRarity()))
|
||||
.add(ENCHANTMENT_FIT_ITEM_TYPES, () -> {
|
||||
if (this.getItemCategories().length == 0) return plugin.getLangManager().getEnum(this.getCategory());
|
||||
|
||||
return String.join(", ", Stream.of(this.getItemCategories()).map(type -> plugin.getLangManager().getEnum(type)).toList());
|
||||
})
|
||||
.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 -> EquipmentSlot.values();
|
||||
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 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) {
|
||||
ItemCategory[] itemCategories = this.getItemCategories();
|
||||
if (itemCategories.length == 0) return false;
|
||||
|
||||
return Stream.of(itemCategories).anyMatch(itemCategory -> itemCategory.isIncluded(item));
|
||||
}
|
||||
|
||||
public int generateLevel() {
|
||||
return Rnd.get(this.getMinLevel(), 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 chargesFormat = "";
|
||||
boolean showLevel = !Config.ENCHANTMENTS_DISPLAY_NAME_HIDE_1ST_LEVEL.get() || level > 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) : "";
|
||||
|
||||
String nameFormat = Config.ENCHANTMENTS_DISPLAY_NAME_FORMAT.get().
|
||||
replace(ENCHANTMENT_NAME, compName)
|
||||
.replace(ENCHANTMENT_LEVEL, compLevel)
|
||||
.replace(ENCHANTMENT_CHARGES, compChrages);
|
||||
|
||||
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) {
|
||||
List<String> description = new ArrayList<>(this.getDescriptionFormatted());
|
||||
description.replaceAll(this.getPlaceholders(level).replacer());
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinCost(int level) {
|
||||
return this.getMinCost().getIntValue(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCost(int level) {
|
||||
return this.getMaxCost().getIntValue(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 setStartLevel(int levelMin) {
|
||||
this.minLevel = Math.max(1, levelMin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinLevel() {
|
||||
return this.minLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxLevel(int levelMax) {
|
||||
this.maxLevel = Math.max(1, levelMax);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return maxLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Modifier getMinCost() {
|
||||
return this.minCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinCost(@NotNull Modifier minCost) {
|
||||
this.minCost = minCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Modifier getMaxCost() {
|
||||
return this.maxCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxCost(@NotNull Modifier maxCost) {
|
||||
this.maxCost = maxCost;
|
||||
}
|
||||
|
||||
/*@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;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.data;
|
||||
|
||||
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 {
|
||||
|
||||
//private final EnchantmentData enchantmentData;
|
||||
private final UniParticle trailParticle;
|
||||
|
||||
private ArrowSettingsImpl(@NotNull UniParticle trailParticle) {
|
||||
//this.enchantmentData = enchantmentData;
|
||||
this.trailParticle = trailParticle;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ArrowSettingsImpl create(@NotNull FileConfig config) {
|
||||
return create(config, UniParticle.of(Particle.REDSTONE));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ArrowSettingsImpl 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),
|
||||
() -> particle,
|
||||
"Sets projectile particle trail effect."
|
||||
).read(config);
|
||||
|
||||
return new ArrowSettingsImpl(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public UniParticle getProjectileTrail() {
|
||||
return this.trailParticle;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.data;
|
||||
|
||||
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 {
|
||||
|
||||
private final Modifier triggerChance;
|
||||
|
||||
private ChanceSettingsImpl(@NotNull Modifier triggerChance) {
|
||||
this.triggerChance = triggerChance;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ChanceSettingsImpl 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.");
|
||||
|
||||
return new ChanceSettingsImpl(chanceMod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTriggerChance(int level) {
|
||||
return this.triggerChance.getValue(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTriggerChance(int level) {
|
||||
return Rnd.chance(this.getTriggerChance(level));
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
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 <= 0 || levelCapMin < this.enchantmentData.getMinLevel()) levelCapMin = this.enchantmentData.getMinLevel();
|
||||
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 > this.enchantmentData.getMinLevel() - 1; 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.data;
|
||||
|
||||
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.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.nightcore.config.FileConfig;
|
||||
|
||||
public class PotionSettingsImpl implements PotionSettings {
|
||||
|
||||
private final PotionEffectType effectType;
|
||||
private final Modifier duration;
|
||||
private final Modifier amplifier;
|
||||
private final boolean isPermanent;
|
||||
private final boolean particles;
|
||||
|
||||
private PotionSettingsImpl(@NotNull PotionEffectType effectType,
|
||||
boolean isPermanent,
|
||||
boolean particles,
|
||||
@NotNull Modifier duration,
|
||||
@NotNull Modifier amplifier) {
|
||||
this.effectType = effectType;
|
||||
this.duration = duration;
|
||||
this.amplifier = amplifier;
|
||||
this.isPermanent = isPermanent;
|
||||
this.particles = particles;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PotionSettingsImpl create(@NotNull EnchantmentData 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)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PotionSettingsImpl create(@NotNull EnchantmentData 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.");
|
||||
|
||||
Modifier amplifierScale = Modifier.read(config, "Settings.Potion_Effect.Level", amplifier,
|
||||
"Potion effect level.");
|
||||
|
||||
return new PotionSettingsImpl(type, isPermanent, data.hasVisualEffects(), durationScale, amplifierScale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermanent() {
|
||||
return this.isPermanent;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (this.getEffectType().getKey().equals(PotionEffectType.NIGHT_VISION.getKey()) && duration < 600) {
|
||||
duration += 30 * 20;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
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);
|
||||
int amplifier = Math.max(0, this.getEffectAmplifier(level) - 1);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,459 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.config.JYML;
|
||||
import su.nexmedia.engine.api.manager.EventListener;
|
||||
import su.nexmedia.engine.api.placeholder.PlaceholderMap;
|
||||
import su.nexmedia.engine.lang.LangManager;
|
||||
import su.nexmedia.engine.utils.ItemUtil;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nexmedia.engine.utils.random.Rnd;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.IEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Periodic;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantDefaults;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ItemCategory;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ObtainType;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
import su.nightexpress.excellentenchants.tier.Tier;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class ExcellentEnchant /*extends Enchantment*/ implements IEnchantment {
|
||||
|
||||
protected final ExcellentEnchants plugin;
|
||||
protected final JYML cfg;
|
||||
protected final String id;
|
||||
protected final EnchantDefaults defaults;
|
||||
protected final NamespacedKey chargesKey;
|
||||
protected final Map<Integer, PlaceholderMap> placeholdersMap;
|
||||
|
||||
public ExcellentEnchant(@NotNull ExcellentEnchants plugin, @NotNull String id) {
|
||||
//super(NamespacedKey.minecraft(id.toLowerCase()));
|
||||
this.plugin = plugin;
|
||||
this.id = id.toLowerCase();//this.getKey().getKey();
|
||||
this.cfg = new JYML(plugin.getDataFolder() + EnchantManager.DIR_ENCHANTS, id + ".yml");
|
||||
this.chargesKey = new NamespacedKey(plugin, this.getId() + ".charges");
|
||||
this.defaults = new EnchantDefaults(this);
|
||||
this.placeholdersMap = new HashMap<>();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
return EnchantUtils.createKey(this.getId());
|
||||
}
|
||||
|
||||
public void loadSettings() {
|
||||
this.cfg.reload();
|
||||
this.placeholdersMap.clear();
|
||||
|
||||
this.getDefaults().load(this);
|
||||
|
||||
for (int i = this.getStartLevel(); i < this.getMaxLevel() + 1; i++) {
|
||||
int level = i;
|
||||
|
||||
PlaceholderMap map = new PlaceholderMap()
|
||||
.add(Placeholders.ENCHANTMENT_DESCRIPTION, () -> String.join("\n", this.getDescription()))
|
||||
.add(Placeholders.ENCHANTMENT_ID, this::getId)
|
||||
.add(Placeholders.ENCHANTMENT_NAME, this::getDisplayName)
|
||||
.add(Placeholders.ENCHANTMENT_NAME_FORMATTED, () -> this.getNameFormatted(level))
|
||||
.add(Placeholders.ENCHANTMENT_LEVEL, () -> NumberUtil.toRoman(level))
|
||||
.add(Placeholders.ENCHANTMENT_LEVEL_MIN, () -> String.valueOf(this.getStartLevel()))
|
||||
.add(Placeholders.ENCHANTMENT_LEVEL_MAX, () -> String.valueOf(this.getMaxLevel()))
|
||||
.add(Placeholders.ENCHANTMENT_TIER, () -> this.getTier().getName())
|
||||
.add(Placeholders.ENCHANTMENT_TIER_COLOR, () -> this.getTier().getColor())
|
||||
.add(Placeholders.ENCHANTMENT_FIT_ITEM_TYPES, () -> {
|
||||
if (this.getFitItemTypes().length == 0) return plugin.getLangManager().getEnum(this.getCategory());
|
||||
|
||||
return String.join(", ", Stream.of(this.getFitItemTypes()).map(type -> plugin.getLangManager().getEnum(type)).toList());
|
||||
})
|
||||
.add(Placeholders.ENCHANTMENT_OBTAIN_CHANCE_ENCHANTING, () -> NumberUtil.format(this.getObtainChance(ObtainType.ENCHANTING)))
|
||||
.add(Placeholders.ENCHANTMENT_OBTAIN_CHANCE_VILLAGER, () -> NumberUtil.format(this.getObtainChance(ObtainType.VILLAGER)))
|
||||
.add(Placeholders.ENCHANTMENT_OBTAIN_CHANCE_LOOT_GENERATION, () -> NumberUtil.format(this.getObtainChance(ObtainType.LOOT_GENERATION)))
|
||||
.add(Placeholders.ENCHANTMENT_OBTAIN_CHANCE_FISHING, () -> NumberUtil.format(this.getObtainChance(ObtainType.FISHING)))
|
||||
.add(Placeholders.ENCHANTMENT_OBTAIN_CHANCE_MOB_SPAWNING, () -> NumberUtil.format(this.getObtainChance(ObtainType.MOB_SPAWNING)))
|
||||
.add(Placeholders.ENCHANTMENT_CHARGES_MAX_AMOUNT, () -> NumberUtil.format(this.getChargesMax(level)))
|
||||
.add(Placeholders.ENCHANTMENT_CHARGES_CONSUME_AMOUNT, () -> NumberUtil.format(this.getChargesConsumeAmount(level)))
|
||||
.add(Placeholders.ENCHANTMENT_CHARGES_RECHARGE_AMOUNT, () -> NumberUtil.format(this.getChargesRechargeAmount(level)))
|
||||
.add(Placeholders.ENCHANTMENT_CHARGES_FUEL_ITEM, () -> ItemUtil.getItemName(this.getChargesFuel()));
|
||||
|
||||
if (this instanceof Chanced chanced) {
|
||||
map.add(Placeholders.ENCHANTMENT_CHANCE, () -> NumberUtil.format(chanced.getTriggerChance(level)));
|
||||
}
|
||||
if (this instanceof Periodic periodic) {
|
||||
map.add(Placeholders.ENCHANTMENT_INTERVAL, () -> NumberUtil.format(periodic.getInterval() / 20D));
|
||||
}
|
||||
if (this instanceof Potioned potioned) {
|
||||
map.add(Placeholders.ENCHANTMENT_POTION_LEVEL, () -> NumberUtil.toRoman(potioned.getEffectAmplifier(level)));
|
||||
map.add(Placeholders.ENCHANTMENT_POTION_DURATION, () -> NumberUtil.format(potioned.getEffectDuration(level) / 20D));
|
||||
map.add(Placeholders.ENCHANTMENT_POTION_TYPE, () -> LangManager.getPotionType(potioned.getEffectType()));
|
||||
}
|
||||
map.add(this.getTier().getPlaceholders());
|
||||
|
||||
this.placeholdersMap.put(level, map);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PlaceholderMap getPlaceholders(int level) {
|
||||
if (level > this.getMaxLevel()) level = this.getMaxLevel();
|
||||
if (level < this.getStartLevel()) level = this.getStartLevel();
|
||||
|
||||
return this.placeholdersMap.get(level);
|
||||
}
|
||||
|
||||
public void addPlaceholder(@NotNull String key, @NotNull Function<Integer, String> replacer) {
|
||||
for (int level = this.getStartLevel(); level < this.getMaxLevel() + 1; level++) {
|
||||
this.getPlaceholders(level).add(key, replacer.apply(level));
|
||||
}
|
||||
}
|
||||
|
||||
public void registerListeners() {
|
||||
if (this instanceof EventListener listener) {
|
||||
this.plugin.getPluginManager().registerEvents(listener, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ItemCategory[] getFitItemTypes() {
|
||||
//FitItemType itemType = FitItemType.getByEnchantmentTarget(this.getCategory());
|
||||
//return new FitItemType[]{itemType};
|
||||
|
||||
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 -> EquipmentSlot.values();
|
||||
default -> throw new IllegalStateException("Unexpected value: " + this.getCategory());
|
||||
};
|
||||
|
||||
/*Set<EquipmentSlot> slots = new HashSet<>();
|
||||
|
||||
for (FitItemType itemType : this.getFitItemTypes()) {
|
||||
slots.addAll(Arrays.asList(itemType.getSlots()));
|
||||
}
|
||||
|
||||
return slots.toArray(new EquipmentSlot[0]);*/
|
||||
}
|
||||
|
||||
public boolean isDisabledInWorld(@NotNull World world) {
|
||||
Set<String> disabled = Config.ENCHANTMENTS_DISABLED_IN_WORLDS.get().getOrDefault(world.getName(), Collections.emptySet());
|
||||
return disabled.contains(this.getKey().getKey()) || disabled.contains(Placeholders.WILDCARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailableToUse(@NotNull LivingEntity entity) {
|
||||
return !this.isDisabledInWorld(entity.getWorld());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JYML getConfig() {
|
||||
return this.cfg;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantDefaults getDefaults() {
|
||||
return defaults;
|
||||
}
|
||||
|
||||
/*@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return getId().toUpperCase();
|
||||
}*/
|
||||
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return this.getDefaults().getDisplayName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getNameFormatted(int level) {
|
||||
String name = this.getTier().getColor() + this.getDisplayName();
|
||||
if (level > 1 || this.getMaxLevel() > 1) {
|
||||
name += " " + NumberUtil.toRoman(level);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getNameFormatted(int level, int charges) {
|
||||
if (!this.isChargesEnabled() || charges < 0) return this.getNameFormatted(level);
|
||||
|
||||
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) return this.getNameFormatted(level);
|
||||
|
||||
String format = entry.getValue().replace(Placeholders.GENERIC_AMOUNT, String.valueOf(charges));
|
||||
return this.getNameFormatted(level) + " " + format;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getDescription() {
|
||||
return this.getDefaults().getDescription();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getDescription(int level) {
|
||||
List<String> description = new ArrayList<>(this.getDescription());
|
||||
description.replaceAll(this.getPlaceholders(level).replacer());
|
||||
return description;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> formatDescription() {
|
||||
return new ArrayList<>(this.getDescription().stream()
|
||||
.map(line -> Config.ENCHANTMENTS_DESCRIPTION_FORMAT.get().replace(Placeholders.GENERIC_DESCRIPTION, line))
|
||||
.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> formatDescription(int level) {
|
||||
return new ArrayList<>(this.getDescription(level).stream()
|
||||
.map(line -> Config.ENCHANTMENTS_DESCRIPTION_FORMAT.get().replace(Placeholders.GENERIC_DESCRIPTION, line))
|
||||
.toList());
|
||||
}
|
||||
|
||||
public boolean hasConflicts() {
|
||||
return !this.getConflicts().isEmpty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<String> getConflicts() {
|
||||
return this.getDefaults().getConflicts();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Tier getTier() {
|
||||
return this.getDefaults().getTier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return this.getDefaults().getLevelMax();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartLevel() {
|
||||
return this.getDefaults().getLevelMin();
|
||||
}
|
||||
|
||||
public int getMaxMergeLevel() {
|
||||
return this.getDefaults().getMaxMergeLevel() < 0 ? this.getMaxLevel() : this.getDefaults().getMaxMergeLevel();
|
||||
}
|
||||
|
||||
public int getLevelByEnchantCost(int expLevel) {
|
||||
int get = this.getDefaults().getLevelByEnchantCost().getValues().entrySet().stream()
|
||||
.filter(en -> expLevel >= en.getValue().intValue()).max(Comparator.comparingInt(Map.Entry::getKey))
|
||||
.map(Map.Entry::getKey).orElse(0);
|
||||
|
||||
return get != 0 ? this.fineLevel(get, ObtainType.ENCHANTING) : 0;
|
||||
}
|
||||
|
||||
public boolean isObtainable(@NotNull ObtainType obtainType) {
|
||||
if (obtainType == ObtainType.ENCHANTING && (this.isTreasure() || this.isCurse())) return false;
|
||||
|
||||
return this.getObtainChance(obtainType) > 0D;
|
||||
}
|
||||
|
||||
public double getObtainChance(@NotNull ObtainType obtainType) {
|
||||
return this.getDefaults().getObtainChance().getOrDefault(obtainType, 0D);
|
||||
}
|
||||
|
||||
public int getObtainLevelMin(@NotNull ObtainType obtainType) {
|
||||
return this.getDefaults().getObtainLevelCap().getOrDefault(obtainType, new int[]{-1, -1})[0];
|
||||
}
|
||||
|
||||
public int getObtainLevelMax(@NotNull ObtainType obtainType) {
|
||||
return this.getDefaults().getObtainLevelCap().getOrDefault(obtainType, new int[]{-1, -1})[1];
|
||||
}
|
||||
|
||||
public int fineLevel(int level, @NotNull ObtainType obtainType) {
|
||||
int levelCapMin = this.getObtainLevelMin(obtainType);
|
||||
int levelCapMax = this.getObtainLevelMax(obtainType);
|
||||
|
||||
if (levelCapMin > 0 && level < levelCapMin) level = levelCapMin;
|
||||
if (levelCapMax > 0 && level > levelCapMax) level = levelCapMax;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
public int generateLevel() {
|
||||
return Rnd.get(this.getStartLevel(), this.getMaxLevel());
|
||||
}
|
||||
|
||||
public int generateLevel(@NotNull ObtainType obtainType) {
|
||||
int levelCapMin = this.getObtainLevelMin(obtainType);
|
||||
int levelCapMax = this.getObtainLevelMax(obtainType);
|
||||
|
||||
if (levelCapMin <= 0 || levelCapMin < this.getStartLevel()) levelCapMin = this.getStartLevel();
|
||||
if (levelCapMax <= 0 || levelCapMax > this.getMaxLevel()) levelCapMax = this.getMaxLevel();
|
||||
|
||||
return Rnd.get(levelCapMin, levelCapMax);
|
||||
}
|
||||
|
||||
public int getAnvilMergeCost(int level) {
|
||||
return (int) this.getDefaults().getAnvilMergeCost().getValue(level);
|
||||
}
|
||||
|
||||
/*@Override
|
||||
@Deprecated
|
||||
public final boolean conflictsWith(@NotNull Enchantment enchantment) {
|
||||
return this.getConflicts().contains(enchantment.getKey().getKey());
|
||||
}*/
|
||||
|
||||
@Deprecated
|
||||
public Enchantment getBackend() {
|
||||
return EnchantUtils.getEnchantment(this.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean checkEnchantCategory(@NotNull ItemStack item) {
|
||||
EnchantmentTarget category = this.getCategory();
|
||||
|
||||
if (category == EnchantmentTarget.WEAPON && ItemUtil.isAxe(item)) {
|
||||
return Config.ENCHANTMENTS_ITEM_SWORD_ENCHANTS_TO_AXES.get();
|
||||
}
|
||||
if (category == EnchantmentTarget.BOW && item.getType() == Material.CROSSBOW) {
|
||||
return Config.ENCHANTMENTS_ITEM_BOW_ENCHANTS_TO_CROSSBOW.get();
|
||||
}
|
||||
if ((category == EnchantmentTarget.ARMOR || category == EnchantmentTarget.ARMOR_TORSO) && item.getType() == Material.ELYTRA) {
|
||||
return Config.ENCHANTMENTS_ITEM_CHESTPLATE_ENCHANTS_TO_ELYTRA.get();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkItemCategory(@NotNull ItemStack item) {
|
||||
ItemCategory[] itemCategories = this.getFitItemTypes();
|
||||
if (itemCategories.length == 0) return false;
|
||||
|
||||
return Stream.of(itemCategories).anyMatch(itemCategory -> itemCategory.isIncluded(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isTreasure() {
|
||||
return this.getDefaults().isTreasure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTradeable() {
|
||||
return this.getDefaults().isTradeable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDiscoverable() {
|
||||
return this.getDefaults().isDiscoverable();
|
||||
}
|
||||
|
||||
public boolean hasVisualEffects() {
|
||||
return this.getDefaults().isVisualEffects();
|
||||
}
|
||||
|
||||
public boolean isChargesEnabled() {
|
||||
return Config.ENCHANTMENTS_CHARGES_ENABLED.get() && this.getDefaults().isChargesEnabled();
|
||||
}
|
||||
|
||||
public boolean isChargesCustomFuel() {
|
||||
return this.getDefaults().isChargesCustomFuel();
|
||||
}
|
||||
|
||||
public int getChargesMax(int level) {
|
||||
return this.isChargesEnabled() ? (int) this.getDefaults().getChargesMax().getValue(level) : 0;
|
||||
}
|
||||
|
||||
public int getChargesConsumeAmount(int level) {
|
||||
return this.isChargesEnabled() ? (int) this.getDefaults().getChargesConsumeAmount().getValue(level) : 0;
|
||||
}
|
||||
|
||||
public int getChargesRechargeAmount(int level) {
|
||||
return this.isChargesEnabled() ? (int) this.getDefaults().getChargesRechargeAmount().getValue(level) : 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ItemStack getChargesFuel() {
|
||||
ItemStack fuelHas = this.getDefaults().getChargesFuel();
|
||||
if (!this.isChargesCustomFuel() || fuelHas == null || fuelHas.getType().isAir()) {
|
||||
return Config.ENCHANTMENTS_CHARGES_FUEL_ITEM.get();
|
||||
}
|
||||
return new ItemStack(fuelHas);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public NamespacedKey getChargesKey() {
|
||||
return chargesKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOutOfCharges(@NotNull ItemStack item) {
|
||||
return EnchantUtils.isOutOfCharges(item, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullOfCharges(@NotNull ItemStack item) {
|
||||
return EnchantUtils.isFullOfCharges(item, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharges(@NotNull ItemStack item) {
|
||||
return EnchantUtils.getCharges(item, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeChargesNoUpdate(@NotNull ItemStack item, int level) {
|
||||
if (!this.isChargesEnabled()) return;
|
||||
|
||||
EnchantUtils.consumeCharges(item, this, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeCharges(@NotNull ItemStack item, int level) {
|
||||
if (!this.isChargesEnabled()) return;
|
||||
|
||||
this.consumeChargesNoUpdate(item, level);
|
||||
EnchantUtils.updateDisplay(item);
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.armor;
|
||||
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
|
||||
public class AquamanEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
|
||||
|
||||
public static final String ID = "aquaman";
|
||||
|
||||
private PotionImplementation potionImplementation;
|
||||
private PeriodImplementation periodImplementation;
|
||||
|
||||
public AquamanEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setLevelMax(1);
|
||||
this.getDefaults().setTier(0.4);
|
||||
this.getDefaults().setDescription("Grants permanent " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " effect.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.WATER_BREATHING, true);
|
||||
this.periodImplementation = PeriodImplementation.create(this, "100");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PeriodImplementation getPeriodImplementation() {
|
||||
return periodImplementation;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
@ -7,51 +7,57 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.CombatEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public class ColdSteelEnchant extends ExcellentEnchant implements Chanced, Potioned, CombatEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class ColdSteelEnchant extends AbstractEnchantmentData implements ChanceData, PotionData, CombatEnchant {
|
||||
|
||||
public static final String ID = "cold_steel";
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
|
||||
public ColdSteelEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to apply " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.) on attacker.");
|
||||
this.getDefaults().setTier(0.3);
|
||||
this.getDefaults().setLevelMax(3);
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
|
||||
public ColdSteelEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(8, 2, 1));
|
||||
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"60 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5");
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.SLOW_DIGGING, false,
|
||||
"4 + " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.SLOW_DIGGING, false,
|
||||
Modifier.add(4, 1, 1, 300),
|
||||
Modifier.add(0, 1,1, 5)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -8,51 +8,58 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.CombatEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
public class DarknessCloakEnchant extends ExcellentEnchant implements Chanced, Potioned, CombatEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class DarknessCloakEnchant extends AbstractEnchantmentData implements ChanceData, PotionData, CombatEnchant {
|
||||
|
||||
public static final String ID = "darkness_cloak";
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
|
||||
public DarknessCloakEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to apply " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.) on attacker.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.2);
|
||||
public DarknessCloakEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"20.0 * " + Placeholders.ENCHANTMENT_LEVEL + " * 0.75");
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(11, 3, 1));
|
||||
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.DARKNESS, false,
|
||||
"2.5" + Placeholders.ENCHANTMENT_LEVEL,
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.DARKNESS, false,
|
||||
Modifier.add(5, 1, 1, 300),
|
||||
Modifier.add(0, 1, 1, 10)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,55 +7,59 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.config.JOption;
|
||||
import su.nexmedia.engine.api.manager.EventListener;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.GenericEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.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.NumberUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
public class ElementalProtectionEnchant extends ExcellentEnchant implements GenericEnchant, EventListener {
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public static final String ID = "elemental_protection";
|
||||
public static final String PLACEHOLDER_PROTECTION_AMOUNT = "%enchantment_protection_amount%";
|
||||
public static final String PLACEHOLDER_PROTECTION_CAPACITY = "%enchantment_protection_capacity%";
|
||||
public class ElementalProtectionEnchant extends AbstractEnchantmentData 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 EnchantScaler protectionAmount;
|
||||
private double protectionCapacity;
|
||||
private boolean protectionAsModifier;
|
||||
private Modifier protectionAmount;
|
||||
private double protectionCapacity;
|
||||
private boolean protectionAsModifier;
|
||||
|
||||
public ElementalProtectionEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("Reduces Poison, Magic, Wither, Lightning, Freeze damage by " + PLACEHOLDER_PROTECTION_AMOUNT + ".");
|
||||
this.getDefaults().setLevelMax(5);
|
||||
this.getDefaults().setTier(0.2);
|
||||
public ElementalProtectionEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
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.");
|
||||
|
||||
this.protectionAmount = EnchantScaler.read(this, "Settings.Protection.Amount",
|
||||
"0.05 * " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
"How protection the enchantment will have?");
|
||||
this.protectionCapacity = JOption.create("Settings.Protection.Capacity", 1D,
|
||||
"Maximal possible protection value from all armor pieces together.").read(cfg);
|
||||
this.protectionAsModifier = JOption.create("Settings.Protection.As_Modifier", false,
|
||||
"When 'true' damage will be reduced by a percent of protection value.",
|
||||
"When 'false' damage will be reduced by a plain protection value.").read(cfg);
|
||||
this.protectionCapacity = ConfigValue.create("Settings.Protection.Capacity",
|
||||
100D,
|
||||
"Maximal possible protection value from all armor pieces together.").read(config);
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_PROTECTION_AMOUNT, level -> NumberUtil.format(this.getProtectionAmount(level)));
|
||||
this.addPlaceholder(PLACEHOLDER_PROTECTION_CAPACITY, level -> NumberUtil.format(this.getProtectionCapacity()));
|
||||
this.protectionAsModifier = ConfigValue.create("Settings.Protection.As_Modifier",
|
||||
true,
|
||||
"Determines if Protection value is percent based or plain amount."
|
||||
).read(config);
|
||||
|
||||
this.addPlaceholder(GENERIC_AMOUNT, level -> NumberUtil.format(this.getProtectionAmount(level)));
|
||||
this.addPlaceholder(GENERIC_MAX, level -> NumberUtil.format(this.getProtectionCapacity()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -84,7 +88,7 @@ public class ElementalProtectionEnchant extends ExcellentEnchant implements Gene
|
||||
|
||||
double protectionAmount = 0D;
|
||||
for (ItemStack armor : EnchantUtils.getEnchantedEquipment(entity).values()) {
|
||||
int level = EnchantUtils.getLevel(armor, this.getBackend());
|
||||
int level = EnchantUtils.getLevel(armor, this.getEnchantment());
|
||||
if (level <= 0) continue;
|
||||
|
||||
protectionAmount += this.getProtectionAmount(level);
|
||||
@ -96,11 +100,9 @@ public class ElementalProtectionEnchant extends ExcellentEnchant implements Gene
|
||||
protectionAmount = this.getProtectionCapacity();
|
||||
}
|
||||
|
||||
if (this.isProtectionAsModifier()) {
|
||||
event.setDamage(Math.max(0, event.getDamage() * (1D - protectionAmount)));
|
||||
}
|
||||
else {
|
||||
event.setDamage(Math.max(0, event.getDamage() - protectionAmount));
|
||||
}
|
||||
double damage = event.getDamage();
|
||||
double blocked = this.isProtectionAsModifier() ? damage * (1D - protectionAmount) : damage - protectionAmount;
|
||||
|
||||
event.setDamage(Math.max(0, blocked));
|
||||
}
|
||||
}
|
||||
|
@ -1,54 +1,61 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.armor;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.CombatEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniSound;
|
||||
|
||||
public class FireShieldEnchant extends ExcellentEnchant implements Chanced, CombatEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class FireShieldEnchant extends AbstractEnchantmentData implements ChanceData, CombatEnchant {
|
||||
|
||||
public static final String ID = "fire_shield";
|
||||
public static final String PLACEHOLDER_FIRE_DURATION = "%enchantment_fire_duration%";
|
||||
|
||||
private EnchantScaler fireDuration;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private Modifier fireDuration;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
public FireShieldEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to ignite the attacker for " + PLACEHOLDER_FIRE_DURATION + "s.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.4);
|
||||
public FireShieldEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3, 2, 1, 100));
|
||||
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
Placeholders.ENCHANTMENT_LEVEL + " * 15.0");
|
||||
this.fireDuration = EnchantScaler.read(this, "Settings.Fire.Duration",
|
||||
"2.5 * " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
this.fireDuration = Modifier.read(config, "Settings.Fire.Duration",
|
||||
Modifier.multiply(2, 1, 1, 600),
|
||||
"Sets the fire duration (in seconds).",
|
||||
"If entity's current fire ticks amount is less than this value, it will be set to this value.",
|
||||
"If entity's current fire ticks amount is greater than this value, it won't be changed.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_FIRE_DURATION, level -> NumberUtil.format(this.getFireDuration(level)));
|
||||
this.addPlaceholder(GENERIC_DURATION, level -> NumberUtil.format(this.getFireDuration(level)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -82,6 +89,11 @@ public class FireShieldEnchant extends ExcellentEnchant implements Chanced, Comb
|
||||
int ticksHas = damager.getFireTicks();
|
||||
if (ticksHas >= ticksToSet) return false;
|
||||
|
||||
if (this.hasVisualEffects()) {
|
||||
UniParticle.of(Particle.FLAME).play(victim.getEyeLocation(), 0.5, 0.1, 35);
|
||||
UniSound.of(Sound.ITEM_FIRECHARGE_USE).play(victim.getLocation());
|
||||
}
|
||||
|
||||
damager.setFireTicks(ticksToSet);
|
||||
return true;
|
||||
}
|
||||
|
@ -18,69 +18,90 @@ import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.Version;
|
||||
import su.nexmedia.engine.api.manager.EventListener;
|
||||
import su.nexmedia.engine.api.server.AbstractTask;
|
||||
import su.nexmedia.engine.utils.Pair;
|
||||
import su.nexmedia.engine.utils.random.Rnd;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Cleanable;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.GenericEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
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.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 ExcellentEnchant implements GenericEnchant, EventListener, Cleanable {
|
||||
public class FlameWalkerEnchant extends AbstractEnchantmentData implements GenericEnchant, 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<Block, Pair<Long, Integer>> BLOCKS_TO_DESTROY = new ConcurrentHashMap<>();
|
||||
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 EnchantScaler blockDecayTime;
|
||||
private BlockTickTask blockTickTask;
|
||||
private Modifier blockDecayTime;
|
||||
|
||||
public FlameWalkerEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("Ability to walk on lava and magma blocks without getting damage.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.7);
|
||||
this.getDefaults().getConflicts().add(Enchantment.FROST_WALKER.getKey().getKey());
|
||||
|
||||
this.blockTickTask = new BlockTickTask(plugin);
|
||||
this.blockTickTask.start();
|
||||
public FlameWalkerEnchant(@NotNull ExcellentEnchantsPlugin 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());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.blockDecayTime = EnchantScaler.read(this, "Settings.Block_Decay", "12.0",
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
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.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
if (this.blockTickTask != null) {
|
||||
this.blockTickTask.stop();
|
||||
this.blockTickTask = null;
|
||||
}
|
||||
BLOCKS_TO_DESTROY.keySet().forEach(block -> block.setType(Material.LAVA));
|
||||
public static 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, Pair.of(System.currentTimeMillis() + (long) seconds * 1000L, Rnd.get(100)));
|
||||
BLOCKS_TO_DESTROY.put(block.getLocation(), Pair.of(System.currentTimeMillis() + (long) seconds * 1000L, Rnd.get(1000)));
|
||||
}
|
||||
|
||||
public static boolean isBlock(@NotNull Block block) {
|
||||
return BLOCKS_TO_DESTROY.containsKey(block);
|
||||
return BLOCKS_TO_DESTROY.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) -> {
|
||||
Block block = location.getBlock();
|
||||
long time = pair.getFirst();
|
||||
if (now >= time) {
|
||||
block.getWorld().getPlayers().forEach(player -> {
|
||||
player.sendBlockDamage(location, 0F, pair.getSecond());
|
||||
});
|
||||
block.setType(Material.LAVA);
|
||||
UniParticle.blockCrack(Material.MAGMA_BLOCK).play(location, 0.5, 0.7, 0.5, 0.03, 30);
|
||||
return;
|
||||
}
|
||||
|
||||
long diff = TimeUnit.MILLISECONDS.toSeconds(time - now);
|
||||
|
||||
float progress = (float) (1D - Math.min(1D, diff / 5D));
|
||||
if (progress > 1F) progress = 1F;
|
||||
if (progress < 0F) progress = 0F;
|
||||
|
||||
float finalProgress = progress;
|
||||
block.getWorld().getPlayers().forEach(player -> {
|
||||
player.sendBlockDamage(location, finalProgress, pair.getSecond());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -106,16 +127,20 @@ public class FlameWalkerEnchant extends ExcellentEnchant implements GenericEncha
|
||||
ItemStack boots = player.getInventory().getBoots();
|
||||
if (boots == null || boots.getType().isAir()) return;
|
||||
|
||||
int level = EnchantUtils.getLevel(boots, this.getBackend());
|
||||
int level = EnchantUtils.getLevel(boots, this.getEnchantment());
|
||||
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;
|
||||
|
||||
plugin.getEnchantNMS().handleFlameWalker(player, player.getLocation(), level).forEach(block -> {
|
||||
Set<Block> blocks = plugin.getEnchantNMS().handleFlameWalker(player, player.getLocation(), level);
|
||||
blocks.forEach(block -> {
|
||||
addBlock(block, Rnd.getDouble(this.getBlockDecayTime(level)) + 1);
|
||||
});
|
||||
if (!blocks.isEmpty()) {
|
||||
this.consumeCharges(boots, level);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -140,7 +165,7 @@ public class FlameWalkerEnchant extends ExcellentEnchant implements GenericEncha
|
||||
private void processExplosion(@NotNull List<Block> blocks) {
|
||||
blocks.removeIf(block -> {
|
||||
if (isBlock(block)) {
|
||||
block.setType(Material.AIR);
|
||||
block.setType(Material.LAVA);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -159,52 +184,10 @@ public class FlameWalkerEnchant extends ExcellentEnchant implements GenericEncha
|
||||
ItemStack boots = equipment.getBoots();
|
||||
if (boots == null || boots.getType().isAir()) return;
|
||||
|
||||
int level = EnchantUtils.getLevel(boots, this.getBackend());
|
||||
int level = EnchantUtils.getLevel(boots, this.getEnchantment());
|
||||
if (level <= 0) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
static class BlockTickTask extends AbstractTask<ExcellentEnchants> {
|
||||
|
||||
public BlockTickTask(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, 1, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void action() {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
BLOCKS_TO_DESTROY.keySet().removeIf(block -> {
|
||||
if (block.isEmpty() || block.getType() != Material.MAGMA_BLOCK) return true;
|
||||
|
||||
Pair<Long, Integer> pair = BLOCKS_TO_DESTROY.get(block);
|
||||
long time = pair.getFirst();
|
||||
if (now >= time) {
|
||||
if (Version.isAtLeast(Version.V1_19_R3)) {
|
||||
block.getWorld().getPlayers().forEach(player -> {
|
||||
player.sendBlockDamage(block.getLocation(), 0F, pair.getSecond());
|
||||
});
|
||||
}
|
||||
|
||||
block.setType(Material.LAVA);
|
||||
UniParticle.blockCrack(Material.MAGMA_BLOCK).play(block.getLocation(), 0.5, 0.7, 0.5, 0.03, 30);
|
||||
return true;
|
||||
}
|
||||
else if (Version.isAtLeast(Version.V1_19_R3)) {
|
||||
long diff = TimeUnit.MILLISECONDS.toSeconds(time - now);
|
||||
|
||||
float progress = (float) (1D - Math.min(1D, diff / 5D));
|
||||
if (progress > 1F) progress = 1F;
|
||||
if (progress < 0F) progress = 0F;
|
||||
|
||||
float finalProgress = progress;
|
||||
block.getWorld().getPlayers().forEach(player -> {
|
||||
player.sendBlockDamage(block.getLocation(), finalProgress, pair.getSecond());
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
this.consumeCharges(boots, level);
|
||||
}
|
||||
}
|
||||
|
@ -7,50 +7,57 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.CombatEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public class HardenedEnchant extends ExcellentEnchant implements Chanced, Potioned, CombatEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class HardenedEnchant extends AbstractEnchantmentData implements ChanceData, PotionData, CombatEnchant {
|
||||
|
||||
public static final String ID = "hardened";
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
|
||||
public HardenedEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to obtain " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.) when damaged.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.4);
|
||||
public HardenedEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"30.0 * " + Placeholders.ENCHANTMENT_LEVEL);
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(2, 2, 1, 100));
|
||||
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.DAMAGE_RESISTANCE, false,
|
||||
"3.0" + Placeholders.ENCHANTMENT_LEVEL,
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.DAMAGE_RESISTANCE, false,
|
||||
Modifier.add(2, 1, 1, 300),
|
||||
Modifier.add(0, 1, 1.5, 5)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,6 +1,8 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.armor;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -8,37 +10,47 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.CombatEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniSound;
|
||||
|
||||
public class IceShieldEnchant extends ExcellentEnchant implements Chanced, Potioned, CombatEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class IceShieldEnchant extends AbstractEnchantmentData implements ChanceData, PotionData, CombatEnchant {
|
||||
|
||||
public static final String ID = "ice_shield";
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
|
||||
public IceShieldEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to freeze and apply " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.) on attacker.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.1);
|
||||
public IceShieldEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this, "25.0 * " + Placeholders.ENCHANTMENT_LEVEL);
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.SLOW, false,
|
||||
"3.0 + " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
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
|
||||
@ -55,14 +67,14 @@ public class IceShieldEnchant extends ExcellentEnchant implements Chanced, Potio
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Chanced getChanceImplementation() {
|
||||
return this.chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return this.chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -78,8 +90,11 @@ public class IceShieldEnchant extends ExcellentEnchant implements Chanced, Potio
|
||||
damager.setFreezeTicks(damager.getMaxFreezeTicks());
|
||||
|
||||
if (this.hasVisualEffects()) {
|
||||
UniParticle.blockCrack(Material.ICE).play(damager.getEyeLocation(), 0.25, 0.1, 20);
|
||||
UniParticle.blockCrack(Material.ICE).play(victim.getEyeLocation(), 0.5, 0.1, 35);
|
||||
UniParticle.of(Particle.CLOUD).play(victim.getEyeLocation(), 0.25, 0.1, 25);
|
||||
UniSound.of(Sound.BLOCK_GLASS_BREAK).play(victim.getLocation());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -5,45 +5,51 @@ import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
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.type.PassiveEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public class JumpingEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class JumpingEnchant extends AbstractEnchantmentData implements PotionData, PassiveEnchant {
|
||||
|
||||
public static final String ID = "bunny_hop";
|
||||
|
||||
private PotionImplementation potionImplementation;
|
||||
private PeriodImplementation periodImplementation;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
private PeriodSettingsImpl periodSettings;
|
||||
|
||||
public JumpingEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.1);
|
||||
this.getDefaults().setDescription("Grants permanent " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " effect.");
|
||||
public JumpingEnchant(@NotNull ExcellentEnchantsPlugin 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.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.JUMP, true);
|
||||
this.periodImplementation = PeriodImplementation.create(this, "100");
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.JUMP, true);
|
||||
this.periodSettings = PeriodSettingsImpl.create(config);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PeriodImplementation getPeriodImplementation() {
|
||||
return periodImplementation;
|
||||
public PeriodicSettings getPeriodSettings() {
|
||||
return periodSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.armor;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
@ -12,56 +13,59 @@ import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.EntityResurrectEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.config.JOption;
|
||||
import su.nexmedia.engine.api.manager.EventListener;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.DeathEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.manager.SimpeListener;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
public class KamikadzeEnchant extends ExcellentEnchant implements Chanced, DeathEnchant, EventListener {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class KamikadzeEnchant extends AbstractEnchantmentData implements ChanceData, DeathEnchant, SimpeListener {
|
||||
|
||||
public static final String ID = "self_destruction";
|
||||
private static final String PLACEHOLDER_EXPLOSION_POWER = "%enchantment_explosion_power%";
|
||||
|
||||
private EnchantScaler explosionSize;
|
||||
private boolean applyOnResurrect;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private Modifier explosionSize;
|
||||
private boolean applyOnResurrect;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
private Entity exploder;
|
||||
|
||||
public KamikadzeEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("%enchantment_trigger_chance%% chance to create an explosion on death.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.3);
|
||||
public KamikadzeEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"20.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 10");
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(0, 5, 1, 100));
|
||||
|
||||
this.applyOnResurrect = JOption.create("Settings.Apply_On_Resurrect", true,
|
||||
this.applyOnResurrect = ConfigValue.create("Settings.Apply_On_Resurrect",
|
||||
true,
|
||||
"Sets whether or not enchantment will trigger on resurrect (when a totem is used)."
|
||||
).read(cfg);
|
||||
).read(config);
|
||||
|
||||
this.explosionSize = EnchantScaler.read(this, "Settings.Explosion.Size",
|
||||
"1.0" + Placeholders.ENCHANTMENT_LEVEL,
|
||||
"A size of the explosion. The more size - the bigger the damage.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_EXPLOSION_POWER, level -> NumberUtil.format(this.getExplosionSize(level)));
|
||||
this.explosionSize = Modifier.read(config, "Settings.Explosion.Size",
|
||||
Modifier.add(1, 1, 1, 5),
|
||||
"A size of the explosion. The more size - the bigger the damage."
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -82,9 +86,16 @@ public class KamikadzeEnchant extends ExcellentEnchant implements Chanced, Death
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
float size = (float) this.getExplosionSize(level);
|
||||
|
||||
this.exploder = entity;
|
||||
boolean exploded = entity.getWorld().createExplosion(entity.getLocation(), size, false, false, entity);
|
||||
this.exploder = null;
|
||||
|
||||
if (exploded && this.hasVisualEffects()) {
|
||||
UniParticle.of(Particle.SMOKE_NORMAL).play(entity.getEyeLocation(), 0.5, 0.1, 60);
|
||||
UniParticle.of(Particle.LAVA).play(entity.getEyeLocation(), 1.25, 0.1, 100);
|
||||
}
|
||||
|
||||
return exploded;
|
||||
}
|
||||
|
||||
|
@ -5,45 +5,51 @@ import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
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.type.PassiveEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public class NightVisionEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class NightVisionEnchant extends AbstractEnchantmentData implements PotionData, PassiveEnchant {
|
||||
|
||||
public static final String ID = "night_vision";
|
||||
|
||||
private PotionImplementation potionImplementation;
|
||||
private PeriodImplementation periodImplementation;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
private PeriodSettingsImpl periodSettings;
|
||||
|
||||
public NightVisionEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("Grants permanent " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " effect.");
|
||||
this.getDefaults().setLevelMax(1);
|
||||
this.getDefaults().setTier(0.7);
|
||||
public NightVisionEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.NIGHT_VISION, true);
|
||||
this.periodImplementation = PeriodImplementation.create(this, "100");
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.NIGHT_VISION, true);
|
||||
this.periodSettings = PeriodSettingsImpl.create(config);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PeriodImplementation getPeriodImplementation() {
|
||||
return periodImplementation;
|
||||
public PeriodicSettings getPeriodSettings() {
|
||||
return periodSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,70 +6,79 @@ import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.EntityUtil;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.PassiveEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.EntityUtil;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
public class RegrowthEnchant extends ExcellentEnchant implements Chanced, PassiveEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class RegrowthEnchant extends AbstractEnchantmentData implements ChanceData, PassiveEnchant {
|
||||
|
||||
public static final String ID = "regrowth";
|
||||
|
||||
private static final String PLACEHOLDER_HEAL_AMOUNT = "%enchantment_heal_amount%";
|
||||
private static final String PLACEHOLDER_HEAL_MIN_HEALTH = "%enchantment_heal_min_health%";
|
||||
private static final String PLACEHOLDER_HEAL_MAX_HEALTH = "%enchantment_heal_max_health%";
|
||||
private Modifier minHealth;
|
||||
private Modifier maxHealth;
|
||||
private Modifier healAmount;
|
||||
|
||||
private EnchantScaler healMinHealth;
|
||||
private EnchantScaler healMaxHealth;
|
||||
private EnchantScaler healAmount;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PeriodSettingsImpl periodSettings;
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PeriodImplementation periodImplementation;
|
||||
|
||||
public RegrowthEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("Restores " + PLACEHOLDER_HEAL_AMOUNT + " hearts every few seconds.");
|
||||
this.getDefaults().setLevelMax(5);
|
||||
this.getDefaults().setTier(0.7);
|
||||
public RegrowthEnchant(@NotNull ExcellentEnchantsPlugin plugin, @NotNull File file) {
|
||||
super(plugin, file);
|
||||
this.setDescription("Restores " + GENERIC_AMOUNT + "❤ every few seconds.");
|
||||
this.setMaxLevel(5);
|
||||
this.setRarity(Rarity.VERY_RARE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"20.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5");
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(100, 0, 1, 100));
|
||||
|
||||
this.periodImplementation = PeriodImplementation.create(this, "100");
|
||||
this.periodSettings = PeriodSettingsImpl.create(config);
|
||||
|
||||
this.healMinHealth = EnchantScaler.read(this, "Settings.Heal.Min_Health", "0.5",
|
||||
"Minimal entity health for the enchantment to have effect.");
|
||||
this.healMaxHealth = EnchantScaler.read(this, "Settings.Heal.Max_Health", "20.0",
|
||||
"Maximal entity health when the enchantment will not heal anymore.");
|
||||
this.healAmount = EnchantScaler.read(this, "Settings.Heal.Amount", "0.25",
|
||||
"Amount of hearts to be restored.");
|
||||
this.minHealth = Modifier.read(config, "Settings.Heal.Min_Health",
|
||||
Modifier.add(0.5, 0, 0),
|
||||
"Minimal entity health for the enchantment to have effect."
|
||||
);
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_HEAL_AMOUNT, level -> NumberUtil.format(this.getHealAmount(level)));
|
||||
this.addPlaceholder(PLACEHOLDER_HEAL_MIN_HEALTH, level -> NumberUtil.format(this.getHealMaxHealth(level)));
|
||||
this.addPlaceholder(PLACEHOLDER_HEAL_MAX_HEALTH, level -> NumberUtil.format(this.getHealMaxHealth(level)));
|
||||
this.maxHealth = Modifier.read(config, "Settings.Heal.Max_Health",
|
||||
Modifier.add(20, 0, 0),
|
||||
"Maximal entity health when the enchantment will not heal anymore."
|
||||
);
|
||||
|
||||
this.healAmount = Modifier.read(config, "Settings.Heal.Amount",
|
||||
Modifier.add(0, 0.1, 1, 10),
|
||||
"Amount of hearts to be restored."
|
||||
);
|
||||
|
||||
this.addPlaceholder(GENERIC_AMOUNT, level -> NumberUtil.format(this.getHealAmount(level)));
|
||||
this.addPlaceholder(GENERIC_MIN, level -> NumberUtil.format(this.getMinHealthToHeal(level)));
|
||||
this.addPlaceholder(GENERIC_MAX, level -> NumberUtil.format(this.getMaxHealthToHeal(level)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PeriodImplementation getPeriodImplementation() {
|
||||
return periodImplementation;
|
||||
public PeriodicSettings getPeriodSettings() {
|
||||
return periodSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -82,12 +91,12 @@ public class RegrowthEnchant extends ExcellentEnchant implements Chanced, Passiv
|
||||
return this.healAmount.getValue(level);
|
||||
}
|
||||
|
||||
public double getHealMinHealth(int level) {
|
||||
return this.healMinHealth.getValue(level);
|
||||
public double getMinHealthToHeal(int level) {
|
||||
return this.minHealth.getValue(level);
|
||||
}
|
||||
|
||||
public double getHealMaxHealth(int level) {
|
||||
return this.healMaxHealth.getValue(level);
|
||||
public double getMaxHealthToHeal(int level) {
|
||||
return this.maxHealth.getValue(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,7 +105,7 @@ public class RegrowthEnchant extends ExcellentEnchant implements Chanced, Passiv
|
||||
|
||||
double healthMax = EntityUtil.getAttribute(entity, Attribute.GENERIC_MAX_HEALTH);
|
||||
double healthHas = entity.getHealth();
|
||||
if (healthHas < this.getHealMinHealth(level) || healthHas > this.getHealMaxHealth(level)) return false;
|
||||
if (healthHas < this.getMinHealthToHeal(level) || healthHas > this.getMaxHealthToHeal(level)) return false;
|
||||
if (healthHas >= healthMax) return false;
|
||||
|
||||
double amount = Math.min(healthMax, healthHas + this.getHealAmount(level));
|
||||
|
@ -5,51 +5,56 @@ import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicSettings;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
|
||||
public class SaturationEnchant extends ExcellentEnchant implements PassiveEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class SaturationEnchant extends AbstractEnchantmentData implements PassiveEnchant {
|
||||
|
||||
public static final String ID = "saturation";
|
||||
|
||||
private static final String PLACEHOLDER_SATURATION_AMOUNT = "%enchantment_saturation_amount%";
|
||||
private static final String PLACEHOLDER_SATURATION_MAX_FOOD_LEVEL = "%enchantment_saturation_max_food_level%";
|
||||
private Modifier feedAmount;
|
||||
private Modifier maxFoodLevel;
|
||||
|
||||
private EnchantScaler saturationAmount;
|
||||
private EnchantScaler saturationMaxFoodLevel;
|
||||
private PeriodSettingsImpl periodSettings;
|
||||
|
||||
private PeriodImplementation periodImplementation;
|
||||
|
||||
public SaturationEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("Restores " + PLACEHOLDER_SATURATION_AMOUNT + " food points every few seconds.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.5);
|
||||
public SaturationEnchant(@NotNull ExcellentEnchantsPlugin plugin, @NotNull File file) {
|
||||
super(plugin, file);
|
||||
this.setDescription("Restores " + GENERIC_AMOUNT + " food points every few seconds.");
|
||||
this.setMaxLevel(3);
|
||||
this.setRarity(Rarity.RARE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.periodImplementation = PeriodImplementation.create(this, "100");
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.periodSettings = PeriodSettingsImpl.create(config);
|
||||
|
||||
this.saturationAmount = EnchantScaler.read(this, "Settings.Saturation.Amount", Placeholders.ENCHANTMENT_LEVEL,
|
||||
this.feedAmount = Modifier.read(config, "Settings.Saturation.Amount",
|
||||
Modifier.add(0, 1, 1, 10),
|
||||
"Amount of food points to restore.");
|
||||
this.saturationMaxFoodLevel = EnchantScaler.read(this, "Settings.Saturation.Max_Food_Level", "20",
|
||||
|
||||
this.maxFoodLevel = Modifier.read(config, "Settings.Saturation.Max_Food_Level",
|
||||
Modifier.add(20, 0, 0),
|
||||
"Maximal player's food level for the enchantment to stop feeding them.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_SATURATION_AMOUNT, level -> NumberUtil.format(this.getSaturationAmount(level)));
|
||||
this.addPlaceholder(PLACEHOLDER_SATURATION_MAX_FOOD_LEVEL, level -> NumberUtil.format(this.getMaxFoodLevel(level)));
|
||||
this.addPlaceholder(GENERIC_AMOUNT, level -> NumberUtil.format(this.getFeedAmount(level)));
|
||||
this.addPlaceholder(GENERIC_MAX, level -> NumberUtil.format(this.getMaxFoodLevel(level)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PeriodImplementation getPeriodImplementation() {
|
||||
return periodImplementation;
|
||||
public PeriodicSettings getPeriodSettings() {
|
||||
return periodSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -58,12 +63,12 @@ public class SaturationEnchant extends ExcellentEnchant implements PassiveEnchan
|
||||
return EnchantmentTarget.ARMOR_HEAD;
|
||||
}
|
||||
|
||||
public final int getSaturationAmount(int level) {
|
||||
return (int) this.saturationAmount.getValue(level);
|
||||
public final int getFeedAmount(int level) {
|
||||
return (int) this.feedAmount.getValue(level);
|
||||
}
|
||||
|
||||
public final int getMaxFoodLevel(int level) {
|
||||
return (int) this.saturationMaxFoodLevel.getValue(level);
|
||||
return (int) this.maxFoodLevel.getValue(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,7 +76,7 @@ public class SaturationEnchant extends ExcellentEnchant implements PassiveEnchan
|
||||
if (!(entity instanceof Player player)) return false;
|
||||
if (player.getFoodLevel() >= this.getMaxFoodLevel(level)) return false;
|
||||
|
||||
int amount = this.getSaturationAmount(level);
|
||||
int amount = this.getFeedAmount(level);
|
||||
player.setFoodLevel(Math.min(20, player.getFoodLevel() + amount));
|
||||
return true;
|
||||
}
|
||||
|
@ -5,45 +5,51 @@ import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
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.type.PassiveEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PeriodImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public class SpeedyEnchant extends ExcellentEnchant implements Potioned, PassiveEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class SpeedyEnchant extends AbstractEnchantmentData implements PotionData, PassiveEnchant {
|
||||
|
||||
public static final String ID = "sonic";
|
||||
|
||||
private PotionImplementation potionImplementation;
|
||||
private PeriodImplementation periodImplementation;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
private PeriodSettingsImpl periodSettings;
|
||||
|
||||
public SpeedyEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("Grants permanent " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " effect.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.3);
|
||||
public SpeedyEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.SPEED, true);
|
||||
this.periodImplementation = PeriodImplementation.create(this, "100");
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.SPEED, true);
|
||||
this.periodSettings = PeriodSettingsImpl.create(config);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PeriodImplementation getPeriodImplementation() {
|
||||
return periodImplementation;
|
||||
public PeriodicSettings getPeriodSettings() {
|
||||
return periodSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,40 +6,44 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.CombatEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
|
||||
public class StoppingForceEnchant extends ExcellentEnchant implements Chanced, CombatEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class StoppingForceEnchant extends AbstractEnchantmentData implements ChanceData, CombatEnchant {
|
||||
|
||||
public static final String ID = "stopping_force";
|
||||
|
||||
public static final String PLACEHOLDER_KNOCKBACK_RESISTANCE = "%knockback_resistance%";
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private Modifier knockbackModifier;
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private EnchantScaler knockbackModifier;
|
||||
|
||||
public StoppingForceEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to resist knockback in combat by " + PLACEHOLDER_KNOCKBACK_RESISTANCE + "%.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.5);
|
||||
public StoppingForceEnchant(@NotNull ExcellentEnchantsPlugin plugin, @NotNull File file) {
|
||||
super(plugin, file);
|
||||
this.setDescription(ENCHANTMENT_CHANCE + "% chance to resist knockback in combat by " + GENERIC_AMOUNT + "%.");
|
||||
this.setMaxLevel(3);
|
||||
this.setRarity(Rarity.UNCOMMON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this, "100.0");
|
||||
this.knockbackModifier = EnchantScaler.read(this, "Settings.Knockback_Modifier",
|
||||
"0.7 - " + Placeholders.ENCHANTMENT_LEVEL + " / 5.0",
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(100, 0, 0, 100));
|
||||
|
||||
this.knockbackModifier = Modifier.read(config, "Settings.Knockback_Modifier",
|
||||
Modifier.add(0.9, -0.2, 1),
|
||||
"Sets the knockback multiplier when taking damage.", "Lower value = less knockback.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_KNOCKBACK_RESISTANCE, level -> NumberUtil.format(this.getKnockbackModifier(level) * 100));
|
||||
this.addPlaceholder(GENERIC_AMOUNT, level -> NumberUtil.format(this.getKnockbackModifier(level) * 100));
|
||||
}
|
||||
|
||||
public double getKnockbackModifier(int level) {
|
||||
@ -60,8 +64,8 @@ public class StoppingForceEnchant extends ExcellentEnchant implements Chanced, C
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Chanced getChanceImplementation() {
|
||||
return this.chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return this.chanceSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,8 +77,10 @@ public class StoppingForceEnchant extends ExcellentEnchant implements Chanced, C
|
||||
public boolean onProtect(@NotNull EntityDamageByEntityEvent event, @NotNull LivingEntity damager, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
double mod = Math.max(0, this.getKnockbackModifier(level));
|
||||
|
||||
this.plugin.runTask(task -> {
|
||||
victim.setVelocity(victim.getVelocity().multiply(this.getKnockbackModifier(level)));
|
||||
victim.setVelocity(victim.getVelocity().multiply(mod));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,121 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.armor;
|
||||
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.world.LootGenerateEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.loot.LootTable;
|
||||
import org.bukkit.loot.LootTables;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.GenericEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.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.StringUtil;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class TreasureHunterEnchant extends AbstractEnchantmentData implements ChanceData, GenericEnchant, SimpeListener {
|
||||
|
||||
public static final String ID = "treasure_hunter";
|
||||
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
private final Set<LootTables> lootTables;
|
||||
|
||||
public TreasureHunterEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
|
||||
this.lootTables = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(2.5, 2.5, 1, 100));
|
||||
|
||||
boolean isWhitelist = ConfigValue.create("Settings.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("Settings.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.ENDER_DRAGON,
|
||||
LootTables.END_CITY_TREASURE
|
||||
),
|
||||
"List of loot tables that are added or excluded (depends on Whitelist setting) for this enchantment.",
|
||||
"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
|
||||
@Override
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
if (!(event.getEntity() instanceof Player player)) return;
|
||||
if (!this.isAvailableToUse(player)) return;
|
||||
|
||||
ItemStack helmet = player.getInventory().getHelmet();
|
||||
if (helmet == null || helmet.getType().isAir()) return;
|
||||
|
||||
int level = EnchantUtils.getLevel(helmet, this.getEnchantment());
|
||||
if (level < 1) return;
|
||||
|
||||
if (!this.checkTriggerChance(level)) return;
|
||||
|
||||
InventoryHolder holder = event.getInventoryHolder();
|
||||
if (holder == null) return;
|
||||
|
||||
Inventory inventory = holder.getInventory();
|
||||
|
||||
LootTable lootTable = Rnd.get(this.lootTables).getLootTable();
|
||||
|
||||
Collection<ItemStack> items = lootTable.populateLoot(Rnd.RANDOM, event.getLootContext());
|
||||
items.forEach(inventory::addItem);
|
||||
|
||||
this.consumeCharges(helmet, level);
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.armor;
|
||||
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
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.type.PassiveEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PeriodSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class WaterBreathingEnchant extends AbstractEnchantmentData implements PotionData, PassiveEnchant {
|
||||
|
||||
public static final String ID = "aquaman";
|
||||
|
||||
private PotionSettingsImpl potionSettings;
|
||||
private PeriodSettingsImpl periodSettings;
|
||||
|
||||
public WaterBreathingEnchant(@NotNull ExcellentEnchantsPlugin 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.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.WATER_BREATHING, true);
|
||||
this.periodSettings = PeriodSettingsImpl.create(config);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PeriodicSettings getPeriodSettings() {
|
||||
return periodSettings;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
@ -11,34 +11,39 @@ import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
|
||||
public class EnchantBomber extends ExcellentEnchant implements Chanced, BowEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class BomberEnchant extends AbstractEnchantmentData implements ChanceData, BowEnchant {
|
||||
|
||||
public static final String ID = "bomber";
|
||||
public static final String PLACEHOLDER_FUSE_TICKS = "%enchantment_fuse_ticks%";
|
||||
|
||||
private EnchantScaler fuseTicks;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private Modifier fuseTicks;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
public EnchantBomber(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch TNT that explodes in " + PLACEHOLDER_FUSE_TICKS + "s.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.7);
|
||||
this.getDefaults().setConflicts(
|
||||
EnchantEnderBow.ID, EnchantGhast.ID,
|
||||
EnchantExplosiveArrows.ID, EnchantPoisonedArrows.ID, EnchantConfusingArrows.ID,
|
||||
EnchantWitheredArrows.ID, EnchantElectrifiedArrows.ID, EnchantDragonfireArrows.ID,
|
||||
public BomberEnchant(@NotNull ExcellentEnchantsPlugin 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,
|
||||
EnchantHover.ID, FlareEnchant.ID,
|
||||
HoverEnchant.ID, FlareEnchant.ID,
|
||||
Enchantment.ARROW_FIRE.getKey().getKey(),
|
||||
Enchantment.ARROW_KNOCKBACK.getKey().getKey(),
|
||||
Enchantment.ARROW_DAMAGE.getKey().getKey()
|
||||
@ -46,21 +51,20 @@ public class EnchantBomber extends ExcellentEnchant implements Chanced, BowEncha
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"5.0 * " + Placeholders.ENCHANTMENT_LEVEL);
|
||||
this.fuseTicks = EnchantScaler.read(this, "Settings.Fuse_Ticks",
|
||||
"100 - " + Placeholders.ENCHANTMENT_LEVEL + " * 10",
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3.5, 1.5, 1, 100));
|
||||
|
||||
this.fuseTicks = Modifier.read(config, "Settings.Fuse_Ticks",
|
||||
Modifier.add(110, -10, 1),
|
||||
"Sets fuse ticks (before it will explode) for the launched TNT.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_FUSE_TICKS, level -> NumberUtil.format((double) this.getFuseTicks(level) / 20D));
|
||||
this.addPlaceholder(GENERIC_TIME, level -> NumberUtil.format((double) this.getFuseTicks(level) / 20D));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
public int getFuseTicks(int level) {
|
||||
@ -84,9 +88,11 @@ public class EnchantBomber extends ExcellentEnchant implements Chanced, BowEncha
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
if (!(event.getProjectile() instanceof Projectile projectile)) return false;
|
||||
|
||||
int fuseTicks = Math.max(1, this.getFuseTicks(level));
|
||||
|
||||
TNTPrimed primed = projectile.getWorld().spawn(projectile.getLocation(), TNTPrimed.class);
|
||||
primed.setVelocity(projectile.getVelocity().multiply(event.getForce() * 1.25));
|
||||
primed.setFuseTicks(this.getFuseTicks(level));
|
||||
primed.setFuseTicks(fuseTicks);
|
||||
primed.setSource(shooter);
|
||||
event.setProjectile(primed);
|
||||
return true;
|
@ -0,0 +1,101 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.*;
|
||||
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.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
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 static final String ID = "confusing_arrows";
|
||||
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
|
||||
public ConfusingArrowsEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.SPELL_MOB));
|
||||
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(10, 5, 1, 100));
|
||||
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.CONFUSION, 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;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
|
||||
return arrow.addCustomEffect(this.createEffect(level), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -12,61 +12,66 @@ import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.*;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
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.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
public class DarknessArrowsEnchant extends ExcellentEnchant implements Chanced, Arrowed, Potioned, BowEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class DarknessArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, PotionData, BowEnchant {
|
||||
|
||||
public static final String ID = "darkness_arrows";
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
|
||||
public DarknessArrowsEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.)");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.1);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
public DarknessArrowsEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.ASH));
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"25.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5.0");
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.DARKNESS, false,
|
||||
"4.0 + " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.ASH));
|
||||
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(8, 4, 1, 100));
|
||||
|
||||
this.potionSettings = PotionSettingsImpl.create(this, config, PotionEffectType.DARKNESS, false,
|
||||
Modifier.add(3.5, 1.5, 1, 300),
|
||||
Modifier.add(0, 1, 1, 5)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return arrowImplementation;
|
||||
public ArrowSettings getArrowSettings() {
|
||||
return arrowSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
public PotionSettings getPotionSettings() {
|
||||
return potionSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -81,6 +86,7 @@ public class DarknessArrowsEnchant extends ExcellentEnchant implements Chanced,
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
|
||||
|
||||
return arrow.addCustomEffect(this.createEffect(level), true);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,168 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.LingeringPotionSplashEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.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.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.ItemUtil;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.Version;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class DragonfireArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, BowEnchant {
|
||||
|
||||
public static final String ID = "dragonfire_arrows";
|
||||
|
||||
private Modifier fireDuration;
|
||||
private Modifier fireRadius;
|
||||
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
public DragonfireArrowsEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.DRAGON_BREATH));
|
||||
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3, 3, 1, 100));
|
||||
|
||||
this.fireDuration = Modifier.read(config, "Settings.Fire.Duration",
|
||||
Modifier.multiply(100, 1, 1, 60 * 20),
|
||||
"Sets the dragonfire cloud effect duration (in ticks). 20 ticks = 1 second.");
|
||||
|
||||
this.fireRadius = Modifier.read(config, "Settings.Fire.Radius",
|
||||
Modifier.add(1, 1, 1, 5),
|
||||
"Sets the dragonfire cloud effect radius.");
|
||||
|
||||
this.addPlaceholder(GENERIC_DURATION, level -> NumberUtil.format(this.getFireDuration(level) / 20D));
|
||||
this.addPlaceholder(GENERIC_RADIUS, level -> NumberUtil.format(this.getFireRadius(level)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowSettings getArrowSettings() {
|
||||
return arrowSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public EnchantmentTarget getCategory() {
|
||||
return EnchantmentTarget.BOW;
|
||||
}
|
||||
|
||||
public int getFireDuration(int level) {
|
||||
return (int) this.fireDuration.getValue(level);
|
||||
}
|
||||
|
||||
public double getFireRadius(int level) {
|
||||
return this.fireRadius.getValue(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
|
||||
return this.checkTriggerChance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
if (event.getHitEntity() != null) return false;
|
||||
if (projectile.getShooter() == null) return false;
|
||||
|
||||
this.createCloud(projectile.getShooter(), projectile.getLocation(), event.getHitEntity(), event.getHitBlock(), event.getHitBlockFace(), level);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
this.createCloud(shooter, victim.getLocation(), victim, null, null, level);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createCloud(@NotNull ProjectileSource shooter, @NotNull Location location,
|
||||
@Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace,
|
||||
int level) {
|
||||
World world = location.getWorld();
|
||||
if (world == null) return;
|
||||
|
||||
// There are some tweaks to respect protection plugins by using event call.
|
||||
|
||||
ItemStack item = new ItemStack(Material.LINGERING_POTION);
|
||||
ItemUtil.editMeta(item, meta -> {
|
||||
if (meta instanceof PotionMeta potionMeta) {
|
||||
potionMeta.addCustomEffect(new PotionEffect(PotionEffectType.HARM, 20, 0), true);
|
||||
}
|
||||
});
|
||||
|
||||
ThrownPotion potion = shooter.launchProjectile(ThrownPotion.class);
|
||||
potion.setItem(item);
|
||||
potion.teleport(location);
|
||||
|
||||
AreaEffectCloud cloud = world.spawn(location, AreaEffectCloud.class);
|
||||
cloud.clearCustomEffects();
|
||||
cloud.setSource(shooter);
|
||||
cloud.setParticle(Particle.DRAGON_BREATH);
|
||||
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);
|
||||
|
||||
LingeringPotionSplashEvent splashEvent;
|
||||
|
||||
if (Version.isAtLeast(Version.V1_20_R3)) {
|
||||
splashEvent = new LingeringPotionSplashEvent(potion, hitEntity, hitBlock, hitFace, cloud);
|
||||
}
|
||||
else {
|
||||
splashEvent = new LingeringPotionSplashEvent(potion, cloud);
|
||||
}
|
||||
|
||||
plugin.getPluginManager().callEvent(splashEvent);
|
||||
if (splashEvent.isCancelled()) {
|
||||
cloud.remove();
|
||||
}
|
||||
potion.remove();
|
||||
}
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.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.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.LocationUtil;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
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 static final String ID = "electrified_arrows";
|
||||
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private Modifier damageModifier;
|
||||
private boolean thunderstormOnly;
|
||||
|
||||
public ElectrifiedArrowsEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.FIREWORKS_SPARK));
|
||||
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(0, 5, 1, 100));
|
||||
|
||||
this.thunderstormOnly = ConfigValue.create("Settings.During_Thunderstorm_Only",
|
||||
false,
|
||||
"Sets whether or not enchantment will have effect only during thunderstorm in the world."
|
||||
).read(config);
|
||||
|
||||
this.damageModifier = Modifier.read(config, "Settings.Damage_Modifier",
|
||||
Modifier.add(1.25, 0.25, 1, 10000),
|
||||
"Sets additional damage caused by enchantment's effect."
|
||||
);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public double getDamage(int level) {
|
||||
return this.damageModifier.getValue(level);
|
||||
}
|
||||
|
||||
@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);
|
||||
UniParticle.blockCrack(block.getType()).play(center, 0.5, 0.1, 100);
|
||||
UniParticle.of(Particle.FIREWORKS_SPARK).play(center, 0.75, 0.05, 120);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
|
||||
return this.checkTriggerChance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
if (event.getHitEntity() != null || event.getHitBlock() == null) return false;
|
||||
|
||||
Block block = event.getHitBlock();
|
||||
this.summonLightning(block);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
this.summonLightning(victim.getLocation().getBlock().getRelative(BlockFace.DOWN));
|
||||
event.setDamage(event.getDamage() + this.getDamage(level));
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
|
||||
public class EnchantConfusingArrows extends ExcellentEnchant implements Chanced, Arrowed, Potioned, BowEnchant {
|
||||
|
||||
public static final String ID = "confusing_arrows";
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
|
||||
public EnchantConfusingArrows(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.)");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.1);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.SPELL_MOB));
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"20.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5.0");
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.CONFUSION, false,
|
||||
"6.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 3.0",
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return arrowImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
|
||||
return arrow.addCustomEffect(this.createEffect(level), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.AreaEffectCloud;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.ThrownPotion;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.LingeringPotionSplashEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.ItemUtil;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
|
||||
public class EnchantDragonfireArrows extends ExcellentEnchant implements Chanced, Arrowed, BowEnchant {
|
||||
|
||||
public static final String ID = "dragonfire_arrows";
|
||||
|
||||
public static final String PLACEHOLDER_FIRE_RADIUS = "%enchantment_fire_radius%";
|
||||
public static final String PLACEHOLDER_FIRE_DURATION = "%enchantment_fire_duration%";
|
||||
|
||||
private EnchantScaler fireDuration;
|
||||
private EnchantScaler fireRadius;
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
|
||||
public EnchantDragonfireArrows(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch an dragonfire arrow (R=" + PLACEHOLDER_FIRE_RADIUS + ", " + PLACEHOLDER_FIRE_DURATION + "s).");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.7);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.DRAGON_BREATH));
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"10.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5");
|
||||
this.fireDuration = EnchantScaler.read(this, "Settings.Fire.Duration",
|
||||
"100 * " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
"Sets the dragonfire cloud effect duration (in ticks). 20 ticks = 1 second.");
|
||||
this.fireRadius = EnchantScaler.read(this, "Settings.Fire.Radius",
|
||||
"2.0 + " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
"Sets the dragonfire cloud effect radius.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_FIRE_DURATION, level -> NumberUtil.format(this.getFireDuration(level) / 20D));
|
||||
this.addPlaceholder(PLACEHOLDER_FIRE_RADIUS, level -> NumberUtil.format(this.getFireRadius(level)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return arrowImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public EnchantmentTarget getCategory() {
|
||||
return EnchantmentTarget.BOW;
|
||||
}
|
||||
|
||||
public int getFireDuration(int level) {
|
||||
return (int) this.fireDuration.getValue(level);
|
||||
}
|
||||
|
||||
public double getFireRadius(int level) {
|
||||
return this.fireRadius.getValue(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
|
||||
return this.checkTriggerChance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
if (!this.isOurProjectile(projectile)) return false;
|
||||
if (event.getHitEntity() != null) return false;
|
||||
if (projectile.getShooter() == null) return false;
|
||||
|
||||
this.createCloud(projectile.getShooter(), projectile.getLocation() , level);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
if (!this.isOurProjectile(projectile)) return false;
|
||||
|
||||
this.createCloud(shooter, victim.getLocation(), level);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createCloud(@NotNull ProjectileSource shooter, @NotNull Location location, int level) {
|
||||
World world = location.getWorld();
|
||||
if (world == null) return;
|
||||
|
||||
// There are some tweaks to respect protection plugins using even call.
|
||||
|
||||
ItemStack item = new ItemStack(Material.LINGERING_POTION);
|
||||
ItemUtil.mapMeta(item, meta -> {
|
||||
if (meta instanceof PotionMeta potionMeta) {
|
||||
potionMeta.addCustomEffect(new PotionEffect(PotionEffectType.HARM, 20, 0), true);
|
||||
}
|
||||
});
|
||||
|
||||
ThrownPotion potion = shooter.launchProjectile(ThrownPotion.class);
|
||||
potion.setItem(item);
|
||||
potion.teleport(location);
|
||||
|
||||
AreaEffectCloud cloud = world.spawn(location, AreaEffectCloud.class);
|
||||
cloud.clearCustomEffects();
|
||||
cloud.setSource(shooter);
|
||||
cloud.setParticle(Particle.DRAGON_BREATH);
|
||||
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);
|
||||
|
||||
LingeringPotionSplashEvent splashEvent = new LingeringPotionSplashEvent(potion, cloud);
|
||||
plugin.getPluginManager().callEvent(splashEvent);
|
||||
if (splashEvent.isCancelled()) {
|
||||
cloud.remove();
|
||||
}
|
||||
potion.remove();
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.LocationUtil;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
|
||||
public class EnchantElectrifiedArrows extends ExcellentEnchant implements Chanced, Arrowed, BowEnchant {
|
||||
|
||||
public static final String ID = "electrified_arrows";
|
||||
|
||||
private static final String META_NO_ITEM_DAMAGE = "itemNoDamage";
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
|
||||
public EnchantElectrifiedArrows(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch an electrified arrow.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.3);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.FIREWORKS_SPARK));
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"10.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return arrowImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public EnchantmentTarget getCategory() {
|
||||
return EnchantmentTarget.BOW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
|
||||
return this.checkTriggerChance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
if (!this.isOurProjectile(projectile)) return false;
|
||||
if (event.getHitEntity() != null || event.getHitBlock() == null) return false;
|
||||
|
||||
Block block = event.getHitBlock();
|
||||
block.getWorld().strikeLightning(block.getLocation()).setMetadata(META_NO_ITEM_DAMAGE, new FixedMetadataValue(plugin, true));
|
||||
if (this.hasVisualEffects()) {
|
||||
Location center = LocationUtil.getCenter(block.getLocation());
|
||||
UniParticle.blockCrack(block.getType()).play(center, 1, 0.05, 120);
|
||||
UniParticle.of(Particle.FIREWORKS_SPARK).play(center, 1, 0.05, 120);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
if (!this.isOurProjectile(projectile)) return false;
|
||||
|
||||
plugin.getServer().getScheduler().runTask(plugin, () -> {
|
||||
if (victim.isDead()) return;
|
||||
victim.setNoDamageTicks(0);
|
||||
victim.getWorld().strikeLightning(victim.getLocation()).setMetadata(META_NO_ITEM_DAMAGE, new FixedMetadataValue(plugin, true));
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onItemDamage(EntityDamageByEntityEvent e) {
|
||||
if (!e.getDamager().hasMetadata(META_NO_ITEM_DAMAGE)) return;
|
||||
if (e.getEntity() instanceof Item || e.getEntity() instanceof ItemFrame) {
|
||||
e.setCancelled(true);
|
||||
e.getEntity().setFireTicks(0);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.config.JOption;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
|
||||
public class EnchantExplosiveArrows extends ExcellentEnchant implements Chanced, Arrowed, BowEnchant {
|
||||
|
||||
public static final String ID = "explosive_arrows";
|
||||
public static final String PLACEHOLDER_EXPLOSION_POWER = "%enchantment_explosion_power%";
|
||||
|
||||
private boolean explosionFireSpread;
|
||||
private boolean explosionDamageItems;
|
||||
private boolean explosionDamageBlocks;
|
||||
private EnchantScaler explosionSize;
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
|
||||
private Entity lastExploder;
|
||||
|
||||
public EnchantExplosiveArrows(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch an explosive arrow.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.7);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.SMOKE_NORMAL));
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"10.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5");
|
||||
this.explosionFireSpread = JOption.create("Settings.Explosion.Fire_Spread", true,
|
||||
"When 'true' creates fire on nearby blocks.").read(cfg);
|
||||
this.explosionDamageItems = JOption.create("Settings.Explosion.Damage_Items", false,
|
||||
"When 'true' inflicts damage to items on the ground.").read(cfg);
|
||||
this.explosionDamageBlocks = JOption.create("Settings.Explosion.Damage_Blocks", false,
|
||||
"When 'true' allows to break blocks by explosion.").read(cfg);
|
||||
this.explosionSize = EnchantScaler.read(this, "Settings.Explosion.Size",
|
||||
"2.0 + " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
"Sets the explosion size. The more size - the bigger explosion.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_EXPLOSION_POWER, level -> NumberUtil.format(this.getExplosionSize(level)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return arrowImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public EnchantmentTarget getCategory() {
|
||||
return EnchantmentTarget.BOW;
|
||||
}
|
||||
|
||||
public final double getExplosionSize(int level) {
|
||||
return this.explosionSize.getValue(level);
|
||||
}
|
||||
|
||||
public final boolean isExplosionFireSpread() {
|
||||
return this.explosionFireSpread;
|
||||
}
|
||||
|
||||
public final boolean isExplosionDamageBlocks() {
|
||||
return this.explosionDamageBlocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
|
||||
return this.checkTriggerChance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
if (!this.isOurProjectile(projectile)) return false;
|
||||
|
||||
if (projectile.getShooter() instanceof Entity entity) {
|
||||
this.lastExploder = entity;
|
||||
}
|
||||
|
||||
World world = projectile.getWorld();
|
||||
float explSize = (float) this.getExplosionSize(level);
|
||||
boolean explFire = this.isExplosionFireSpread();
|
||||
boolean explBlocks = this.isExplosionDamageBlocks();
|
||||
boolean exploded = world.createExplosion(projectile.getLocation(), explSize, explFire, explBlocks, this.lastExploder);
|
||||
this.lastExploder = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onItemDamage(EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() != EntityDamageEvent.DamageCause.ENTITY_EXPLOSION) return;
|
||||
if (this.explosionDamageItems) return;
|
||||
if (this.lastExploder == null || this.lastExploder != event.getDamager()) return;
|
||||
|
||||
if (event.getEntity() instanceof Item || event.getEntity() instanceof ItemFrame) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
|
||||
public class EnchantHover extends ExcellentEnchant implements Chanced, Arrowed, Potioned, BowEnchant {
|
||||
|
||||
public static final String ID = "hover";
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
|
||||
public EnchantHover(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.)");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.1);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.BUBBLE_POP));
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"10.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5");
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.LEVITATION, false,
|
||||
"2.5 + " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return arrowImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
|
||||
return arrow.addCustomEffect(this.createEffect(level), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
|
||||
public class EnchantPoisonedArrows extends ExcellentEnchant implements Chanced, Arrowed, Potioned, BowEnchant {
|
||||
|
||||
public static final String ID = "poisoned_arrows";
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
|
||||
public EnchantPoisonedArrows(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.)");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.1);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.SLIME));
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"25.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5");
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.POISON, false,
|
||||
"2.5 + " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return arrowImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
|
||||
return arrow.addCustomEffect(this.createEffect(level), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.PotionImplementation;
|
||||
|
||||
public class EnchantWitheredArrows extends ExcellentEnchant implements Chanced, Arrowed, Potioned, BowEnchant {
|
||||
|
||||
public static final String ID = "withered_arrows";
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private PotionImplementation potionImplementation;
|
||||
|
||||
public EnchantWitheredArrows(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to launch an arrow with " + Placeholders.ENCHANTMENT_POTION_TYPE + " " + Placeholders.ENCHANTMENT_POTION_LEVEL + " (" + Placeholders.ENCHANTMENT_POTION_DURATION + "s.)");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.5);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.SPELL_WITCH));
|
||||
this.chanceImplementation = ChanceImplementation.create(this,
|
||||
"15.0 + " + Placeholders.ENCHANTMENT_LEVEL + " * 5.0");
|
||||
this.potionImplementation = PotionImplementation.create(this, PotionEffectType.WITHER, false,
|
||||
"2.5 + " + Placeholders.ENCHANTMENT_LEVEL + " * 0.75",
|
||||
Placeholders.ENCHANTMENT_LEVEL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return arrowImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PotionImplementation getPotionImplementation() {
|
||||
return potionImplementation;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
|
||||
return arrow.addCustomEffect(this.createEffect(level), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -11,30 +11,35 @@ 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.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
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.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public class EnchantEnderBow extends ExcellentEnchant implements BowEnchant, Chanced {
|
||||
import java.io.File;
|
||||
|
||||
public class EnderBowEnchant extends AbstractEnchantmentData implements ChanceData, BowEnchant {
|
||||
|
||||
public static final String ID = "ender_bow";
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
public EnchantEnderBow(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("Shoots ender pearls instead of arrows.");
|
||||
this.getDefaults().setLevelMax(1);
|
||||
this.getDefaults().setTier(1.0);
|
||||
public EnderBowEnchant(@NotNull ExcellentEnchantsPlugin plugin, @NotNull File file) {
|
||||
super(plugin, file);
|
||||
this.setDescription("Shoots ender pearls instead of arrows.");
|
||||
this.setMaxLevel(1);
|
||||
this.setRarity(Rarity.VERY_RARE);
|
||||
|
||||
this.getDefaults().setConflicts(
|
||||
EnchantBomber.ID, EnchantGhast.ID,
|
||||
EnchantExplosiveArrows.ID, EnchantPoisonedArrows.ID, EnchantConfusingArrows.ID,
|
||||
EnchantWitheredArrows.ID, EnchantElectrifiedArrows.ID, EnchantDragonfireArrows.ID,
|
||||
this.setConflicts(
|
||||
BomberEnchant.ID, GhastEnchant.ID,
|
||||
ExplosiveArrowsEnchant.ID, PoisonedArrowsEnchant.ID, ConfusingArrowsEnchant.ID,
|
||||
WitheredArrowsEnchant.ID, ElectrifiedArrowsEnchant.ID, DragonfireArrowsEnchant.ID,
|
||||
DarknessArrowsEnchant.ID, VampiricArrowsEnchant.ID,
|
||||
EnchantHover.ID, FlareEnchant.ID,
|
||||
HoverEnchant.ID, FlareEnchant.ID,
|
||||
Enchantment.ARROW_FIRE.getKey().getKey(),
|
||||
Enchantment.ARROW_KNOCKBACK.getKey().getKey(),
|
||||
Enchantment.ARROW_DAMAGE.getKey().getKey()
|
||||
@ -42,15 +47,14 @@ public class EnchantEnderBow extends ExcellentEnchant implements BowEnchant, Cha
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this, "100");
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@Override
|
@ -0,0 +1,148 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
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.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.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.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.manager.SimpeListener;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class ExplosiveArrowsEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, BowEnchant, SimpeListener {
|
||||
|
||||
public static final String ID = "explosive_arrows";
|
||||
|
||||
private boolean explosionFireSpread;
|
||||
private boolean explosionDamageItems;
|
||||
private boolean explosionDamageBlocks;
|
||||
private Modifier explosionSize;
|
||||
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
private Entity lastExploder;
|
||||
|
||||
public ExplosiveArrowsEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.SMOKE_NORMAL));
|
||||
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3, 2, 1, 100));
|
||||
|
||||
this.explosionFireSpread = ConfigValue.create("Settings.Explosion.Fire_Spread",
|
||||
true,
|
||||
"When 'true' creates fire on nearby blocks.").read(config);
|
||||
|
||||
this.explosionDamageItems = ConfigValue.create("Settings.Explosion.Damage_Items",
|
||||
false,
|
||||
"When 'true' inflicts damage to items on the ground.").read(config);
|
||||
|
||||
this.explosionDamageBlocks = ConfigValue.create("Settings.Explosion.Damage_Blocks",
|
||||
false,
|
||||
"When 'true' allows to break blocks by explosion.").read(config);
|
||||
|
||||
this.explosionSize = Modifier.read(config, "Settings.Explosion.Size",
|
||||
Modifier.add(1, 1, 1, 5),
|
||||
"Sets the explosion size. The more size - the bigger explosion.");
|
||||
|
||||
this.addPlaceholder(GENERIC_RADIUS, level -> NumberUtil.format(this.getExplosionSize(level)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowSettings getArrowSettings() {
|
||||
return arrowSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public EnchantmentTarget getCategory() {
|
||||
return EnchantmentTarget.BOW;
|
||||
}
|
||||
|
||||
public final double getExplosionSize(int level) {
|
||||
return this.explosionSize.getValue(level);
|
||||
}
|
||||
|
||||
public final boolean isExplosionFireSpread() {
|
||||
return this.explosionFireSpread;
|
||||
}
|
||||
|
||||
public final boolean isExplosionDamageBlocks() {
|
||||
return this.explosionDamageBlocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
|
||||
return this.checkTriggerChance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
if (projectile.getShooter() instanceof Entity entity) {
|
||||
this.lastExploder = entity;
|
||||
}
|
||||
|
||||
World world = projectile.getWorld();
|
||||
float explSize = (float) this.getExplosionSize(level);
|
||||
boolean explFire = this.isExplosionFireSpread();
|
||||
boolean explBlocks = this.isExplosionDamageBlocks();
|
||||
/*boolean exploded = */world.createExplosion(projectile.getLocation(), explSize, explFire, explBlocks, this.lastExploder);
|
||||
this.lastExploder = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onItemDamage(EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() != EntityDamageEvent.DamageCause.ENTITY_EXPLOSION) return;
|
||||
if (this.explosionDamageItems) return;
|
||||
if (this.lastExploder == null || this.lastExploder != event.getDamager()) return;
|
||||
|
||||
if (event.getEntity() instanceof Item || event.getEntity() instanceof ItemFrame) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,36 +18,42 @@ import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
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.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ArrowSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
public class FlareEnchant extends ExcellentEnchant implements Chanced, Arrowed, BowEnchant {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class FlareEnchant extends AbstractEnchantmentData implements ChanceData, ArrowData, BowEnchant {
|
||||
|
||||
public static final String ID = "flare";
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
|
||||
public FlareEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
public FlareEnchant(@NotNull ExcellentEnchantsPlugin plugin, File file) {
|
||||
super(plugin, file);
|
||||
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to create a torch where arrow lands.");
|
||||
this.getDefaults().setLevelMax(1);
|
||||
this.getDefaults().setTier(0.4);
|
||||
this.setDescription(ENCHANTMENT_CHANCE + "% chance to create a torch where arrow lands.");
|
||||
this.setMaxLevel(1);
|
||||
this.setRarity(Rarity.RARE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this, "100.0");
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.of(Particle.FIREWORKS_SPARK));
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config);
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.FIREWORKS_SPARK));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -64,40 +70,38 @@ public class FlareEnchant extends ExcellentEnchant implements Chanced, Arrowed,
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Chanced getChanceImplementation() {
|
||||
return this.chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return this.chanceSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrowImplementation getArrowImplementation() {
|
||||
return this.arrowImplementation;
|
||||
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 arrow)) return false;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
if (!(event.getProjectile() instanceof Arrow)) return false;
|
||||
|
||||
this.addData(arrow);
|
||||
return true;
|
||||
return this.checkTriggerChance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent e, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
Block block = e.getHitBlock();
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
Block block = event.getHitBlock();
|
||||
if (block == null) return false;
|
||||
|
||||
BlockFace face = e.getHitBlockFace();
|
||||
BlockFace face = event.getHitBlockFace();
|
||||
if (face == null || face == BlockFace.DOWN) return false;
|
||||
|
||||
Block relative = block.getRelative(face);
|
||||
if (!relative.getType().isAir()) return false;
|
||||
|
||||
if (projectile.getShooter() instanceof Player player) {
|
||||
BlockPlaceEvent event = new BlockPlaceEvent(relative, relative.getState(), block, new ItemStack(Material.TORCH), player,true, EquipmentSlot.HAND);
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled() || !event.canBuild()) return false;
|
||||
BlockPlaceEvent placeEvent = new BlockPlaceEvent(relative, relative.getState(), block, new ItemStack(Material.TORCH), player,true, EquipmentSlot.HAND);
|
||||
plugin.getPluginManager().callEvent(placeEvent);
|
||||
if (placeEvent.isCancelled() || !placeEvent.canBuild()) return false;
|
||||
}
|
||||
|
||||
if (face == BlockFace.UP) {
|
||||
|
@ -12,36 +12,40 @@ import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.api.config.JOption;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public class EnchantGhast extends ExcellentEnchant implements BowEnchant, Chanced {
|
||||
import java.io.File;
|
||||
|
||||
public class GhastEnchant extends AbstractEnchantmentData implements ChanceData, BowEnchant {
|
||||
|
||||
public static final String ID = "ghast";
|
||||
|
||||
private boolean fireSpread;
|
||||
private EnchantScaler yield;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private boolean fireSpread;
|
||||
private Modifier yield;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
public EnchantGhast(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription("Shoots fireballs instead of arrows.");
|
||||
this.getDefaults().setLevelMax(1);
|
||||
this.getDefaults().setTier(0.3);
|
||||
public GhastEnchant(@NotNull ExcellentEnchantsPlugin plugin, @NotNull File file) {
|
||||
super(plugin, file);
|
||||
this.setDescription("Shoots fireballs instead of arrows.");
|
||||
this.setMaxLevel(1);
|
||||
this.setRarity(Rarity.UNCOMMON);
|
||||
|
||||
this.getDefaults().setConflicts(
|
||||
EnchantEnderBow.ID, EnchantBomber.ID,
|
||||
EnchantExplosiveArrows.ID, EnchantPoisonedArrows.ID, EnchantConfusingArrows.ID,
|
||||
EnchantWitheredArrows.ID, EnchantElectrifiedArrows.ID, EnchantDragonfireArrows.ID,
|
||||
this.setConflicts(
|
||||
EnderBowEnchant.ID, BomberEnchant.ID,
|
||||
ExplosiveArrowsEnchant.ID, PoisonedArrowsEnchant.ID, ConfusingArrowsEnchant.ID,
|
||||
WitheredArrowsEnchant.ID, ElectrifiedArrowsEnchant.ID, DragonfireArrowsEnchant.ID,
|
||||
DarknessArrowsEnchant.ID, VampiricArrowsEnchant.ID,
|
||||
EnchantHover.ID, FlareEnchant.ID,
|
||||
HoverEnchant.ID, FlareEnchant.ID,
|
||||
Enchantment.ARROW_FIRE.getKey().getKey(),
|
||||
Enchantment.ARROW_KNOCKBACK.getKey().getKey(),
|
||||
Enchantment.ARROW_DAMAGE.getKey().getKey()
|
||||
@ -49,19 +53,22 @@ public class EnchantGhast extends ExcellentEnchant implements BowEnchant, Chance
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
this.chanceImplementation = ChanceImplementation.create(this, "100");
|
||||
this.fireSpread = JOption.create("Settings.Fire_Spread", true,
|
||||
"When 'true' creates fire on nearby blocks.").read(cfg);
|
||||
this.yield = EnchantScaler.read(this, "Settings.Yield", "1.0 + " + Placeholders.ENCHANTMENT_LEVEL,
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config);
|
||||
|
||||
this.fireSpread = ConfigValue.create("Settings.Fire_Spread",
|
||||
true,
|
||||
"When 'true' creates fire on nearby blocks.").read(config);
|
||||
|
||||
this.yield = Modifier.read(config, "Settings.Yield",
|
||||
Modifier.add(2, 0, 1, 5),
|
||||
"Fireball explosion size/radius. The more value = the bigger the explosion.");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceImplementation getChanceImplementation() {
|
||||
return chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return chanceSettings;
|
||||
}
|
||||
|
||||
public boolean isFireSpread() {
|
@ -0,0 +1,101 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.*;
|
||||
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.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
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 static final String ID = "hover";
|
||||
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
|
||||
public HoverEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.BUBBLE_POP));
|
||||
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(3, 3, 1, 100));
|
||||
|
||||
this.potionSettings = PotionSettingsImpl.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;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
|
||||
return arrow.addCustomEffect(this.createEffect(level), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.impl.bow;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.*;
|
||||
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.PotionSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
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 static final String ID = "poisoned_arrows";
|
||||
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private PotionSettingsImpl potionSettings;
|
||||
|
||||
public PoisonedArrowsEnchant(@NotNull ExcellentEnchantsPlugin 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.of(Particle.SLIME));
|
||||
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(7.5, 2.5, 1, 100));
|
||||
|
||||
this.potionSettings = PotionSettingsImpl.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;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
|
||||
return arrow.addCustomEffect(this.createEffect(level), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHit(@NotNull ProjectileHitEvent event, LivingEntity user, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDamage(@NotNull EntityDamageByEntityEvent event, @NotNull Projectile projectile, @NotNull LivingEntity shooter, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -11,47 +11,51 @@ import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
|
||||
public class SniperEnchant extends ExcellentEnchant implements BowEnchant, Chanced {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class SniperEnchant extends AbstractEnchantmentData implements BowEnchant, ChanceData {
|
||||
|
||||
public static final String ID = "sniper";
|
||||
|
||||
private static final String PLACEHOLDER_PROJECTILE_SPEED = "%enchantment_projectile_speed%";
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private Modifier speedModifier;
|
||||
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private EnchantScaler speedModifier;
|
||||
public SniperEnchant(@NotNull ExcellentEnchantsPlugin plugin, @NotNull File file) {
|
||||
super(plugin, file);
|
||||
|
||||
public SniperEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
|
||||
this.getDefaults().setDescription("Increases projectile speed by " + PLACEHOLDER_PROJECTILE_SPEED + "%");
|
||||
this.getDefaults().setLevelMax(5);
|
||||
this.getDefaults().setTier(0.3);
|
||||
this.setDescription("Increases projectile speed by " + GENERIC_AMOUNT + "%");
|
||||
this.setMaxLevel(5);
|
||||
this.setRarity(Rarity.UNCOMMON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config);
|
||||
|
||||
this.chanceImplementation = ChanceImplementation.create(this, "100.0");
|
||||
this.speedModifier = EnchantScaler.read(this, "Settings.Speed_Modifier",
|
||||
"1.0 + " + Placeholders.ENCHANTMENT_LEVEL + " / 5.0", "Sets projectile's speed modifier.");
|
||||
this.speedModifier = Modifier.read(config, "Settings.Speed_Modifier",
|
||||
Modifier.add(1, 0.2, 1, 3D),
|
||||
"Sets projectile's speed modifier.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_PROJECTILE_SPEED, level -> NumberUtil.format(this.getSpeedModifier(level) * 100D));
|
||||
this.addPlaceholder(GENERIC_AMOUNT, level -> NumberUtil.format(this.getSpeedModifier(level) * 100D));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Chanced getChanceImplementation() {
|
||||
return this.chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return this.chanceSettings;
|
||||
}
|
||||
|
||||
public double getSpeedModifier(int level) {
|
||||
|
@ -14,50 +14,54 @@ import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nexmedia.engine.utils.EntityUtil;
|
||||
import su.nexmedia.engine.utils.NumberUtil;
|
||||
import su.nexmedia.engine.utils.values.UniParticle;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchants;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Arrowed;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
|
||||
import su.nightexpress.excellentenchants.ExcellentEnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
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.type.BowEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ArrowImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentData;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ArrowSettingsImpl;
|
||||
import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.EntityUtil;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
public class VampiricArrowsEnchant extends ExcellentEnchant implements BowEnchant, Arrowed, Chanced {
|
||||
import java.io.File;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
|
||||
public class VampiricArrowsEnchant extends AbstractEnchantmentData implements BowEnchant, ArrowData, ChanceData {
|
||||
|
||||
public static final String ID = "vampiric_arrows";
|
||||
|
||||
public static final String PLACEHOLDER_HEAL_AMOUNT = "%heal_amount%";
|
||||
private ArrowSettingsImpl arrowSettings;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
private Modifier healAmount;
|
||||
|
||||
private ArrowImplementation arrowImplementation;
|
||||
private ChanceImplementation chanceImplementation;
|
||||
private EnchantScaler healAmount;
|
||||
|
||||
public VampiricArrowsEnchant(@NotNull ExcellentEnchants plugin) {
|
||||
super(plugin, ID);
|
||||
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to restore " + PLACEHOLDER_HEAL_AMOUNT + "❤ on arrow hit.");
|
||||
this.getDefaults().setLevelMax(3);
|
||||
this.getDefaults().setTier(0.3);
|
||||
this.getDefaults().setConflicts(EnchantEnderBow.ID, EnchantGhast.ID, EnchantBomber.ID);
|
||||
public VampiricArrowsEnchant(@NotNull ExcellentEnchantsPlugin plugin, @NotNull File file) {
|
||||
super(plugin, file);
|
||||
this.setDescription(ENCHANTMENT_CHANCE + "% chance to restore " + GENERIC_AMOUNT + "❤ on arrow hit.");
|
||||
this.setMaxLevel(3);
|
||||
this.setRarity(Rarity.RARE);
|
||||
this.setConflicts(EnderBowEnchant.ID, GhastEnchant.ID, BomberEnchant.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
super.loadSettings();
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.arrowSettings = ArrowSettingsImpl.create(config, UniParticle.redstone(Color.RED, 1f));
|
||||
|
||||
this.arrowImplementation = ArrowImplementation.create(this, UniParticle.redstone(Color.RED, 1f));
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(8, 4, 1, 100));
|
||||
|
||||
this.chanceImplementation = ChanceImplementation.create(this, "20.0 * " + Placeholders.ENCHANTMENT_LEVEL);
|
||||
this.healAmount = Modifier.read(config, "Settings.Heal_Amount",
|
||||
Modifier.add(0, 1, 1, 10),
|
||||
"Amount of health to be restored on hit."
|
||||
);
|
||||
|
||||
this.healAmount = EnchantScaler.read(this, "Settings.Heal_Amount",
|
||||
Placeholders.ENCHANTMENT_LEVEL,
|
||||
"Amount of health to be restored on hit.");
|
||||
|
||||
this.addPlaceholder(PLACEHOLDER_HEAL_AMOUNT, level -> NumberUtil.format(this.getHealAmount(level)));
|
||||
this.addPlaceholder(GENERIC_AMOUNT, level -> NumberUtil.format(this.getHealAmount(level)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -68,14 +72,14 @@ public class VampiricArrowsEnchant extends ExcellentEnchant implements BowEnchan
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Arrowed getArrowImplementation() {
|
||||
return this.arrowImplementation;
|
||||
public ArrowSettings getArrowSettings() {
|
||||
return this.arrowSettings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Chanced getChanceImplementation() {
|
||||
return this.chanceImplementation;
|
||||
public ChanceSettings getChanceSettings() {
|
||||
return this.chanceSettings;
|
||||
}
|
||||
|
||||
public double getHealAmount(int level) {
|
||||
@ -90,11 +94,9 @@ public class VampiricArrowsEnchant extends ExcellentEnchant implements BowEnchan
|
||||
|
||||
@Override
|
||||
public boolean onShoot(@NotNull EntityShootBowEvent event, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
|
||||
if (!(event.getProjectile() instanceof Arrow arrow)) return false;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
if (!(event.getProjectile() instanceof Arrow)) return false;
|
||||
|
||||
this.addData(arrow);
|
||||
return true;
|
||||
return this.checkTriggerChance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user