This commit is contained in:
nulli0n 2023-02-11 15:04:45 +06:00
parent 7d82eaa31f
commit 6b0f9cdc43
19 changed files with 135 additions and 33 deletions

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>3.3.0.4</version>
<version>3.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -24,10 +24,16 @@
<repository>
<id>sk89q-repo</id>
<url>https://maven.enginehub.org/repo/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>dmulloy2-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
@ -45,27 +51,27 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>3.3.0.4</version>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_17_R1</artifactId>
<version>3.3.0.4</version>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_18_R2</artifactId>
<version>3.3.0.4</version>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R1</artifactId>
<version>3.3.0.4</version>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R2</artifactId>
<version>3.3.0.4</version>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>fr.neatmonster</groupId>

View File

@ -97,11 +97,14 @@ public class ExcellentEnchants extends NexPlugin<ExcellentEnchants> {
@Override
public void registerHooks() {
if (Hooks.hasPlugin(HookId.PROTOCOL_LIB)) {
ProtocolHook.setup();
}
else {
this.warn(HookId.PROTOCOL_LIB + " is not installed. Enchantments won't be displayed on items.");
if (Config.ENCHANTMENTS_DISPLAY_MODE.get() == 2) {
if (Hooks.hasPlugin(HookId.PROTOCOL_LIB)) {
ProtocolHook.setup();
}
else {
this.warn(HookId.PROTOCOL_LIB + " is not installed. Set display mode to Plain lore.");
Config.ENCHANTMENTS_DISPLAY_MODE.set(1);
}
}
}

View File

@ -247,7 +247,7 @@ public abstract class ExcellentEnchant extends Enchantment implements IEnchantme
@NotNull
public String getNameFormatted(int level, int charges) {
if (!this.isChargesEnabled()) return this.getNameFormatted(level);
if (!this.isChargesEnabled() || charges < 0) return this.getNameFormatted(level);
int chargesMax = this.getChargesMax(level);
double percent = (double) charges / (double) chargesMax * 100D;

View File

@ -86,6 +86,7 @@ public class BookCommand extends AbstractCommand<ExcellentEnchants> {
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
EnchantManager.addEnchantment(item, enchantment, level, true);
EnchantManager.updateEnchantmentsDisplay(item);
PlayerUtil.addItem(player, item);
plugin.getMessage(Lang.COMMAND_BOOK_DONE)

View File

@ -83,6 +83,7 @@ public class EnchantCommand extends AbstractCommand<ExcellentEnchants> {
}
else EnchantManager.removeEnchantment(item, enchantment);
EnchantManager.updateEnchantmentsDisplay(item);
plugin.getMessage(Lang.COMMAND_ENCHANT_DONE).send(sender);
}
}

View File

@ -91,6 +91,7 @@ public class TierbookCommand extends AbstractCommand<ExcellentEnchants> {
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
EnchantManager.addEnchantment(item, enchant, level, true);
EnchantManager.updateEnchantmentsDisplay(item);
PlayerUtil.addItem(player, item);
plugin.getMessage(Lang.COMMAND_TIER_BOOK_DONE)

View File

@ -26,7 +26,8 @@ public class Config {
);
public static final JOption<Boolean> ENCHANTMENTS_CHARGES_ENABLED = JOption.create("Enchantments.Charges.Enabled", false,
"Enables the enchantment Charges feature."); // TODO Wiki link
"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 -> StringUtil.color(cfg.getString(path + "." + v, "")), (o,n) -> n, TreeMap::new)),
@ -64,6 +65,13 @@ public class Config {
"To disable all enchantments for a world, use '" + Placeholders.WILDCARD + "' instead of enchantment names.")
.setWriter((cfg, path, map) -> map.forEach((world, enchants) -> cfg.set(path + "." + world, enchants)));
public static final JOption<Integer> ENCHANTMENTS_DISPLAY_MODE = JOption.create("Enchantments.Display.Mode", 1,
"Sets how enchantment names and descriptions will be handled on items.",
"1 = Plain modification of item's lore (lore changes are real and persistent).",
"2 = Packet modification of item's lore (no real changes are made to the items). Requires ProtocolLib.",
"Plain mode is faster, but may not reflect all changes immediately.",
"Packet mode is slower, but instantly reflect all changes. In creative mode, there is a chance for lore duplication.");
public static final JOption<Boolean> ENCHANTMENTS_DESCRIPTION_ENABLED = JOption.create("Enchantments.Description.Enabled", true,
"When 'true', adds the enchantment description to item lore under enchantment names.",
"Note #1: You must have ProtocolLib installed for this feature to work (as well as for enchantments name display).",

View File

@ -1,10 +1,12 @@
package su.nightexpress.excellentenchants.enchantment;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
@ -114,8 +116,7 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
// Класс для исключения неудачных попыток.
EnchantPopulator populator = new EnchantPopulator(obtainType, item);
// Херачим до талого, пока нужное количество не будет добавлено
// или не закончатся чары и/или тиры.
// Добавляем сколько можем, пока нужное количество не будет добавлено или не закончатся чары и/или тиры.
while (!populator.isEmpty() && enchRoll > 0) {
// Достигнут максимум чар (любых) для итема, заканчиваем.
if (enchantsToAdd.size() >= enchMax) break;
@ -159,6 +160,7 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
EnchantManager.getEnchantsToPopulate(item, obtainType).forEach((enchantment, level) -> {
EnchantManager.addEnchantment(item, enchantment, level, false);
});
EnchantManager.updateEnchantmentsDisplay(item);
return EnchantManager.getEnchantmentsAmount(item) != enchantsHad;
}
@ -193,11 +195,52 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
item.setItemMeta(meta);
}
public static final NamespacedKey KEY_LORE_SIZE = new NamespacedKey(ExcellentEnchantsAPI.PLUGIN, "lore_size");
public static boolean updateEnchantmentsDisplay(@NotNull ItemStack item) {
if (Config.ENCHANTMENTS_DISPLAY_MODE.get() != 1) return false;
if (!isEnchantable(item)) {
PDCUtil.remove(item, KEY_LORE_SIZE);
return false;
}
Map<ExcellentEnchant, Integer> enchants = EnchantManager.getExcellentEnchantments(item);
int sizeHas = PDCUtil.getInt(item, KEY_LORE_SIZE).orElse(0);
int sizeReal = enchants.size() + enchants.keySet().stream().map(ExcellentEnchant::getDescription).mapToInt(List::size).sum();
ItemMeta meta = item.getItemMeta();
if (meta == null) return false;
List<String> lore = meta.getLore() == null ? new ArrayList<>() : meta.getLore();
for (int index = 0; index < sizeHas && !lore.isEmpty(); index++) {
lore.remove(0);
}
if (!meta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) {
enchants.forEach((enchant, level) -> {
lore.addAll(0, enchant.formatDescription(level));
});
enchants.forEach((enchant, level) -> {
lore.add(0, enchant.getNameFormatted(level, getEnchantmentCharges(meta, enchant)));
});
}
meta.setLore(lore);
PDCUtil.set(meta, KEY_LORE_SIZE, sizeReal);
item.setItemMeta(meta);
return true;
}
@NotNull
public static Map<Enchantment, Integer> getEnchantments(@NotNull ItemStack item) {
ItemMeta meta = item.getItemMeta();
if (meta == null) return Collections.emptyMap();
return meta == null ? Collections.emptyMap() : getEnchantments(meta);
}
@NotNull
public static Map<Enchantment, Integer> getEnchantments(@NotNull ItemMeta meta) {
return (meta instanceof EnchantmentStorageMeta meta2) ? meta2.getStoredEnchants() : meta.getEnchants();
}
@ -214,7 +257,11 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
}
public static int getEnchantmentCharges(@NotNull ItemStack item, @NotNull ExcellentEnchant enchant) {
return PDCUtil.getIntData(item, enchant.getChargesKey());
return enchant.isChargesEnabled() ? PDCUtil.getIntData(item, enchant.getChargesKey()) : -1;
}
public static int getEnchantmentCharges(@NotNull ItemMeta meta, @NotNull ExcellentEnchant enchant) {
return enchant.isChargesEnabled() ? PDCUtil.getIntData(meta, enchant.getChargesKey()) : -1;
}
public static boolean isEnchantmentOutOfCharges(@NotNull ItemStack item, @NotNull ExcellentEnchant enchant) {
@ -269,7 +316,17 @@ public class EnchantManager extends AbstractManager<ExcellentEnchants> {
@NotNull
public static Map<ExcellentEnchant, Integer> getExcellentEnchantments(@NotNull ItemStack item) {
return EnchantManager.getEnchantments(item).entrySet().stream()
return getExcellentEnchantments(EnchantManager.getEnchantments(item));
}
@NotNull
public static Map<ExcellentEnchant, Integer> getExcellentEnchantments(@NotNull ItemMeta meta) {
return getExcellentEnchantments(EnchantManager.getEnchantments(meta));
}
@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());

View File

@ -113,7 +113,11 @@ public class EnchantSaturation extends ExcellentEnchant implements PassiveEnchan
public void action() {
for (LivingEntity entity : this.getEntities()) {
EnchantManager.getEquippedEnchants(entity, EnchantSaturation.class).forEach((item, enchants) -> {
enchants.forEach((enchant, level) -> enchant.onTrigger(entity, item, level));
enchants.forEach((enchant, level) -> {
if (enchant.onTrigger(entity, item, level)) {
enchant.consumeCharges(item);
}
});
});
}
}

View File

@ -113,7 +113,7 @@ public class EnchantDivineTouch extends ExcellentEnchant implements Chanced, Blo
e.setExpToDrop(0);
e.setDropItems(true);
block.setMetadata(META_HANDLE, new FixedMetadataValue(this.plugin, true));
return true;
return false; // Do not consume charges
}
// Update spawner type of the placed spawner mined by Divine Touch.

View File

@ -64,6 +64,7 @@ public class EnchantAnvilListener extends AbstractListener<ExcellentEnchants> {
EnchantManager.getExcellentEnchantments(first).forEach((hasEnch, hasLevel) -> {
EnchantManager.addEnchantment(result2, hasEnch, hasLevel, true);
});
EnchantManager.updateEnchantmentsDisplay(result2);
e.setResult(result2);
return true;
}
@ -86,6 +87,7 @@ public class EnchantAnvilListener extends AbstractListener<ExcellentEnchants> {
}
PDCUtil.setData(result2, RECHARGED, count);
EnchantManager.updateEnchantmentsDisplay(result2);
e.setResult(result2);
this.plugin.runTask(c -> e.getInventory().setRepairCost(chargeables.size()), false);
return true;
@ -120,6 +122,7 @@ public class EnchantAnvilListener extends AbstractListener<ExcellentEnchants> {
if (first.equals(result2)) return false;
EnchantManager.updateEnchantmentsDisplay(result2);
e.setResult(result2);
// NMS ContainerAnvil will set level cost to 0 right after calling the event, need 1 tick delay.

View File

@ -7,6 +7,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.enchantment.EnchantItemEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.entity.VillagerAcquireTradeEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
@ -19,6 +20,7 @@ import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.manager.AbstractListener;
import su.nexmedia.engine.hooks.Hooks;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant;
import su.nightexpress.excellentenchants.config.Config;
@ -80,9 +82,20 @@ public class EnchantGenericListener extends AbstractListener<ExcellentEnchants>
curses.forEach((excellentEnchant, level) -> {
EnchantManager.addEnchantment(result, excellentEnchant, level, true);
});
EnchantManager.updateEnchantmentsDisplay(result);
});
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEnchantUpdatePickup(EntityPickupItemEvent e) {
if (!(e.getEntity() instanceof Player player)) return;
Item item = e.getItem();
ItemStack itemStack = item.getItemStack();
if (EnchantManager.updateEnchantmentsDisplay(itemStack)) {
item.setItemStack(itemStack);
}
}
// ---------------------------------------------------------------
// Handle Enchanting Table
@ -117,6 +130,7 @@ public class EnchantGenericListener extends AbstractListener<ExcellentEnchants>
EnchantManager.restoreEnchantmentCharges(result, enchant);
}
});
EnchantManager.updateEnchantmentsDisplay(result);
e.getInventory().setItem(0, result);
});
@ -177,6 +191,8 @@ public class EnchantGenericListener extends AbstractListener<ExcellentEnchants>
if (Config.getObtainSettings(ObtainType.MOB_SPAWNING).isEmpty()) return;
LivingEntity entity = e.getEntity();
if (Hooks.isMythicMob(entity)) return;
EntityEquipment equipment = entity.getEquipment();
if (equipment == null) return;
@ -184,6 +200,7 @@ public class EnchantGenericListener extends AbstractListener<ExcellentEnchants>
ItemStack item = equipment.getItem(slot);
if (EnchantManager.isEnchantable(item)) {
EnchantManager.populateEnchantments(item, ObtainType.MOB_SPAWNING);
EnchantManager.getExcellentEnchantments(item).keySet().forEach(enchant -> EnchantManager.restoreEnchantmentCharges(item, enchant));
equipment.setItem(slot, item);
}
}

View File

@ -7,6 +7,7 @@ import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import org.bukkit.GameMode;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
import org.bukkit.inventory.meta.ItemMeta;
@ -82,9 +83,9 @@ public class ProtocolHook {
ItemStack copy = new ItemStack(item);
ItemMeta meta = copy.getItemMeta();
if (meta == null) return item;
if (meta == null || meta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) return item;
Map<ExcellentEnchant, Integer> enchants = EnchantManager.getExcellentEnchantments(item)
Map<ExcellentEnchant, Integer> enchants = EnchantManager.getExcellentEnchantments(meta)
.entrySet().stream()
.sorted(Comparator.comparing(e -> e.getKey().getTier().getPriority()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (old,nev) -> nev, LinkedHashMap::new));
@ -105,7 +106,7 @@ public class ProtocolHook {
});
}
enchants.forEach((enchant, level) -> {
int charges = EnchantManager.getEnchantmentCharges(item, enchant);
int charges = EnchantManager.getEnchantmentCharges(meta, enchant);
lore.add(0, enchant.getNameFormatted(level, charges));
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>ExcellentEnchants</artifactId>
<packaging>pom</packaging>
<version>3.3.0.4</version>
<version>3.3.1</version>
<modules>
<module>Core</module>
<module>NMS</module>