This commit is contained in:
nulli0n 2023-04-12 16:04:42 +06:00
parent 92e28f8239
commit 38af06c3d3
48 changed files with 389 additions and 473 deletions

2
.gitignore vendored
View File

@ -13,3 +13,5 @@
/V1_19_R1/pom.xml.versionsBackup
/V1_19_R2/target/
/V1_19_R2/pom.xml.versionsBackup
/V1_19_R3/target/
/V1_19_R3/pom.xml.versionsBackup

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>3.3.1</version>
<version>3.3.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -55,27 +55,32 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>3.3.1</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_17_R1</artifactId>
<version>3.3.1</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_18_R2</artifactId>
<version>3.3.1</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R1</artifactId>
<version>3.3.1</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R2</artifactId>
<version>3.3.1</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R3</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>fr.neatmonster</groupId>

View File

@ -22,6 +22,7 @@ import su.nightexpress.excellentenchants.nms.v1_17_R1.V1_17_R1;
import su.nightexpress.excellentenchants.nms.v1_18_R2.V1_18_R2;
import su.nightexpress.excellentenchants.nms.v1_19_R1.V1_19_R1;
import su.nightexpress.excellentenchants.nms.v1_19_R2.V1_19_R2;
import su.nightexpress.excellentenchants.nms.v1_19_R3.V1_19_R3;
import su.nightexpress.excellentenchants.tier.TierManager;
public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
@ -72,6 +73,7 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
case V1_18_R2 -> new V1_18_R2();
case V1_19_R1 -> new V1_19_R1();
case V1_19_R2 -> new V1_19_R2();
case V1_19_R3 -> new V1_19_R3();
};
return true;
}

View File

@ -12,10 +12,7 @@ import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.api.config.JYML;
import su.nexmedia.engine.api.manager.IListener;
import su.nexmedia.engine.lang.LangManager;
import su.nexmedia.engine.utils.ItemUtil;
import su.nexmedia.engine.utils.NumberUtil;
import su.nexmedia.engine.utils.Scaler;
import su.nexmedia.engine.utils.StringUtil;
import su.nexmedia.engine.utils.*;
import su.nexmedia.engine.utils.random.Rnd;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.Placeholders;
@ -77,7 +74,8 @@ public abstract class ExcellentEnchant extends Enchantment implements IEnchantme
this.cfg.reload();
this.displayName = JOption.create("Name", StringUtil.capitalizeFully(this.getId().replace("_", " ")),
"Enchantment display name. It will be shown in item lore.").read(cfg);
"Enchantment display name. It will be shown in item lore.")
.mapReader(Colorizer::apply).read(cfg);
this.tier = plugin.getTierManager().getTierById(JOption.create("Tier", Placeholders.DEFAULT,
"Enchantment tier. Must be a valid tier identifier from the 'tiers.yml'.").read(cfg));
@ -88,7 +86,8 @@ public abstract class ExcellentEnchant extends Enchantment implements IEnchantme
this.description = JOption.create("Description", new ArrayList<>(),
"Enchantment description. It will be shown in item lore under enchantment name.",
"You can use 'Enchantment' placeholders: " + Placeholders.URL_PLACEHOLDERS).read(cfg);
"You can use 'Enchantment' placeholders: " + Placeholders.URL_PLACEHOLDERS)
.mapReader(Colorizer::apply).read(cfg);
this.isTreasure = JOption.create("Is_Treasure", false,
"Sets whether this enchantment is a treasure enchantment.",
@ -250,8 +249,8 @@ public abstract class ExcellentEnchant extends Enchantment implements IEnchantme
if (!this.isChargesEnabled() || charges < 0) return this.getNameFormatted(level);
int chargesMax = this.getChargesMax(level);
double percent = (double) charges / (double) chargesMax * 100D;
Map.Entry<Double, String> entry = Config.ENCHANTMENTS_CHARGES_FORMAT.get().floorEntry(percent);
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));

View File

@ -9,11 +9,6 @@ public interface Potioned {
@NotNull Potioned getPotionImplementation();
/*@NotNull
default UnaryOperator<String> replacePlaceholders(int level) {
return this.getPotionImplementation().replacePlaceholders(level);
}*/
default boolean isPermanent() {
return this.getPotionImplementation().isPermanent();
}
@ -34,10 +29,6 @@ public interface Potioned {
return this.getPotionImplementation().createEffect(level);
}
default boolean hasEffect(@NotNull LivingEntity target) {
return this.getPotionImplementation().hasEffect(target);
}
default boolean addEffect(@NotNull LivingEntity target, int level) {
return this.getPotionImplementation().addEffect(target, level);
}

View File

@ -9,6 +9,7 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.command.AbstractCommand;
import su.nexmedia.engine.lang.LangManager;
import su.nexmedia.engine.utils.CollectionsUtil;
import su.nexmedia.engine.utils.PlayerUtil;
import su.nexmedia.engine.utils.StringUtil;
import su.nexmedia.engine.utils.random.Rnd;
@ -49,7 +50,7 @@ public class BookCommand extends AbstractCommand<ExcellentEnchants> {
@NotNull
public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (arg == 1) {
return PlayerUtil.getPlayerNames();
return CollectionsUtil.playerNames(player);
}
if (arg == 2) {
return Arrays.stream(Enchantment.values()).map(e -> e.getKey().getKey()).toList();

View File

@ -6,6 +6,7 @@ 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.utils.CollectionsUtil;
import su.nexmedia.engine.utils.Placeholders;
import su.nexmedia.engine.utils.PlayerUtil;
import su.nexmedia.engine.utils.StringUtil;
@ -48,7 +49,7 @@ public class TierbookCommand extends AbstractCommand<ExcellentEnchants> {
@NotNull
public List<String> getTab(@NotNull Player player, int arg, @NotNull String[] args) {
if (arg == 1) {
return PlayerUtil.getPlayerNames();
return CollectionsUtil.playerNames(player);
}
if (arg == 2) {
return plugin.getTierManager().getTierIds();

View File

@ -21,23 +21,34 @@ public class Config {
public static final JOption<Long> TASKS_ARROW_TRAIL_TICKS_INTERVAL = JOption.create("Tasks.Arrow_Trail.Tick_Interval", 1L,
"Sets how often (in ticks) arrow trail particle effects will be spawned behind the arrow.");
public static final JOption<Long> TASKS_PASSIVE_POTION_EFFECTS_APPLY_INTERVAL = JOption.create("Tasks.Passive_Potion_Effects.Apply_Interval", 150L,
"Sets how often (in ticks) the plugin will apply permanent potion effects from enchanted items to an entity who wear them.",
"This setting does NOT refreshes currently active effects, but only attempts to add them if absent."
public static final JOption<Long> TASKS_PASSIVE_POTION_EFFECTS_APPLY_INTERVAL = JOption.create("Tasks.Passive_Potion_Effects.Apply_Interval", 100L,
"Sets how often (in ticks) the plugin will apply permanent potion effects from enchanted items to an entity who wear them."
);
public static final JOption<Boolean> ENCHANTMENTS_CHARGES_ENABLED = JOption.create("Enchantments.Charges.Enabled", false,
"Enables the enchantment Charges feature.",
Placeholders.URL_WIKI + "Charges-System");
public static final JOption<TreeMap<Double, String>> ENCHANTMENTS_CHARGES_FORMAT = new JOption<TreeMap<Double, String>>("Enchantments.Charges.Format",
(cfg, path, def) -> cfg.getSection(path).stream().collect(Collectors.toMap(k -> StringUtil.getDouble(k, 0), v -> Colorizer.apply(cfg.getString(path + "." + v, "")), (o,n) -> n, TreeMap::new)),
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;
},
() -> {
TreeMap<Double, String> map = new TreeMap<>();
map.put(0D, "#ff9a9a(" + Placeholders.GENERIC_AMOUNT + "⚡)");
map.put(25D, "#ffc39a(" + Placeholders.GENERIC_AMOUNT + "⚡)");
map.put(50D, "#f6ff9a(" + Placeholders.GENERIC_AMOUNT + "⚡)");
map.put(75D, "#bcff9a(" + Placeholders.GENERIC_AMOUNT + "⚡)");
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 + "⚡)");
return map;
},
"Enchantment charges format depends on amount of charges left (in percent).",
@ -76,12 +87,11 @@ public class Config {
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.",
"Note #1: You must have ProtocolLib installed for this feature to work (as well as for enchantments name display).",
"Note #2: Description is not shown while you're in Creative gamemode.");
"For Display-Mode = 2 description is not shown while you're in Creative gamemode.");
public static final JOption<String> ENCHANTMENTS_DESCRIPTION_FORMAT = JOption.create("Enchantments.Description.Format",
"&8▸ " + Placeholders.GENERIC_DESCRIPTION,
"Sets the global enchantment description format.");
"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?");

View File

@ -10,14 +10,12 @@ import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nexmedia.engine.api.manager.AbstractManager;
import su.nexmedia.engine.utils.CollectionsUtil;
import su.nexmedia.engine.utils.EntityUtil;
import su.nexmedia.engine.utils.ItemUtil;
import su.nexmedia.engine.utils.PDCUtil;
import su.nexmedia.engine.utils.Pair;
import su.nexmedia.engine.utils.random.Rnd;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.ExcellentEnchantsAPI;
@ -38,7 +36,6 @@ import su.nightexpress.excellentenchants.tier.Tier;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class EnchantManager extends AbstractManager<ExcellentEnchants> {
@ -217,6 +214,7 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
for (int index = 0; index < sizeHas && !lore.isEmpty(); index++) {
lore.remove(0);
}
//lore.removeIf(str -> enchants.keySet().stream().anyMatch(enchant -> str.contains(enchant.getDisplayName())));
if (!meta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) {
if (Config.ENCHANTMENTS_DESCRIPTION_ENABLED.get()) {
@ -232,7 +230,9 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
else sizeReal = 0;
meta.setLore(lore);
if (sizeReal > 0) {
PDCUtil.set(meta, KEY_LORE_SIZE, sizeReal);
}
item.setItemMeta(meta);
return true;
}
@ -261,11 +261,11 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
}
public static int getEnchantmentCharges(@NotNull ItemStack item, @NotNull ExcellentEnchant enchant) {
return enchant.isChargesEnabled() ? PDCUtil.getIntData(item, enchant.getChargesKey()) : -1;
return enchant.isChargesEnabled() ? PDCUtil.getInt(item, enchant.getChargesKey()).orElse(-0) : -1;
}
public static int getEnchantmentCharges(@NotNull ItemMeta meta, @NotNull ExcellentEnchant enchant) {
return enchant.isChargesEnabled() ? PDCUtil.getIntData(meta, enchant.getChargesKey()) : -1;
return enchant.isChargesEnabled() ? PDCUtil.getInt(meta, enchant.getChargesKey()).orElse(0) : -1;
}
public static boolean isEnchantmentOutOfCharges(@NotNull ItemStack item, @NotNull ExcellentEnchant enchant) {
@ -311,7 +311,7 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
int level = getEnchantmentLevel(item, enchant);
int max = enchant.getChargesMax(level);
PDCUtil.setData(item, enchant.getChargesKey(), Math.max(0, Math.min(charges, max)));
PDCUtil.set(item, enchant.getChargesKey(), Math.max(0, Math.min(charges, max)));
}
public static int getExcellentEnchantmentsAmount(@NotNull ItemStack item) {
@ -330,44 +330,26 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
@NotNull
private static Map<ExcellentEnchant, Integer> getExcellentEnchantments(@NotNull Map<Enchantment, Integer> enchants) {
return enchants.entrySet().stream()
.map(entry -> {
ExcellentEnchant enchant = EnchantRegister.get(entry.getKey().getKey());
return enchant == null ? null : Pair.of(enchant, entry.getValue());
})
.filter(Objects::nonNull)
//.sorted(Comparator.comparing(p -> p.getFirst().getPriority(), Comparator.reverseOrder()))
.collect(Collectors.toMap(Pair::getFirst, Pair::getSecond, (old, nev) -> nev, LinkedHashMap::new));
Map<ExcellentEnchant, Integer> map = new HashMap<>();
enchants.forEach((enchantment, level) -> {
ExcellentEnchant excellent = EnchantRegister.get(enchantment.getKey());
if (excellent != null) {
map.put(excellent, level);
}
});
return map;
}
@SuppressWarnings("unchecked")
@NotNull
public static <T extends IEnchantment> Map<T, Integer> getExcellentEnchantments(@NotNull ItemStack item, @NotNull Class<T> clazz) {
return EnchantManager.getEnchantments(item).entrySet().stream()
.map(entry -> {
ExcellentEnchant enchant = EnchantRegister.get(entry.getKey().getKey());
if (enchant == null || !clazz.isAssignableFrom(enchant.getClass())) return null;
return Pair.of((T) enchant, entry.getValue());
})
.filter(Objects::nonNull)
.sorted(Comparator.comparing(p -> p.getFirst().getPriority(), Comparator.reverseOrder()))
.collect(Collectors.toMap(Pair::getFirst, Pair::getSecond, (old, nev) -> nev, LinkedHashMap::new));
}
Map<T, Integer> map = new HashMap<>();
EnchantManager.getEnchantments(item).forEach((enchantment, level) -> {
ExcellentEnchant excellent = EnchantRegister.get(enchantment.getKey());
if (excellent == null || !clazz.isAssignableFrom(excellent.getClass())) return;
@Nullable
public static ExcellentEnchant getEnchantmentByEffect(@NotNull LivingEntity entity, @NotNull PotionEffect effect) {
Enchantment enchantment = ExcellentEnchantsAPI.PLUGIN.getEnchantNMS().getEnchantmentByEffect(entity, effect);
if (enchantment instanceof ExcellentEnchant enchant) return enchant;
return null;
}
public static boolean isEnchantmentEffect(@NotNull LivingEntity entity, @NotNull PotionEffect effect) {
return getEnchantmentByEffect(entity, effect) != null;
}
public static boolean hasEnchantmentEffect(@NotNull LivingEntity entity, @NotNull ExcellentEnchant enchant) {
return entity.getActivePotionEffects().stream().anyMatch(effect -> enchant.equals(getEnchantmentByEffect(entity, effect)));
map.put(clazz.cast(excellent), level);
});
return CollectionsUtil.sort(map, Comparator.comparing(p -> p.getKey().getPriority(), Comparator.reverseOrder()));
}
@NotNull

View File

@ -26,7 +26,7 @@ public class EnchantAquaman extends PotionEnchant implements PassiveEnchant {
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
if (!this.isAvailableToUse(entity) || this.hasEffect(entity)) return false;
if (!this.isAvailableToUse(entity)) return false;
return this.addEffect(entity, level);
}

View File

@ -26,7 +26,7 @@ public class EnchantBunnyHop extends PotionEnchant implements PassiveEnchant {
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
if (!this.isAvailableToUse(entity) || this.hasEffect(entity)) return false;
if (!this.isAvailableToUse(entity)) return false;
return this.addEffect(entity, level);
}

View File

@ -26,7 +26,7 @@ public class EnchantNightVision extends PotionEnchant implements PassiveEnchant
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
if (!this.isAvailableToUse(entity) || this.hasEffect(entity)) return false;
if (!this.isAvailableToUse(entity)) return false;
return this.addEffect(entity, level);
}

View File

@ -26,7 +26,7 @@ public class EnchantSonic extends PotionEnchant implements PassiveEnchant {
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
if (!this.isAvailableToUse(entity) || this.hasEffect(entity)) return false;
if (!this.isAvailableToUse(entity)) return false;
return this.addEffect(entity, level);
}

View File

@ -11,17 +11,33 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant;
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.api.enchantment.util.EnchantPriority;
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
public class EnchantEnderBow extends ExcellentEnchant implements BowEnchant {
public class EnchantEnderBow extends ExcellentEnchant implements BowEnchant, Chanced {
public static final String ID = "ender_bow";
private ChanceImplementation chanceImplementation;
public EnchantEnderBow(@NotNull ExcellentEnchants plugin) {
super(plugin, ID, EnchantPriority.HIGHEST);
}
@Override
public void loadConfig() {
super.loadConfig();
this.chanceImplementation = ChanceImplementation.create(this);
}
@NotNull
@Override
public ChanceImplementation getChanceImplementation() {
return chanceImplementation;
}
@Override
@NotNull
public EnchantmentTarget getItemTarget() {
@ -31,6 +47,7 @@ public class EnchantEnderBow extends ExcellentEnchant implements BowEnchant {
@Override
public boolean onShoot(@NotNull EntityShootBowEvent e, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
if (!this.isAvailableToUse(shooter)) return false;
if (!this.checkTriggerChance(level)) return false;
if (!(e.getProjectile() instanceof Projectile projectile)) return false;
EnderPearl pearl = shooter.launchProjectile(EnderPearl.class);

View File

@ -15,17 +15,20 @@ import su.nexmedia.engine.api.config.JOption;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant;
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.type.BowEnchant;
import su.nightexpress.excellentenchants.api.enchantment.util.EnchantPriority;
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
public class EnchantGhast extends ExcellentEnchant implements BowEnchant {
public class EnchantGhast extends ExcellentEnchant implements BowEnchant, Chanced {
public static final String ID = "ghast";
private boolean fireSpread;
private EnchantScaler yield;
private ChanceImplementation chanceImplementation;
public EnchantGhast(@NotNull ExcellentEnchants plugin) {
super(plugin, ID, EnchantPriority.HIGHEST);
@ -34,12 +37,19 @@ public class EnchantGhast extends ExcellentEnchant implements BowEnchant {
@Override
public void loadConfig() {
super.loadConfig();
this.chanceImplementation = ChanceImplementation.create(this);
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,
"Fireball explosion size/radius. The more value = the bigger the explosion.");
}
@NotNull
@Override
public ChanceImplementation getChanceImplementation() {
return chanceImplementation;
}
public boolean isFireSpread() {
return fireSpread;
}
@ -57,6 +67,7 @@ public class EnchantGhast extends ExcellentEnchant implements BowEnchant {
@Override
public boolean onShoot(@NotNull EntityShootBowEvent e, @NotNull LivingEntity shooter, @NotNull ItemStack bow, int level) {
if (!this.isAvailableToUse(shooter)) return false;
if (!this.checkTriggerChance(level)) return false;
if (!(e.getProjectile() instanceof Projectile projectile)) return false;
Fireball fireball;

View File

@ -81,12 +81,12 @@ public final class ArrowImplementation implements Arrowed {
@Override
public void addData(@NotNull Projectile projectile) {
PDCUtil.setData(projectile, this.getProjectileKey(), this.enchant.getId());
PDCUtil.set(projectile, this.getProjectileKey(), this.enchant.getId());
}
@Override
public boolean isOurProjectile(@NotNull Projectile projectile) {
String enchantId = PDCUtil.getStringData(projectile, this.getProjectileKey());
String enchantId = PDCUtil.getString(projectile, this.getProjectileKey()).orElse(null);
return this.enchant.getId().equalsIgnoreCase(enchantId);
}
}

View File

@ -5,11 +5,10 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.utils.Scaler;
import su.nightexpress.excellentenchants.ExcellentEnchantsAPI;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant;
import su.nightexpress.excellentenchants.api.enchantment.meta.Potioned;
import su.nightexpress.excellentenchants.enchantment.EnchantManager;
import su.nightexpress.excellentenchants.config.Config;
import su.nightexpress.excellentenchants.enchantment.config.EnchantScaler;
public final class PotionImplementation implements Potioned {
@ -18,14 +17,14 @@ public final class PotionImplementation implements Potioned {
public static final String PLACEHOLDER_POTION_DURATION = "%enchantment_potion_duration%";
public static final String PLACEHOLDER_POTION_TYPE = "%enchantment_potion_type%";
private final ExcellentEnchant enchant;
//private final ExcellentEnchant enchant;
private final PotionEffectType effectType;
private final Scaler duration;
private final Scaler amplifier;
private final boolean isPermanent;
private PotionImplementation(@NotNull ExcellentEnchant enchant, @NotNull PotionEffectType effectType, boolean isPermanent) {
this.enchant = enchant;
//this.enchant = enchant;
this.effectType = effectType;
this.duration = EnchantScaler.read(enchant, "Settings.Potion_Effect.Duration", "5.0 * " + Placeholders.ENCHANTMENT_LEVEL,
"Potion effect duration (in seconds). This setting is useless for 'permanent' effects.");
@ -55,6 +54,13 @@ public final class PotionImplementation implements Potioned {
}
public int getEffectDuration(int level) {
if (this.isPermanent()) {
int duration = Config.TASKS_PASSIVE_POTION_EFFECTS_APPLY_INTERVAL.get().intValue() + 30;
if (this.getEffectType().getName().equalsIgnoreCase(PotionEffectType.NIGHT_VISION.getName())) {
duration += 30 * 20;
}
return duration;
}
return (int) (this.duration.getValue(level) * 20);
}
@ -70,17 +76,8 @@ public final class PotionImplementation implements Potioned {
return new PotionEffect(this.getEffectType(), duration, amplifier, false, false);
}
public boolean hasEffect(@NotNull LivingEntity entity) {
return EnchantManager.hasEnchantmentEffect(entity, this.enchant);
}
public boolean addEffect(@NotNull LivingEntity target, int level) {
if (this.isPermanent()) {
ExcellentEnchantsAPI.PLUGIN.getEnchantNMS().addEnchantmentEffect(target, this.enchant, this.createEffect(level));
}
else {
target.addPotionEffect(this.createEffect(level));
}
return true;
}
}

View File

@ -74,7 +74,7 @@ public class EnchantBlastMining extends ExcellentEnchant implements Chanced, Blo
}
private boolean isBlockHardEnough(@NotNull Block block, int level) {
float strength = plugin.getNMS().getBlockStrength(block);
float strength = block.getType().getHardness();//plugin.getNMS().getBlockStrength(block);
return (strength >= this.getMinBlockStrength(level));
}
@ -136,7 +136,8 @@ public class EnchantBlastMining extends ExcellentEnchant implements Chanced, Blo
// Break all 'exploded' blocks by a player, adding metadata to them to prevent trigger enchantment in a loop.
blockList.forEach(block -> {
block.setMetadata(META_EXPLOSION_MINED, new FixedMetadataValue(plugin, true));
plugin.getNMS().breakBlock(player, block);
//plugin.getNMS().breakBlock(player, block);
player.breakBlock(block);
block.removeMetadata(META_EXPLOSION_MINED, plugin);
});

View File

@ -18,6 +18,7 @@ import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.utils.Colorizer;
import su.nexmedia.engine.utils.EffectUtil;
import su.nexmedia.engine.utils.LocationUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
@ -49,7 +50,8 @@ public class EnchantDivineTouch extends ExcellentEnchant implements Chanced, Blo
this.chanceImplementation = ChanceImplementation.create(this);
this.spawnerName = JOption.create("Settings.Spawner_Item.Name", "&aMob Spawner &7(" + Placeholders.GENERIC_TYPE + ")",
"Spawner item display name.",
"Placeholder '" + Placeholders.GENERIC_TYPE + "' for the mob type.").read(cfg);
"Placeholder '" + Placeholders.GENERIC_TYPE + "' for the mob type.")
.mapReader(Colorizer::apply).read(cfg);
}
@NotNull

View File

@ -26,7 +26,7 @@ public class EnchantHaste extends PotionEnchant implements PassiveEnchant {
@Override
public boolean onTrigger(@NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
if (!this.isAvailableToUse(entity) || this.hasEffect(entity)) return false;
if (!this.isAvailableToUse(entity)) return false;
return this.addEffect(entity, level);
}

View File

@ -18,20 +18,24 @@ import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.utils.MessageUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant;
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant;
import su.nightexpress.excellentenchants.api.enchantment.type.InteractEnchant;
import su.nightexpress.excellentenchants.api.enchantment.util.EnchantPriority;
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
import su.nightexpress.excellentenchants.enchantment.type.FitItemType;
import java.util.Set;
public class EnchantReplanter extends ExcellentEnchant implements InteractEnchant, BlockBreakEnchant {
public class EnchantReplanter extends ExcellentEnchant implements Chanced, InteractEnchant, BlockBreakEnchant {
public static final String ID = "replanter";
private boolean replantOnRightClick;
private boolean replantOnPlantBreak;
private ChanceImplementation chanceImplementation;
private static final Set<Material> CROPS = Set.of(
Material.WHEAT_SEEDS, Material.BEETROOT_SEEDS,
Material.MELON_SEEDS, Material.PUMPKIN_SEEDS,
@ -44,12 +48,19 @@ public class EnchantReplanter extends ExcellentEnchant implements InteractEnchan
@Override
public void loadConfig() {
super.loadConfig();
this.chanceImplementation = ChanceImplementation.create(this);
this.replantOnRightClick = JOption.create("Settings.Replant.On_Right_Click", true,
"When 'true', player will be able to replant crops when right-clicking farmland blocks.").read(cfg);
this.replantOnPlantBreak = JOption.create("Settings.Replant.On_Plant_Break", true,
"When 'true', crops will be automatically replanted when player break plants with enchanted tool in hand.").read(cfg);
}
@NotNull
@Override
public ChanceImplementation getChanceImplementation() {
return chanceImplementation;
}
public boolean isReplantOnPlantBreak() {
return replantOnPlantBreak;
}
@ -107,8 +118,9 @@ public class EnchantReplanter extends ExcellentEnchant implements InteractEnchan
@Override
public boolean onInteract(@NotNull PlayerInteractEvent e, @NotNull Player player, @NotNull ItemStack item, int level) {
if (!this.isAvailableToUse(player)) return false;
if (!this.isReplantOnRightClick()) return false;
if (!this.isAvailableToUse(player)) return false;
if (!this.checkTriggerChance(level)) return false;
// Check for a event hand. We dont want to trigger it twice.
if (e.getHand() != EquipmentSlot.HAND) return false;
@ -133,7 +145,7 @@ public class EnchantReplanter extends ExcellentEnchant implements InteractEnchan
|| seed != Material.NETHER_WART && blockGround.getType() == Material.FARMLAND) {
if (this.takeSeeds(player, seed)) {
MessageUtil.sound(player, seed == Material.NETHER_WART ? Sound.ITEM_NETHER_WART_PLANT : Sound.ITEM_CROP_PLANT);
plugin.getNMS().sendAttackPacket(player, 0);
plugin.getEnchantNMS().sendAttackPacket(player, 0);
blockPlant.setType(this.fineSeedsToBlock(seed));
break;
}
@ -144,8 +156,9 @@ public class EnchantReplanter extends ExcellentEnchant implements InteractEnchan
@Override
public boolean onBreak(@NotNull BlockBreakEvent e, @NotNull Player player, @NotNull ItemStack item, int level) {
if (!this.isAvailableToUse(player)) return false;
if (!this.isReplantOnPlantBreak()) return false;
if (!this.isAvailableToUse(player)) return false;
if (!this.checkTriggerChance(level)) return false;
Block blockPlant = e.getBlock();
//if (EnchantTelekinesis.isDropHandled(blockPlant)) return false;

View File

@ -20,6 +20,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.utils.Colorizer;
import su.nexmedia.engine.utils.ItemUtil;
import su.nexmedia.engine.utils.PDCUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
@ -59,10 +60,10 @@ public class EnchantSilkChest extends ExcellentEnchant implements BlockDropEncha
super.loadConfig();
this.chestName = JOption.create("Settings.Chest_Item.Name", "Chest &7(" + Placeholders.GENERIC_AMOUNT + " items)",
"Chest item display name.",
"Use '" + Placeholders.GENERIC_AMOUNT + "' for items amount.").read(cfg);
"Use '" + Placeholders.GENERIC_AMOUNT + "' for items amount.").mapReader(Colorizer::apply).read(cfg);
this.chestLore = JOption.create("Settings.Chest_Item.Lore", new ArrayList<>(),
"Chest item lore.",
"Use '" + Placeholders.GENERIC_AMOUNT + "' for items amount.").read(cfg);
"Use '" + Placeholders.GENERIC_AMOUNT + "' for items amount.").mapReader(Colorizer::apply).read(cfg);
}
@Deprecated
@ -83,7 +84,7 @@ public class EnchantSilkChest extends ExcellentEnchant implements BlockDropEncha
}
public boolean isSilkChest(@NotNull ItemStack item) {
return PDCUtil.getBooleanData(item, this.keyChest) || PDCUtil.getStringData(item, this.getItemKey(0)) != null;
return PDCUtil.getBoolean(item, this.keyChest).orElse(false) || PDCUtil.getString(item, this.getItemKey(0)).orElse(null) != null;
}
@NotNull
@ -105,7 +106,7 @@ public class EnchantSilkChest extends ExcellentEnchant implements BlockDropEncha
chestStack.setItemMeta(stateMeta);
ItemUtil.replace(chestStack, str -> str.replace(Placeholders.GENERIC_AMOUNT, String.valueOf(amount)));
PDCUtil.setData(chestStack, this.keyChest, true);
PDCUtil.set(chestStack, this.keyChest, true);
return chestStack;
// Store and count chest items.
@ -172,7 +173,7 @@ public class EnchantSilkChest extends ExcellentEnchant implements BlockDropEncha
Inventory inventory = chest.getBlockInventory();
for (int pos = 0; pos < inventory.getSize(); pos++) {
String data = PDCUtil.getStringData(item, this.getItemKey(pos));
String data = PDCUtil.getString(item, this.getItemKey(pos)).orElse(null);
if (data == null) continue;
ItemStack itemInv = ItemUtil.fromBase64(data);

View File

@ -9,23 +9,39 @@ import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.utils.PlayerUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant;
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockDropEnchant;
import su.nightexpress.excellentenchants.api.enchantment.util.EnchantDropContainer;
import su.nightexpress.excellentenchants.api.enchantment.util.EnchantPriority;
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
import su.nightexpress.excellentenchants.enchantment.type.FitItemType;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class EnchantTelekinesis extends ExcellentEnchant implements BlockDropEnchant {
public class EnchantTelekinesis extends ExcellentEnchant implements Chanced, BlockDropEnchant {
public static final String ID = "telekinesis";
private ChanceImplementation chanceImplementation;
public EnchantTelekinesis(@NotNull ExcellentEnchants plugin) {
super(plugin, ID, EnchantPriority.LOWEST);
}
@Override
public void loadConfig() {
super.loadConfig();
this.chanceImplementation = ChanceImplementation.create(this);
}
@NotNull
@Override
public ChanceImplementation getChanceImplementation() {
return chanceImplementation;
}
@Override
@NotNull
public FitItemType[] getFitItemTypes() {
@ -41,6 +57,7 @@ public class EnchantTelekinesis extends ExcellentEnchant implements BlockDropEnc
@Override
public boolean onDrop(@NotNull BlockDropItemEvent e, @NotNull EnchantDropContainer dropContainer, @NotNull Player player, @NotNull ItemStack item, int level) {
if (!this.isAvailableToUse(player)) return false;
if (!this.checkTriggerChance(level)) return false;
List<ItemStack> drops = new ArrayList<>();
drops.addAll(e.getItems().stream().map(Item::getItemStack).toList());

View File

@ -117,7 +117,8 @@ public class EnchantTunnel extends ExcellentEnchant implements BlockBreakEnchant
// Add metadata to prevent enchantment triggering in a loop.
blockAdd.setMetadata(META_BLOCK_TUNNEL, new FixedMetadataValue(plugin, true));
plugin.getNMS().breakBlock(player, blockAdd);
//plugin.getNMS().breakBlock(player, blockAdd);
player.breakBlock(blockAdd);
blockAdd.removeMetadata(META_BLOCK_TUNNEL, plugin);
}

View File

@ -114,7 +114,8 @@ public class EnchantVeinminer extends ExcellentEnchant implements BlockBreakEnch
EffectUtil.playEffect(LocationUtil.getCenter(ore.getLocation()), Particle.BLOCK_CRACK.name(), ore.getType().name(), 0.2, 0.2, 0.2, 0.1, 20);
ore.setMetadata(META_BLOCK_VEINED, new FixedMetadataValue(plugin, true));
plugin.getNMS().breakBlock(player, ore);
//plugin.getNMS().breakBlock(player, ore);
player.breakBlock(ore);
ore.removeMetadata(META_BLOCK_VEINED, plugin);
});
}

View File

@ -8,17 +8,33 @@ import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.utils.PlayerUtil;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant;
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.type.DeathEnchant;
import su.nightexpress.excellentenchants.api.enchantment.util.EnchantPriority;
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
public class EnchantNimble extends ExcellentEnchant implements DeathEnchant {
public class EnchantNimble extends ExcellentEnchant implements Chanced, DeathEnchant {
public static final String ID = "nimble";
private ChanceImplementation chanceImplementation;
public EnchantNimble(@NotNull ExcellentEnchants plugin) {
super(plugin, ID, EnchantPriority.LOWEST);
}
@Override
public void loadConfig() {
super.loadConfig();
this.chanceImplementation = ChanceImplementation.create(this);
}
@NotNull
@Override
public ChanceImplementation getChanceImplementation() {
return chanceImplementation;
}
@NotNull
@Override
public EnchantmentTarget getItemTarget() {
@ -28,6 +44,7 @@ public class EnchantNimble extends ExcellentEnchant implements DeathEnchant {
@Override
public boolean onKill(@NotNull EntityDeathEvent e, @NotNull LivingEntity entity, @NotNull Player killer, int level) {
if (!this.isAvailableToUse(entity)) return false;
if (!this.checkTriggerChance(level)) return false;
e.getDrops().forEach(item -> PlayerUtil.addItem(killer, item));
e.getDrops().clear();

View File

@ -80,7 +80,7 @@ public class EnchantThrifty extends ExcellentEnchant implements Chanced, DeathEn
if (!this.isAvailableToUse(entity)) return false;
if (this.ignoredEntityTypes.contains(entity.getType())) return false;
if (PDCUtil.getBooleanData(entity, this.keyEntityIgnored)) return false;
if (PDCUtil.getBoolean(entity, this.keyEntityIgnored).orElse(false)) return false;
if (!this.checkTriggerChance(level)) return false;
Material material = Material.getMaterial(entity.getType().name() + "_SPAWN_EGG");
@ -105,6 +105,6 @@ public class EnchantThrifty extends ExcellentEnchant implements Chanced, DeathEn
public void onCreatureSpawn(CreatureSpawnEvent e) {
if (!this.ignoredSpawnReasons.contains(e.getSpawnReason())) return;
PDCUtil.setData(e.getEntity(), this.keyEntityIgnored, true);
PDCUtil.set(e.getEntity(), this.keyEntityIgnored, true);
}
}

View File

@ -86,7 +86,7 @@ public class EnchantAnvilListener extends AbstractListener<ExcellentEnchants> {
count++;
}
PDCUtil.setData(result2, RECHARGED, count);
PDCUtil.set(result2, RECHARGED, count);
EnchantManager.updateEnchantmentsDisplay(result2);
e.setResult(result2);
this.plugin.runTask(c -> e.getInventory().setRepairCost(chargeables.size()), false);
@ -138,14 +138,14 @@ public class EnchantAnvilListener extends AbstractListener<ExcellentEnchants> {
ItemStack item = e.getCurrentItem();
if (item == null) return;
int count = PDCUtil.getIntData(item, RECHARGED);
int count = PDCUtil.getInt(item, RECHARGED).orElse(0);
if (count == 0) return;
Player player = (Player) e.getWhoClicked();
if (player.getLevel() < inventory.getRepairCost()) return;
player.setLevel(player.getLevel() - inventory.getRepairCost());
PDCUtil.removeData(item, RECHARGED);
PDCUtil.remove(item, RECHARGED);
e.getView().setCursor(item);
e.setCancelled(false);

View File

@ -13,7 +13,6 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.LootGenerateEvent;
import org.bukkit.inventory.*;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
@ -36,16 +35,6 @@ public class EnchantGenericListener extends AbstractListener<ExcellentEnchants>
super(enchantManager.plugin());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onEnchantPotionEffectQuit(PlayerQuitEvent e) {
Player player = e.getPlayer();
player.getActivePotionEffects().stream()
.filter(effect -> EnchantManager.isEnchantmentEffect(player, effect)).forEach(effect -> {
player.removePotionEffect(effect.getType());
});
}
// ---------------------------------------------------------------
// Update enchantment lore after grindstone
// ---------------------------------------------------------------
@ -190,6 +179,7 @@ public class EnchantGenericListener extends AbstractListener<ExcellentEnchants>
public void onEnchantPopulateSpawn(CreatureSpawnEvent e) {
//if (Config.getObtainSettings(ObtainType.MOB_SPAWNING).isEmpty()) return;
LivingEntity entity = e.getEntity();
if (entity.getType() == EntityType.ARMOR_STAND) return;
this.plugin.runTaskLater(task -> {
EntityEquipment equipment = entity.getEquipment();

View File

@ -13,6 +13,7 @@ import su.nexmedia.engine.api.menu.MenuClick;
import su.nexmedia.engine.api.menu.MenuItem;
import su.nexmedia.engine.api.menu.MenuItemType;
import su.nexmedia.engine.lang.LangManager;
import su.nexmedia.engine.utils.Colorizer;
import su.nexmedia.engine.utils.ItemUtil;
import su.nexmedia.engine.utils.PDCUtil;
import su.nexmedia.engine.utils.StringUtil;
@ -46,9 +47,9 @@ public class EnchantmentsListMenu extends AbstractMenuAuto<ExcellentEnchants, Ex
this.iconCache = new HashMap<>();
this.enchantIcon = cfg.getItem("Enchantments.Icon");
this.enchantLoreConflicts = StringUtil.color(cfg.getStringList("Enchantments.Lore.Conflicts"));
this.enchantLoreCharges = StringUtil.color(cfg.getStringList("Enchantments.Lore.Charges"));
this.enchantLoreObtaining = StringUtil.color(cfg.getStringList("Enchantments.Lore.Obtaining"));
this.enchantLoreConflicts = Colorizer.apply(cfg.getStringList("Enchantments.Lore.Conflicts"));
this.enchantLoreCharges = Colorizer.apply(cfg.getStringList("Enchantments.Lore.Charges"));
this.enchantLoreObtaining = Colorizer.apply(cfg.getStringList("Enchantments.Lore.Obtaining"));
this.enchantSlots = cfg.getIntArray("Enchantments.Slots");
MenuClick click = (player, type, e) -> {
@ -100,12 +101,12 @@ public class EnchantmentsListMenu extends AbstractMenuAuto<ExcellentEnchants, Ex
ItemStack itemClick = e.getCurrentItem();
if (itemClick == null) return;
int levelHas = PDCUtil.getIntData(itemClick, this.keyLevel);
int levelHas = PDCUtil.getInt(itemClick, this.keyLevel).orElse(0);
if (levelHas == 0) levelHas = enchant.getStartLevel();
if (++levelHas > enchant.getMaxLevel()) levelHas = enchant.getStartLevel();
itemClick = this.getEnchantIcon(enchant, levelHas);
PDCUtil.setData(itemClick, this.keyLevel, levelHas);
PDCUtil.set(itemClick, this.keyLevel, levelHas);
e.setCurrentItem(itemClick);
};

View File

@ -5,7 +5,7 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nexmedia.engine.api.manager.IPlaceholder;
import su.nexmedia.engine.utils.StringUtil;
import su.nexmedia.engine.utils.Colorizer;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.type.ObtainType;
@ -38,7 +38,7 @@ public class Tier implements IPlaceholder {
@NotNull Map<ObtainType, Double> chance) {
this.id = id.toLowerCase();
this.priority = priority;
this.name = StringUtil.color(name);
this.name = Colorizer.apply(name);
this.color = color;
this.chance = chance;
this.enchants = new HashSet<>();

View File

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

View File

@ -1,60 +1,16 @@
package su.nightexpress.excellentenchants.nms;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nexmedia.engine.utils.EntityUtil;
import su.nexmedia.engine.utils.ItemUtil;
import java.util.Map;
import java.util.Set;
public interface EnchantNMS {
int EFFECT_DURATION_MAX = 30 * 20;
int EFFECT_DURATION_MIN = 20 * 20;
// TODO Move in 'API' module?
@Deprecated
static int getEnchantmentLevel(@NotNull ItemStack item, @NotNull Enchantment enchant) {
ItemMeta meta = item.getItemMeta();
if (meta == null) return 0;
return meta.getEnchantLevel(enchant);
}
@NotNull
@Deprecated
static Map<EquipmentSlot, ItemStack> getEquipmentEnchanted(@NotNull LivingEntity entity) {
Map<EquipmentSlot, ItemStack> equipment = EntityUtil.getEquippedItems(entity);
equipment.entrySet().removeIf(entry -> {
ItemStack item = entry.getValue();
EquipmentSlot slot = entry.getKey();
if (item == null || item.getType().isAir() || item.getType() == Material.ENCHANTED_BOOK) return true;
if ((slot == EquipmentSlot.HAND || slot == EquipmentSlot.OFF_HAND) && ItemUtil.isArmor(item)) return true;
return !item.hasItemMeta();
});
return equipment;
}
// TODO Move in 'API' module?
@Deprecated
static int getEquippedEnchantLevel(@NotNull LivingEntity entity, @NotNull Enchantment enchant) {
return getEquipmentEnchanted(entity).values().stream()
.map(item -> getEnchantmentLevel(item, enchant)).max(Integer::compareTo).orElse(0);
}
void addEnchantmentEffect(@NotNull LivingEntity entity, @NotNull Enchantment enchant, @NotNull PotionEffect effect);
@Nullable Enchantment getEnchantmentByEffect(@NotNull LivingEntity entity, @NotNull PotionEffect type);
void sendAttackPacket(@NotNull Player player, int id);
@NotNull Set<Block> handleFlameWalker(@NotNull LivingEntity entity, @NotNull Location location, int level);
}

View File

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

View File

@ -1,48 +0,0 @@
package su.nightexpress.excellentenchants.nms.v1_17_R1;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.utils.Reflex;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
public class CustomEffectInstance extends MobEffectInstance {
private final Enchantment enchantment;
public CustomEffectInstance(MobEffect effect, int amplifier, @NotNull Enchantment enchantment) {
super(effect, EnchantNMS.EFFECT_DURATION_MAX, amplifier);
this.enchantment = enchantment;
}
@NotNull
public Enchantment getEnchantment() {
return enchantment;
}
@Override
public boolean update(MobEffectInstance effect) {
/*if (effect instanceof CustomEffectInstance custom) {
return false;
}
if (effect.getAmplifier() > this.getAmplifier()) {
}*/
return false;
}
public boolean tick(LivingEntity entity, Runnable runnable) {
if (EnchantNMS.getEquippedEnchantLevel((org.bukkit.entity.LivingEntity) entity.getBukkitEntity(), this.getEnchantment()) <= 0) {
return false;
}
if (super.tick(entity, runnable)) {
if (this.getDuration() <= EnchantNMS.EFFECT_DURATION_MIN) {
Reflex.setFieldValue(this, "c", EnchantNMS.EFFECT_DURATION_MAX);
}
return true;
}
return false;
}
}

View File

@ -1,9 +1,8 @@
package su.nightexpress.excellentenchants.nms.v1_17_R1;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
@ -13,13 +12,11 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import java.util.HashSet;
@ -28,20 +25,11 @@ import java.util.Set;
public class V1_17_R1 implements EnchantNMS {
@Override
public void addEnchantmentEffect(@NotNull LivingEntity entity, @NotNull Enchantment enchant, @NotNull PotionEffect effect) {
net.minecraft.world.entity.LivingEntity entity1 = ((CraftLivingEntity)entity).getHandle();
entity1.addEffect(new CustomEffectInstance(MobEffect.byId(effect.getType().getId()), effect.getAmplifier(), enchant), EntityPotionEffectEvent.Cause.PLUGIN);
}
@Override
@Nullable
public Enchantment getEnchantmentByEffect(@NotNull LivingEntity entity, @NotNull PotionEffect type) {
net.minecraft.world.entity.LivingEntity entity1 = ((CraftLivingEntity)entity).getHandle();
MobEffectInstance handle = entity1.getEffect(MobEffect.byId(type.getType().getId()));
if (handle instanceof CustomEffectInstance instance) {
return instance.getEnchantment();
}
return null;
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;
Entity entity = craftPlayer.getHandle();
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
craftPlayer.getHandle().connection.send(packet);
}
@Override

View File

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

View File

@ -1,48 +0,0 @@
package su.nightexpress.excellentenchants.nms.v1_18_R2;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.utils.Reflex;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
public class CustomEffectInstance extends MobEffectInstance {
private final Enchantment enchantment;
public CustomEffectInstance(MobEffect effect, int amplifier, @NotNull Enchantment enchantment) {
super(effect, EnchantNMS.EFFECT_DURATION_MAX, amplifier);
this.enchantment = enchantment;
}
@NotNull
public Enchantment getEnchantment() {
return enchantment;
}
@Override
public boolean update(MobEffectInstance effect) {
/*if (effect instanceof CustomEffectInstance custom) {
return false;
}
if (effect.getAmplifier() > this.getAmplifier()) {
}*/
return false;
}
public boolean tick(LivingEntity entity, Runnable runnable) {
if (EnchantNMS.getEquippedEnchantLevel((org.bukkit.entity.LivingEntity) entity.getBukkitEntity(), this.getEnchantment()) <= 0) {
return false;
}
if (super.tick(entity, runnable)) {
if (this.getDuration() <= EnchantNMS.EFFECT_DURATION_MIN) {
Reflex.setFieldValue(this, "c", EnchantNMS.EFFECT_DURATION_MAX);
}
return true;
}
return false;
}
}

View File

@ -1,9 +1,8 @@
package su.nightexpress.excellentenchants.nms.v1_18_R2;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
@ -13,13 +12,11 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R2.event.CraftEventFactory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import java.util.HashSet;
@ -28,20 +25,11 @@ import java.util.Set;
public class V1_18_R2 implements EnchantNMS {
@Override
public void addEnchantmentEffect(@NotNull LivingEntity entity, @NotNull Enchantment enchant, @NotNull PotionEffect effect) {
net.minecraft.world.entity.LivingEntity entity1 = ((CraftLivingEntity)entity).getHandle();
entity1.addEffect(new CustomEffectInstance(MobEffect.byId(effect.getType().getId()), effect.getAmplifier(), enchant), EntityPotionEffectEvent.Cause.PLUGIN);
}
@Override
@Nullable
public Enchantment getEnchantmentByEffect(@NotNull LivingEntity entity, @NotNull PotionEffect type) {
net.minecraft.world.entity.LivingEntity entity1 = ((CraftLivingEntity)entity).getHandle();
MobEffectInstance handle = entity1.getEffect(MobEffect.byId(type.getType().getId()));
if (handle instanceof CustomEffectInstance instance) {
return instance.getEnchantment();
}
return null;
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;
Entity entity = craftPlayer.getHandle();
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
craftPlayer.getHandle().connection.send(packet);
}
@Override

View File

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

View File

@ -1,48 +0,0 @@
package su.nightexpress.excellentenchants.nms.v1_19_R1;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.utils.Reflex;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
public class CustomEffectInstance extends MobEffectInstance {
private final Enchantment enchantment;
public CustomEffectInstance(MobEffect effect, int amplifier, @NotNull Enchantment enchantment) {
super(effect, EnchantNMS.EFFECT_DURATION_MAX, amplifier);
this.enchantment = enchantment;
}
@NotNull
public Enchantment getEnchantment() {
return enchantment;
}
@Override
public boolean update(MobEffectInstance effect) {
/*if (effect instanceof CustomEffectInstance custom) {
return false;
}
if (effect.getAmplifier() > this.getAmplifier()) {
}*/
return false;
}
public boolean tick(LivingEntity entity, Runnable runnable) {
if (EnchantNMS.getEquippedEnchantLevel((org.bukkit.entity.LivingEntity) entity.getBukkitEntity(), this.getEnchantment()) <= 0) {
return false;
}
if (super.tick(entity, runnable)) {
if (this.getDuration() <= EnchantNMS.EFFECT_DURATION_MIN) {
Reflex.setFieldValue(this, "c", EnchantNMS.EFFECT_DURATION_MAX);
}
return true;
}
return false;
}
}

View File

@ -1,9 +1,8 @@
package su.nightexpress.excellentenchants.nms.v1_19_R1;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
@ -13,13 +12,11 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R1.event.CraftEventFactory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import java.util.HashSet;
@ -28,20 +25,11 @@ import java.util.Set;
public class V1_19_R1 implements EnchantNMS {
@Override
public void addEnchantmentEffect(@NotNull LivingEntity entity, @NotNull Enchantment enchant, @NotNull PotionEffect effect) {
net.minecraft.world.entity.LivingEntity entity1 = ((CraftLivingEntity)entity).getHandle();
entity1.addEffect(new CustomEffectInstance(MobEffect.byId(effect.getType().getId()), effect.getAmplifier(), enchant), EntityPotionEffectEvent.Cause.PLUGIN);
}
@Override
@Nullable
public Enchantment getEnchantmentByEffect(@NotNull LivingEntity entity, @NotNull PotionEffect type) {
net.minecraft.world.entity.LivingEntity entity1 = ((CraftLivingEntity)entity).getHandle();
MobEffectInstance handle = entity1.getEffect(MobEffect.byId(type.getType().getId()));
if (handle instanceof CustomEffectInstance instance) {
return instance.getEnchantment();
}
return null;
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;
Entity entity = craftPlayer.getHandle();
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
craftPlayer.getHandle().connection.send(packet);
}
@Override

View File

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

View File

@ -1,50 +0,0 @@
package su.nightexpress.excellentenchants.nms.v1_19_R2;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.utils.Reflex;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
public class CustomEffectInstance extends MobEffectInstance {
private static final int MIN = 60 * 60 * 20;
private final Enchantment enchantment;
public CustomEffectInstance(MobEffect effect, int amplifier, @NotNull Enchantment enchantment) {
super(effect, EnchantNMS.EFFECT_DURATION_MAX, amplifier);
this.enchantment = enchantment;
}
@NotNull
public Enchantment getEnchantment() {
return enchantment;
}
@Override
public boolean update(MobEffectInstance effect) {
/*if (effect instanceof CustomEffectInstance custom) {
return false;
}
if (effect.getAmplifier() > this.getAmplifier()) {
}*/
return false;
}
public boolean tick(LivingEntity entity, Runnable runnable) {
if (EnchantNMS.getEquippedEnchantLevel((org.bukkit.entity.LivingEntity) entity.getBukkitEntity(), this.getEnchantment()) <= 0) {
return false;
}
if (super.tick(entity, runnable)) {
if (this.getDuration() <= EnchantNMS.EFFECT_DURATION_MIN) {
Reflex.setFieldValue(this, "c", EnchantNMS.EFFECT_DURATION_MAX);
}
return true;
}
return false;
}
}

View File

@ -1,9 +1,8 @@
package su.nightexpress.excellentenchants.nms.v1_19_R2;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
@ -13,13 +12,11 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R2.event.CraftEventFactory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import java.util.HashSet;
@ -28,20 +25,11 @@ import java.util.Set;
public class V1_19_R2 implements EnchantNMS {
@Override
public void addEnchantmentEffect(@NotNull LivingEntity entity, @NotNull Enchantment enchant, @NotNull PotionEffect effect) {
net.minecraft.world.entity.LivingEntity entity1 = ((CraftLivingEntity)entity).getHandle();
entity1.addEffect(new CustomEffectInstance(MobEffect.byId(effect.getType().getId()), effect.getAmplifier(), enchant), EntityPotionEffectEvent.Cause.PLUGIN);
}
@Override
@Nullable
public Enchantment getEnchantmentByEffect(@NotNull LivingEntity entity, @NotNull PotionEffect type) {
net.minecraft.world.entity.LivingEntity entity1 = ((CraftLivingEntity)entity).getHandle();
MobEffectInstance handle = entity1.getEffect(MobEffect.byId(type.getType().getId()));
if (handle instanceof CustomEffectInstance instance) {
return instance.getEnchantment();
}
return null;
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;
Entity entity = craftPlayer.getHandle();
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
craftPlayer.getHandle().connection.send(packet);
}
@Override

71
V1_19_R3/pom.xml Normal file
View File

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

View File

@ -0,0 +1,68 @@
package su.nightexpress.excellentenchants.nms.v1_19_R3;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R3.event.CraftEventFactory;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import java.util.HashSet;
import java.util.Set;
public class V1_19_R3 implements EnchantNMS {
@Override
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;
Entity entity = craftPlayer.getHandle();
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
craftPlayer.getHandle().connection.send(packet);
}
@Override
@NotNull
public Set<Block> handleFlameWalker(@NotNull LivingEntity bukkitEntity, @NotNull Location location, int level) {
Entity entity = ((CraftLivingEntity) bukkitEntity).getHandle();
BlockPos pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
ServerLevel world = ((CraftWorld) bukkitEntity.getWorld()).getHandle();
int radius = Math.min(16, 2 + level);
BlockState bStone = Blocks.MAGMA_BLOCK.defaultBlockState();
BlockPos.MutableBlockPos posAbove = new BlockPos.MutableBlockPos();
Set<Block> blocks = new HashSet<>();
for (BlockPos posNear : BlockPos.betweenClosed(pos.offset(-radius, -1, -radius), pos.offset(radius, -1, radius))) {
if (!posNear.closerThan(entity.blockPosition(), radius)) continue;
posAbove.set(posNear.getX(), posNear.getY() + 1, posNear.getZ());
BlockState bLavaAbove = world.getBlockState(posAbove);
BlockState bLava = world.getBlockState(posNear);
if (!bLavaAbove.isAir()) continue;
if (!bLava.getBlock().equals(Blocks.LAVA)) continue;
if (bLava.getValue(LiquidBlock.LEVEL) != 0) continue;
if (!bStone.canSurvive(world, posNear)) continue;
if (!world.isUnobstructed(bStone, posNear, CollisionContext.empty())) continue;
if (!CraftEventFactory.handleBlockFormEvent(world, posNear, bStone, entity)) continue;
//world.scheduleTick(posNear, Blocks.STONE, Rnd.get(60, 120));
Location bukkitLoc = new Location(world.getWorld(), posNear.getX(), posNear.getY(), posNear.getZ());
blocks.add(bukkitLoc.getBlock());
}
return blocks;
}
}

View File

@ -7,7 +7,7 @@
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>ExcellentEnchants</artifactId>
<packaging>pom</packaging>
<version>3.3.1</version>
<version>3.3.3</version>
<modules>
<module>Core</module>
<module>NMS</module>
@ -15,6 +15,7 @@
<module>V1_18_R2</module>
<module>V1_19_R1</module>
<module>V1_19_R2</module>
<module>V1_19_R3</module>
</modules>
<properties>
@ -26,7 +27,7 @@
<dependency>
<groupId>su.nexmedia</groupId>
<artifactId>NexEngine</artifactId>
<version>2.2.9</version>
<version>2.2.10</version>
</dependency>
</dependencies>