mirror of
https://github.com/nulli0n/ExcellentEnchants-spigot.git
synced 2025-03-11 13:13:38 +01:00
v4.3.2
This commit is contained in:
parent
b3a2e62c42
commit
01c497aaa4
4
.gitignore
vendored
4
.gitignore
vendored
@ -10,4 +10,6 @@
|
||||
/MC_1_21/target/
|
||||
/MC_1_21/pom.xml.versionsBackup
|
||||
/MC_1_21_3/target/
|
||||
/MC_1_21_3/pom.xml.versionsBackup
|
||||
/MC_1_21_3/pom.xml.versionsBackup
|
||||
/MC_1_21_4/target/
|
||||
/MC_1_21_4/pom.xml.versionsBackup
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -8,18 +8,17 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.MetaHolder;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.placeholder.PlaceholderMap;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public interface CustomEnchantment extends MetaHolder {
|
||||
|
||||
default void clear() {
|
||||
// default void clear() {
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@NotNull PlaceholderMap getPlaceholders(int level);
|
||||
@NotNull UnaryOperator<String> replacePlaceholders(int level);
|
||||
|
||||
@NotNull FileConfig getConfig();
|
||||
|
||||
@ -84,7 +83,4 @@ public interface CustomEnchantment extends MetaHolder {
|
||||
void fuelCharges(@NotNull ItemStack item, int level);
|
||||
|
||||
void consumeCharges(@NotNull ItemStack item, int level);
|
||||
|
||||
@Deprecated
|
||||
void consumeChargesNoUpdate(@NotNull ItemStack item, int level);
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.nightcore.util.TimeUtil;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
|
||||
public class DecayBlock {
|
||||
|
||||
private final Location location;
|
||||
private final long createDate;
|
||||
private final long decayDate;
|
||||
private final int sourceId;
|
||||
|
||||
public DecayBlock(@NotNull Location location, double seconds) {
|
||||
this.location = location;
|
||||
this.createDate = System.currentTimeMillis();
|
||||
this.decayDate = TimeUtil.createFutureTimestamp(seconds);
|
||||
this.sourceId = Rnd.nextInt(10000);
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
//long start = booster.getCreationDate();
|
||||
float end = this.decayDate - this.createDate;
|
||||
float now = System.currentTimeMillis() - this.createDate;
|
||||
|
||||
return /*1F - */now / end;
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
return TimeUtil.isPassed(this.decayDate);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Location getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public int getSourceId() {
|
||||
return this.sourceId;
|
||||
}
|
||||
|
||||
public long getDecayDate() {
|
||||
return this.decayDate;
|
||||
}
|
||||
}
|
@ -18,13 +18,11 @@ public class ItemsCategory {
|
||||
|
||||
private final Supplier<Set<Material>> supplier;
|
||||
private final EquipmentSlot[] slots;
|
||||
// private final EnchantmentTarget target;
|
||||
private final String localized;
|
||||
|
||||
public ItemsCategory(@NotNull Supplier<Set<Material>> supplier, EquipmentSlot[] slots/*, @Nullable EnchantmentTarget target*/, @Nullable String localized) {
|
||||
public ItemsCategory(@NotNull Supplier<Set<Material>> supplier, EquipmentSlot[] slots, @Nullable String localized) {
|
||||
this.supplier = supplier;
|
||||
this.slots = slots;
|
||||
// this.target = target;
|
||||
this.localized = localized;
|
||||
}
|
||||
|
||||
@ -62,13 +60,6 @@ public class ItemsCategory {
|
||||
return slots;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Only for compatibility reasons with versions < 1.21
|
||||
// */
|
||||
// public EnchantmentTarget getTarget() {
|
||||
// return target;
|
||||
// }
|
||||
|
||||
public String getLocalized() {
|
||||
return localized;
|
||||
}
|
||||
@ -77,7 +68,6 @@ public class ItemsCategory {
|
||||
|
||||
private Supplier<Set<Material>> supplier;
|
||||
private EquipmentSlot[] slots;
|
||||
// private EnchantmentTarget target;
|
||||
private String localized;
|
||||
|
||||
public Builder() {
|
||||
@ -87,7 +77,7 @@ public class ItemsCategory {
|
||||
|
||||
@NotNull
|
||||
public ItemsCategory build() {
|
||||
return new ItemsCategory(this.supplier, this.slots, /*this.target,*/ this.localized);
|
||||
return new ItemsCategory(this.supplier, this.slots, this.localized);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -102,13 +92,6 @@ public class ItemsCategory {
|
||||
return this;
|
||||
}
|
||||
|
||||
// @NotNull
|
||||
// @Deprecated
|
||||
// public Builder target(EnchantmentTarget target) {
|
||||
// this.target = target;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
@NotNull
|
||||
public Builder localized(@NotNull LangString localized) {
|
||||
return this.localized(localized.getString());
|
||||
|
@ -15,5 +15,4 @@ public enum TradeType {
|
||||
SWAMP_SPECIAL,
|
||||
TAIGA_COMMON,
|
||||
TAIGA_SPECIAL
|
||||
;
|
||||
}
|
||||
|
@ -1,22 +1,16 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment.bridge;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.nightcore.util.Pair;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public interface FlameWalker {
|
||||
|
||||
Map<Location, Pair<Long, Integer>> MAGMA_BLOCKS = new ConcurrentHashMap<>();
|
||||
void removeBlocks();
|
||||
|
||||
static void addBlock(@NotNull Block block, double seconds) {
|
||||
MAGMA_BLOCKS.put(block.getLocation(), Pair.of(System.currentTimeMillis() + (long) seconds * 1000L, Rnd.get(1000)));
|
||||
}
|
||||
void tickBlocks();
|
||||
|
||||
void addBlock(@NotNull Block block, int level);
|
||||
|
||||
@NotNull Modifier getRadius();
|
||||
|
||||
|
16
Core/pom.xml
16
Core/pom.xml
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -89,25 +89,31 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>MC_1_21_4</artifactId>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>MC_1_21_3</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>MC_1_21</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
@ -17,6 +17,7 @@ import su.nightexpress.excellentenchants.hook.impl.PlaceholderHook;
|
||||
import su.nightexpress.excellentenchants.hook.impl.ProtocolLibHook;
|
||||
import su.nightexpress.excellentenchants.nms.EnchantNMS;
|
||||
import su.nightexpress.excellentenchants.nms.Internal_1_21_3;
|
||||
import su.nightexpress.excellentenchants.nms.Internal_1_21_4;
|
||||
import su.nightexpress.excellentenchants.rarity.RarityManager;
|
||||
import su.nightexpress.excellentenchants.registry.EnchantRegistry;
|
||||
import su.nightexpress.nightcore.NightPlugin;
|
||||
@ -79,12 +80,14 @@ public class EnchantsPlugin extends NightPlugin implements ImprovedCommands {
|
||||
if (this.rarityManager != null) this.rarityManager.shutdown();
|
||||
|
||||
this.registry.shutdown();
|
||||
Keys.clear();
|
||||
}
|
||||
|
||||
private boolean loadInternals() {
|
||||
this.enchantNMS = switch (Version.getCurrent()) {
|
||||
case MC_1_21 -> new Internal_1_21(this);
|
||||
case MC_1_21_3 -> new Internal_1_21_3(this);
|
||||
case MC_1_21_4 -> new Internal_1_21_4(this);
|
||||
default -> null;
|
||||
};
|
||||
|
||||
|
@ -5,10 +5,10 @@ import su.nightexpress.excellentenchants.api.enchantment.meta.ChanceMeta;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.PeriodMeta;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.PotionMeta;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
|
||||
import su.nightexpress.excellentenchants.util.EnchantPlaceholders;
|
||||
import su.nightexpress.nightcore.language.LangAssets;
|
||||
import su.nightexpress.nightcore.util.ItemUtil;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.placeholder.PlaceholderList;
|
||||
|
||||
public class Placeholders extends su.nightexpress.nightcore.util.Placeholders {
|
||||
|
||||
@ -53,24 +53,24 @@ public class Placeholders extends su.nightexpress.nightcore.util.Placeholders {
|
||||
public static final String ENCHANTMENT_CHARGES_RECHARGE_AMOUNT = "%enchantment_charges_recharge_amount%";
|
||||
public static final String ENCHANTMENT_CHARGES_FUEL_ITEM = "%enchantment_charges_fuel_item%";
|
||||
|
||||
public static EnchantPlaceholders forEnchant(@NotNull GameEnchantment enchantment) {
|
||||
EnchantPlaceholders placeholders = new EnchantPlaceholders();
|
||||
|
||||
placeholders
|
||||
.add(ENCHANTMENT_ID, enchantment::getId)
|
||||
.add(ENCHANTMENT_NAME, enchantment::getDisplayName)
|
||||
.add(ENCHANTMENT_DESCRIPTION, () -> String.join("\n", enchantment.getDescription()))
|
||||
@NotNull
|
||||
public static PlaceholderList<Integer> forEnchant(@NotNull GameEnchantment enchantment) {
|
||||
PlaceholderList<Integer> placeholders = PlaceholderList.create(list -> list
|
||||
.add(ENCHANTMENT_ID, level -> enchantment.getId())
|
||||
.add(ENCHANTMENT_NAME, level -> enchantment.getDisplayName())
|
||||
.add(ENCHANTMENT_DESCRIPTION, level -> String.join("\n", enchantment.getDescription()))
|
||||
//.add(ENCHANTMENT_DESCRIPTION_FORMATTED, () -> String.join("\n", enchantment.getDescriptionFormatted()))
|
||||
.add(ENCHANTMENT_DESCRIPTION_REPLACED, level -> String.join("\n", enchantment.getDescription(level)))
|
||||
.add(ENCHANTMENT_LEVEL, NumberUtil::toRoman)
|
||||
.add(ENCHANTMENT_LEVEL_MIN, () -> String.valueOf(1))
|
||||
.add(ENCHANTMENT_LEVEL_MAX, () -> String.valueOf(enchantment.getDefinition().getMaxLevel()))
|
||||
.add(ENCHANTMENT_RARITY, () -> enchantment.getDefinition().getRarity().getName())
|
||||
.add(ENCHANTMENT_FIT_ITEM_TYPES, () -> enchantment.getDefinition().getSupportedItems().getLocalized())
|
||||
.add(ENCHANTMENT_LEVEL_MIN, level -> String.valueOf(1))
|
||||
.add(ENCHANTMENT_LEVEL_MAX, level -> String.valueOf(enchantment.getDefinition().getMaxLevel()))
|
||||
.add(ENCHANTMENT_RARITY, level -> enchantment.getDefinition().getRarity().getName())
|
||||
.add(ENCHANTMENT_FIT_ITEM_TYPES, level -> enchantment.getDefinition().getSupportedItems().getLocalized())
|
||||
.add(ENCHANTMENT_CHARGES_MAX_AMOUNT, level -> NumberUtil.format(enchantment.getCharges().getMaxAmount(level)))
|
||||
.add(ENCHANTMENT_CHARGES_CONSUME_AMOUNT, level -> NumberUtil.format(enchantment.getCharges().getConsumeAmount(level)))
|
||||
.add(ENCHANTMENT_CHARGES_RECHARGE_AMOUNT, level -> NumberUtil.format(enchantment.getCharges().getRechargeAmount(level)))
|
||||
.add(ENCHANTMENT_CHARGES_FUEL_ITEM, () -> ItemUtil.getItemName(enchantment.getCharges().getFuel()));
|
||||
.add(ENCHANTMENT_CHARGES_FUEL_ITEM, level -> ItemUtil.getItemName(enchantment.getCharges().getFuel()))
|
||||
);
|
||||
|
||||
if (enchantment instanceof ChanceMeta chanceMeta) {
|
||||
placeholders.add(ENCHANTMENT_CHANCE, level -> NumberUtil.format(chanceMeta.getTriggerChance(level)));
|
||||
|
@ -31,7 +31,7 @@ public class BaseCommands {
|
||||
public static void load(@NotNull EnchantsPlugin plugin) {
|
||||
ChainedNode rootNode = plugin.getRootNode();
|
||||
|
||||
ReloadCommand.inject(plugin, rootNode, Perms.COMMAND_RELOAD);
|
||||
rootNode.addChildren(ReloadCommand.builder(plugin, Perms.COMMAND_RELOAD));
|
||||
|
||||
rootNode.addChildren(DirectNode.builder(plugin, "book")
|
||||
.description(Lang.COMMAND_BOOK_DESC)
|
||||
@ -111,10 +111,10 @@ public class BaseCommands {
|
||||
EnchantUtils.add(item, enchantment, level, true);
|
||||
Players.addItem(player, item);
|
||||
|
||||
Lang.COMMAND_BOOK_DONE.getMessage()
|
||||
Lang.COMMAND_BOOK_DONE.getMessage().send(context.getSender(), replacer -> replacer
|
||||
.replace(Placeholders.GENERIC_ENCHANT, EnchantUtils.getLocalized(enchantment))
|
||||
.replace(Placeholders.forPlayer(player))
|
||||
.send(context.getSender());
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -138,12 +138,12 @@ public class BaseCommands {
|
||||
EnchantUtils.add(item, enchantment, level, true);
|
||||
}
|
||||
|
||||
(context.getSender() == player ? Lang.COMMAND_ENCHANT_DONE_SELF : Lang.COMMAND_ENCHANT_DONE_OTHERS).getMessage()
|
||||
(context.getSender() == player ? Lang.COMMAND_ENCHANT_DONE_SELF : Lang.COMMAND_ENCHANT_DONE_OTHERS).getMessage().send(context.getSender(), replacer -> replacer
|
||||
.replace(Placeholders.forPlayer(player))
|
||||
.replace(Placeholders.GENERIC_ITEM, ItemUtil.getItemName(item))
|
||||
.replace(Placeholders.GENERIC_ENCHANT, EnchantUtils.getLocalized(enchantment))
|
||||
.replace(Placeholders.GENERIC_LEVEL, NumberUtil.toRoman(level))
|
||||
.send(context.getSender());
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -163,11 +163,11 @@ public class BaseCommands {
|
||||
Enchantment enchantment = arguments.getEnchantmentArgument(CommandArguments.ENCHANT);
|
||||
EnchantUtils.remove(item, enchantment);
|
||||
|
||||
(context.getSender() == player ? Lang.COMMAND_DISENCHANT_DONE_SELF : Lang.COMMAND_DISENCHANT_DONE_OTHERS).getMessage()
|
||||
(context.getSender() == player ? Lang.COMMAND_DISENCHANT_DONE_SELF : Lang.COMMAND_DISENCHANT_DONE_OTHERS).getMessage().send(context.getSender(), replacer -> replacer
|
||||
.replace(Placeholders.forPlayer(player))
|
||||
.replace(Placeholders.GENERIC_ITEM, ItemUtil.getItemName(item))
|
||||
.replace(Placeholders.GENERIC_ENCHANT, EnchantUtils.getLocalized(enchantment))
|
||||
.send(context.getSender());
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -178,9 +178,9 @@ public class BaseCommands {
|
||||
int amount = arguments.getIntArgument(CommandArguments.AMOUNT, 1);
|
||||
|
||||
if (!enchantment.hasCharges()) {
|
||||
Lang.COMMAND_GET_FUEL_ERROR_NO_CHARGES.getMessage()
|
||||
Lang.COMMAND_GET_FUEL_ERROR_NO_CHARGES.getMessage().send(context.getSender(), replacer -> replacer
|
||||
.replace(Placeholders.GENERIC_NAME, enchantment.getDisplayName())
|
||||
.send(context.getSender());
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -189,10 +189,10 @@ public class BaseCommands {
|
||||
|
||||
Players.addItem(player, fuel);
|
||||
|
||||
Lang.COMMAND_GET_FUEL_DONE.getMessage()
|
||||
Lang.COMMAND_GET_FUEL_DONE.getMessage().send(context.getSender(), replacer -> replacer
|
||||
.replace(Placeholders.GENERIC_AMOUNT, NumberUtil.format(amount))
|
||||
.replace(Placeholders.GENERIC_NAME, ItemUtil.getItemName(fuel))
|
||||
.send(context.getSender());
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -204,7 +204,7 @@ public class BaseCommands {
|
||||
plugin.getEnchantManager().openEnchantsMenu(player);
|
||||
|
||||
if (player != context.getSender()) {
|
||||
Lang.COMMAND_LIST_DONE_OTHERS.getMessage().replace(Placeholders.forPlayer(player)).send(context.getSender());
|
||||
Lang.COMMAND_LIST_DONE_OTHERS.getMessage().send(context.getSender(), replacer -> replacer.replace(Placeholders.forPlayer(player)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -229,10 +229,10 @@ public class BaseCommands {
|
||||
EnchantUtils.add(item, enchantment, level, true);
|
||||
Players.addItem(player, item);
|
||||
|
||||
Lang.COMMAND_RARITY_BOOK_DONE.getMessage()
|
||||
Lang.COMMAND_RARITY_BOOK_DONE.getMessage().send(context.getSender(), replacer -> replacer
|
||||
.replace(Placeholders.GENERIC_NAME, rarity.getName())
|
||||
.replace(Placeholders.forPlayer(player))
|
||||
.send(context.getSender());
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
package su.nightexpress.excellentenchants.config;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import su.nightexpress.excellentenchants.util.ChargesFormat;
|
||||
import su.nightexpress.excellentenchants.util.EnchantBlacklist;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.Lists;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.bukkit.NightItem;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
import static su.nightexpress.nightcore.util.text.tag.Tags.*;
|
||||
@ -116,14 +120,12 @@ public class Config {
|
||||
"[**] Disabled enchantments will be removed from all items forever!"
|
||||
);
|
||||
|
||||
public static final ConfigValue<Map<String, Set<String>>> ENCHANTMENTS_DISABLED_IN_WORLDS = ConfigValue.forMap("Enchantments.Disabled.ByWorld",
|
||||
String::toLowerCase,
|
||||
(cfg, path, worldName) -> cfg.getStringSet(path + "." + worldName).stream().map(String::toLowerCase).collect(Collectors.toSet()),
|
||||
(cfg, path, map) -> map.forEach((world, enchants) -> cfg.set(path + "." + world, enchants)),
|
||||
() -> Map.of(
|
||||
"your_world_name", Lists.newSet("enchantment_name", "ice_aspect"),
|
||||
"another_world", Lists.newSet("another_enchantment", "ice_aspect")
|
||||
),
|
||||
public static final ConfigValue<Map<String, EnchantBlacklist>> ENCHANTMENTS_DISABLED_IN_WORLDS = ConfigValue.forMapById("Enchantments.Disabled.ByWorld",
|
||||
EnchantBlacklist::read,
|
||||
map -> {
|
||||
map.put("your_world_name", new EnchantBlacklist(Lists.newSet("enchantment_name", "ice_aspect")));
|
||||
map.put("another_world", new EnchantBlacklist(Lists.newSet("another_enchantment", "ice_aspect")));
|
||||
},
|
||||
"Put here CUSTOM enchantment names that you want to disable in specific worlds.",
|
||||
"To disable all enchantments for a world, use '" + WILDCARD + "' instead of enchantment names.",
|
||||
"Enchantment names are equal to their config file names in the '" + DIR_ENCHANTS + "' directory.",
|
||||
@ -170,17 +172,13 @@ public class Config {
|
||||
WIKI_CHRAGES
|
||||
);
|
||||
|
||||
public static final ConfigValue<TreeMap<Integer, String>> ENCHANTMENTS_CHARGES_FORMAT = ConfigValue.forTreeMap("Enchantments.Charges.Format",
|
||||
raw -> NumberUtil.getInteger(raw, 0),
|
||||
(cfg, path, value) -> cfg.getString(path + "." + value, GENERIC_AMOUNT),
|
||||
(cfg, path, map) -> map.forEach((perc, str) -> cfg.set(path + "." + perc, str)),
|
||||
() -> {
|
||||
TreeMap<Integer, String> map = new TreeMap<>();
|
||||
map.put(0, LIGHT_RED.enclose("(" + GENERIC_AMOUNT + "⚡)"));
|
||||
map.put(25, LIGHT_ORANGE.enclose("(" + GENERIC_AMOUNT + "⚡)"));
|
||||
map.put(50, LIGHT_YELLOW.enclose("(" + GENERIC_AMOUNT + "⚡)"));
|
||||
map.put(75, LIGHT_GREEN.enclose("(" + GENERIC_AMOUNT + "⚡)"));
|
||||
return map;
|
||||
public static final ConfigValue<Map<String, ChargesFormat>> ENCHANTMENTS_CHARGES_FORMAT = ConfigValue.forMapById("Enchantments.Charges.Formation",
|
||||
ChargesFormat::read,
|
||||
map -> {
|
||||
map.put("zero", new ChargesFormat(0, LIGHT_RED.enclose("(" + GENERIC_AMOUNT + "⚡)")));
|
||||
map.put("low", new ChargesFormat(25, LIGHT_ORANGE.enclose("(" + GENERIC_AMOUNT + "⚡)")));
|
||||
map.put("medium", new ChargesFormat(50, LIGHT_YELLOW.enclose("(" + GENERIC_AMOUNT + "⚡)")));
|
||||
map.put("high", new ChargesFormat(75, LIGHT_GREEN.enclose("(" + GENERIC_AMOUNT + "⚡)")));
|
||||
},
|
||||
"Enchantment charges format depends on amount of charges left (in percent).",
|
||||
"If you don't want to display charges, leave only keys with negative values.",
|
||||
@ -194,8 +192,8 @@ public class Config {
|
||||
"[Default is false]"
|
||||
);
|
||||
|
||||
public static final ConfigValue<ItemStack> ENCHANTMENTS_CHARGES_FUEL_ITEM = ConfigValue.create("Enchantments.Charges.Fuel_Item",
|
||||
new ItemStack(Material.LAPIS_LAZULI),
|
||||
public static final ConfigValue<NightItem> ENCHANTMENTS_CHARGES_FUEL_ITEM = ConfigValue.create("Enchantments.Charges.Fuel_Item",
|
||||
new NightItem(Material.LAPIS_LAZULI),
|
||||
"Default item used to recharge item's enchantments on anvils.",
|
||||
"If you want different item for certain enchantments, you can do it in that enchantment configs.",
|
||||
"Item Options: " + WIKI_ITEMS_URL
|
||||
@ -209,4 +207,9 @@ public class Config {
|
||||
public static boolean isChargesEnabled() {
|
||||
return ENCHANTMENTS_CHARGES_ENABLED.get();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static EnchantBlacklist getDisabledEnchantments(@NotNull World world) {
|
||||
return ENCHANTMENTS_DISABLED_IN_WORLDS.get().get(world.getName().toLowerCase());
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,18 @@ import su.nightexpress.excellentenchants.EnchantsPlugin;
|
||||
public class Keys {
|
||||
|
||||
public static NamespacedKey itemRecharged;
|
||||
|
||||
public static NamespacedKey keyLevel;
|
||||
public static NamespacedKey entitySpawnReason;
|
||||
|
||||
public static void loadKeys(@NotNull EnchantsPlugin plugin) {
|
||||
itemRecharged = new NamespacedKey(plugin, "item.recharged");
|
||||
keyLevel = new NamespacedKey(plugin, "list_display_level");
|
||||
entitySpawnReason = new NamespacedKey(plugin, "entity.spawn_reason");
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
itemRecharged = null;
|
||||
keyLevel = null;
|
||||
entitySpawnReason = null;
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.EnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.ConfigBridge;
|
||||
import su.nightexpress.excellentenchants.api.EnchantmentID;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.bridge.FlameWalker;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.PeriodMeta;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.PassiveEnchant;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.armor.FlameWalkerEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.listener.AnvilListener;
|
||||
import su.nightexpress.excellentenchants.enchantment.listener.GenericListener;
|
||||
import su.nightexpress.excellentenchants.enchantment.menu.EnchantsMenu;
|
||||
@ -25,7 +26,6 @@ public class EnchantManager extends AbstractManager<EnchantsPlugin> {
|
||||
|
||||
private final Set<PassiveEnchant> passiveEnchants;
|
||||
|
||||
|
||||
private EnchantsMenu enchantsMenu;
|
||||
|
||||
public EnchantManager(@NotNull EnchantsPlugin plugin) {
|
||||
@ -40,17 +40,25 @@ public class EnchantManager extends AbstractManager<EnchantsPlugin> {
|
||||
this.addListener(new GenericListener(this.plugin, this));
|
||||
this.addListener(new AnvilListener(this.plugin));
|
||||
|
||||
this.addTask(this.plugin.createAsyncTask(this::displayProjectileTrails).setTicksInterval(Config.CORE_PROJECTILE_PARTICLE_INTERVAL.get()));
|
||||
this.addAsyncTask(this::displayProjectileTrails, Config.CORE_PROJECTILE_PARTICLE_INTERVAL.get());
|
||||
|
||||
if (!this.passiveEnchants.isEmpty()) {
|
||||
this.addTask(this.plugin.createTask(this::updatePassiveEnchantEffects).setTicksInterval(ConfigBridge.getEnchantsTickInterval()));
|
||||
this.addTask(this::updatePassiveEnchantEffects, ConfigBridge.getEnchantsTickInterval());
|
||||
}
|
||||
if (EnchantRegistry.isRegistered(EnchantmentID.FLAME_WALKER)) {
|
||||
this.addTask(this.plugin.createTask(FlameWalkerEnchant::tickBlocks).setSecondsInterval(1));
|
||||
|
||||
CustomEnchantment enchantment = EnchantRegistry.getById(EnchantmentID.FLAME_WALKER);
|
||||
if (enchantment instanceof FlameWalker flameWalker) {
|
||||
this.addTask(flameWalker::tickBlocks, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown() {
|
||||
CustomEnchantment enchantment = EnchantRegistry.getById(EnchantmentID.FLAME_WALKER);
|
||||
if (enchantment instanceof FlameWalker flameWalker) {
|
||||
flameWalker.removeBlocks();
|
||||
}
|
||||
|
||||
if (this.enchantsMenu != null) this.enchantsMenu.clear();
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import su.nightexpress.excellentenchants.api.enchantment.Charges;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.bukkit.NightItem;
|
||||
|
||||
import static su.nightexpress.nightcore.util.Placeholders.WIKI_ITEMS_URL;
|
||||
|
||||
@ -18,7 +19,7 @@ public class EnchantCharges implements Charges {
|
||||
private Modifier maxAmount;
|
||||
private Modifier consumeAmount;
|
||||
private Modifier rechargeAmount;
|
||||
private ItemStack fuel;
|
||||
private NightItem fuel;
|
||||
|
||||
public EnchantCharges() {
|
||||
|
||||
@ -54,7 +55,7 @@ public class EnchantCharges implements Charges {
|
||||
);
|
||||
|
||||
this.fuel = ConfigValue.create("Charges.Fuel_Item",
|
||||
new ItemStack(Material.LAPIS_LAZULI),
|
||||
new NightItem(Material.LAPIS_LAZULI),
|
||||
"An item, that will be used to restore enchantment charges on anvils.",
|
||||
WIKI_ITEMS_URL
|
||||
).read(config);
|
||||
@ -93,11 +94,10 @@ public class EnchantCharges implements Charges {
|
||||
|
||||
@NotNull
|
||||
public ItemStack getFuel() {
|
||||
ItemStack fuelHas = this.fuel;
|
||||
if (!this.isCustomFuel() || fuelHas == null || fuelHas.getType().isAir()) {
|
||||
return new ItemStack(Config.ENCHANTMENTS_CHARGES_FUEL_ITEM.get());
|
||||
if (!this.isCustomFuel() || this.fuel == null || this.fuel.getMaterial().isAir()) {
|
||||
return Config.ENCHANTMENTS_CHARGES_FUEL_ITEM.get().getItemStack();
|
||||
}
|
||||
return new ItemStack(fuelHas);
|
||||
return this.fuel.getItemStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -12,31 +12,30 @@ import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.meta.EnchantMeta;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.excellentenchants.util.EnchantPlaceholders;
|
||||
import su.nightexpress.excellentenchants.util.EnchantBlacklist;
|
||||
import su.nightexpress.excellentenchants.util.EnchantUtils;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.manager.AbstractFileData;
|
||||
import su.nightexpress.nightcore.manager.SimpeListener;
|
||||
import su.nightexpress.nightcore.util.PDCUtil;
|
||||
import su.nightexpress.nightcore.util.placeholder.PlaceholderMap;
|
||||
import su.nightexpress.nightcore.util.placeholder.PlaceholderList;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public abstract class GameEnchantment extends AbstractFileData<EnchantsPlugin> implements CustomEnchantment {
|
||||
|
||||
protected final EnchantMeta meta;
|
||||
protected final EnchantDefinition definition;
|
||||
protected final EnchantDistribution distribution;
|
||||
protected final EnchantCharges charges;
|
||||
private final NamespacedKey chargesKey;
|
||||
private final EnchantPlaceholders placeholders;
|
||||
private final String logPrefix;
|
||||
protected final EnchantMeta meta;
|
||||
protected final EnchantDefinition definition;
|
||||
protected final EnchantDistribution distribution;
|
||||
protected final EnchantCharges charges;
|
||||
private final NamespacedKey chargesKey;
|
||||
private final PlaceholderList<Integer> placeholders;
|
||||
private final String logPrefix;
|
||||
|
||||
private Enchantment enchantment;
|
||||
private boolean hiddenFromList;
|
||||
@ -125,9 +124,10 @@ public abstract class GameEnchantment extends AbstractFileData<EnchantsPlugin> i
|
||||
this.plugin.error(this.logPrefix + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PlaceholderMap getPlaceholders(int level) {
|
||||
return this.placeholders.toMap(level);
|
||||
public UnaryOperator<String> replacePlaceholders(int level) {
|
||||
return this.placeholders.replacer(level);
|
||||
}
|
||||
|
||||
public void addPlaceholder(@NotNull String key, @NotNull Function<Integer, String> replacer) {
|
||||
@ -166,8 +166,8 @@ public abstract class GameEnchantment extends AbstractFileData<EnchantsPlugin> i
|
||||
|
||||
@Override
|
||||
public boolean isAvailableToUse(@NotNull World world) {
|
||||
Set<String> disabled = Config.ENCHANTMENTS_DISABLED_IN_WORLDS.get().getOrDefault(world.getName().toLowerCase(), Collections.emptySet());
|
||||
return disabled.isEmpty() || (!disabled.contains(this.getId()) && !disabled.contains(Placeholders.WILDCARD));
|
||||
EnchantBlacklist blacklist = Config.getDisabledEnchantments(world);
|
||||
return blacklist == null || !blacklist.contains(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -183,7 +183,7 @@ public abstract class GameEnchantment extends AbstractFileData<EnchantsPlugin> i
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFormattedName() {
|
||||
return this.isCurse() ? this.getDisplayName() : this.getPlaceholders(1).replacer().apply(this.definition.getRarity().getNameFormat());
|
||||
return this.isCurse() ? this.getDisplayName() : this.replacePlaceholders(1).apply(this.definition.getRarity().getNameFormat());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -208,7 +208,7 @@ public abstract class GameEnchantment extends AbstractFileData<EnchantsPlugin> i
|
||||
description.replaceAll(line -> {
|
||||
line = lineFormat.replace(Placeholders.GENERIC_DESCRIPTION, line);
|
||||
line = EnchantUtils.replaceComponents(this, line, level, charges);
|
||||
line = this.getPlaceholders(level).replacer().apply(line);
|
||||
line = this.replacePlaceholders(level).apply(line);
|
||||
return line;
|
||||
});
|
||||
return description;
|
||||
@ -297,7 +297,7 @@ public abstract class GameEnchantment extends AbstractFileData<EnchantsPlugin> i
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeChargesNoUpdate(@NotNull ItemStack item, int level) {
|
||||
public void consumeCharges(@NotNull ItemStack item, int level) {
|
||||
if (!this.hasCharges()) return;
|
||||
|
||||
int charges = this.getCharges(item);
|
||||
@ -305,11 +305,4 @@ public abstract class GameEnchantment extends AbstractFileData<EnchantsPlugin> i
|
||||
|
||||
this.setCharges(item, level, charges < consumeAmount ? 0 : Math.max(0, charges - consumeAmount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeCharges(@NotNull ItemStack item, int level) {
|
||||
if (!this.hasCharges()) return;
|
||||
|
||||
this.consumeChargesNoUpdate(item, level);
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,10 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.EnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.DecayBlock;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.TradeType;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.GenericEnchant;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.bridge.FlameWalker;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.type.GenericEnchant;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDefinition;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.EnchantDistribution;
|
||||
import su.nightexpress.excellentenchants.enchantment.impl.GameEnchantment;
|
||||
@ -32,17 +33,21 @@ import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.manager.SimpeListener;
|
||||
import su.nightexpress.nightcore.util.BukkitThing;
|
||||
import su.nightexpress.nightcore.util.Lists;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class FlameWalkerEnchant extends GameEnchantment implements GenericEnchant, FlameWalker, SimpeListener {
|
||||
|
||||
private static final BlockFace[] FACES = {BlockFace.SOUTH, BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST};
|
||||
|
||||
private final Map<Location, DecayBlock> magmaBlocks = new ConcurrentHashMap<>();
|
||||
|
||||
private Modifier radius;
|
||||
private Modifier blockDecayTime;
|
||||
|
||||
@ -86,45 +91,47 @@ public class FlameWalkerEnchant extends GameEnchantment implements GenericEnchan
|
||||
return this.blockDecayTime.getValue(level);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void clear() {
|
||||
// this.removeBlocks();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
MAGMA_BLOCKS.keySet().forEach(location -> location.getBlock().setType(Material.LAVA));
|
||||
MAGMA_BLOCKS.clear();
|
||||
public void removeBlocks() {
|
||||
magmaBlocks.keySet().forEach(location -> location.getBlock().setType(Material.LAVA));
|
||||
magmaBlocks.clear();
|
||||
}
|
||||
|
||||
public static boolean isBlock(@NotNull Block block) {
|
||||
return MAGMA_BLOCKS.containsKey(block.getLocation());
|
||||
public boolean isBlock(@NotNull Block block) {
|
||||
return magmaBlocks.containsKey(block.getLocation());
|
||||
}
|
||||
|
||||
public static void tickBlocks() {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
MAGMA_BLOCKS.keySet().removeIf(location -> location.getBlock().isLiquid() || location.getBlock().getType() != Material.MAGMA_BLOCK);
|
||||
MAGMA_BLOCKS.forEach((location, pair) -> {
|
||||
@Override
|
||||
public void tickBlocks() {
|
||||
magmaBlocks.keySet().removeIf(location -> location.getBlock().isLiquid() || location.getBlock().getType() != Material.MAGMA_BLOCK);
|
||||
magmaBlocks.forEach((location, decayBlock) -> {
|
||||
Block block = location.getBlock();
|
||||
long time = pair.getFirst();
|
||||
if (now >= time) {
|
||||
if (decayBlock.isExpired()) {
|
||||
block.getWorld().getPlayers().forEach(player -> {
|
||||
player.sendBlockDamage(location, 0F, pair.getSecond());
|
||||
player.sendBlockDamage(location, 0F, decayBlock.getSourceId());
|
||||
});
|
||||
block.setType(Material.LAVA);
|
||||
UniParticle.blockCrack(Material.MAGMA_BLOCK).play(location, 0.5, 0.7, 0.5, 0.03, 30);
|
||||
return;
|
||||
}
|
||||
|
||||
long diff = TimeUnit.MILLISECONDS.toSeconds(time - now);
|
||||
|
||||
float progress = (float) (1D - Math.min(1D, diff / 5D));
|
||||
if (progress > 1F) progress = 1F;
|
||||
if (progress < 0F) progress = 0F;
|
||||
|
||||
float finalProgress = progress;
|
||||
float progress = decayBlock.getProgress();
|
||||
block.getWorld().getPlayers().forEach(player -> {
|
||||
player.sendBlockDamage(location, finalProgress, pair.getSecond());
|
||||
player.sendBlockDamage(location, progress, decayBlock.getSourceId());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBlock(@NotNull Block block, int level) {
|
||||
this.magmaBlocks.put(block.getLocation(), new DecayBlock(block.getLocation(), Rnd.getDouble(this.getBlockDecayTime(level)) + 1));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
@ -80,6 +80,7 @@ public class TreasureHunterEnchant extends GameEnchantment implements ChanceMeta
|
||||
"Available loot table names: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/loot/LootTables.html"
|
||||
).read(config);
|
||||
|
||||
this.lootTables.clear();
|
||||
if (isWhitelist) {
|
||||
this.lootTables.addAll(tables);
|
||||
}
|
||||
@ -89,10 +90,10 @@ public class TreasureHunterEnchant extends GameEnchantment implements ChanceMeta
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.lootTables.clear();
|
||||
}
|
||||
// @Override
|
||||
// public void clear() {
|
||||
// this.lootTables.clear();
|
||||
// }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onLootExplore(LootGenerateEvent event) {
|
||||
|
@ -48,6 +48,7 @@ public class SurvivalistEnchant extends GameEnchantment implements FishingEnchan
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.meta.setProbability(Probability.create(config));
|
||||
|
||||
this.cookingRecipes.clear();
|
||||
this.plugin.getServer().recipeIterator().forEachRemaining(recipe -> {
|
||||
if (recipe instanceof CookingRecipe<?> cookingRecipe && cookingRecipe.getInput().getType().isItem() && !cookingRecipe.getResult().getType().isAir()) {
|
||||
this.cookingRecipes.add(cookingRecipe);
|
||||
@ -55,10 +56,10 @@ public class SurvivalistEnchant extends GameEnchantment implements FishingEnchan
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.cookingRecipes.clear();
|
||||
}
|
||||
// @Override
|
||||
// public void clear() {
|
||||
// this.cookingRecipes.clear();
|
||||
// }
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
|
@ -84,6 +84,9 @@ public class SmelterEnchant extends GameEnchantment implements ChanceMeta, Block
|
||||
|
||||
this.sound = ConfigValue.create("Settings.Sound", NightSound.of(Sound.BLOCK_LAVA_EXTINGUISH), "Sound to play on smelting.").read(config);
|
||||
|
||||
this.recipes.clear();
|
||||
this.exemptedItems.clear();
|
||||
|
||||
this.exemptedItems.addAll(ConfigValue.forSet("Settings.Exempted_Blocks",
|
||||
BukkitThing::getMaterial,
|
||||
(cfg, path, set) -> cfg.set(path, set.stream().map(BukkitThing::toString).toList()),
|
||||
@ -100,11 +103,11 @@ public class SmelterEnchant extends GameEnchantment implements ChanceMeta, Block
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.recipes.clear();
|
||||
this.exemptedItems.clear();
|
||||
}
|
||||
// @Override
|
||||
// public void clear() {
|
||||
// this.recipes.clear();
|
||||
// this.exemptedItems.clear();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean onDrop(@NotNull BlockDropItemEvent event, @NotNull LivingEntity entity, @NotNull ItemStack item, int level) {
|
||||
|
@ -80,7 +80,7 @@ public class RestoreEnchant extends GameEnchantment implements GenericEnchant, C
|
||||
if (!this.checkTriggerChance(level)) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
this.consumeChargesNoUpdate(item, level);
|
||||
this.consumeCharges(item, level);
|
||||
|
||||
double restorePercent = 100D - this.getDurabilityRestore(level);
|
||||
int restored = (int) (maxDurability * (restorePercent / 100D));
|
||||
|
@ -79,7 +79,7 @@ public class SoulboundEnchant extends GameEnchantment implements GenericEnchant,
|
||||
world.dropItemNaturally(location, save);
|
||||
}
|
||||
else {
|
||||
this.consumeChargesNoUpdate(save, EnchantUtils.getLevel(save, this.getBukkitEnchantment()));
|
||||
this.consumeCharges(save, EnchantUtils.getLevel(save, this.getBukkitEnchantment()));
|
||||
player.getInventory().addItem(save);
|
||||
}
|
||||
});
|
||||
|
@ -107,6 +107,7 @@ public class ScavengerEnchant extends GameEnchantment implements ChanceMeta, Dea
|
||||
"Available loot table names: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/loot/LootTables.html"
|
||||
).read(config);
|
||||
|
||||
this.lootTables.clear();
|
||||
if (isWhitelist) {
|
||||
this.lootTables.addAll(tables);
|
||||
}
|
||||
@ -116,10 +117,10 @@ public class ScavengerEnchant extends GameEnchantment implements ChanceMeta, Dea
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.lootTables.clear();
|
||||
}
|
||||
// @Override
|
||||
// public void clear() {
|
||||
// this.lootTables.clear();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean onKill(@NotNull EntityDeathEvent event, @NotNull LivingEntity entity, @NotNull Player killer, @NotNull ItemStack weapon, int level) {
|
||||
|
@ -41,27 +41,11 @@ public class AnvilListener extends AbstractListener<EnchantsPlugin> {
|
||||
if (second == null) second = new ItemStack(Material.AIR);
|
||||
if (result == null) result = new ItemStack(Material.AIR);
|
||||
|
||||
//if (first.getType().isAir() || first.getAmount() > 1 || !EnchantUtils.isEnchantable(first)) return;
|
||||
|
||||
//if (this.handleRename(event, first, second, result)) return;
|
||||
|
||||
if (this.handleRecharge(event, first, second)) return;
|
||||
|
||||
this.handleCombine(event, first, second, result);
|
||||
}
|
||||
|
||||
/*private boolean handleRename(@NotNull PrepareAnvilEvent event, @NotNull ItemStack first, @NotNull ItemStack second, @NotNull ItemStack result) {
|
||||
if (!(second.getType().isAir() || second.getType() != first.getType() && !EnchantUtils.isEnchantedBook(second))) return false;
|
||||
if (result.getType() != first.getType()) return false;
|
||||
|
||||
ItemStack renamed = new ItemStack(result);
|
||||
EnchantUtils.getCustomEnchantments(first).forEach((hasEnch, hasLevel) -> EnchantUtils.add(renamed, hasEnch.getEnchantment(), hasLevel, true));
|
||||
EnchantUtils.updateDisplay(renamed);
|
||||
|
||||
event.setResult(renamed);
|
||||
return true;
|
||||
}*/
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
private boolean handleRecharge(@NotNull PrepareAnvilEvent event, @NotNull ItemStack first, @NotNull ItemStack second) {
|
||||
if (!Config.isChargesEnabled()) return false;
|
||||
@ -82,7 +66,6 @@ public class AnvilListener extends AbstractListener<EnchantsPlugin> {
|
||||
}
|
||||
|
||||
PDCUtil.set(recharged, Keys.itemRecharged, count);
|
||||
//EnchantUtils.updateDisplay(recharged);
|
||||
event.setResult(recharged);
|
||||
|
||||
this.plugin.runTask(task -> event.getView().setRepairCost(chargable.size()));
|
||||
@ -92,66 +75,26 @@ public class AnvilListener extends AbstractListener<EnchantsPlugin> {
|
||||
private boolean handleCombine(@NotNull PrepareAnvilEvent event, @NotNull ItemStack first, @NotNull ItemStack second, @NotNull ItemStack result) {
|
||||
ItemStack merged = new ItemStack(result.getType().isAir() ? first : result);
|
||||
|
||||
/*AtomicInteger repairCost = new AtomicInteger(event.getInventory().getRepairCost());
|
||||
EnchantUtils.getCustomEnchantments(first).forEach((data, level) -> {
|
||||
if (EnchantUtils.add(merged, data.getEnchantment(), level, false)) {
|
||||
repairCost.addAndGet(data.getAnvilCost());
|
||||
}
|
||||
});*/
|
||||
|
||||
if (EnchantUtils.countCustomEnchantments(merged) > Config.CORE_ITEM_ENCHANT_LIMIT.get()) {
|
||||
event.setResult(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<CustomEnchantment, Integer> chargesMap = new HashMap<>();
|
||||
EnchantUtils.getCustomEnchantments(result).forEach((data, level) -> {
|
||||
int chargesFirst = data.getCharges(first);
|
||||
int chargesSecond = data.getCharges(second);
|
||||
EnchantUtils.getCustomEnchantments(result).forEach((enchantment, level) -> {
|
||||
int chargesFirst = enchantment.getCharges(first);
|
||||
int chargesSecond = enchantment.getCharges(second);
|
||||
|
||||
chargesMap.put(data, chargesFirst + chargesSecond);
|
||||
data.setCharges(merged, level, chargesFirst + chargesSecond);
|
||||
chargesMap.put(enchantment, chargesFirst + chargesSecond);
|
||||
enchantment.setCharges(merged, level, chargesFirst + chargesSecond);
|
||||
});
|
||||
|
||||
//this.plugin.runTask(task -> event.getInventory().setRepairCost(repairCost.get()));
|
||||
|
||||
if (!chargesMap.isEmpty()/* || repairCost.get() != event.getInventory().getRepairCost()*/) {
|
||||
if (!chargesMap.isEmpty()) {
|
||||
event.setResult(merged);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
/*
|
||||
if (second.getType().isAir() || second.getAmount() > 1 || !EnchantUtils.isEnchantable(second)) return false;
|
||||
if (EnchantUtils.isEnchantedBook(first) && second.getType() != first.getType()) return false;
|
||||
Map<EnchantmentData, Integer> firstEnchants = EnchantUtils.getCustomEnchantments(first);
|
||||
//Map<EnchantmentData, Integer> secondEnchants = EnchantUtils.getCustomEnchantments(second);
|
||||
Map<EnchantmentData, Integer> charges = new HashMap<>(firstEnchants.keySet().stream().collect(Collectors.toMap(k -> k, v -> v.getCharges(first))));
|
||||
AtomicInteger repairCost = new AtomicInteger(event.getInventory().getRepairCost());
|
||||
|
||||
if (EnchantUtils.isEnchantedBook(second) || second.getType() == first.getType()) {
|
||||
EnchantUtils.getCustomEnchantments(second).forEach((data, level) -> {
|
||||
int maxMergeLevel = data.getMaxMergeLevel() < 0 ? data.getMaxLevel() : data.getMaxMergeLevel();
|
||||
|
||||
firstEnchants.merge(data, level, (oldLvl, newLvl) -> oldLvl.equals(newLvl) ? Math.min(maxMergeLevel, oldLvl + 1) : Math.max(oldLvl, newLvl));
|
||||
charges.merge(data, data.getCharges(second), Integer::sum);
|
||||
});
|
||||
}
|
||||
|
||||
firstEnchants.forEach((enchantmentData, level) -> {
|
||||
if (EnchantUtils.add(merged, enchantmentData.getEnchantment(), level, false)) {
|
||||
repairCost.addAndGet(enchantmentData.getAnvilMergeCost(level));
|
||||
enchantmentData.setCharges(merged, level, charges.getOrDefault(enchantmentData, 0));
|
||||
}
|
||||
});
|
||||
|
||||
if (first.equals(merged)) return false;
|
||||
|
||||
EnchantUtils.updateDisplay(merged);
|
||||
event.setResult(merged);
|
||||
this.plugin.runTask(task -> event.getInventory().setRepairCost(repairCost.get()));
|
||||
return true;*/
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
|
@ -26,7 +26,7 @@ public class GenericListener extends AbstractListener<EnchantsPlugin> {
|
||||
|
||||
//private final EnchantManager enchantManager;
|
||||
|
||||
public GenericListener(@NotNull EnchantsPlugin plugin, @NotNull EnchantManager enchantManager) {
|
||||
public GenericListener(@NotNull EnchantsPlugin plugin, @NotNull EnchantManager manager) {
|
||||
super(plugin);
|
||||
//this.enchantManager = enchantManager;
|
||||
}
|
||||
|
@ -1,47 +1,53 @@
|
||||
package su.nightexpress.excellentenchants.enchantment.menu;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MenuType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.EnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.excellentenchants.config.Keys;
|
||||
import su.nightexpress.excellentenchants.registry.EnchantRegistry;
|
||||
import su.nightexpress.excellentenchants.util.EnchantUtils;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.core.CoreLang;
|
||||
import su.nightexpress.nightcore.menu.MenuOptions;
|
||||
import su.nightexpress.nightcore.menu.MenuSize;
|
||||
import su.nightexpress.nightcore.menu.MenuViewer;
|
||||
import su.nightexpress.nightcore.menu.api.AutoFill;
|
||||
import su.nightexpress.nightcore.menu.api.AutoFilled;
|
||||
import su.nightexpress.nightcore.menu.impl.ConfigMenu;
|
||||
import su.nightexpress.nightcore.menu.item.ItemHandler;
|
||||
import su.nightexpress.nightcore.menu.item.MenuItem;
|
||||
import su.nightexpress.nightcore.util.*;
|
||||
import su.nightexpress.nightcore.ui.menu.MenuViewer;
|
||||
import su.nightexpress.nightcore.ui.menu.data.ConfigBased;
|
||||
import su.nightexpress.nightcore.ui.menu.data.Filled;
|
||||
import su.nightexpress.nightcore.ui.menu.data.MenuFiller;
|
||||
import su.nightexpress.nightcore.ui.menu.data.MenuLoader;
|
||||
import su.nightexpress.nightcore.ui.menu.item.MenuItem;
|
||||
import su.nightexpress.nightcore.ui.menu.type.NormalMenu;
|
||||
import su.nightexpress.nightcore.util.ItemUtil;
|
||||
import su.nightexpress.nightcore.util.Lists;
|
||||
import su.nightexpress.nightcore.util.NumberUtil;
|
||||
import su.nightexpress.nightcore.util.PDCUtil;
|
||||
import su.nightexpress.nightcore.util.bukkit.NightItem;
|
||||
import su.nightexpress.nightcore.util.placeholder.Replacer;
|
||||
import su.nightexpress.nightcore.util.text.NightMessage;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
import static su.nightexpress.nightcore.util.text.tag.Tags.*;
|
||||
|
||||
public class EnchantsMenu extends ConfigMenu<EnchantsPlugin> implements AutoFilled<CustomEnchantment> {
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class EnchantsMenu extends NormalMenu<EnchantsPlugin> implements ConfigBased, Filled<CustomEnchantment> {
|
||||
|
||||
private static final String FILE_NAME = "enchants.yml";
|
||||
|
||||
private static final String CONFLICTS = "%conflicts%";
|
||||
private static final String CHARGES = "%charges%";
|
||||
|
||||
private final NamespacedKey keyLevel;
|
||||
private final Map<String, Map<Integer, ItemStack>> iconCache;
|
||||
|
||||
private ItemStack enchantIcon;
|
||||
private NightItem enchantIcon;
|
||||
private String enchantName;
|
||||
private List<String> enchantLoreMain;
|
||||
private List<String> enchantLoreConflicts;
|
||||
@ -49,78 +55,13 @@ public class EnchantsMenu extends ConfigMenu<EnchantsPlugin> implements AutoFill
|
||||
private int[] enchantSlots;
|
||||
|
||||
public EnchantsMenu(@NotNull EnchantsPlugin plugin) {
|
||||
super(plugin, FileConfig.loadOrExtract(plugin, Config.DIR_MENU, FILE_NAME));
|
||||
this.keyLevel = new NamespacedKey(plugin, "list_display_level");
|
||||
this.iconCache = new HashMap<>();
|
||||
super(plugin, MenuType.GENERIC_9X4, BLACK.enclose("Custom Enchantments"));
|
||||
|
||||
this.load();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
super.clear();
|
||||
this.iconCache.clear();
|
||||
this.load(FileConfig.loadOrExtract(plugin, Config.DIR_MENU, FILE_NAME));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional() {
|
||||
this.enchantIcon = ConfigValue.create("Enchantment.Icon", new ItemStack(Material.ENCHANTED_BOOK)).read(this.cfg);
|
||||
|
||||
this.enchantName = ConfigValue.create("Enchantment.Name",
|
||||
LIGHT_YELLOW.enclose(BOLD.enclose(ENCHANTMENT_NAME + " " + ENCHANTMENT_LEVEL))
|
||||
).read(this.cfg);
|
||||
|
||||
this.enchantLoreMain = ConfigValue.create("Enchantment.Lore.Main",
|
||||
Lists.newList(
|
||||
ENCHANTMENT_RARITY,
|
||||
"",
|
||||
ENCHANTMENT_DESCRIPTION_REPLACED,
|
||||
DARK_GRAY.enclose("(click to switch levels)"),
|
||||
"",
|
||||
LIGHT_YELLOW.enclose(BOLD.enclose("Info:")),
|
||||
LIGHT_YELLOW.enclose("▪ " + LIGHT_GRAY.enclose("Applies to: ") + ENCHANTMENT_FIT_ITEM_TYPES),
|
||||
LIGHT_YELLOW.enclose("▪ " + LIGHT_GRAY.enclose("Levels: ") + ENCHANTMENT_LEVEL_MIN + LIGHT_GRAY.enclose(" - ") + ENCHANTMENT_LEVEL_MAX),
|
||||
CHARGES,
|
||||
CONFLICTS
|
||||
)).read(this.cfg);
|
||||
|
||||
this.enchantLoreConflicts = ConfigValue.create("Enchantment.Lore.Conflicts",
|
||||
Lists.newList(
|
||||
"",
|
||||
LIGHT_RED.enclose(BOLD.enclose("Conflicts:")),
|
||||
LIGHT_RED.enclose("✘ ") + LIGHT_GRAY.enclose(GENERIC_NAME)
|
||||
)).read(this.cfg);
|
||||
|
||||
this.enchantLoreCharges = ConfigValue.create("Enchantment.Lore.Charges",
|
||||
Lists.newList(
|
||||
LIGHT_YELLOW.enclose("▪ " + LIGHT_GRAY.enclose("Charges: ") + GENERIC_AMOUNT + "⚡" + LIGHT_GRAY.enclose(" (" + WHITE.enclose(GENERIC_ITEM) + ")")))
|
||||
).read(this.cfg);
|
||||
|
||||
this.enchantSlots = ConfigValue.create("Enchantment.Slots", IntStream.range(0, 27).toArray()).read(this.cfg);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected MenuOptions createDefaultOptions() {
|
||||
return new MenuOptions(BLACK.enclose("Custom Enchantments"), MenuSize.CHEST_36);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected List<MenuItem> createDefaultItems() {
|
||||
List<MenuItem> list = new ArrayList<>();
|
||||
|
||||
ItemStack nextPageStack = ItemUtil.getSkinHead(SKIN_ARROW_RIGHT);
|
||||
ItemUtil.editMeta(nextPageStack, meta -> meta.setDisplayName(CoreLang.EDITOR_ITEM_NEXT_PAGE.getLocalizedName()));
|
||||
|
||||
ItemStack prevPageStack = ItemUtil.getSkinHead(SKIN_ARROW_LEFT);
|
||||
ItemUtil.editMeta(prevPageStack, meta -> meta.setDisplayName(CoreLang.EDITOR_ITEM_PREVIOUS_PAGE.getLocalizedName()));
|
||||
|
||||
list.add(new MenuItem(nextPageStack).setSlots(35).setHandler(ItemHandler.forNextPage(this)).setPriority(5));
|
||||
list.add(new MenuItem(prevPageStack).setSlots(27).setHandler(ItemHandler.forPreviousPage(this)).setPriority(5));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepare(@NotNull MenuViewer viewer, @NotNull MenuOptions options) {
|
||||
protected void onPrepare(@NotNull MenuViewer viewer, @NotNull InventoryView view) {
|
||||
this.autoFill(viewer);
|
||||
}
|
||||
|
||||
@ -130,37 +71,39 @@ public class EnchantsMenu extends ConfigMenu<EnchantsPlugin> implements AutoFill
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutoFill(@NotNull MenuViewer viewer, @NotNull AutoFill<CustomEnchantment> autoFill) {
|
||||
@NotNull
|
||||
public MenuFiller<CustomEnchantment> createFiller(@NotNull MenuViewer viewer) {
|
||||
var autoFill = MenuFiller.builder(this);
|
||||
|
||||
autoFill.setSlots(this.enchantSlots);
|
||||
autoFill.setItems(EnchantRegistry.getRegistered().stream()
|
||||
.filter(Predicate.not(CustomEnchantment::isHiddenFromList))
|
||||
.sorted(Comparator.comparing(data -> NightMessage.stripAll(data.getDisplayName())))
|
||||
.toList()
|
||||
);
|
||||
autoFill.setItemCreator(enchantmentData -> this.getEnchantIcon(enchantmentData, 1));
|
||||
autoFill.setClickAction(enchantmentData -> (viewer1, event) -> {
|
||||
autoFill.setItemCreator(enchantmentData -> this.buildEnchantIcon(enchantmentData, 1));
|
||||
autoFill.setItemClick(enchantmentData -> (viewer1, event) -> {
|
||||
if (!event.isLeftClick()) return;
|
||||
|
||||
ItemStack currentItem = event.getCurrentItem();
|
||||
if (currentItem == null) return;
|
||||
|
||||
int levelHas = PDCUtil.getInt(currentItem, this.keyLevel).orElse(1);
|
||||
int levelHas = PDCUtil.getInt(currentItem, Keys.keyLevel).orElse(1);
|
||||
if (++levelHas > enchantmentData.getDefinition().getMaxLevel()) {
|
||||
levelHas = 1;
|
||||
}
|
||||
currentItem = this.getEnchantIcon(enchantmentData, levelHas);
|
||||
PDCUtil.set(currentItem, this.keyLevel, levelHas);
|
||||
event.setCurrentItem(currentItem);
|
||||
});
|
||||
}
|
||||
|
||||
private ItemStack getEnchantIcon(@NotNull CustomEnchantment enchant, int level) {
|
||||
return this.iconCache.computeIfAbsent(enchant.getId(), k -> new HashMap<>()).computeIfAbsent(level, k -> this.buildEnchantIcon(enchant, level));
|
||||
ItemStack item = this.buildEnchantIcon(enchantmentData, levelHas).getItemStack();
|
||||
PDCUtil.set(item, Keys.keyLevel, levelHas);
|
||||
event.setCurrentItem(item);
|
||||
});
|
||||
|
||||
return autoFill.build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ItemStack buildEnchantIcon(@NotNull CustomEnchantment enchant, int level) {
|
||||
ItemStack icon = new ItemStack(this.enchantIcon);
|
||||
private NightItem buildEnchantIcon(@NotNull CustomEnchantment enchant, int level) {
|
||||
NightItem icon = this.enchantIcon.copy();
|
||||
|
||||
List<String> conflicts = new ArrayList<>();
|
||||
if (enchant.getDefinition().hasConflicts()) {
|
||||
@ -178,21 +121,64 @@ public class EnchantsMenu extends ConfigMenu<EnchantsPlugin> implements AutoFill
|
||||
List<String> charges = new ArrayList<>();
|
||||
if (enchant.hasCharges()) {
|
||||
for (String line : this.enchantLoreCharges) {
|
||||
charges.add(line
|
||||
charges.add(Replacer.create()
|
||||
.replace(GENERIC_AMOUNT, NumberUtil.format(enchant.getCharges().getMaxAmount(level)))
|
||||
.replace(GENERIC_ITEM, ItemUtil.getItemName(enchant.getCharges().getFuel()))
|
||||
.apply(line)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ItemReplacer.create(icon).hideFlags().trimmed()
|
||||
icon.setHideComponents(true)
|
||||
.setDisplayName(this.enchantName)
|
||||
.setLore(this.enchantLoreMain)
|
||||
.replace(CHARGES, charges)
|
||||
.replace(CONFLICTS, conflicts)
|
||||
.replace(enchant.getPlaceholders(level))
|
||||
.writeMeta();
|
||||
.replacement(replacer -> replacer
|
||||
.replace(CHARGES, charges)
|
||||
.replace(CONFLICTS, conflicts)
|
||||
.replace(enchant.replacePlaceholders(level))
|
||||
);
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadConfiguration(@NotNull FileConfig config, @NotNull MenuLoader loader) {
|
||||
this.enchantIcon = ConfigValue.create("Enchantment.Icon", new NightItem(Material.ENCHANTED_BOOK)).read(config);
|
||||
|
||||
this.enchantName = ConfigValue.create("Enchantment.Name",
|
||||
LIGHT_YELLOW.enclose(BOLD.enclose(ENCHANTMENT_NAME + " " + ENCHANTMENT_LEVEL))
|
||||
).read(config);
|
||||
|
||||
this.enchantLoreMain = ConfigValue.create("Enchantment.Lore.Main",
|
||||
Lists.newList(
|
||||
ENCHANTMENT_RARITY,
|
||||
"",
|
||||
ENCHANTMENT_DESCRIPTION_REPLACED,
|
||||
DARK_GRAY.enclose("(click to switch levels)"),
|
||||
"",
|
||||
LIGHT_YELLOW.enclose(BOLD.enclose("Info:")),
|
||||
LIGHT_YELLOW.enclose("▪ " + LIGHT_GRAY.enclose("Applies to: ") + ENCHANTMENT_FIT_ITEM_TYPES),
|
||||
LIGHT_YELLOW.enclose("▪ " + LIGHT_GRAY.enclose("Levels: ") + ENCHANTMENT_LEVEL_MIN + LIGHT_GRAY.enclose(" - ") + ENCHANTMENT_LEVEL_MAX),
|
||||
CHARGES,
|
||||
CONFLICTS
|
||||
)).read(config);
|
||||
|
||||
this.enchantLoreConflicts = ConfigValue.create("Enchantment.Lore.Conflicts",
|
||||
Lists.newList(
|
||||
"",
|
||||
LIGHT_RED.enclose(BOLD.enclose("Conflicts:")),
|
||||
LIGHT_RED.enclose("✘ ") + LIGHT_GRAY.enclose(GENERIC_NAME)
|
||||
)).read(config);
|
||||
|
||||
this.enchantLoreCharges = ConfigValue.create("Enchantment.Lore.Charges",
|
||||
Lists.newList(
|
||||
LIGHT_YELLOW.enclose("▪ " + LIGHT_GRAY.enclose("Charges: ") + GENERIC_AMOUNT + "⚡" + LIGHT_GRAY.enclose(" (" + WHITE.enclose(GENERIC_ITEM) + ")")))
|
||||
).read(config);
|
||||
|
||||
this.enchantSlots = ConfigValue.create("Enchantment.Slots", IntStream.range(0, 27).toArray()).read(config);
|
||||
|
||||
|
||||
loader.addDefaultItem(MenuItem.buildNextPage(this, 35));
|
||||
loader.addDefaultItem(MenuItem.buildPreviousPage(this, 27));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,43 +40,39 @@ public class PacketEventsHook {
|
||||
if (player == null) return;
|
||||
if (!EnchantUtils.canUpdateDisplay(player)) return;
|
||||
|
||||
if (type == PacketType.Play.Server.SET_SLOT) {
|
||||
WrapperPlayServerSetSlot setSlot = new WrapperPlayServerSetSlot(event);
|
||||
switch (type) {
|
||||
case PacketType.Play.Server.SET_SLOT -> {
|
||||
WrapperPlayServerSetSlot setSlot = new WrapperPlayServerSetSlot(event);
|
||||
|
||||
ItemStack item = EnchantUtils.addDescription(toBukkit(setSlot.getItem()));
|
||||
setSlot.setItem(fromBukkit(item));
|
||||
}
|
||||
else if (type == PacketType.Play.Server.WINDOW_ITEMS) {
|
||||
WrapperPlayServerWindowItems windowItems = new WrapperPlayServerWindowItems(event);
|
||||
ItemStack item = EnchantUtils.addDescription(toBukkit(setSlot.getItem()));
|
||||
setSlot.setItem(fromBukkit(item));
|
||||
}
|
||||
case PacketType.Play.Server.WINDOW_ITEMS -> {
|
||||
WrapperPlayServerWindowItems windowItems = new WrapperPlayServerWindowItems(event);
|
||||
|
||||
windowItems.getItems().replaceAll(packetItem -> {
|
||||
return fromBukkit(EnchantUtils.addDescription(toBukkit(packetItem)));
|
||||
});
|
||||
}
|
||||
else if (type == PacketType.Play.Server.MERCHANT_OFFERS) {
|
||||
WrapperPlayServerMerchantOffers merchantOffers = new WrapperPlayServerMerchantOffers(event);
|
||||
windowItems.getItems().replaceAll(packetItem -> {
|
||||
return fromBukkit(EnchantUtils.addDescription(toBukkit(packetItem)));
|
||||
});
|
||||
}
|
||||
case PacketType.Play.Server.MERCHANT_OFFERS -> {
|
||||
WrapperPlayServerMerchantOffers merchantOffers = new WrapperPlayServerMerchantOffers(event);
|
||||
|
||||
List<MerchantOffer> offers = merchantOffers.getMerchantOffers();
|
||||
offers.forEach(offer -> {
|
||||
ItemStack result = toBukkit(offer.getOutputItem());
|
||||
offer.setOutputItem(fromBukkit(EnchantUtils.addDescription(result)));
|
||||
});
|
||||
List<MerchantOffer> offers = merchantOffers.getMerchantOffers();
|
||||
offers.forEach(offer -> {
|
||||
ItemStack result = toBukkit(offer.getOutputItem());
|
||||
offer.setOutputItem(fromBukkit(EnchantUtils.addDescription(result)));
|
||||
});
|
||||
}
|
||||
default -> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else return;
|
||||
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ItemStack toBukkit(@NotNull com.github.retrooper.packetevents.protocol.item.ItemStack pooperStack/*, @NotNull ClientVersion version*/) {
|
||||
// pooperStack.getEnchantments(version).forEach(enchantment -> {
|
||||
// String name = enchantment.getType().getName().getKey();
|
||||
// CustomEnchantment custom = EnchantRegistry.getById(name);
|
||||
// if (custom == null) return;
|
||||
//
|
||||
// EnchantUtils.add(item, custom.getBukkitEnchantment(), enchantment.getLevel(), true);
|
||||
// });
|
||||
|
||||
private static ItemStack toBukkit(@NotNull com.github.retrooper.packetevents.protocol.item.ItemStack pooperStack) {
|
||||
return SpigotConversionUtil.toBukkitItemStack(pooperStack);
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ public class PlaceholderHook {
|
||||
CustomEnchantment enchant = EnchantRegistry.getByKey(NamespacedKey.minecraft(chargesSplit[0].toLowerCase()));
|
||||
if (enchant == null) return null;
|
||||
|
||||
int level = NumberUtil.getInteger(chargesSplit[1], 1);
|
||||
int level = NumberUtil.getIntegerAbs(chargesSplit[1], 1);
|
||||
|
||||
return String.valueOf(enchant.getCharges().getMaxAmount(level));
|
||||
}
|
||||
|
@ -72,10 +72,7 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
|
||||
|
||||
// Prevent to register enchantments during the runtime.
|
||||
if (this.freezed) {
|
||||
getRegistered().forEach(enchantment -> {
|
||||
enchantment.clear();
|
||||
this.load(enchantment);
|
||||
});
|
||||
getRegistered().forEach(this::load);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -184,10 +181,10 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
|
||||
|
||||
@Override
|
||||
protected void onShutdown() {
|
||||
if (!freezed) {
|
||||
getRegistered().forEach(CustomEnchantment::clear);
|
||||
ENCHANTS_MAP.clear();
|
||||
}
|
||||
// if (!freezed) {
|
||||
// getRegistered().forEach(CustomEnchantment::clear);
|
||||
// ENCHANTS_MAP.clear();
|
||||
// }
|
||||
}
|
||||
|
||||
private <T extends CustomEnchantment> void registerType(@NotNull Class<T> enchantClass) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package su.nightexpress.excellentenchants.registry.wrapper;
|
||||
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -38,7 +37,7 @@ public class WrappedEvent<E extends Event, T extends CustomEnchantment> implemen
|
||||
LivingEntity entity = this.dataGather.getEntity(event);
|
||||
if (entity == null) return;
|
||||
|
||||
Player player = entity instanceof Player user ? user : null;
|
||||
//Player player = entity instanceof Player user ? user : null;
|
||||
|
||||
this.dataGather.getEnchants(event, this.enchantClass, entity).forEach((item, enchants) -> {
|
||||
enchants.forEach((enchant, level) -> {
|
||||
@ -46,7 +45,7 @@ public class WrappedEvent<E extends Event, T extends CustomEnchantment> implemen
|
||||
if (!enchant.isAvailableToUse(entity)) return;
|
||||
if (enchant.isOutOfCharges(item)) return;
|
||||
if (this.dataGather.useEnchant(event, entity, item, enchant, level)) {
|
||||
enchant.consumeChargesNoUpdate(item, level);
|
||||
enchant.consumeCharges(item, level);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,53 @@
|
||||
package su.nightexpress.excellentenchants.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.config.Writeable;
|
||||
|
||||
public class ChargesFormat implements Writeable {
|
||||
|
||||
private final int threshold;
|
||||
private final String format;
|
||||
|
||||
public ChargesFormat(int threshold, @NotNull String format) {
|
||||
this.threshold = threshold;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFormatted(int charges) {
|
||||
return this.format.replace(Placeholders.GENERIC_AMOUNT, String.valueOf(charges));
|
||||
}
|
||||
|
||||
public boolean isAboveThreshold(int percent) {
|
||||
return percent >= this.threshold;
|
||||
}
|
||||
|
||||
public boolean isUnderThreshold(int percent) {
|
||||
return percent < this.threshold;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ChargesFormat read(@NotNull FileConfig config, @NotNull String path) {
|
||||
int threshold = config.getInt(path + ".Threshold");
|
||||
String format = config.getString(path + ".Format", Placeholders.GENERIC_AMOUNT);
|
||||
|
||||
return new ChargesFormat(threshold, format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull FileConfig config, @NotNull String path) {
|
||||
config.set(path + ".Threshold", this.threshold);
|
||||
config.set(path + ".Format", this.format);
|
||||
}
|
||||
|
||||
public int getThreshold() {
|
||||
return this.threshold;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFormat() {
|
||||
return this.format;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package su.nightexpress.excellentenchants.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.config.Writeable;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EnchantBlacklist implements Writeable {
|
||||
|
||||
private final Set<String> enchantNames;
|
||||
|
||||
public EnchantBlacklist(@NotNull Set<String> enchantNames) {
|
||||
this.enchantNames = enchantNames.stream().map(String::toLowerCase).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public boolean contains(@NotNull CustomEnchantment enchantment) {
|
||||
return this.contains(enchantment.getId());
|
||||
}
|
||||
|
||||
public boolean contains(@NotNull String name) {
|
||||
return this.enchantNames.contains(Placeholders.WILDCARD) || this.enchantNames.contains(name.toLowerCase());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static EnchantBlacklist read(@NotNull FileConfig config, @NotNull String path) {
|
||||
Set<String> names = config.getStringSet(path);
|
||||
return new EnchantBlacklist(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull FileConfig config, @NotNull String path) {
|
||||
config.set(path, this.enchantNames);
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
package su.nightexpress.excellentenchants.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.nightcore.util.Pair;
|
||||
import su.nightexpress.nightcore.util.placeholder.PlaceholderMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class EnchantPlaceholders {
|
||||
|
||||
private final List<Pair<String, Function<Integer, String>>> keys;
|
||||
|
||||
public EnchantPlaceholders() {
|
||||
this(new ArrayList<>());
|
||||
}
|
||||
|
||||
public EnchantPlaceholders(@NotNull EnchantPlaceholders other) {
|
||||
this(other.getKeys());
|
||||
}
|
||||
|
||||
public EnchantPlaceholders(@NotNull List<Pair<String, Function<Integer, String>>> keys) {
|
||||
this.keys = new ArrayList<>(keys);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static EnchantPlaceholders fusion(@NotNull EnchantPlaceholders... others) {
|
||||
EnchantPlaceholders map = new EnchantPlaceholders();
|
||||
for (EnchantPlaceholders other : others) {
|
||||
map.add(other);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Pair<String, Function<Integer, String>>> getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantPlaceholders add(@NotNull EnchantPlaceholders other) {
|
||||
this.getKeys().addAll(other.getKeys());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantPlaceholders add(@NotNull String key, @NotNull String replacer) {
|
||||
this.add(key, level -> replacer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantPlaceholders add(@NotNull String key, @NotNull Supplier<String> replacer) {
|
||||
this.add(key, level -> replacer.get());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EnchantPlaceholders add(@NotNull String key, @NotNull Function<Integer, String> replacer) {
|
||||
this.getKeys().add(Pair.of(key, replacer));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.getKeys().clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PlaceholderMap toMap(int level) {
|
||||
List<Pair<String, Supplier<String>>> list = new ArrayList<>();
|
||||
this.getKeys().forEach(pair -> {
|
||||
list.add(Pair.of(pair.getFirst(), () -> pair.getSecond().apply(level)));
|
||||
});
|
||||
return new PlaceholderMap(list);
|
||||
}
|
||||
}
|
@ -31,8 +31,6 @@ import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static su.nightexpress.excellentenchants.Placeholders.*;
|
||||
import static su.nightexpress.excellentenchants.Placeholders.GENERIC_CHARGES;
|
||||
import static su.nightexpress.nightcore.util.Placeholders.GENERIC_VALUE;
|
||||
|
||||
public class EnchantUtils {
|
||||
|
||||
@ -110,9 +108,13 @@ public class EnchantUtils {
|
||||
if (showCharges) {
|
||||
int chargesMax = enchantment.getCharges().getMaxAmount(level);
|
||||
int percent = (int) Math.ceil((double) charges / (double) chargesMax * 100D);
|
||||
Map.Entry<Integer, String> entry = Config.ENCHANTMENTS_CHARGES_FORMAT.get().floorEntry(percent);
|
||||
if (entry != null) {
|
||||
chargesFormat = entry.getValue().replace(GENERIC_AMOUNT, String.valueOf(charges));
|
||||
|
||||
ChargesFormat format = Config.ENCHANTMENTS_CHARGES_FORMAT.get().values().stream()
|
||||
.filter(f -> f.isAboveThreshold(percent))
|
||||
.max(Comparator.comparingInt(ChargesFormat::getThreshold)).orElse(null);
|
||||
|
||||
if (format != null) {
|
||||
chargesFormat = format.getFormatted(charges);
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,30 +300,9 @@ public class EnchantUtils {
|
||||
Map<EquipmentSlot, ItemStack> equipment = EntityUtil.getEquippedItems(entity, slots);
|
||||
equipment.values().removeIf(item -> item == null || isEnchantedBook(item) || !item.hasItemMeta());
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/*@NotNull
|
||||
private static Map<ItemStack, Map<EnchantmentData, Integer>> getEquipped(@NotNull LivingEntity entity) {
|
||||
Map<ItemStack, Map<EnchantmentData, Integer>> map = new HashMap<>();
|
||||
getEnchantedEquipment(entity).values().forEach(item -> {
|
||||
map.computeIfAbsent(item, k -> new LinkedHashMap<>()).putAll(getCustomEnchantments(item));
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T extends EnchantmentData> Map<ItemStack, Map<T, Integer>> getEquipped(@NotNull LivingEntity entity, @NotNull Class<T> clazz) {
|
||||
return getEquipped(entity, clazz, EQUIPMENT_SLOTS);
|
||||
}*/
|
||||
|
||||
@Nullable
|
||||
public static ItemStack getEquipped(@NotNull LivingEntity entity, @NotNull EquipmentSlot slot) {
|
||||
EntityEquipment equipment = entity.getEquipment();
|
||||
|
@ -16,80 +16,66 @@ public class ItemCategories {
|
||||
|
||||
public static final ItemsCategory HELMET = ItemsCategory.buildDirect(getItemsBySlot(EquipmentSlot.HEAD)).slots(EquipmentSlot.HEAD)
|
||||
.localized(Lang.ITEM_CATEGORY_HELMET)
|
||||
/*.target(EnchantmentTarget.ARMOR_HEAD)*/.build();
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory CHESTPLATE = ItemsCategory.buildDirect(getItemsBySlot(EquipmentSlot.CHEST)).slots(EquipmentSlot.CHEST)
|
||||
.localized(Lang.ITEM_CATEGORY_CHESTPLATE)
|
||||
/*.target(EnchantmentTarget.ARMOR_TORSO)*/.build();
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory LEGGINGS = ItemsCategory.buildDirect(getItemsBySlot(EquipmentSlot.LEGS)).slots(EquipmentSlot.LEGS)
|
||||
.localized(Lang.ITEM_CATEGORY_LEGGINGS)
|
||||
//.target(EnchantmentTarget.ARMOR_LEGS)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory BOOTS = ItemsCategory.buildDirect(getItemsBySlot(EquipmentSlot.FEET)).slots(EquipmentSlot.FEET)
|
||||
.localized(Lang.ITEM_CATEGORY_BOOTS)
|
||||
//.target(EnchantmentTarget.ARMOR_FEET)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory ELYTRA = ItemsCategory.buildDirect(Material.ELYTRA).slots(EquipmentSlot.CHEST)
|
||||
.localized(Lang.ITEM_CATEGORY_ELYTRA)
|
||||
//.target(EnchantmentTarget.ARMOR_TORSO)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory SWORD = ItemsCategory.buildDirect(Tag.ITEMS_SWORDS).slots(EquipmentSlot.HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_SWORD)
|
||||
//.target(EnchantmentTarget.WEAPON)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory AXE = ItemsCategory.buildDirect(Tag.ITEMS_AXES).slots(EquipmentSlot.HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_AXE)
|
||||
//.target(EnchantmentTarget.TOOL)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory HOE = ItemsCategory.buildDirect(Tag.ITEMS_HOES).slots(EquipmentSlot.HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_HOE)
|
||||
//.target(EnchantmentTarget.TOOL)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory PICKAXE = ItemsCategory.buildDirect(Tag.ITEMS_PICKAXES).slots(EquipmentSlot.HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_PICKAXE)
|
||||
//.target(EnchantmentTarget.TOOL)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory SHOVEL = ItemsCategory.buildDirect(Tag.ITEMS_SHOVELS).slots(EquipmentSlot.HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_SHOVEL)
|
||||
//.target(EnchantmentTarget.TOOL)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory TRIDENT = ItemsCategory.buildDirect(Material.TRIDENT).slots(EquipmentSlot.HAND, EquipmentSlot.OFF_HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_TRIDENT)
|
||||
//.target(EnchantmentTarget.TRIDENT)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory BOW = ItemsCategory.buildDirect(Material.BOW).slots(EquipmentSlot.HAND, EquipmentSlot.OFF_HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_BOW)
|
||||
//.target(EnchantmentTarget.BOW)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory CROSSBOW = ItemsCategory.buildDirect(Material.CROSSBOW).slots(EquipmentSlot.HAND, EquipmentSlot.OFF_HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_CROSSBOW)
|
||||
//.target(EnchantmentTarget.CROSSBOW)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory FISHING_ROD = ItemsCategory.buildDirect(Material.FISHING_ROD).slots(EquipmentSlot.HAND, EquipmentSlot.OFF_HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_FISHING_ROD)
|
||||
//.target(EnchantmentTarget.FISHING_ROD)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory SHIELD = ItemsCategory.buildDirect(Material.SHIELD).slots(EquipmentSlot.OFF_HAND)
|
||||
.localized(Lang.ITEM_CATEGORY_SHIELD)
|
||||
//.target(EnchantmentTarget.BREAKABLE)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory BREAKABLE = ItemsCategory.buildDirect(getItemsWithDurability()).slots(EquipmentSlot.values())
|
||||
.localized(Lang.ITEM_CATEGORY_BREAKABLE)
|
||||
//.target(EnchantmentTarget.BREAKABLE)
|
||||
.build();
|
||||
|
||||
public static final ItemsCategory ARMOR = ItemsCategory.buildRef(() -> {
|
||||
@ -99,14 +85,14 @@ public class ItemCategories {
|
||||
materials.addAll(getItemsBySlot(EquipmentSlot.LEGS));
|
||||
materials.addAll(getItemsBySlot(EquipmentSlot.FEET));
|
||||
return materials;
|
||||
}).slots(EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET)./*target(EnchantmentTarget.ARMOR).*/localized(Lang.ITEM_CATEGORY_ARMOR).build();
|
||||
}).slots(EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET).localized(Lang.ITEM_CATEGORY_ARMOR).build();
|
||||
|
||||
public static final ItemsCategory TOOL = ItemsCategory.buildDirect(
|
||||
Tag.ITEMS_AXES,
|
||||
Tag.ITEMS_HOES,
|
||||
Tag.ITEMS_PICKAXES,
|
||||
Tag.ITEMS_SHOVELS
|
||||
).slots(EquipmentSlot.HAND)/*.target(EnchantmentTarget.TOOL)*/.localized(Lang.ITEM_CATEGORY_TOOL).build();
|
||||
).slots(EquipmentSlot.HAND).localized(Lang.ITEM_CATEGORY_TOOL).build();
|
||||
|
||||
|
||||
public static final ItemsCategory WEAPON = ItemsCategory.buildRef(() -> {
|
||||
@ -117,7 +103,7 @@ public class ItemCategories {
|
||||
}
|
||||
|
||||
return materials;
|
||||
}).slots(EquipmentSlot.HAND)./*target(EnchantmentTarget.WEAPON).*/localized(Lang.ITEM_CATEGORY_WEAPON).build();
|
||||
}).slots(EquipmentSlot.HAND).localized(Lang.ITEM_CATEGORY_WEAPON).build();
|
||||
|
||||
|
||||
public static final ItemsCategory BOWS = ItemsCategory.buildRef(() -> {
|
||||
@ -128,7 +114,7 @@ public class ItemCategories {
|
||||
}
|
||||
|
||||
return materials;
|
||||
}).slots(EquipmentSlot.HAND, EquipmentSlot.OFF_HAND)./*target(EnchantmentTarget.BOW).*/localized(Lang.ITEM_CATEGORY_BOWS).build();
|
||||
}).slots(EquipmentSlot.HAND, EquipmentSlot.OFF_HAND).localized(Lang.ITEM_CATEGORY_BOWS).build();
|
||||
|
||||
|
||||
public static final ItemsCategory TORSO = ItemsCategory.buildRef(() -> {
|
||||
@ -139,7 +125,7 @@ public class ItemCategories {
|
||||
}
|
||||
|
||||
return materials;
|
||||
}).slots(EquipmentSlot.CHEST)./*target(EnchantmentTarget.ARMOR_TORSO).*/localized(Lang.ITEM_CATEGORY_TORSO).build();
|
||||
}).slots(EquipmentSlot.CHEST).localized(Lang.ITEM_CATEGORY_TORSO).build();
|
||||
|
||||
|
||||
public static final ItemsCategory ALL_RANGE_WEAPON = ItemsCategory.buildRef(() -> {
|
||||
@ -149,7 +135,7 @@ public class ItemCategories {
|
||||
materials.addAll(TRIDENT.getMaterials());
|
||||
materials.addAll(TOOL.getMaterials());
|
||||
return materials;
|
||||
}).slots(EquipmentSlot.HAND)./*target(EnchantmentTarget.BREAKABLE).*/localized(Lang.ITEM_CATEGORY_ALL_WEAPON).build();
|
||||
}).slots(EquipmentSlot.HAND).localized(Lang.ITEM_CATEGORY_ALL_WEAPON).build();
|
||||
|
||||
public static final ItemsCategory MINING_TOOLS = ItemsCategory.buildRef(() -> {
|
||||
Set<Material> materials = new HashSet<>();
|
||||
@ -157,7 +143,7 @@ public class ItemCategories {
|
||||
materials.addAll(PICKAXE.getMaterials());
|
||||
materials.addAll(SHOVEL.getMaterials());
|
||||
return materials;
|
||||
}).slots(EquipmentSlot.HAND)./*target(EnchantmentTarget.TOOL).*/localized(Lang.ITEM_CATEGORY_MINING_TOOLS).build();
|
||||
}).slots(EquipmentSlot.HAND).localized(Lang.ITEM_CATEGORY_MINING_TOOLS).build();
|
||||
|
||||
|
||||
@NotNull
|
||||
|
@ -1,72 +1,72 @@
|
||||
Command:
|
||||
List:
|
||||
Desc: 'Lista de encantamentos personalizados.'
|
||||
Usage: '[jogador]'
|
||||
DoneOthers: <light_gray>Abriu o GUI para o jogador <light_yellow>%player_name%</light_yellow>.</light_gray>
|
||||
GetFuel:
|
||||
Desc: 'Obtém um item de recarga.'
|
||||
Usage: <enchant> [quantidade]
|
||||
Done: <light_gray>Você recebeu <light_yellow>x%amount% %name%</light_yellow>.</light_gray>
|
||||
Enchant:
|
||||
Usage: <enchant> <nivel> [jogador] [slot]
|
||||
Desc: 'Encanta o item na mão.'
|
||||
Done:
|
||||
Self: <light_gray>O encantamento de <light_yellow>%item%</light_yellow> é <light_yellow>%enchant% %level%</light_yellow>!</light_gray>
|
||||
Others: <light_gray>O encantamento de <light_yellow>%item%</light_yellow> do jogador <light_yellow>%player_display_name%</light_yellow> é <light_yellow>%enchant% %level%</light_yellow>!</light_gray>
|
||||
Error:
|
||||
NoItem: <red>Não há item para encantar!</red>
|
||||
Book:
|
||||
Usage: <jogador> <enchant> <nivel>
|
||||
Desc: 'Concede um livro de encantamento personalizado.'
|
||||
Done: <light_gray>Concedeu o livro de encantamento <light_yellow>%enchant%</light_yellow> para <light_yellow>%player_display_name%</light_yellow>.</light_gray>
|
||||
RarityBook:
|
||||
Usage: <jogador> <nivel> <raridade>
|
||||
Desc: 'Concede um livro de encantamento com uma raridade específica.'
|
||||
Done: <light_gray>Concedeu o livro de encantamento <light_yellow>%name%</light_yellow> para <light_yellow>%player_display_name%</light_yellow>.</light_gray>
|
||||
Error:
|
||||
InvalidEnchantment: <red>Parâmetro inválido.</red>
|
||||
InvalidRarity: <red>Tipo de raridade inválido!</red>
|
||||
ItemCategory:
|
||||
HELMET: 'Capacete'
|
||||
CHESTPLATE: 'Peitoral'
|
||||
LEGGINGS: 'Calças'
|
||||
BOOTS: 'Botas'
|
||||
ELYTRA: 'Elytra'
|
||||
SWORD: 'Espada'
|
||||
TRIDENT: 'Tridente'
|
||||
AXE: 'Machado'
|
||||
BOW: 'Arco'
|
||||
CROSSBOW: 'Besta'
|
||||
HOE: 'Enxada'
|
||||
PICKAXE: 'Picareta'
|
||||
SHOVEL: 'Pá'
|
||||
FISHING_ROD: 'Vara de pesca'
|
||||
SHIELD: 'Escudo'
|
||||
TOOL: 'Ferramenta'
|
||||
EnchantmentTarget:
|
||||
ALL: 'Todos'
|
||||
ARMOR: 'Armadura'
|
||||
ARMOR_FEET: 'Botas'
|
||||
ARMOR_LEGS: 'Calças'
|
||||
ARMOR_TORSO: 'Peitoral'
|
||||
ARMOR_HEAD: 'Capacete'
|
||||
WEAPON: 'Arma'
|
||||
TOOL: 'Ferramenta'
|
||||
BOW: 'Arco'
|
||||
FISHING_ROD: 'Vara de pesca'
|
||||
BREAKABLE: 'Durabilidade'
|
||||
WEARABLE: 'Vestível'
|
||||
TRIDENT: 'Tridente'
|
||||
CROSSBOW: 'Besta'
|
||||
VANISHABLE: 'Desaparecível'
|
||||
DistributionWay:
|
||||
ENCHANTING: 'Encantamento'
|
||||
VILLAGER: 'Aldeão'
|
||||
LOOT_GENERATION: 'Geração de saque'
|
||||
FISHING: 'Pesca'
|
||||
MOB_EQUIPMENT: 'Equipamento de mob'
|
||||
Rarity:
|
||||
COMMON: '<white>Comum</white>'
|
||||
UNCOMMON: '<light_green>Incomum</light_green>'
|
||||
RARE: '<purple>Raro</purple>'
|
||||
Command:
|
||||
List:
|
||||
Desc: 'Lista de encantamentos personalizados.'
|
||||
Usage: '[jogador]'
|
||||
DoneOthers: <light_gray>Abriu o GUI para o jogador <light_yellow>%player_name%</light_yellow>.</light_gray>
|
||||
GetFuel:
|
||||
Desc: 'Obtém um item de recarga.'
|
||||
Usage: <enchant> [quantidade]
|
||||
Done: <light_gray>Você recebeu <light_yellow>x%amount% %name%</light_yellow>.</light_gray>
|
||||
Enchant:
|
||||
Usage: <enchant> <nivel> [jogador] [slot]
|
||||
Desc: 'Encanta o item na mão.'
|
||||
Done:
|
||||
Self: <light_gray>O encantamento de <light_yellow>%item%</light_yellow> é <light_yellow>%enchant% %level%</light_yellow>!</light_gray>
|
||||
Others: <light_gray>O encantamento de <light_yellow>%item%</light_yellow> do jogador <light_yellow>%player_display_name%</light_yellow> é <light_yellow>%enchant% %level%</light_yellow>!</light_gray>
|
||||
Error:
|
||||
NoItem: <red>Não há item para encantar!</red>
|
||||
Book:
|
||||
Usage: <jogador> <enchant> <nivel>
|
||||
Desc: 'Concede um livro de encantamento personalizado.'
|
||||
Done: <light_gray>Concedeu o livro de encantamento <light_yellow>%enchant%</light_yellow> para <light_yellow>%player_display_name%</light_yellow>.</light_gray>
|
||||
RarityBook:
|
||||
Usage: <jogador> <nivel> <raridade>
|
||||
Desc: 'Concede um livro de encantamento com uma raridade específica.'
|
||||
Done: <light_gray>Concedeu o livro de encantamento <light_yellow>%name%</light_yellow> para <light_yellow>%player_display_name%</light_yellow>.</light_gray>
|
||||
Error:
|
||||
InvalidEnchantment: <red>Parâmetro inválido.</red>
|
||||
InvalidRarity: <red>Tipo de raridade inválido!</red>
|
||||
ItemCategory:
|
||||
HELMET: 'Capacete'
|
||||
CHESTPLATE: 'Peitoral'
|
||||
LEGGINGS: 'Calças'
|
||||
BOOTS: 'Botas'
|
||||
ELYTRA: 'Elytra'
|
||||
SWORD: 'Espada'
|
||||
TRIDENT: 'Tridente'
|
||||
AXE: 'Machado'
|
||||
BOW: 'Arco'
|
||||
CROSSBOW: 'Besta'
|
||||
HOE: 'Enxada'
|
||||
PICKAXE: 'Picareta'
|
||||
SHOVEL: 'Pá'
|
||||
FISHING_ROD: 'Vara de pesca'
|
||||
SHIELD: 'Escudo'
|
||||
TOOL: 'Ferramenta'
|
||||
EnchantmentTarget:
|
||||
ALL: 'Todos'
|
||||
ARMOR: 'Armadura'
|
||||
ARMOR_FEET: 'Botas'
|
||||
ARMOR_LEGS: 'Calças'
|
||||
ARMOR_TORSO: 'Peitoral'
|
||||
ARMOR_HEAD: 'Capacete'
|
||||
WEAPON: 'Arma'
|
||||
TOOL: 'Ferramenta'
|
||||
BOW: 'Arco'
|
||||
FISHING_ROD: 'Vara de pesca'
|
||||
BREAKABLE: 'Durabilidade'
|
||||
WEARABLE: 'Vestível'
|
||||
TRIDENT: 'Tridente'
|
||||
CROSSBOW: 'Besta'
|
||||
VANISHABLE: 'Desaparecível'
|
||||
DistributionWay:
|
||||
ENCHANTING: 'Encantamento'
|
||||
VILLAGER: 'Aldeão'
|
||||
LOOT_GENERATION: 'Geração de saque'
|
||||
FISHING: 'Pesca'
|
||||
MOB_EQUIPMENT: 'Equipamento de mob'
|
||||
Rarity:
|
||||
COMMON: '<white>Comum</white>'
|
||||
UNCOMMON: '<light_green>Incomum</light_green>'
|
||||
RARE: '<purple>Raro</purple>'
|
||||
VERY_RARE: '<red>Mítico</red>'
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>MC_1_21</artifactId>
|
||||
@ -28,13 +28,13 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -57,7 +57,6 @@ import su.nightexpress.excellentenchants.api.enchantment.bridge.FlameWalker;
|
||||
import su.nightexpress.excellentenchants.nms.EnchantNMS;
|
||||
import su.nightexpress.nightcore.NightPlugin;
|
||||
import su.nightexpress.nightcore.util.Reflex;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
import su.nightexpress.nightcore.util.text.NightMessage;
|
||||
|
||||
import java.util.*;
|
||||
@ -407,7 +406,8 @@ public class Internal_1_21 implements EnchantNMS {
|
||||
blocks.add(CraftBlock.at(world, posNear));
|
||||
}
|
||||
|
||||
blocks.forEach(block -> FlameWalker.addBlock(block, Rnd.getDouble(flameWalker.getBlockDecayTime(level)) + 1));
|
||||
//blocks.forEach(block -> FlameWalker.addBlock(block, Rnd.getDouble(flameWalker.getBlockDecayTime(level)) + 1));
|
||||
blocks.forEach(block -> flameWalker.addBlock(block, level));
|
||||
|
||||
return !blocks.isEmpty();
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>MC_1_21_3</artifactId>
|
||||
@ -28,13 +28,13 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -53,7 +53,6 @@ import su.nightexpress.excellentenchants.api.enchantment.*;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.bridge.FlameWalker;
|
||||
import su.nightexpress.nightcore.NightPlugin;
|
||||
import su.nightexpress.nightcore.util.Reflex;
|
||||
import su.nightexpress.nightcore.util.random.Rnd;
|
||||
import su.nightexpress.nightcore.util.text.NightMessage;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@ -482,7 +481,8 @@ public class Internal_1_21_3 implements EnchantNMS {
|
||||
blocks.add(CraftBlock.at(world, posNear));
|
||||
}
|
||||
|
||||
blocks.forEach(block -> FlameWalker.addBlock(block, Rnd.getDouble(flameWalker.getBlockDecayTime(level)) + 1));
|
||||
//blocks.forEach(block -> FlameWalker.addBlock(block, Rnd.getDouble(flameWalker.getBlockDecayTime(level)) + 1));
|
||||
blocks.forEach(block -> flameWalker.addBlock(block, level));
|
||||
|
||||
return !blocks.isEmpty();
|
||||
}
|
||||
|
79
MC_1_21_4/pom.xml
Normal file
79
MC_1_21_4/pom.xml
Normal file
@ -0,0 +1,79 @@
|
||||
<?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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<version>4.3.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>MC_1_21_4</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.21.4-R0.1-SNAPSHOT</version>
|
||||
<classifier>remapped-mojang</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
<version>2.0.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>remap</goal>
|
||||
</goals>
|
||||
<id>remap-obf</id>
|
||||
<configuration>
|
||||
<srgIn>org.spigotmc:minecraft-server:1.21.4-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
|
||||
<reverse>true</reverse>
|
||||
<remappedDependencies>org.spigotmc:spigot:1.21.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.21.4-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
|
||||
<remappedDependencies>org.spigotmc:spigot:1.21.4-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
79
MC_1_21_4/pom.xml.versionsBackup
Normal file
79
MC_1_21_4/pom.xml.versionsBackup
Normal file
@ -0,0 +1,79 @@
|
||||
<?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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<version>4.3.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>MC_1_21_4</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.21.4-R0.1-SNAPSHOT</version>
|
||||
<classifier>remapped-mojang</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.3.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.3.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
<version>2.0.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>remap</goal>
|
||||
</goals>
|
||||
<id>remap-obf</id>
|
||||
<configuration>
|
||||
<srgIn>org.spigotmc:minecraft-server:1.21.4-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
|
||||
<reverse>true</reverse>
|
||||
<remappedDependencies>org.spigotmc:spigot:1.21.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.21.4-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
|
||||
<remappedDependencies>org.spigotmc:spigot:1.21.4-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,504 @@
|
||||
package su.nightexpress.excellentenchants.nms;
|
||||
|
||||
import net.minecraft.core.*;
|
||||
import net.minecraft.core.component.DataComponentMap;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.EnchantmentTags;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.EquipmentSlotGroup;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.projectile.FishingHook;
|
||||
import net.minecraft.world.flag.FeatureFlags;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.enchantment.Enchantment;
|
||||
import net.minecraft.world.level.Level;
|
||||
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.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.CraftEquipmentSlot;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.block.CraftBlockType;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.enchantments.CraftEnchantment;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftFishHook;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftLivingEntity;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.event.CraftEventFactory;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.util.CraftChatMessage;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.util.CraftNamespacedKey;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.api.ConfigBridge;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.*;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.bridge.FlameWalker;
|
||||
import su.nightexpress.nightcore.NightPlugin;
|
||||
import su.nightexpress.nightcore.util.Reflex;
|
||||
import su.nightexpress.nightcore.util.text.NightMessage;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class Internal_1_21_4 implements EnchantNMS {
|
||||
|
||||
private static final MinecraftServer SERVER;
|
||||
private static final MappedRegistry<Enchantment> ENCHANTS;
|
||||
private static final MappedRegistry<Item> ITEMS;
|
||||
|
||||
private static final String REGISTRY_FROZEN_TAGS_FIELD = "j"; // frozenTags
|
||||
private static final String REGISTRY_ALL_TAGS_FIELD = "k"; // allTags
|
||||
private static final String TAG_SET_UNBOUND_METHOD = "a"; // .unbound()
|
||||
private static final String TAG_SET_MAP_FIELD = "val$map";
|
||||
|
||||
static {
|
||||
SERVER = ((CraftServer) Bukkit.getServer()).getServer();
|
||||
ENCHANTS = (MappedRegistry<Enchantment>) SERVER.registryAccess().lookup(Registries.ENCHANTMENT).orElseThrow();
|
||||
ITEMS = (MappedRegistry<Item>) SERVER.registryAccess().lookup(Registries.ITEM).orElseThrow();
|
||||
}
|
||||
|
||||
private final NightPlugin plugin;
|
||||
|
||||
public Internal_1_21_4(@NotNull NightPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static <T> ResourceKey<T> getResourceKey(@NotNull Registry<T> registry, @NotNull String name) {
|
||||
return ResourceKey.create(registry.key(), ResourceLocation.withDefaultNamespace(name));
|
||||
}
|
||||
|
||||
private static <T> TagKey<T> getTagKey(@NotNull Registry<T> registry, @NotNull String name) {
|
||||
return TagKey.create(registry.key(), ResourceLocation.withDefaultNamespace(name));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
private static <T> Map<TagKey<T>, HolderSet.Named<T>> getFrozenTags(@NotNull MappedRegistry<T> registry) {
|
||||
return (Map<TagKey<T>, HolderSet.Named<T>>) Reflex.getFieldValue(registry, REGISTRY_FROZEN_TAGS_FIELD);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static <T> Object getAllTags(@NotNull MappedRegistry<T> registry) {
|
||||
return Reflex.getFieldValue(registry, REGISTRY_ALL_TAGS_FIELD);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
private static <T> Map<TagKey<T>, HolderSet.Named<T>> getTagsMap(@NotNull Object tagSet) {
|
||||
// new HashMap, because original is ImmutableMap.
|
||||
return new HashMap<>((Map<TagKey<T>, HolderSet.Named<T>>) Reflex.getFieldValue(tagSet, TAG_SET_MAP_FIELD));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unfreezeRegistry() {
|
||||
unfreeze(ENCHANTS);
|
||||
unfreeze(ITEMS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void freezeRegistry() {
|
||||
freeze(ITEMS);
|
||||
freeze(ENCHANTS);
|
||||
|
||||
//this.displayTags();
|
||||
}
|
||||
|
||||
private static <T> void unfreeze(@NotNull MappedRegistry<T> registry) {
|
||||
Reflex.setFieldValue(registry, "l", false); // MappedRegistry#frozen
|
||||
Reflex.setFieldValue(registry, "m", new IdentityHashMap<>()); // MappedRegistry#unregisteredIntrusiveHolders
|
||||
}
|
||||
|
||||
private static <T> void freeze(@NotNull MappedRegistry<T> registry) {
|
||||
// Get original TagSet object of the registry before unbound.
|
||||
// We MUST keep original TagSet object and only modify an inner map object inside it.
|
||||
// Otherwise it will throw an Network Error on client join because of 'broken' tags that were bound to other TagSet object.
|
||||
Object tagSet = getAllTags(registry);
|
||||
|
||||
// Get a copy of original TagSet's tags map.
|
||||
Map<TagKey<T>, HolderSet.Named<T>> tagsMap = getTagsMap(tagSet);
|
||||
// Get 'frozenTags' map with all tags of the registry.
|
||||
Map<TagKey<T>, HolderSet.Named<T>> frozenTags = getFrozenTags(registry);
|
||||
|
||||
// Here we add all registered and bound vanilla tags to the 'frozenTags' map for further freeze & bind.
|
||||
// For some reason 'frozenTags' map does not contain all the tags, so some of them will be absent if not added back here
|
||||
// and result in broken gameplay features.
|
||||
tagsMap.forEach(frozenTags::putIfAbsent);
|
||||
|
||||
// We MUST 'unbound' the registry tags to be able to call .freeze() method of it.
|
||||
// Otherwise it will throw an error saying tags are not bound.
|
||||
unbound(registry);
|
||||
|
||||
// This method will register all tags from the 'frozenTags' map and assign a new TagSet object to the 'allTags' field of registry.
|
||||
// But we MUST replace the 'allTags' field value with the original (before unbound) TagSet object to prevent Network Error for clients.
|
||||
registry.freeze();
|
||||
|
||||
// Here we need to put in 'tagsMap' map of TagSet object all new/custom registered tags.
|
||||
// Otherwise it will cause Network Error because custom tags are not present in the TagSet tags map.
|
||||
// frozenTags.forEach((k, v) -> {
|
||||
// if (!tagsMap.containsKey(k)) {
|
||||
// System.out.println("ADD MISSING NEW TAG TO " + registry + ": " + k);
|
||||
// tagsMap.put(k, v);
|
||||
// }
|
||||
// });
|
||||
frozenTags.forEach(tagsMap::putIfAbsent);
|
||||
|
||||
// Update inner tags map of the TagSet object that is 'allTags' field of the registry.
|
||||
Reflex.setFieldValue(tagSet, TAG_SET_MAP_FIELD, tagsMap);
|
||||
// Assign original TagSet object with modified tags map to the 'allTags' field of the registry.
|
||||
Reflex.setFieldValue(registry, REGISTRY_ALL_TAGS_FIELD, tagSet);
|
||||
}
|
||||
|
||||
private static <T> void unbound(@NotNull MappedRegistry<T> registry) {
|
||||
Class<?> tagSetClass = Reflex.getInnerClass(MappedRegistry.class.getName(), "TagSet");
|
||||
|
||||
Method unboundMethod = Reflex.getMethod(tagSetClass, TAG_SET_UNBOUND_METHOD);
|
||||
Object unboundTagSet = Reflex.invokeMethod(unboundMethod, registry); // new TagSet object.
|
||||
|
||||
Reflex.setFieldValue(registry, REGISTRY_ALL_TAGS_FIELD, unboundTagSet);
|
||||
}
|
||||
|
||||
//VanillaRegistries.createLookup().lookup(Registries.ENCHANTMENT).get();
|
||||
|
||||
// Create Enchantment reference.
|
||||
//Holder.Reference<Enchantment> reference = Holder.Reference.createStandAlone(ENCHANTMENT_REGISTRY.holderOwner(), key);
|
||||
// Bind enchantment value to the reference (or it will be null).
|
||||
//Reflex.setFieldValue(reference, "e", enchantment);
|
||||
|
||||
@Override
|
||||
public void addExclusives(@NotNull CustomEnchantment customEnchantment) {
|
||||
ResourceKey<Enchantment> enchantKey = getResourceKey(ENCHANTS, customEnchantment.getId());
|
||||
Enchantment enchantment = ENCHANTS.getValue(enchantKey);
|
||||
if (enchantment == null) {
|
||||
this.plugin.error(customEnchantment.getId() + ": Could not set exclusive item list. Enchantment is not registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
TagKey<Enchantment> exclusivesKey = getTagKey(ENCHANTS, "exclusive_set/" + customEnchantment.getId());
|
||||
|
||||
customEnchantment.getDefinition().getConflicts().forEach(enchantId -> {
|
||||
ResourceKey<Enchantment> conflictKey = getResourceKey(ENCHANTS, enchantId);
|
||||
Holder.Reference<Enchantment> reference = ENCHANTS.get(conflictKey).orElse(null);
|
||||
if (reference == null) return;
|
||||
|
||||
addInTag(exclusivesKey, reference);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public org.bukkit.enchantments.Enchantment registerEnchantment(@NotNull CustomEnchantment customEnchantment) {
|
||||
Definition customDefinition = customEnchantment.getDefinition();
|
||||
|
||||
Component display = CraftChatMessage.fromJSON(NightMessage.asJson(customEnchantment.getFormattedName()));
|
||||
HolderSet.Named<Item> supportedItems = createItemsSet("enchant_supported", customEnchantment, customDefinition.getSupportedItems());
|
||||
HolderSet.Named<Item> primaryItems = createItemsSet("enchant_primary", customEnchantment, customDefinition.getPrimaryItems());
|
||||
int weight = customDefinition.getRarity().getWeight();
|
||||
int maxLevel = customDefinition.getMaxLevel();
|
||||
Enchantment.Cost minCost = nmsCost(customDefinition.getMinCost());
|
||||
Enchantment.Cost maxCost = nmsCost(customDefinition.getMaxCost());
|
||||
int anvilCost = customDefinition.getAnvilCost();
|
||||
EquipmentSlotGroup[] slots = nmsSlots(customDefinition);
|
||||
|
||||
Enchantment.EnchantmentDefinition definition = Enchantment.definition(supportedItems, primaryItems, weight, maxLevel, minCost, maxCost, anvilCost, slots);
|
||||
HolderSet<Enchantment> exclusiveSet = createExclusiveSet(customEnchantment);
|
||||
DataComponentMap.Builder builder = DataComponentMap.builder();
|
||||
|
||||
Enchantment enchantment = new Enchantment(display, definition, exclusiveSet, builder.build());
|
||||
|
||||
// Create a new Holder for the custom enchantment.
|
||||
Holder.Reference<Enchantment> reference = ENCHANTS.createIntrusiveHolder(enchantment);
|
||||
|
||||
// Add it into Registry.
|
||||
Registry.register(ENCHANTS, customEnchantment.getId(), enchantment);
|
||||
|
||||
// Now it's possible to add/remove it from vanilla tags since we have a valid, registered Reference.
|
||||
this.setupDistribution(customEnchantment, reference);
|
||||
|
||||
// Return the bukkit mirror.
|
||||
return CraftEnchantment.minecraftToBukkit(enchantment);
|
||||
}
|
||||
|
||||
// public void displayTags() {
|
||||
// displayTag(EnchantmentTags.CURSE);
|
||||
// displayTag(EnchantmentTags.TREASURE);
|
||||
// displayTag(EnchantmentTags.NON_TREASURE);
|
||||
// displayTag(EnchantmentTags.IN_ENCHANTING_TABLE);
|
||||
// displayTag(EnchantmentTags.DOUBLE_TRADE_PRICE);
|
||||
// displayTag(EnchantmentTags.ON_TRADED_EQUIPMENT);
|
||||
// displayTag(EnchantmentTags.ON_MOB_SPAWN_EQUIPMENT);
|
||||
// displayTag(EnchantmentTags.ON_RANDOM_LOOT);
|
||||
// displayTag(EnchantmentTags.ARMOR_EXCLUSIVE);
|
||||
// displayTag(EnchantmentTags.TRADEABLE);
|
||||
// }
|
||||
//
|
||||
// public void displayTag(TagKey<Enchantment> tagKey) {
|
||||
// ENCHANTS.get(tagKey).ifPresent(holders -> {
|
||||
// System.out.println(tagKey + ": " + holders.stream().map(Holder::value).toList());
|
||||
// });
|
||||
// System.out.println(" ");
|
||||
// }
|
||||
|
||||
private void setupDistribution(@NotNull CustomEnchantment customEnchantment, @NotNull Holder.Reference<Enchantment> reference) {
|
||||
boolean experimentalTrades = SERVER.getWorldData().enabledFeatures().contains(FeatureFlags.TRADE_REBALANCE);
|
||||
Distribution distribution = customEnchantment.getDistribution();
|
||||
|
||||
// Any enchantment can be treasure.
|
||||
if (distribution.isTreasure()) {
|
||||
addInTag(EnchantmentTags.TREASURE, reference);
|
||||
addInTag(EnchantmentTags.DOUBLE_TRADE_PRICE, reference);
|
||||
}
|
||||
else addInTag(EnchantmentTags.NON_TREASURE, reference);
|
||||
|
||||
// Any enchantment can be on random loot.
|
||||
if (distribution.isOnRandomLoot() && ConfigBridge.isGlobalDistRandomLoot()) {
|
||||
addInTag(EnchantmentTags.ON_RANDOM_LOOT, reference);
|
||||
}
|
||||
|
||||
// Only non-treasure enchantments should be on mob equipment, traded equipment and non-rebalanced trades.
|
||||
if (!distribution.isTreasure()) {
|
||||
if (distribution.isOnMobSpawnEquipment() && ConfigBridge.isGlobalDistMobEquipment()) {
|
||||
addInTag(EnchantmentTags.ON_MOB_SPAWN_EQUIPMENT, reference);
|
||||
}
|
||||
|
||||
if (distribution.isOnTradedEquipment() && ConfigBridge.isGlobalDistTradeEquipment()) {
|
||||
addInTag(EnchantmentTags.ON_TRADED_EQUIPMENT, reference);
|
||||
}
|
||||
}
|
||||
|
||||
// Any enchantment can be tradable.
|
||||
if (experimentalTrades) {
|
||||
if (distribution.isTradable() && ConfigBridge.isGlobalDistTrading()) {
|
||||
distribution.getTrades().forEach(tradeType -> {
|
||||
addInTag(getTradeKey(tradeType), reference);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (distribution.isTradable() && ConfigBridge.isGlobalDistTrading()) {
|
||||
addInTag(EnchantmentTags.TRADEABLE, reference);
|
||||
}
|
||||
else removeFromTag(EnchantmentTags.TRADEABLE, reference);
|
||||
}
|
||||
|
||||
if (customEnchantment.isCurse()) {
|
||||
addInTag(EnchantmentTags.CURSE, reference);
|
||||
}
|
||||
else {
|
||||
// Only non-curse and non-treasure enchantments should go in enchanting table.
|
||||
if (!distribution.isTreasure()) {
|
||||
if (distribution.isDiscoverable() && ConfigBridge.isGlobalDistEnchanting()) {
|
||||
addInTag(EnchantmentTags.IN_ENCHANTING_TABLE, reference);
|
||||
}
|
||||
else removeFromTag(EnchantmentTags.IN_ENCHANTING_TABLE, reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addInTag(@NotNull TagKey<Enchantment> tagKey, @NotNull Holder.Reference<Enchantment> reference) {
|
||||
modfiyTag(ENCHANTS, tagKey, reference, List::add);
|
||||
}
|
||||
|
||||
private void removeFromTag(@NotNull TagKey<Enchantment> tagKey, @NotNull Holder.Reference<Enchantment> reference) {
|
||||
modfiyTag(ENCHANTS, tagKey, reference, List::remove);
|
||||
}
|
||||
|
||||
private <T> void modfiyTag(@NotNull MappedRegistry<T> registry,
|
||||
@NotNull TagKey<T> tagKey,
|
||||
@NotNull Holder.Reference<T> reference,
|
||||
@NotNull BiConsumer<List<Holder<T>>, Holder.Reference<T>> consumer) {
|
||||
|
||||
HolderSet.Named<T> holders = registry.get(tagKey).orElse(null);
|
||||
if (holders == null) {
|
||||
this.plugin.warn(tagKey + ": Could not modify HolderSet. HolderSet is NULL.");
|
||||
return;
|
||||
}
|
||||
|
||||
List<Holder<T>> contents = new ArrayList<>(holders.stream().toList());
|
||||
consumer.accept(contents, reference);
|
||||
|
||||
registry.bindTag(tagKey, contents);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static HolderSet.Named<Item> createItemsSet(@NotNull String prefix, @NotNull CustomEnchantment customEnchantment, @NotNull ItemsCategory category) {
|
||||
TagKey<Item> customKey = getTagKey(ITEMS, prefix + "/" + customEnchantment.getId());
|
||||
List<Holder<Item>> holders = new ArrayList<>();
|
||||
|
||||
category.getMaterials().forEach(material -> {
|
||||
ResourceLocation location = CraftNamespacedKey.toMinecraft(material.getKey());
|
||||
Holder.Reference<Item> holder = ITEMS.get(location).orElse(null);
|
||||
if (holder == null) return;
|
||||
|
||||
holders.add(holder);
|
||||
});
|
||||
|
||||
// Creates new tag, puts it in the 'frozenTags' map and binds holders to it.
|
||||
ITEMS.bindTag(customKey, holders);
|
||||
|
||||
return getFrozenTags(ITEMS).get(customKey);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static HolderSet.Named<Enchantment> createExclusiveSet(@NotNull CustomEnchantment customEnchantment) {
|
||||
TagKey<Enchantment> customKey = getTagKey(ENCHANTS, "exclusive_set/" + customEnchantment.getId());
|
||||
List<Holder<Enchantment>> holders = new ArrayList<>();
|
||||
|
||||
// Creates new tag, puts it in the 'frozenTags' map and binds holders to it.
|
||||
ENCHANTS.bindTag(customKey, holders);
|
||||
|
||||
return getFrozenTags(ENCHANTS).get(customKey);
|
||||
}
|
||||
|
||||
// private static HolderSet.Named<Enchantment> getExclusiveSet(@NotNull CustomEnchantment data) {
|
||||
// TagKey<Enchantment> customKey = TagKey.create(Registries.ENCHANTMENT, ResourceLocation.withDefaultNamespace("exclusives/" + data.getId()));
|
||||
// return ENCHANTS.get(customKey).orElse(null);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
private static TagKey<Enchantment> getTradeKey(@NotNull TradeType tradeType) {
|
||||
return switch (tradeType) {
|
||||
case DESERT_COMMON -> EnchantmentTags.TRADES_DESERT_COMMON;
|
||||
case DESERT_SPECIAL -> EnchantmentTags.TRADES_DESERT_SPECIAL;
|
||||
case PLAINS_COMMON -> EnchantmentTags.TRADES_PLAINS_COMMON;
|
||||
case PLAINS_SPECIAL -> EnchantmentTags.TRADES_PLAINS_SPECIAL;
|
||||
case SAVANNA_COMMON -> EnchantmentTags.TRADES_SAVANNA_COMMON;
|
||||
case SAVANNA_SPECIAL -> EnchantmentTags.TRADES_SAVANNA_SPECIAL;
|
||||
case JUNGLE_COMMON -> EnchantmentTags.TRADES_JUNGLE_COMMON;
|
||||
case JUNGLE_SPECIAL -> EnchantmentTags.TRADES_JUNGLE_SPECIAL;
|
||||
case SNOW_COMMON -> EnchantmentTags.TRADES_SNOW_COMMON;
|
||||
case SNOW_SPECIAL -> EnchantmentTags.TRADES_SNOW_SPECIAL;
|
||||
case SWAMP_COMMON -> EnchantmentTags.TRADES_SWAMP_COMMON;
|
||||
case SWAMP_SPECIAL -> EnchantmentTags.TRADES_SWAMP_SPECIAL;
|
||||
case TAIGA_COMMON -> EnchantmentTags.TRADES_TAIGA_COMMON;
|
||||
case TAIGA_SPECIAL -> EnchantmentTags.TRADES_TAIGA_SPECIAL;
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Enchantment.Cost nmsCost(@NotNull Cost cost) {
|
||||
return new Enchantment.Cost(cost.base(), cost.perLevel());
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
private static EquipmentSlotGroup[] nmsSlots(@NotNull Definition definition) {
|
||||
EquipmentSlot[] slots = definition.getSupportedItems().getSlots();
|
||||
EquipmentSlotGroup[] nmsSlots = new EquipmentSlotGroup[slots.length];
|
||||
|
||||
for (int index = 0; index < nmsSlots.length; index++) {
|
||||
EquipmentSlot bukkitSlot = slots[index];
|
||||
nmsSlots[index] = CraftEquipmentSlot.getNMSGroup(bukkitSlot.getGroup());
|
||||
}
|
||||
|
||||
return nmsSlots;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAttackPacket(@NotNull Player player, int id) {
|
||||
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||
ServerPlayer entity = craftPlayer.getHandle();
|
||||
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
|
||||
craftPlayer.getHandle().connection.send(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void retrieveHook(@NotNull FishHook hook, @NotNull ItemStack item, @NotNull EquipmentSlot slot) {
|
||||
CraftFishHook craftFishHook = (CraftFishHook) hook;
|
||||
FishingHook handle = craftFishHook.getHandle();
|
||||
|
||||
net.minecraft.world.entity.player.Player owner = handle.getPlayerOwner();
|
||||
if (owner == null) return;
|
||||
|
||||
int result = handle.retrieve(CraftItemStack.asNMSCopy(item));
|
||||
|
||||
net.minecraft.world.entity.EquipmentSlot hand = slot == EquipmentSlot.HAND ? net.minecraft.world.entity.EquipmentSlot.MAINHAND : net.minecraft.world.entity.EquipmentSlot.OFFHAND;
|
||||
|
||||
net.minecraft.world.item.ItemStack itemStack = owner.getItemBySlot(hand);
|
||||
if (itemStack == null) return;
|
||||
|
||||
itemStack.hurtAndBreak(result, handle.getPlayerOwner(), hand);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Material getItemBlockVariant(@NotNull Material material) {
|
||||
ItemStack itemStack = new ItemStack(material);
|
||||
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
if (nmsStack.getItem() instanceof BlockItem blockItem) {
|
||||
return CraftBlockType.minecraftToBukkit(blockItem.getBlock());
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleFlameWalker(@NotNull FlameWalker flameWalker, @NotNull LivingEntity bukkitEntity, int level) {
|
||||
Entity entity = ((CraftLivingEntity) bukkitEntity).getHandle();
|
||||
BlockPos pos = entity.blockPosition();
|
||||
Level world = entity.level();
|
||||
|
||||
int radius = (int) flameWalker.getRadius().getValue(level);
|
||||
BlockState magmaState = 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 aboveLava = world.getBlockState(posAbove);
|
||||
BlockState lavaState = world.getBlockState(posNear);
|
||||
|
||||
if (!aboveLava.isAir()) continue;
|
||||
if (!lavaState.getBlock().equals(Blocks.LAVA)) continue;
|
||||
if (lavaState.getValue(LiquidBlock.LEVEL) != 0) continue;
|
||||
if (!magmaState.canSurvive(world, posNear)) continue;
|
||||
if (!world.isUnobstructed(magmaState, posNear, CollisionContext.empty())) continue;
|
||||
if (!CraftEventFactory.handleBlockFormEvent(world, posNear, magmaState, entity)) continue;
|
||||
|
||||
blocks.add(CraftBlock.at(world, posNear));
|
||||
}
|
||||
|
||||
blocks.forEach(block -> flameWalker.addBlock(block, level));
|
||||
|
||||
return !blocks.isEmpty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public org.bukkit.entity.Item popResource(@NotNull Block block, @NotNull ItemStack item) {
|
||||
Level world = ((CraftWorld)block.getWorld()).getHandle();
|
||||
BlockPos pos = ((CraftBlock)block).getPosition();
|
||||
net.minecraft.world.item.ItemStack itemstack = CraftItemStack.asNMSCopy(item);
|
||||
|
||||
float yMod = EntityType.ITEM.getHeight() / 2.0F;
|
||||
double x = (pos.getX() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D);
|
||||
double y = (pos.getY() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D) - yMod;
|
||||
double z = (pos.getZ() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D);
|
||||
|
||||
ItemEntity itemEntity = new ItemEntity(world, x, y, z, itemstack);
|
||||
itemEntity.setDefaultPickUpDelay();
|
||||
return (org.bukkit.entity.Item) itemEntity.getBukkitEntity();
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
5
pom.xml
5
pom.xml
@ -7,13 +7,14 @@
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
<modules>
|
||||
<module>API</module>
|
||||
<module>Core</module>
|
||||
<module>NMS</module>
|
||||
<module>MC_1_21</module>
|
||||
<module>MC_1_21_3</module>
|
||||
<module>MC_1_21_4</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
@ -26,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.nightcore</groupId>
|
||||
<artifactId>nightcore</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.7.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user