This commit is contained in:
nulli0n 2022-04-16 14:27:39 +06:00
parent 9a8a909378
commit 66970daa24
47 changed files with 743 additions and 349 deletions

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<version>3.1.4</version> <version>3.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -32,27 +32,27 @@
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId> <artifactId>NMS</artifactId>
<version>3.1.4</version> <version>3.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_16_R1</artifactId> <artifactId>V1_16_R1</artifactId>
<version>3.1.4</version> <version>3.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_17_R1</artifactId> <artifactId>V1_17_R1</artifactId>
<version>3.1.4</version> <version>3.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_18_R1</artifactId> <artifactId>V1_18_R1</artifactId>
<version>3.1.4</version> <version>3.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_18_R2</artifactId> <artifactId>V1_18_R2</artifactId>
<version>3.1.4</version> <version>3.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>fr.neatmonster</groupId> <groupId>fr.neatmonster</groupId>

View File

@ -16,8 +16,6 @@ import su.nightexpress.excellentenchants.nms.EnchantNMS;
public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> { public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
private static ExcellentEnchants instance;
public static boolean isLoaded = false; public static boolean isLoaded = false;
private Config config; private Config config;
@ -26,14 +24,6 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
private EnchantNMS enchantNMS; private EnchantNMS enchantNMS;
private EnchantManager enchantManager; private EnchantManager enchantManager;
public ExcellentEnchants() {
instance = this;
}
public static ExcellentEnchants getInstance() {
return instance;
}
@Override @Override
public void enable() { public void enable() {
if (!this.setNMS()) { if (!this.setNMS()) {
@ -54,11 +44,6 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
} }
} }
@Override
public boolean useNewConfigFields() {
return true;
}
private boolean setNMS() { private boolean setNMS() {
Version current = Version.CURRENT; Version current = Version.CURRENT;
if (current == null) return false; if (current == null) return false;

View File

@ -4,8 +4,8 @@ public class Perms {
public static final String PREFIX = "excellentenchants."; public static final String PREFIX = "excellentenchants.";
public static final String ADMIN = PREFIX + "admin"; //public static final String ADMIN = PREFIX + "admin";
public static final String USER = PREFIX + "user"; //public static final String USER = PREFIX + "user";
public static final String COMMAND_BOOK = PREFIX + "command.book"; public static final String COMMAND_BOOK = PREFIX + "command.book";
public static final String COMMAND_ENCHANT = PREFIX + "command.enchant"; public static final String COMMAND_ENCHANT = PREFIX + "command.enchant";

View File

@ -0,0 +1,29 @@
package su.nightexpress.excellentenchants.api.enchantment;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class EnchantDropContainer {
private final BlockDropItemEvent parent;
private final List<ItemStack> drop;
public EnchantDropContainer(@NotNull BlockDropItemEvent parent) {
this.parent = parent;
this.drop = new ArrayList<>();
}
@NotNull
public BlockDropItemEvent getParent() {
return parent;
}
@NotNull
public List<ItemStack> getDrop() {
return drop;
}
}

View File

@ -118,7 +118,7 @@ public abstract class ExcellentEnchant extends Enchantment implements IListener
@NotNull @NotNull
public UnaryOperator<String> replacePlaceholders(int level) { public UnaryOperator<String> replacePlaceholders(int level) {
String conflicts = this.getConflicts().isEmpty() ? plugin.lang().Other_None.getMsg() : this.getConflicts().stream().filter(Objects::nonNull).map(en -> plugin.lang().getEnchantment(en)).collect(Collectors.joining("\n")); String conflicts = this.getConflicts().isEmpty() ? plugin.lang().Other_None.getLocalized() : this.getConflicts().stream().filter(Objects::nonNull).map(en -> plugin.lang().getEnchantment(en)).collect(Collectors.joining("\n"));
return str -> str return str -> str
.replace(PLACEHOLDER_NAME, this.getDisplayName()) .replace(PLACEHOLDER_NAME, this.getDisplayName())
@ -135,7 +135,7 @@ public abstract class ExcellentEnchant extends Enchantment implements IListener
.replace(PLACEHOLDER_OBTAIN_CHANCE_LOOT_GENERATION, NumberUtil.format(this.getObtainChance(ObtainType.LOOT_GENERATION))) .replace(PLACEHOLDER_OBTAIN_CHANCE_LOOT_GENERATION, NumberUtil.format(this.getObtainChance(ObtainType.LOOT_GENERATION)))
.replace(PLACEHOLDER_OBTAIN_CHANCE_FISHING, NumberUtil.format(this.getObtainChance(ObtainType.FISHING))) .replace(PLACEHOLDER_OBTAIN_CHANCE_FISHING, NumberUtil.format(this.getObtainChance(ObtainType.FISHING)))
.replace(PLACEHOLDER_OBTAIN_CHANCE_MOB_SPAWNING, NumberUtil.format(this.getObtainChance(ObtainType.MOB_SPAWNING))) .replace(PLACEHOLDER_OBTAIN_CHANCE_MOB_SPAWNING, NumberUtil.format(this.getObtainChance(ObtainType.MOB_SPAWNING)))
.replace(PLACEHOLDER_COST_ITEM, this.hasCostItem() ? ItemUtil.getItemName(this.costItem) : plugin.lang().Other_None.getMsg()) .replace(PLACEHOLDER_COST_ITEM, this.hasCostItem() ? ItemUtil.getItemName(this.costItem) : plugin.lang().Other_None.getLocalized())
; ;
} }

View File

@ -0,0 +1,11 @@
package su.nightexpress.excellentenchants.api.enchantment.type;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public interface BlockDropEnchant {
boolean use(@NotNull BlockDropItemEvent e, @NotNull Player player, @NotNull ItemStack item, int level);
}

View File

@ -1,15 +1,11 @@
package su.nightexpress.excellentenchants.api.enchantment.type; package su.nightexpress.excellentenchants.api.enchantment.type;
import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantDropContainer;
import java.util.List;
public interface CustomDropEnchant { public interface CustomDropEnchant {
@NotNull List<ItemStack> getCustomDrops(@NotNull Player player, @NotNull ItemStack item, @NotNull Block block, int level); void handleDrop(@NotNull EnchantDropContainer e, @NotNull Player player, @NotNull ItemStack item, int level);
boolean isEventMustHaveDrops();
} }

View File

@ -28,13 +28,13 @@ public class BookCommand extends AbstractCommand<ExcellentEnchants> {
@Override @Override
@NotNull @NotNull
public String getDescription() { public String getDescription() {
return plugin.lang().Command_Book_Desc.getMsg(); return plugin.lang().Command_Book_Desc.getLocalized();
} }
@Override @Override
@NotNull @NotNull
public String getUsage() { public String getUsage() {
return plugin.lang().Command_Book_Usage.getMsg(); return plugin.lang().Command_Book_Usage.getLocalized();
} }
@Override @Override
@ -44,17 +44,17 @@ public class BookCommand extends AbstractCommand<ExcellentEnchants> {
@Override @Override
@NotNull @NotNull
public List<String> getTab(@NotNull Player player, int i, @NotNull String[] args) { public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (i == 1) { if (arg == 1) {
return PlayerUtil.getPlayerNames(); return PlayerUtil.getPlayerNames();
} }
if (i == 2) { if (arg == 2) {
return Arrays.stream(Enchantment.values()).map(e -> e.getKey().getKey()).toList(); return Arrays.stream(Enchantment.values()).map(e -> e.getKey().getKey()).toList();
} }
if (i == 3) { if (arg == 3) {
return Arrays.asList("-1", "1", "5", "10"); return Arrays.asList("-1", "1", "5", "10");
} }
return super.getTab(player, i, args); return super.getTab(player, arg, args);
} }
@Override @Override

View File

@ -27,13 +27,13 @@ public class EnchantCommand extends AbstractCommand<ExcellentEnchants> {
@Override @Override
@NotNull @NotNull
public String getDescription() { public String getDescription() {
return plugin.lang().Command_Enchant_Desc.getMsg(); return plugin.lang().Command_Enchant_Desc.getLocalized();
} }
@Override @Override
@NotNull @NotNull
public String getUsage() { public String getUsage() {
return plugin.lang().Command_Enchant_Usage.getMsg(); return plugin.lang().Command_Enchant_Usage.getLocalized();
} }
@Override @Override
@ -43,14 +43,14 @@ public class EnchantCommand extends AbstractCommand<ExcellentEnchants> {
@Override @Override
@NotNull @NotNull
public List<String> getTab(@NotNull Player player, int i, @NotNull String[] args) { public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (i == 1) { if (arg == 1) {
return Arrays.stream(Enchantment.values()).map(e -> e.getKey().getKey()).toList(); return Arrays.stream(Enchantment.values()).map(e -> e.getKey().getKey()).toList();
} }
if (i == 2) { if (arg == 2) {
return Arrays.asList("-1", "1", "5", "10"); return Arrays.asList("-1", "1", "5", "10");
} }
return super.getTab(player, i, args); return super.getTab(player, arg, args);
} }
@Override @Override
@ -81,12 +81,12 @@ public class EnchantCommand extends AbstractCommand<ExcellentEnchants> {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
if (meta == null) return; if (meta == null) return;
if (meta instanceof EnchantmentStorageMeta) { if (meta instanceof EnchantmentStorageMeta storageMeta) {
if (level == 0) { if (level == 0) {
((EnchantmentStorageMeta) meta).removeStoredEnchant(enchantment); storageMeta.removeStoredEnchant(enchantment);
} }
else { else {
((EnchantmentStorageMeta) meta).addStoredEnchant(enchantment, level, true); storageMeta.addStoredEnchant(enchantment, level, true);
} }
} }
else { else {

View File

@ -22,7 +22,7 @@ public class ListCommand extends AbstractCommand<ExcellentEnchants> {
@Override @Override
@NotNull @NotNull
public String getDescription() { public String getDescription() {
return plugin.lang().Command_List_Desc.getMsg(); return plugin.lang().Command_List_Desc.getLocalized();
} }
@Override @Override

View File

@ -27,13 +27,13 @@ public class TierbookCommand extends AbstractCommand<ExcellentEnchants> {
@Override @Override
@NotNull @NotNull
public String getDescription() { public String getDescription() {
return plugin.lang().Command_TierBook_Desc.getMsg(); return plugin.lang().Command_TierBook_Desc.getLocalized();
} }
@Override @Override
@NotNull @NotNull
public String getUsage() { public String getUsage() {
return plugin.lang().Command_TierBook_Usage.getMsg(); return plugin.lang().Command_TierBook_Usage.getLocalized();
} }
@Override @Override
@ -43,17 +43,17 @@ public class TierbookCommand extends AbstractCommand<ExcellentEnchants> {
@Override @Override
@NotNull @NotNull
public List<String> getTab(@NotNull Player player, int i, @NotNull String[] args) { public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (i == 1) { if (arg == 1) {
return PlayerUtil.getPlayerNames(); return PlayerUtil.getPlayerNames();
} }
if (i == 2) { if (arg == 2) {
return EnchantManager.getTierIds(); return EnchantManager.getTierIds();
} }
if (i == 3) { if (arg == 3) {
return Arrays.asList("-1", "1", "5", "10"); return Arrays.asList("-1", "1", "5", "10");
} }
return super.getTab(player, i, args); return super.getTab(player, arg, args);
} }
@Override @Override

View File

@ -11,11 +11,6 @@ public class Lang extends CoreLang {
public Lang(@NotNull ExcellentEnchants plugin) { public Lang(@NotNull ExcellentEnchants plugin) {
super(plugin); super(plugin);
}
@Override
public void setup() {
super.setup();
this.setupEnum(EnchantmentTarget.class); this.setupEnum(EnchantmentTarget.class);
this.setupEnum(FitItemType.class); this.setupEnum(FitItemType.class);
} }

View File

@ -123,17 +123,6 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
return true; return true;
} }
@Deprecated
public static boolean hasEnchant(@NotNull ItemStack item, @NotNull Enchantment enchantment) {
return item.getEnchantmentLevel(enchantment) != 0;
}
@Deprecated
public static int getEnchantLevel(@NotNull ItemStack item, @NotNull Enchantment enchantment) {
ItemMeta meta = item.getItemMeta();
return meta != null ? meta.getEnchantLevel(enchantment) : item.getEnchantmentLevel(enchantment);
}
public static void updateItemLoreEnchants(@NotNull ItemStack item) { public static void updateItemLoreEnchants(@NotNull ItemStack item) {
EnchantRegister.ENCHANT_LIST.forEach(ench -> { EnchantRegister.ENCHANT_LIST.forEach(ench -> {
ItemUtil.delLore(item, ench.getId()); ItemUtil.delLore(item, ench.getId());

View File

@ -58,6 +58,7 @@ public class EnchantRegister {
public static final EnchantRage RAGE; public static final EnchantRage RAGE;
public static final EnchantScavenger SCAVENGER; public static final EnchantScavenger SCAVENGER;
public static final EnchantSurprise SURPRISE; public static final EnchantSurprise SURPRISE;
public static final EnchantTemper TEMPER;
public static final EnchantThrifty THRIFTY; public static final EnchantThrifty THRIFTY;
public static final EnchantThunder THUNDER; public static final EnchantThunder THUNDER;
public static final EnchantVillageDefender VILLAGE_DEFENDER; public static final EnchantVillageDefender VILLAGE_DEFENDER;
@ -75,14 +76,18 @@ public class EnchantRegister {
public static final EnchantRegrowth REGROWTH; public static final EnchantRegrowth REGROWTH;
public static final EnchantBomber BOMBER; public static final EnchantBomber BOMBER;
public static final EnchantConfusingArrows CONFUSING_ARROWS;
public static final EnchantDragonfireArrows DRAGONFIRE_ARROWS;
public static final EnchantElectrifiedArrows ELECTRIFIED_ARROWS;
public static final EnchantEnderBow ENDER_BOW; public static final EnchantEnderBow ENDER_BOW;
public static final EnchantGhast GHAST; public static final EnchantGhast GHAST;
public static final EnchantHover HOVER;
public static final EnchantPoisonedArrows POISONED_ARROWS; public static final EnchantPoisonedArrows POISONED_ARROWS;
public static final EnchantWitheredArrows WITHERED_ARROWS; public static final EnchantWitheredArrows WITHERED_ARROWS;
public static final EnchantExplosiveArrows EXPLOSIVE_ARROWS; public static final EnchantExplosiveArrows EXPLOSIVE_ARROWS;
static { static {
PLUGIN = ExcellentEnchants.getInstance(); PLUGIN = ExcellentEnchants.getPlugin(ExcellentEnchants.class);
PLUGIN.getConfigManager().extract("enchants"); PLUGIN.getConfigManager().extract("enchants");
ENCHANT_LIST = new HashSet<>(); ENCHANT_LIST = new HashSet<>();
@ -119,6 +124,7 @@ public class EnchantRegister {
ROCKET = init(EnchantRocket.class, EnchantRocket.ID); ROCKET = init(EnchantRocket.class, EnchantRocket.ID);
SCAVENGER = init(EnchantScavenger.class, EnchantScavenger.ID); SCAVENGER = init(EnchantScavenger.class, EnchantScavenger.ID);
SURPRISE = init(EnchantSurprise.class, EnchantSurprise.ID); SURPRISE = init(EnchantSurprise.class, EnchantSurprise.ID);
TEMPER = init(EnchantTemper.class, EnchantTemper.ID);
THRIFTY = init(EnchantThrifty.class, EnchantThrifty.ID); THRIFTY = init(EnchantThrifty.class, EnchantThrifty.ID);
THUNDER = init(EnchantThunder.class, EnchantThunder.ID); THUNDER = init(EnchantThunder.class, EnchantThunder.ID);
VAMPIRE = init(EnchantVampire.class, EnchantVampire.ID); VAMPIRE = init(EnchantVampire.class, EnchantVampire.ID);
@ -140,9 +146,13 @@ public class EnchantRegister {
// Bow enchants // Bow enchants
BOMBER = init(EnchantBomber.class, EnchantBomber.ID); BOMBER = init(EnchantBomber.class, EnchantBomber.ID);
CONFUSING_ARROWS = init(EnchantConfusingArrows.class, EnchantConfusingArrows.ID);
DRAGONFIRE_ARROWS = init(EnchantDragonfireArrows.class, EnchantDragonfireArrows.ID);
ELECTRIFIED_ARROWS = init(EnchantElectrifiedArrows.class, EnchantElectrifiedArrows.ID);
ENDER_BOW = init(EnchantEnderBow.class, EnchantEnderBow.ID); ENDER_BOW = init(EnchantEnderBow.class, EnchantEnderBow.ID);
EXPLOSIVE_ARROWS = init(EnchantExplosiveArrows.class, EnchantExplosiveArrows.ID); EXPLOSIVE_ARROWS = init(EnchantExplosiveArrows.class, EnchantExplosiveArrows.ID);
GHAST = init(EnchantGhast.class, EnchantGhast.ID); GHAST = init(EnchantGhast.class, EnchantGhast.ID);
HOVER = init(EnchantHover.class, EnchantHover.ID);
POISONED_ARROWS = init(EnchantPoisonedArrows.class, EnchantPoisonedArrows.ID); POISONED_ARROWS = init(EnchantPoisonedArrows.class, EnchantPoisonedArrows.ID);
WITHERED_ARROWS = init(EnchantWitheredArrows.class, EnchantWitheredArrows.ID); WITHERED_ARROWS = init(EnchantWitheredArrows.class, EnchantWitheredArrows.ID);

View File

@ -62,6 +62,8 @@ public class EnchantBomber extends IEnchantChanceTemplate implements BowEnchant
this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS); this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS);
this.addConflict(EnchantRegister.WITHERED_ARROWS); this.addConflict(EnchantRegister.WITHERED_ARROWS);
this.addConflict(EnchantRegister.POISONED_ARROWS); this.addConflict(EnchantRegister.POISONED_ARROWS);
this.addConflict(EnchantRegister.DRAGONFIRE_ARROWS);
this.addConflict(EnchantRegister.ELECTRIFIED_ARROWS);
this.addConflict(Enchantment.ARROW_FIRE); this.addConflict(Enchantment.ARROW_FIRE);
this.addConflict(Enchantment.ARROW_DAMAGE); this.addConflict(Enchantment.ARROW_DAMAGE);
this.addConflict(Enchantment.ARROW_KNOCKBACK); this.addConflict(Enchantment.ARROW_KNOCKBACK);

View File

@ -0,0 +1,17 @@
package su.nightexpress.excellentenchants.manager.enchants.bow;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JYML;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowPotionTemplate;
public class EnchantConfusingArrows extends IEnchantBowPotionTemplate {
public static final String ID = "confusing_arrows";
public EnchantConfusingArrows(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM, PotionEffectType.CONFUSION);
}
}

View File

@ -0,0 +1,82 @@
package su.nightexpress.excellentenchants.manager.enchants.bow;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JYML;
import su.nexmedia.engine.utils.NumberUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowTemplate;
import su.nightexpress.excellentenchants.manager.EnchantRegister;
import su.nightexpress.excellentenchants.manager.object.EnchantScaler;
import java.util.function.UnaryOperator;
public class EnchantDragonfireArrows extends IEnchantBowTemplate {
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 final EnchantScaler fireDuration;
private final EnchantScaler fireRadius;
public EnchantDragonfireArrows(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM);
this.fireDuration = new EnchantScaler(this, "Settings.Fire.Duration");
this.fireRadius = new EnchantScaler(this, "Settings.Fire.Radius");
}
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(EnchantRegister.CONFUSING_ARROWS);
this.addConflict(EnchantRegister.POISONED_ARROWS);
this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS);
this.addConflict(EnchantRegister.WITHERED_ARROWS);
this.addConflict(EnchantRegister.ELECTRIFIED_ARROWS);
}
@Override
@NotNull
public UnaryOperator<String> replacePlaceholders(int level) {
return str -> super.replacePlaceholders(level).apply(str
.replace(PLACEHOLDER_FIRE_DURATION, NumberUtil.format(this.getFireDuration(level) / 20D))
.replace(PLACEHOLDER_FIRE_RADIUS, NumberUtil.format(this.getFireRadius(level)))
);
}
public int getFireDuration(int level) {
return (int) this.fireDuration.getValue(level);
}
public double getFireRadius(int level) {
return this.fireRadius.getValue(level);
}
@Override
public boolean use(@NotNull ProjectileHitEvent e, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
if (!super.use(e, projectile, bow, level)) return false;
World world = projectile.getWorld();
AreaEffectCloud cloud = world.spawn(projectile.getLocation(), AreaEffectCloud.class);
cloud.clearCustomEffects();
cloud.setSource(projectile.getShooter());
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);
return true;
}
}

View File

@ -0,0 +1,59 @@
package su.nightexpress.excellentenchants.manager.enchants.bow;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JYML;
import su.nexmedia.engine.utils.EffectUtil;
import su.nexmedia.engine.utils.LocationUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowTemplate;
import su.nightexpress.excellentenchants.manager.EnchantRegister;
public class EnchantElectrifiedArrows extends IEnchantBowTemplate {
public static final String ID = "electrified_arrows";
public EnchantElectrifiedArrows(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM);
}
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(EnchantRegister.CONFUSING_ARROWS);
this.addConflict(EnchantRegister.POISONED_ARROWS);
this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS);
this.addConflict(EnchantRegister.WITHERED_ARROWS);
this.addConflict(EnchantRegister.DRAGONFIRE_ARROWS);
}
@Override
public boolean use(@NotNull ProjectileHitEvent e, @NotNull Projectile projectile, @NotNull ItemStack bow, int level) {
if (!super.use(e, projectile, bow, level)) return false;
Entity entity = e.getHitEntity();
Block block = e.getHitBlock();
if (entity instanceof LivingEntity victim) {
plugin.getServer().getScheduler().runTask(plugin, () -> {
victim.setNoDamageTicks(0);
victim.getWorld().strikeLightning(victim.getLocation());
});
}
else if (block != null) {
block.getWorld().strikeLightning(block.getLocation());
EffectUtil.playEffect(LocationUtil.getCenter(block.getLocation()), Particle.BLOCK_CRACK, block.getType().name(), 1D, 1D, 1D, 0.05, 150);
EffectUtil.playEffect(LocationUtil.getCenter(block.getLocation()), Particle.FIREWORKS_SPARK, "", 1D, 1D, 1D, 0.05, 150);
}
else return false;
return true;
}
}

View File

@ -33,6 +33,8 @@ public class EnchantEnderBow extends IEnchantChanceTemplate implements BowEnchan
this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS); this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS);
this.addConflict(EnchantRegister.WITHERED_ARROWS); this.addConflict(EnchantRegister.WITHERED_ARROWS);
this.addConflict(EnchantRegister.POISONED_ARROWS); this.addConflict(EnchantRegister.POISONED_ARROWS);
this.addConflict(EnchantRegister.DRAGONFIRE_ARROWS);
this.addConflict(EnchantRegister.ELECTRIFIED_ARROWS);
this.addConflict(Enchantment.ARROW_FIRE); this.addConflict(Enchantment.ARROW_FIRE);
this.addConflict(Enchantment.ARROW_DAMAGE); this.addConflict(Enchantment.ARROW_DAMAGE);
this.addConflict(Enchantment.ARROW_KNOCKBACK); this.addConflict(Enchantment.ARROW_KNOCKBACK);

View File

@ -18,6 +18,7 @@ import su.nexmedia.engine.utils.NumberUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority; import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowTemplate; import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowTemplate;
import su.nightexpress.excellentenchants.manager.EnchantRegister;
import su.nightexpress.excellentenchants.manager.object.EnchantScaler; import su.nightexpress.excellentenchants.manager.object.EnchantScaler;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
@ -51,6 +52,16 @@ public class EnchantExplosiveArrows extends IEnchantBowTemplate {
this.cfg.addMissing("Settings.Explosion.Damage_Blocks", false); this.cfg.addMissing("Settings.Explosion.Damage_Blocks", false);
} }
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(EnchantRegister.CONFUSING_ARROWS);
this.addConflict(EnchantRegister.POISONED_ARROWS);
this.addConflict(EnchantRegister.ELECTRIFIED_ARROWS);
this.addConflict(EnchantRegister.WITHERED_ARROWS);
this.addConflict(EnchantRegister.DRAGONFIRE_ARROWS);
}
@Override @Override
@NotNull @NotNull
public UnaryOperator<String> replacePlaceholders(int level) { public UnaryOperator<String> replacePlaceholders(int level) {

View File

@ -50,6 +50,8 @@ public class EnchantGhast extends IEnchantChanceTemplate implements BowEnchant {
this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS); this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS);
this.addConflict(EnchantRegister.WITHERED_ARROWS); this.addConflict(EnchantRegister.WITHERED_ARROWS);
this.addConflict(EnchantRegister.POISONED_ARROWS); this.addConflict(EnchantRegister.POISONED_ARROWS);
this.addConflict(EnchantRegister.DRAGONFIRE_ARROWS);
this.addConflict(EnchantRegister.ELECTRIFIED_ARROWS);
this.addConflict(Enchantment.ARROW_FIRE); this.addConflict(Enchantment.ARROW_FIRE);
this.addConflict(Enchantment.ARROW_KNOCKBACK); this.addConflict(Enchantment.ARROW_KNOCKBACK);
} }

View File

@ -0,0 +1,17 @@
package su.nightexpress.excellentenchants.manager.enchants.bow;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JYML;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowPotionTemplate;
public class EnchantHover extends IEnchantBowPotionTemplate {
public static final String ID = "hover";
public EnchantHover(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM, PotionEffectType.LEVITATION);
}
}

View File

@ -6,6 +6,7 @@ import su.nexmedia.engine.api.config.JYML;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority; import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowPotionTemplate; import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowPotionTemplate;
import su.nightexpress.excellentenchants.manager.EnchantRegister;
public class EnchantPoisonedArrows extends IEnchantBowPotionTemplate { public class EnchantPoisonedArrows extends IEnchantBowPotionTemplate {
@ -14,4 +15,14 @@ public class EnchantPoisonedArrows extends IEnchantBowPotionTemplate {
public EnchantPoisonedArrows(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) { public EnchantPoisonedArrows(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM, PotionEffectType.POISON); super(plugin, cfg, EnchantPriority.MEDIUM, PotionEffectType.POISON);
} }
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(EnchantRegister.CONFUSING_ARROWS);
this.addConflict(EnchantRegister.ELECTRIFIED_ARROWS);
this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS);
this.addConflict(EnchantRegister.WITHERED_ARROWS);
this.addConflict(EnchantRegister.DRAGONFIRE_ARROWS);
}
} }

View File

@ -6,6 +6,7 @@ import su.nexmedia.engine.api.config.JYML;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority; import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowPotionTemplate; import su.nightexpress.excellentenchants.api.enchantment.IEnchantBowPotionTemplate;
import su.nightexpress.excellentenchants.manager.EnchantRegister;
public class EnchantWitheredArrows extends IEnchantBowPotionTemplate { public class EnchantWitheredArrows extends IEnchantBowPotionTemplate {
@ -14,4 +15,14 @@ public class EnchantWitheredArrows extends IEnchantBowPotionTemplate {
public EnchantWitheredArrows(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) { public EnchantWitheredArrows(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM, PotionEffectType.WITHER); super(plugin, cfg, EnchantPriority.MEDIUM, PotionEffectType.WITHER);
} }
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(EnchantRegister.CONFUSING_ARROWS);
this.addConflict(EnchantRegister.POISONED_ARROWS);
this.addConflict(EnchantRegister.EXPLOSIVE_ARROWS);
this.addConflict(EnchantRegister.ELECTRIFIED_ARROWS);
this.addConflict(EnchantRegister.DRAGONFIRE_ARROWS);
}
} }

View File

@ -22,7 +22,7 @@ public class EnchantCurseOfMisfortune extends IEnchantChanceTemplate implements
public static final String ID = "curse_of_misfortune"; public static final String ID = "curse_of_misfortune";
public EnchantCurseOfMisfortune(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) { public EnchantCurseOfMisfortune(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.LOW); super(plugin, cfg, EnchantPriority.LOWEST);
this.dropExp = cfg.getBoolean("Settings.Drop_Exp"); this.dropExp = cfg.getBoolean("Settings.Drop_Exp");
} }
@ -58,7 +58,6 @@ public class EnchantCurseOfMisfortune extends IEnchantChanceTemplate implements
@Override @Override
public boolean use(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) { public boolean use(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) {
if (!this.isEnchantmentAvailable(player)) return false; if (!this.isEnchantmentAvailable(player)) return false;
if (EnchantTelekinesis.isDropHandled(e.getBlock())) return false;
if (!this.checkTriggerChance(level)) return false; if (!this.checkTriggerChance(level)) return false;
if (!this.takeCostItem(player)) return false; if (!this.takeCostItem(player)) return false;

View File

@ -3,23 +3,26 @@ package su.nightexpress.excellentenchants.manager.enchants.tool;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner; import org.bukkit.block.CreatureSpawner;
import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta; import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JYML; import su.nexmedia.engine.api.config.JYML;
import su.nexmedia.engine.utils.EffectUtil; import su.nexmedia.engine.utils.EffectUtil;
import su.nexmedia.engine.utils.LocationUtil; import su.nexmedia.engine.utils.LocationUtil;
import su.nexmedia.engine.utils.StringUtil; import su.nexmedia.engine.utils.StringUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantDropContainer;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority; import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate; import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant; import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant;
@ -27,17 +30,15 @@ import su.nightexpress.excellentenchants.api.enchantment.type.CustomDropEnchant;
import su.nightexpress.excellentenchants.manager.EnchantRegister; import su.nightexpress.excellentenchants.manager.EnchantRegister;
import su.nightexpress.excellentenchants.manager.type.FitItemType; import su.nightexpress.excellentenchants.manager.type.FitItemType;
import java.util.Collections;
import java.util.List;
public class EnchantDivineTouch extends IEnchantChanceTemplate implements BlockBreakEnchant, CustomDropEnchant { public class EnchantDivineTouch extends IEnchantChanceTemplate implements BlockBreakEnchant, CustomDropEnchant {
public static final String ID = "divine_touch";
private static final String META_HANDLE = ID + "_handle";
private final String particleName; private final String particleName;
private final String particleData; private final String particleData;
private final String spawnerName; private final String spawnerName;
public static final String ID = "divine_touch";
public EnchantDivineTouch(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) { public EnchantDivineTouch(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM); super(plugin, cfg, EnchantPriority.MEDIUM);
@ -46,12 +47,6 @@ public class EnchantDivineTouch extends IEnchantChanceTemplate implements BlockB
this.spawnerName = StringUtil.color(cfg.getString("Settings.Spawner_Item.Name", "&aMob Spawner &7(%type%)")); this.spawnerName = StringUtil.color(cfg.getString("Settings.Spawner_Item.Name", "&aMob Spawner &7(%type%)"));
} }
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(EnchantRegister.SMELTER);
}
@Override @Override
protected void updateConfig() { protected void updateConfig() {
super.updateConfig(); super.updateConfig();
@ -67,6 +62,12 @@ public class EnchantDivineTouch extends IEnchantChanceTemplate implements BlockB
return new FitItemType[]{FitItemType.PICKAXE}; return new FitItemType[]{FitItemType.PICKAXE};
} }
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(EnchantRegister.SMELTER);
}
@Override @Override
@NotNull @NotNull
public EnchantmentTarget getItemTarget() { public EnchantmentTarget getItemTarget() {
@ -90,36 +91,31 @@ public class EnchantDivineTouch extends IEnchantChanceTemplate implements BlockB
} }
@Override @Override
@NotNull public void handleDrop(@NotNull EnchantDropContainer e, @NotNull Player player, @NotNull ItemStack item, int level) {
public List<ItemStack> getCustomDrops(@NotNull Player player, @NotNull ItemStack item, @NotNull Block block, int level) { BlockDropItemEvent parent = e.getParent();
if (!(block.getState() instanceof CreatureSpawner spawnerBlock)) return Collections.emptyList(); BlockState state = parent.getBlockState();
Block block = state.getBlock();
if (!block.hasMetadata(META_HANDLE)) return;
if (!(state instanceof CreatureSpawner spawnerBlock)) return;
return Collections.singletonList(this.getSpawner(spawnerBlock)); e.getDrop().add(this.getSpawner(spawnerBlock));
}
@Override Location location = LocationUtil.getCenter(block.getLocation());
public boolean isEventMustHaveDrops() { EffectUtil.playEffect(location, this.particleName, this.particleData, 0.3f, 0.3f, 0.3f, 0.15f, 30);
return false; block.removeMetadata(META_HANDLE, this.plugin);
} }
@Override @Override
public boolean use(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) { public boolean use(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) {
if (!this.isEnchantmentAvailable(player)) return false;
Block block = e.getBlock(); Block block = e.getBlock();
if (EnchantTelekinesis.isDropHandled(block)) return false; if (!this.isEnchantmentAvailable(player)) return false;
if (!(block.getState() instanceof CreatureSpawner spawnerBlock)) return false; if (!(block.getState() instanceof CreatureSpawner spawnerBlock)) return false;
if (this.isEventMustHaveDrops() && !e.isDropItems()) return false;
if (!this.checkTriggerChance(level)) return false; if (!this.checkTriggerChance(level)) return false;
if (!this.takeCostItem(player)) return false; if (!this.takeCostItem(player)) return false;
Location location = LocationUtil.getCenter(block.getLocation());
World world = block.getWorld();
this.getCustomDrops(player, item, block, level).forEach(itemSpawner -> world.dropItemNaturally(location, itemSpawner));
EffectUtil.playEffect(location, this.particleName, this.particleData, 0.3f, 0.3f, 0.3f, 0.15f, 30);
e.setExpToDrop(0); e.setExpToDrop(0);
e.setDropItems(false); e.setDropItems(true);
block.setMetadata(META_HANDLE, new FixedMetadataValue(this.plugin, true));
return true; return true;
} }
@ -130,16 +126,8 @@ public class EnchantDivineTouch extends IEnchantChanceTemplate implements BlockB
if (block.getType() != Material.SPAWNER) return; if (block.getType() != Material.SPAWNER) return;
Player player = e.getPlayer(); Player player = e.getPlayer();
ItemStack spawner = player.getInventory().getItemInMainHand(); ItemStack spawner = player.getInventory().getItem(e.getHand());
if (spawner.getType().isAir() || spawner.getType() != Material.SPAWNER) { if (spawner.getType() != Material.SPAWNER || !(spawner.getItemMeta() instanceof BlockStateMeta meta)) return;
spawner = player.getInventory().getItemInOffHand();
}
if (spawner.getType().isAir() || spawner.getType() != Material.SPAWNER) {
return;
}
BlockStateMeta meta = (BlockStateMeta) spawner.getItemMeta();
if (meta == null) return;
CreatureSpawner spawnerItem = (CreatureSpawner) meta.getBlockState(); CreatureSpawner spawnerItem = (CreatureSpawner) meta.getBlockState();
CreatureSpawner spawnerBlock = (CreatureSpawner) block.getState(); CreatureSpawner spawnerBlock = (CreatureSpawner) block.getState();

View File

@ -6,10 +6,11 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.event.inventory.InventoryPickupItemEvent;
@ -23,18 +24,16 @@ import su.nexmedia.engine.utils.ItemUtil;
import su.nexmedia.engine.utils.PDCUtil; import su.nexmedia.engine.utils.PDCUtil;
import su.nexmedia.engine.utils.StringUtil; import su.nexmedia.engine.utils.StringUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantDropContainer;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority; import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate; import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant;
import su.nightexpress.excellentenchants.api.enchantment.type.CustomDropEnchant; import su.nightexpress.excellentenchants.api.enchantment.type.CustomDropEnchant;
import su.nightexpress.excellentenchants.manager.type.FitItemType; import su.nightexpress.excellentenchants.manager.type.FitItemType;
import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
public class EnchantSilkChest extends IEnchantChanceTemplate implements BlockBreakEnchant, CustomDropEnchant { public class EnchantSilkChest extends IEnchantChanceTemplate implements CustomDropEnchant {
private final Map<Integer, NamespacedKey> keyItems; private final Map<Integer, NamespacedKey> keyItems;
private final String chestName; private final String chestName;
@ -42,7 +41,7 @@ public class EnchantSilkChest extends IEnchantChanceTemplate implements BlockBre
public static final String ID = "silk_chest"; public static final String ID = "silk_chest";
public EnchantSilkChest(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) { public EnchantSilkChest(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM); super(plugin, cfg, EnchantPriority.HIGH);
this.keyItems = new TreeMap<>(); this.keyItems = new TreeMap<>();
this.chestName = StringUtil.color(cfg.getString("Settings.Chest_Item.Name", "%name% &7(%items% items)")); this.chestName = StringUtil.color(cfg.getString("Settings.Chest_Item.Name", "%name% &7(%items% items)"));
@ -78,8 +77,7 @@ public class EnchantSilkChest extends IEnchantChanceTemplate implements BlockBre
@NotNull @NotNull
public ItemStack getSilkChest(@NotNull Chest chest) { public ItemStack getSilkChest(@NotNull Chest chest) {
Block block = chest.getBlock(); ItemStack chestItem = new ItemStack(chest.getType());
ItemStack chestItem = new ItemStack(block.getType());
// Store and count chest items. // Store and count chest items.
int amount = 0; int amount = 0;
@ -91,7 +89,7 @@ public class EnchantSilkChest extends IEnchantChanceTemplate implements BlockBre
String base64 = ItemUtil.toBase64(itemInv); String base64 = ItemUtil.toBase64(itemInv);
if (base64 == null) continue; if (base64 == null) continue;
if (base64.length() >= Short.MAX_VALUE) { if (base64.length() >= Short.MAX_VALUE) {
block.getWorld().dropItemNaturally(block.getLocation(), itemInv); chest.getWorld().dropItemNaturally(chest.getLocation(), itemInv);
continue; continue;
} }
PDCUtil.setData(chestItem, this.getItemKey(count++), base64); PDCUtil.setData(chestItem, this.getItemKey(count++), base64);
@ -110,38 +108,26 @@ public class EnchantSilkChest extends IEnchantChanceTemplate implements BlockBre
} }
@Override @Override
@NotNull public void handleDrop(@NotNull EnchantDropContainer e, @NotNull Player player, @NotNull ItemStack item, int level) {
public List<ItemStack> getCustomDrops(@NotNull Player player, @NotNull ItemStack item, @NotNull Block block, int level) { BlockDropItemEvent parent = e.getParent();
if (block.getType() == Material.ENDER_CHEST) return Collections.emptyList(); BlockState state = parent.getBlockState();
if (!(block.getState() instanceof Chest chest)) return Collections.emptyList(); Block block = state.getBlock();
return Collections.singletonList(this.getSilkChest(chest)); if (!this.isEnchantmentAvailable(player)) return;
} if (!(state instanceof Chest chest)) return;
if (!this.checkTriggerChance(level)) return;
if (!this.takeCostItem(player)) return;
@Override // Добавляем в сундук обратно предметы из дроп листа, кроме самого сундука.
public boolean isEventMustHaveDrops() { parent.getItems().removeIf(drop -> drop.getItemStack().getType() == state.getType());
return true; chest.getBlockInventory().addItem(parent.getItems().stream().map(Item::getItemStack).toList().toArray(new ItemStack[0]));
}
@Override // Добавляем кастомный сундук в кастомный дроп лист.
public boolean use(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) { e.getDrop().add(this.getSilkChest(chest));
Block block = e.getBlock();
if (!this.isEnchantmentAvailable(player)) return false;
if (EnchantTelekinesis.isDropHandled(block)) return false;
if (block.getType() == Material.ENDER_CHEST) return false;
if (this.isEventMustHaveDrops() && !e.isDropItems()) return false;
if (!this.checkTriggerChance(level)) return false;
if (!(block.getState() instanceof Chest chest)) return false;
if (!this.takeCostItem(player)) return false;
// Drop custom chest and do not drop the original one. // Очищаем инвентарь сундука и дефолтный дроп лист.
this.getCustomDrops(player, item, block, level).forEach(chestItem -> block.getWorld().dropItemNaturally(block.getLocation(), chestItem));
// Do not drop chest items.
chest.getBlockInventory().clear(); chest.getBlockInventory().clear();
e.setDropItems(false); parent.getItems().clear();
return true;
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)

View File

@ -2,11 +2,10 @@ package su.nightexpress.excellentenchants.manager.enchants.tool;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Container;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JYML; import su.nexmedia.engine.api.config.JYML;
@ -16,29 +15,26 @@ import su.nexmedia.engine.utils.MessageUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority; import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate; import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant; import su.nightexpress.excellentenchants.api.enchantment.type.BlockDropEnchant;
import su.nightexpress.excellentenchants.api.enchantment.type.CustomDropEnchant;
import su.nightexpress.excellentenchants.manager.EnchantRegister; import su.nightexpress.excellentenchants.manager.EnchantRegister;
import su.nightexpress.excellentenchants.manager.type.FitItemType; import su.nightexpress.excellentenchants.manager.type.FitItemType;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public class EnchantSmelter extends IEnchantChanceTemplate implements BlockBreakEnchant, CustomDropEnchant { public class EnchantSmelter extends IEnchantChanceTemplate implements BlockDropEnchant {
private final String sound; public static final String ID = "smelter";
private final Sound sound;
private final String particleName; private final String particleName;
private final String particleData; private final String particleData;
private final Map<Material, Material> smeltingTable; private final Map<Material, Material> smeltingTable;
public static final String ID = "smelter";
public EnchantSmelter(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) { public EnchantSmelter(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM); super(plugin, cfg, EnchantPriority.MEDIUM);
this.sound = cfg.getString("Settings.Sound", ""); this.sound = cfg.getEnum("Settings.Sound", Sound.class);
this.particleName = cfg.getString("Settings.Particle.Name", Particle.FLAME.name()); this.particleName = cfg.getString("Settings.Particle.Name", Particle.FLAME.name());
this.particleData = cfg.getString("Settings.Particle.Data", ""); this.particleData = cfg.getString("Settings.Particle.Data", "");
this.smeltingTable = new HashMap<>(); this.smeltingTable = new HashMap<>();
@ -58,13 +54,6 @@ public class EnchantSmelter extends IEnchantChanceTemplate implements BlockBreak
} }
} }
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(Enchantment.SILK_TOUCH);
this.addConflict(EnchantRegister.DIVINE_TOUCH);
}
@Override @Override
protected void updateConfig() { protected void updateConfig() {
super.updateConfig(); super.updateConfig();
@ -81,6 +70,13 @@ public class EnchantSmelter extends IEnchantChanceTemplate implements BlockBreak
return new FitItemType[]{FitItemType.PICKAXE, FitItemType.AXE, FitItemType.SHOVEL}; return new FitItemType[]{FitItemType.PICKAXE, FitItemType.AXE, FitItemType.SHOVEL};
} }
@Override
protected void addConflicts() {
super.addConflicts();
this.addConflict(Enchantment.SILK_TOUCH);
this.addConflict(EnchantRegister.DIVINE_TOUCH);
}
@Override @Override
@NotNull @NotNull
public EnchantmentTarget getItemTarget() { public EnchantmentTarget getItemTarget() {
@ -88,57 +84,30 @@ public class EnchantSmelter extends IEnchantChanceTemplate implements BlockBreak
} }
@Override @Override
@NotNull public boolean use(@NotNull BlockDropItemEvent e, @NotNull Player player, @NotNull ItemStack item, int level) {
public List<ItemStack> getCustomDrops(@NotNull Player player, @NotNull ItemStack item, @NotNull Block block, int level) { if (!this.isEnchantmentAvailable(player)) return false;
if (block.getState() instanceof Container) return Collections.emptyList(); if (!this.checkTriggerChance(level)) return false;
if (e.getItems().stream().noneMatch(drop -> this.isSmeltable(drop.getItemStack().getType()))) return false;
if (!this.takeCostItem(player)) return false;
List<ItemStack> drops = plugin.getNMS().getBlockDrops(block, player, item); e.getItems().forEach(drop -> {
return this.smelt(drops); Material material = this.smeltingTable.get(drop.getItemStack().getType());
if (material != null) drop.getItemStack().setType(material);
});
Block block = e.getBlockState().getBlock();
this.playEffect(block);
return true;
} }
public boolean isSmeltable(@NotNull Material material) { public boolean isSmeltable(@NotNull Material material) {
return this.smeltingTable.containsKey(material); return this.smeltingTable.containsKey(material);
} }
@NotNull @Deprecated
public List<ItemStack> smelt(@NotNull List<ItemStack> drops) {
return drops.stream().peek(drop -> {
Material material = this.smeltingTable.get(drop.getType());
if (material != null) drop.setType(material);
}).toList();
}
public void playEffect(@NotNull Block block) { public void playEffect(@NotNull Block block) {
Location location = LocationUtil.getCenter(block.getLocation(), true); Location location = LocationUtil.getCenter(block.getLocation(), true);
MessageUtil.sound(location, this.sound); MessageUtil.sound(location, this.sound);
EffectUtil.playEffect(location, this.particleName, this.particleData, 0.2f, 0.2f, 0.2f, 0.05f, 30); EffectUtil.playEffect(location, this.particleName, this.particleData, 0.2f, 0.2f, 0.2f, 0.05f, 30);
} }
@Override
public boolean isEventMustHaveDrops() {
return true;
}
@Override
public boolean use(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) {
Block block = e.getBlock();
if (!this.isEnchantmentAvailable(player)) return false;
if (EnchantTelekinesis.isDropHandled(block)) return false;
if (this.isEventMustHaveDrops() && !e.isDropItems()) return false;
if (!this.checkTriggerChance(level)) return false;
List<ItemStack> defaults = plugin.getNMS().getBlockDrops(block, player, item);
List<ItemStack> custom = this.getCustomDrops(player, item, block, level);
if (custom.isEmpty() || custom.containsAll(defaults)) return false;
if (!this.takeCostItem(player)) return false;
e.setDropItems(false);
World world = block.getWorld();
Location location = LocationUtil.getCenter(block.getLocation(), true);
custom.forEach(itemSmelt -> world.dropItem(location, itemSmelt));
this.playEffect(block);
return true;
}
} }

View File

@ -1,15 +1,11 @@
package su.nightexpress.excellentenchants.manager.enchants.tool; package su.nightexpress.excellentenchants.manager.enchants.tool;
import com.google.common.collect.Sets;
import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.block.Container;
import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JYML; import su.nexmedia.engine.api.config.JYML;
import su.nexmedia.engine.api.config.LangMessage; import su.nexmedia.engine.api.config.LangMessage;
@ -17,35 +13,27 @@ import su.nexmedia.engine.utils.ItemUtil;
import su.nexmedia.engine.utils.PlayerUtil; import su.nexmedia.engine.utils.PlayerUtil;
import su.nexmedia.engine.utils.StringUtil; import su.nexmedia.engine.utils.StringUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantDropContainer;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority; import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate; import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant;
import su.nightexpress.excellentenchants.api.enchantment.type.CustomDropEnchant; import su.nightexpress.excellentenchants.api.enchantment.type.CustomDropEnchant;
import su.nightexpress.excellentenchants.manager.EnchantManager;
import su.nightexpress.excellentenchants.manager.EnchantRegister;
import su.nightexpress.excellentenchants.manager.type.FitItemType; import su.nightexpress.excellentenchants.manager.type.FitItemType;
import java.util.*; import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
public class EnchantTelekinesis extends IEnchantChanceTemplate implements BlockBreakEnchant { public class EnchantTelekinesis extends IEnchantChanceTemplate implements CustomDropEnchant {
public static final String META_BLOCK_DROP_HANDLER = "telekinesis_drop_handler";
private final LangMessage messageDropReceived; private final LangMessage messageDropReceived;
private final String messageItemName; private final String messageItemName;
private final String messageItemSeparator; private final String messageItemSeparator;
public static final String ID = "telekinesis"; public static final String ID = "telekinesis";
private static final Set<Material> INFESTED = Sets.newHashSet(
Material.INFESTED_CHISELED_STONE_BRICKS, Material.INFESTED_COBBLESTONE,
Material.INFESTED_CRACKED_STONE_BRICKS, Material.INFESTED_DEEPSLATE,
Material.INFESTED_MOSSY_STONE_BRICKS, Material.INFESTED_STONE,
Material.INFESTED_STONE_BRICKS
);
public EnchantTelekinesis(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) { public EnchantTelekinesis(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.HIGHEST); super(plugin, cfg, EnchantPriority.LOWEST);
this.messageDropReceived = new LangMessage(plugin.lang(), cfg.getString("Settings.Message.Drop_Received", "")); this.messageDropReceived = new LangMessage(plugin.lang(), cfg.getString("Settings.Message.Drop_Received", ""));
this.messageItemName = StringUtil.color(cfg.getString("Settings.Message.Item_Name", "&7x%item_amount% &f%item_name%")); this.messageItemName = StringUtil.color(cfg.getString("Settings.Message.Item_Name", "&7x%item_amount% &f%item_name%"));
@ -64,10 +52,6 @@ public class EnchantTelekinesis extends IEnchantChanceTemplate implements BlockB
cfg.addMissing("Settings.Message.Item_Separator", "&7, "); cfg.addMissing("Settings.Message.Item_Separator", "&7, ");
} }
public static boolean isDropHandled(@NotNull Block block) {
return block.hasMetadata(META_BLOCK_DROP_HANDLER);
}
@Override @Override
@NotNull @NotNull
public UnaryOperator<String> replacePlaceholders(int level) { public UnaryOperator<String> replacePlaceholders(int level) {
@ -87,54 +71,17 @@ public class EnchantTelekinesis extends IEnchantChanceTemplate implements BlockB
} }
@Override @Override
public boolean use(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) { public void handleDrop(@NotNull EnchantDropContainer e, @NotNull Player player, @NotNull ItemStack item, int level) {
if (!this.isEnchantmentAvailable(player)) return false; BlockDropItemEvent parent = e.getParent();
if (e.getBlock().getState() instanceof Container) return false; Block block = parent.getBlockState().getBlock();
if (INFESTED.contains(e.getBlock().getType())) return false;
if (!e.isDropItems()) return false;
if (!this.checkTriggerChance(level)) return false;
EnchantCurseOfMisfortune curseOfMisfortune = EnchantRegister.CURSE_OF_MISFORTUNE; if (!this.isEnchantmentAvailable(player)) return;
if (curseOfMisfortune != null && item.containsEnchantment(curseOfMisfortune)) { //if (block.getState() instanceof Container) return;
if (curseOfMisfortune.use(e, player, item, level)) { if (!this.checkTriggerChance(level)) return;
return false;
}
}
Block block = e.getBlock(); List<ItemStack> drops = new ArrayList<>();
List<ItemStack> drops = new ArrayList<>(plugin.getNMS().getBlockDrops(block, player, item)); drops.addAll(parent.getItems().stream().map(Item::getItemStack).toList());
drops.addAll(e.getDrop());
// Check inventory space.
if (drops.stream().anyMatch(itemDrop -> PlayerUtil.countItemSpace(player, itemDrop) == 0)) return false;
// Tell other enchantments that block drops are handled by Telekinesis.
block.setMetadata(META_BLOCK_DROP_HANDLER, new FixedMetadataValue(plugin, true));
for (Map.Entry<CustomDropEnchant, Integer> entry : EnchantManager.getItemCustomEnchants(item, CustomDropEnchant.class).entrySet()) {
CustomDropEnchant dropEnchant = entry.getKey();
int dropLevel = entry.getValue();
if (dropEnchant.isEventMustHaveDrops() && !e.isDropItems()) continue;
if (dropEnchant instanceof IEnchantChanceTemplate chanceEnchant) {
if (!chanceEnchant.checkTriggerChance(dropLevel)) continue;
}
if (dropEnchant instanceof EnchantSilkChest && block.getState() instanceof Chest) {
drops.removeIf(drop -> drop.getType() == block.getType());
}
if (dropEnchant instanceof EnchantSmelter smelter) {
boolean isSmelted = drops.stream().anyMatch(drop -> smelter.isSmeltable(drop.getType()));
smelter.smelt(drops);
if (isSmelted) smelter.playEffect(block);
continue; // Do not add smelted items twice, only replace current ones.
}
if (dropEnchant instanceof EnchantTreasures treasures) {
if (treasures.getTreasure(block) != null) {
treasures.playEffect(block);
}
}
drops.addAll(dropEnchant.getCustomDrops(player, item, block, dropLevel));
}
drops.removeIf(Objects::isNull); drops.removeIf(Objects::isNull);
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
@ -148,10 +95,7 @@ public class EnchantTelekinesis extends IEnchantChanceTemplate implements BlockB
}); });
this.messageDropReceived.replace("%items%", builder.toString()).send(player); this.messageDropReceived.replace("%items%", builder.toString()).send(player);
e.setDropItems(false); e.getDrop().clear();
plugin.getServer().getScheduler().runTask(plugin, c -> { parent.getItems().clear();
block.removeMetadata(META_BLOCK_DROP_HANDLER, plugin);
});
return true;
} }
} }

View File

@ -7,43 +7,40 @@ import org.bukkit.Sound;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import su.nexmedia.engine.NexEngine;
import su.nexmedia.engine.api.config.JYML; import su.nexmedia.engine.api.config.JYML;
import su.nexmedia.engine.api.manager.ICleanable; import su.nexmedia.engine.api.manager.ICleanable;
import su.nexmedia.engine.manager.player.listener.PlayerBlockPlacedListener; import su.nexmedia.engine.manager.player.PlayerBlockTracker;
import su.nexmedia.engine.utils.EffectUtil; import su.nexmedia.engine.utils.EffectUtil;
import su.nexmedia.engine.utils.LocationUtil; import su.nexmedia.engine.utils.LocationUtil;
import su.nexmedia.engine.utils.MessageUtil; import su.nexmedia.engine.utils.MessageUtil;
import su.nexmedia.engine.utils.random.Rnd; import su.nexmedia.engine.utils.random.Rnd;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantDropContainer;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority; import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate; import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant;
import su.nightexpress.excellentenchants.api.enchantment.type.CustomDropEnchant; import su.nightexpress.excellentenchants.api.enchantment.type.CustomDropEnchant;
import su.nightexpress.excellentenchants.manager.type.FitItemType; import su.nightexpress.excellentenchants.manager.type.FitItemType;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Predicate; import java.util.function.Predicate;
public class EnchantTreasures extends IEnchantChanceTemplate implements BlockBreakEnchant, CustomDropEnchant, ICleanable { public class EnchantTreasures extends IEnchantChanceTemplate implements CustomDropEnchant, ICleanable {
private final String particleName; private final String particleName;
private final String particleData; private final String particleData;
private final String sound; private final String sound;
private final Map<Material, Map<Material, Double>> treasures; private final Map<Material, Map<Material, Double>> treasures;
private final Predicate<Block> userBlockFilter; private final Predicate<Block> blockTracker;
public static final String ID = "treasures"; public static final String ID = "treasures";
public EnchantTreasures(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) { public EnchantTreasures(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.LOWEST); super(plugin, cfg, EnchantPriority.MEDIUM);
this.particleName = cfg.getString("Settings.Particle.Name", Particle.REDSTONE.name()); this.particleName = cfg.getString("Settings.Particle.Name", Particle.REDSTONE.name());
this.particleData = cfg.getString("Settings.Particle.Data", "200,180,0"); this.particleData = cfg.getString("Settings.Particle.Data", "200,180,0");
@ -72,15 +69,15 @@ public class EnchantTreasures extends IEnchantChanceTemplate implements BlockBre
} }
} }
NexEngine.get().getPlayerManager().enableUserBlockListening(); PlayerBlockTracker.initialize();
PlayerBlockPlacedListener.BLOCK_FILTERS.add(this.userBlockFilter = (block) -> { PlayerBlockTracker.BLOCK_FILTERS.add(this.blockTracker = (block) -> {
return this.getTreasure(block) != null; return this.getTreasure(block.getType()) != null;
}); });
} }
@Override @Override
public void clear() { public void clear() {
PlayerBlockPlacedListener.BLOCK_FILTERS.remove(this.userBlockFilter); PlayerBlockTracker.BLOCK_FILTERS.remove(this.blockTracker);
} }
@Override @Override
@ -105,50 +102,34 @@ public class EnchantTreasures extends IEnchantChanceTemplate implements BlockBre
} }
@Override @Override
@NotNull public void handleDrop(@NotNull EnchantDropContainer e, @NotNull Player player, @NotNull ItemStack item, int level) {
public List<ItemStack> getCustomDrops(@NotNull Player player, @NotNull ItemStack item, @NotNull Block block, int level) { BlockDropItemEvent parent = e.getParent();
ItemStack drop = this.getTreasure(block); Block block = parent.getBlockState().getBlock();
if (PlayerBlockPlacedListener.isUserPlaced(block) || drop == null) return Collections.emptyList(); if (!this.isEnchantmentAvailable(player)) return;
return Collections.singletonList(drop); if (PlayerBlockTracker.isTracked(block)) return;
} if (!this.checkTriggerChance(level)) return;
if (!this.takeCostItem(player)) return;
@Override ItemStack treasure = this.getTreasure(parent.getBlockState().getType());
public boolean isEventMustHaveDrops() { if (treasure == null) return;
return false;
e.getDrop().add(treasure);
this.playEffect(block);
} }
@Nullable @Nullable
public final ItemStack getTreasure(@NotNull Block block) { public final ItemStack getTreasure(@NotNull Material type) {
Map<Material, Double> treasures = this.treasures.get(block.getType()); Map<Material, Double> treasures = this.treasures.get(type);
if (treasures == null) return null; if (treasures == null) return null;
Material mat = Rnd.get(treasures); Material mat = Rnd.get(treasures);
return mat != null && !mat.isAir() ? new ItemStack(mat) : null; return mat != null && !mat.isAir() ? new ItemStack(mat) : null;
} }
@Deprecated
public void playEffect(@NotNull Block block) { public void playEffect(@NotNull Block block) {
Location location = LocationUtil.getCenter(block.getLocation()); Location location = LocationUtil.getCenter(block.getLocation());
MessageUtil.sound(location, this.sound); MessageUtil.sound(location, this.sound);
EffectUtil.playEffect(location, this.particleName, this.particleData, 0.2f, 0.2f, 0.2f, 0.12f, 20); EffectUtil.playEffect(location, this.particleName, this.particleData, 0.2f, 0.2f, 0.2f, 0.12f, 20);
} }
@Override
public boolean use(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) {
Block block = e.getBlock();
if (!this.isEnchantmentAvailable(player)) return false;
if (EnchantTelekinesis.isDropHandled(block)) return false;
if (this.isEventMustHaveDrops() && !e.isDropItems()) return false;
if (PlayerBlockPlacedListener.isUserPlaced(block)) return false;
if (!this.checkTriggerChance(level)) return false;
if (!this.takeCostItem(player)) return false;
Location location = LocationUtil.getCenter(block.getLocation());
List<ItemStack> drops = this.getCustomDrops(player, item, block, level);
if (drops.isEmpty()) return false;
drops.forEach(itemDrop -> block.getWorld().dropItem(location, itemDrop));
this.playEffect(block);
return true;
}
} }

View File

@ -0,0 +1,90 @@
package su.nightexpress.excellentenchants.manager.enchants.weapon;
import org.bukkit.attribute.Attribute;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JYML;
import su.nexmedia.engine.utils.EntityUtil;
import su.nexmedia.engine.utils.NumberUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.EnchantPriority;
import su.nightexpress.excellentenchants.api.enchantment.IEnchantChanceTemplate;
import su.nightexpress.excellentenchants.api.enchantment.type.CombatEnchant;
import su.nightexpress.excellentenchants.manager.object.EnchantScaler;
import java.util.function.UnaryOperator;
public class EnchantTemper extends IEnchantChanceTemplate implements CombatEnchant {
public static final String ID = "temper";
public static final String PLACEHOLDER_DAMAGE_AMOUNT = "%enchantment_damage_amount%";
public static final String PLACEHOLDER_DAMAGE_CAPACITY = "%enchantment_damage_capacity%";
public static final String PLACEHOLDER_HEALTH_POINT = "%enchantment_health_point%";
private final EnchantScaler damageAmount;
private final EnchantScaler damageCapacity;
private final EnchantScaler healthPoint;
public EnchantTemper(@NotNull ExcellentEnchants plugin, @NotNull JYML cfg) {
super(plugin, cfg, EnchantPriority.MEDIUM);
this.damageAmount = new EnchantScaler(this, "Settings.Damage.Amount");
this.damageCapacity = new EnchantScaler(this, "Settings.Damage.Capacity");
this.healthPoint = new EnchantScaler(this, "Settings.Health.Point");
}
public double getDamageAmount(int level) {
return this.damageAmount.getValue(level);
}
public double getDamageCapacity(int level) {
return this.damageCapacity.getValue(level);
}
public double getHealthPoint(int level) {
return this.healthPoint.getValue(level);
}
@Override
@NotNull
public UnaryOperator<String> replacePlaceholders(int level) {
return str -> super.replacePlaceholders(level).apply(str
.replace(PLACEHOLDER_DAMAGE_AMOUNT, NumberUtil.format(this.getDamageAmount(level) * 100D))
.replace(PLACEHOLDER_DAMAGE_CAPACITY, NumberUtil.format(this.getDamageCapacity(level) * 100D))
.replace(PLACEHOLDER_HEALTH_POINT, NumberUtil.format(this.getHealthPoint(level)))
);
}
@NotNull
@Override
public EnchantmentTarget getItemTarget() {
return EnchantmentTarget.WEAPON;
}
@Override
public boolean use(@NotNull EntityDamageByEntityEvent e, @NotNull LivingEntity damager, @NotNull LivingEntity victim, @NotNull ItemStack weapon, int level) {
if (!this.isEnchantmentAvailable(damager)) return false;
if (!this.checkTriggerChance(level)) return false;
double healthPoint = this.getHealthPoint(level);
double healthHas = damager.getHealth();
double healthMax = EntityUtil.getAttribute(damager, Attribute.GENERIC_MAX_HEALTH);
double healthDiff = healthMax - healthHas;
if (healthHas >= healthMax || healthDiff < healthPoint) return false;
int pointAmount = (int) (healthDiff / healthPoint);
if (pointAmount == 0) return false;
if (!this.takeCostItem(damager)) return false;
double damageAmount = this.getDamageAmount(level);
double damageCap = this.getDamageCapacity(level);
double damageFinal = Math.min(damageCap, damageAmount * pointAmount);
e.setDamage(e.getDamage() * damageFinal);
return true;
}
}

View File

@ -249,7 +249,7 @@ public class EnchantGenericListener extends AbstractListener<ExcellentEnchants>
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEnchantPopulatePiglinBarter(CreatureSpawnEvent e) { public void onEnchantPopulateSpawn(CreatureSpawnEvent e) {
if (Config.getObtainSettings(ObtainType.MOB_SPAWNING) == null) return; if (Config.getObtainSettings(ObtainType.MOB_SPAWNING) == null) return;
LivingEntity entity = e.getEntity(); LivingEntity entity = e.getEntity();

View File

@ -10,6 +10,7 @@ import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDeathEvent;
@ -23,6 +24,7 @@ import su.nexmedia.engine.api.manager.AbstractListener;
import su.nexmedia.engine.utils.EntityUtil; import su.nexmedia.engine.utils.EntityUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.type.*; import su.nightexpress.excellentenchants.api.enchantment.type.*;
import su.nightexpress.excellentenchants.api.enchantment.EnchantDropContainer;
import su.nightexpress.excellentenchants.manager.EnchantManager; import su.nightexpress.excellentenchants.manager.EnchantManager;
public class EnchantHandlerListener extends AbstractListener<ExcellentEnchants> { public class EnchantHandlerListener extends AbstractListener<ExcellentEnchants> {
@ -192,4 +194,26 @@ public class EnchantHandlerListener extends AbstractListener<ExcellentEnchants>
blockEnchant.use(e, player, tool, level); blockEnchant.use(e, player, tool, level);
}); });
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEnchantBlockDropItem(BlockDropItemEvent e) {
Player player = e.getPlayer();
if (player.getGameMode() == GameMode.CREATIVE) return;
ItemStack tool = player.getInventory().getItemInMainHand();
if (tool.getType().isAir() || tool.getType() == Material.ENCHANTED_BOOK) return;
EnchantManager.getItemCustomEnchants(tool, BlockDropEnchant.class).forEach((blockEnchant, level) -> {
blockEnchant.use(e, player, tool, level);
});
EnchantDropContainer dropContainer = new EnchantDropContainer(e);
EnchantManager.getItemCustomEnchants(tool, CustomDropEnchant.class).forEach((blockEnchant, level) -> {
blockEnchant.handleDrop(dropContainer, player, tool, level);
});
dropContainer.getDrop().forEach(item -> {
e.getBlockState().getBlock().getWorld().dropItem(e.getBlockState().getLocation(), item);
});
}
} }

View File

@ -2,6 +2,7 @@ package su.nightexpress.excellentenchants.manager.object;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -117,7 +118,7 @@ public class EnchantListGUI extends AbstractMenu<ExcellentEnchants> {
} }
@Override @Override
public boolean cancelClick(@NotNull SlotType slotType, int slot) { public boolean cancelClick(@NotNull InventoryClickEvent e, @NotNull SlotType slotType) {
return true; return true;
} }
} }

View File

@ -0,0 +1,32 @@
Is_Treasure: false
Name: Confusing Arrows
Tier: common
Description:
- '%enchantment_trigger_chance%% chance to launch an arrow with %enchantment_potion_type% %enchantment_potion_level% (%enchantment_potion_duration%s.)'
Level:
Min: 1
Max: 3
Anvil:
Merge_Cost: '%enchantment_level%'
Fishing:
Chance: 45.0
Enchanting_Table:
Level_By_Exp_Cost: '9 * %enchantment_level%'
Chance: 60.0
Villagers:
Chance: 75.0
Loot_Generation:
Chance: 60.0
Mob_Spawning:
Chance: 35.0
Settings:
Trigger_Chance: '20.0 + %enchantment_level% * 5.0'
Cost:
Enabled: false
Item:
Material: AIR
Amount: 1
Potion_Effect:
Duration: '6.0 + %enchantment_level% * 3.0'
Level: '%enchantment_level%'

View File

@ -0,0 +1,35 @@
Is_Treasure: false
Name: Dragonfire Arrows
Tier: exotic
Description:
- '%enchantment_trigger_chance%% chance to launch an dragonfire arrow (R=%enchantment_fire_radius%, %enchantment_fire_duration%s).'
Level:
Min: 1
Max: 3
Anvil:
Merge_Cost: '%enchantment_level%'
Fishing:
Chance: 25.0
Enchanting_Table:
Level_By_Exp_Cost: '9 * %enchantment_level%'
Chance: 20.0
Villagers:
Chance: 25.0
Loot_Generation:
Chance: 30.0
Mob_Spawning:
Chance: 5.0
Settings:
Trigger_Chance: '10.0 + %enchantment_level% * 5'
Cost:
Enabled: false
Item:
Material: AIR
Amount: 1
Fire:
Duration: '%enchantment_level% * 100.0'
Radius: '2.0 + %enchantment_level%'
Arrow:
Trail:
Name: 'DRAGON_BREATH'
Data: ''

View File

@ -0,0 +1,33 @@
Is_Treasure: false
Name: Electrified Arrows
Tier: rare
Description:
- '%enchantment_trigger_chance%% chance to launch an electrified arrow.'
Level:
Min: 1
Max: 3
Anvil:
Merge_Cost: '%enchantment_level%'
Fishing:
Chance: 75.0
Enchanting_Table:
Level_By_Exp_Cost: '9 * %enchantment_level%'
Chance: 25.0
Villagers:
Chance: 45.0
Loot_Generation:
Chance: 40.0
Mob_Spawning:
Chance: 10.0
Settings:
Trigger_Chance: '10.0 + %enchantment_level% * 5'
Cost:
Enabled: false
Item:
Material: AIR
Amount: 1
Arrow:
Trail:
Name: 'FIREWORKS_SPARK'
Data: ''

View File

@ -0,0 +1,31 @@
Is_Treasure: false
Name: Hover
Tier: common
Description:
- '%enchantment_trigger_chance%% chance to launch an arrow with %enchantment_potion_type% %enchantment_potion_level% (%enchantment_potion_duration%s.)'
Level:
Min: 1
Max: 3
Anvil:
Merge_Cost: '%enchantment_level%'
Fishing:
Chance: 50.0
Enchanting_Table:
Level_By_Exp_Cost: '9 * %enchantment_level%'
Chance: 30.0
Villagers:
Chance: 40.0
Loot_Generation:
Chance: 40.0
Mob_Spawning:
Chance: 10.0
Settings:
Trigger_Chance: '10.0 + %enchantment_level% * 5'
Cost:
Enabled: false
Item:
Material: AIR
Amount: 1
Potion_Effect:
Duration: '2.5 + %enchantment_level%'
Level: '%enchantment_level%'

View File

@ -0,0 +1,34 @@
Is_Treasure: false
Name: Temper
Tier: rare
Description:
- '%enchantment_trigger_chance%% chance to inflict %enchantment_damage_amount%% (max. %enchantment_damage_capacity%%) more damage for each %enchantment_health_point% hearts missing.'
Level:
Min: 1
Max: 5
Anvil:
Merge_Cost: '%enchantment_level%'
Fishing:
Chance: 25.0
Enchanting_Table:
Level_By_Exp_Cost: '6 * %enchantment_level%'
Chance: 15.0
Villagers:
Chance: 20.0
Loot_Generation:
Chance: 25.0
Mob_Spawning:
Chance: 10.0
Settings:
Trigger_Chance: '100.0'
Cost:
Enabled: false
Item:
Material: AIR
Amount: 1
Damage:
Amount: '0.01 * %enchantment_level%'
Capacity: '2.0'
Health:
Point: '0.5'

View File

@ -0,0 +1,18 @@
Command:
List:
Desc: Lista de todos los encantamientos personalizados.
Enchant:
Usage: <enchant> <level>
Desc: Encanta el item de tu mano.
Done: '&a¡Encantado con éxito!'
Book:
Usage: <player> <enchant> <level>
Desc: Da un libro encantado personalizado.
Done: Se ha dado un libro encantado de &6%enchant%&7 a &6%player%&7.
TierBook:
Usage: <player> <tier> <level>
Desc: Da un libro encantado.
Error: '&c¡Rareza inválida!'
Done: Se ha dado un libro encantado &6%tier%&7 a &6%player%&7.
Error:
NoEnchant: '&cNo hay tal encanto.'

View File

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

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<version>3.1.4</version> <version>3.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -25,7 +25,7 @@
<dependency> <dependency>
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId> <artifactId>NMS</artifactId>
<version>3.1.4</version> <version>3.2.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
<groupId>su.nightexpress.excellentenchants</groupId> <groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>ExcellentEnchants</artifactId> <artifactId>ExcellentEnchants</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.4</version> <version>3.2.0</version>
<modules> <modules>
<module>Core</module> <module>Core</module>
<module>NMS</module> <module>NMS</module>
@ -26,7 +26,7 @@
<dependency> <dependency>
<groupId>su.nexmedia</groupId> <groupId>su.nexmedia</groupId>
<artifactId>NexEngine</artifactId> <artifactId>NexEngine</artifactId>
<version>2.1.1</version> <version>2.1.2</version>
</dependency> </dependency>
</dependencies> </dependencies>