mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
Feature/datapack (#58)
Add support for enchantment of the-bracken-pack datapack also do some minor enchantment fix
This commit is contained in:
commit
914cd0b949
23 changed files with 849 additions and 124 deletions
|
|
@ -16,7 +16,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "xyz.alexcrea"
|
group = "xyz.alexcrea"
|
||||||
version = "1.10.1"
|
version = "1.11.0"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// EcoEnchants
|
// EcoEnchants
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package xyz.alexcrea.cuanvil.dependency.datapack
|
||||||
|
|
||||||
|
import io.papermc.paper.datapack.Datapack
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
object DataPackTester {
|
||||||
|
val legacyNames: List<String>
|
||||||
|
get() = Bukkit.getDataPackManager().dataPacks
|
||||||
|
.stream().filter { obj -> obj.isEnabled }
|
||||||
|
.map { pack -> pack.key.key }
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
val enabledPacks: List<String>
|
||||||
|
get() {
|
||||||
|
try {
|
||||||
|
// will throw error if do not exist
|
||||||
|
Bukkit::class.java.getDeclaredMethod("getDatapackManager")
|
||||||
|
|
||||||
|
return Bukkit.getDatapackManager().enabledPacks
|
||||||
|
.stream().map { obj: Datapack -> obj.name }
|
||||||
|
.toList()
|
||||||
|
} catch (e: NoSuchMethodException) {
|
||||||
|
return legacyNames
|
||||||
|
} catch (e: Exception){
|
||||||
|
// Assume cause UnimplementedOperationException on mock server
|
||||||
|
return Collections.emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -105,7 +105,9 @@ public class MaterialGroupApi {
|
||||||
if (group instanceof IncludeGroup includeGroup) {
|
if (group instanceof IncludeGroup includeGroup) {
|
||||||
changed = writeKnownGroup("include", includeGroup);
|
changed = writeKnownGroup("include", includeGroup);
|
||||||
} else if (group instanceof ExcludeGroup excludeGroup) {
|
} else if (group instanceof ExcludeGroup excludeGroup) {
|
||||||
changed = writeKnownGroup("exclude", excludeGroup);
|
throw new UnsupportedOperationException("exclude group is temporarily disable for the time being. sorry");
|
||||||
|
// This code do not do what is intended ? idk why do it exist
|
||||||
|
//changed = writeKnownGroup("exclude", excludeGroup);
|
||||||
} else {
|
} else {
|
||||||
changed = writeUnknownGroup(group);
|
changed = writeUnknownGroup(group);
|
||||||
}
|
}
|
||||||
|
|
@ -124,13 +126,24 @@ public class MaterialGroupApi {
|
||||||
Set<Material> materialSet = group.getNonGroupInheritedMaterials();
|
Set<Material> materialSet = group.getNonGroupInheritedMaterials();
|
||||||
Set<AbstractMaterialGroup> groupSet = group.getGroups();
|
Set<AbstractMaterialGroup> groupSet = group.getGroups();
|
||||||
|
|
||||||
|
boolean empty = true;
|
||||||
if (!materialSet.isEmpty()) {
|
if (!materialSet.isEmpty()) {
|
||||||
config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materialSetToStringList(materialSet));
|
config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materialSetToStringList(materialSet));
|
||||||
|
empty = false;
|
||||||
|
} else {
|
||||||
|
config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, null);
|
||||||
}
|
}
|
||||||
if (!groupSet.isEmpty()) {
|
if (!groupSet.isEmpty()) {
|
||||||
config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, materialGroupSetToStringList(groupSet));
|
config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, materialGroupSetToStringList(groupSet));
|
||||||
|
empty = false;
|
||||||
|
} else {
|
||||||
|
config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty) {
|
||||||
|
config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, null);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (!config.isConfigurationSection(group.getName())) return false;
|
|
||||||
|
|
||||||
config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, groupType);
|
config.set(basePath + ItemGroupManager.GROUP_TYPE_PATH, groupType);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -76,12 +76,12 @@ public class CAEnchantmentRegistry {
|
||||||
*/
|
*/
|
||||||
public boolean register(@NotNull CAEnchantment enchantment) {
|
public boolean register(@NotNull CAEnchantment enchantment) {
|
||||||
if (byKeyMap.containsKey(enchantment.getKey())) {
|
if (byKeyMap.containsKey(enchantment.getKey())) {
|
||||||
if (!enchantment.equals(byKeyMap.get(enchantment.getKey()))) {
|
if (Objects.equals(enchantment, byKeyMap.get(enchantment.getKey()))) {
|
||||||
// We are trying to register the exact same enchantment. so we just skip it.
|
// We are trying to register the exact same enchantment. so we just skip it.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ConfigHolder.DEFAULT_CONFIG.getConfig().getBoolean("caution_secret_do_not_log_duplicated_registered_key", false)){
|
if (ConfigHolder.DEFAULT_CONFIG.getConfig().getBoolean("caution_secret_do_not_log_duplicated_registered_key", false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import java.lang.reflect.Method;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -25,17 +26,17 @@ import java.util.logging.Level;
|
||||||
*/
|
*/
|
||||||
public class CABukkitEnchantment extends CAEnchantmentBase {
|
public class CABukkitEnchantment extends CAEnchantmentBase {
|
||||||
|
|
||||||
private final @NotNull Enchantment enchantment;
|
public final @NotNull Enchantment bukkit;
|
||||||
|
|
||||||
public CABukkitEnchantment(@NotNull Enchantment enchantment, @Nullable EnchantmentRarity rarity){
|
public CABukkitEnchantment(@NotNull Enchantment bukkit, @Nullable EnchantmentRarity rarity){
|
||||||
super(enchantment.getKey(),
|
super(bukkit.getKey(),
|
||||||
rarity,
|
rarity,
|
||||||
enchantment.getMaxLevel());
|
bukkit.getMaxLevel());
|
||||||
this.enchantment = enchantment;
|
this.bukkit = bukkit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CABukkitEnchantment(@NotNull Enchantment enchantment){
|
public CABukkitEnchantment(@NotNull Enchantment bukkit){
|
||||||
this(enchantment, getRarity(enchantment));
|
this(bukkit, getRarity(bukkit));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -51,9 +52,9 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
|
||||||
@Override
|
@Override
|
||||||
public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) {
|
public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||||
if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
|
if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
|
||||||
return ((EnchantmentStorageMeta)meta).getStoredEnchantLevel(this.enchantment);
|
return ((EnchantmentStorageMeta)meta).getStoredEnchantLevel(this.bukkit);
|
||||||
} else {
|
} else {
|
||||||
return meta.getEnchantLevel(this.enchantment);
|
return meta.getEnchantLevel(this.bukkit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,9 +63,9 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
|
||||||
if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
|
if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
|
||||||
EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)meta);
|
EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)meta);
|
||||||
|
|
||||||
return bookMeta.getStoredEnchants().containsKey(this.enchantment);
|
return bookMeta.getStoredEnchants().containsKey(this.bukkit);
|
||||||
}else{
|
}else{
|
||||||
return item.containsEnchantment(this.enchantment);
|
return item.containsEnchantment(this.bukkit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,10 +75,10 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
|
||||||
EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta());
|
EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta());
|
||||||
|
|
||||||
assert bookMeta != null;
|
assert bookMeta != null;
|
||||||
bookMeta.addStoredEnchant(this.enchantment, level, true);
|
bookMeta.addStoredEnchant(this.bukkit, level, true);
|
||||||
item.setItemMeta(bookMeta);
|
item.setItemMeta(bookMeta);
|
||||||
} else {
|
} else {
|
||||||
item.addUnsafeEnchantment(this.enchantment, level);
|
item.addUnsafeEnchantment(this.bukkit, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -88,10 +89,10 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
|
||||||
EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta());
|
EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta());
|
||||||
|
|
||||||
assert bookMeta != null;
|
assert bookMeta != null;
|
||||||
bookMeta.removeStoredEnchant(this.enchantment);
|
bookMeta.removeStoredEnchant(this.bukkit);
|
||||||
item.setItemMeta(bookMeta);
|
item.setItemMeta(bookMeta);
|
||||||
}else{
|
}else{
|
||||||
item.removeEnchantment(this.enchantment);
|
item.removeEnchantment(this.bukkit);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +108,7 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected Enchantment getEnchant() {
|
protected Enchantment getEnchant() {
|
||||||
return this.enchantment;
|
return this.bukkit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Method getAnvilCostMethod;
|
private static Method getAnvilCostMethod;
|
||||||
|
|
@ -163,7 +164,7 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.enchantment.equals(other.getEnchant());
|
return Objects.equals(this.bukkit, other.getEnchant());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent an enchantment incompatible with every other enchantments
|
||||||
|
*/
|
||||||
|
public class CAIncompatibleAllEnchant extends CABukkitEnchantment implements AdditionalTestEnchantment {
|
||||||
|
|
||||||
|
public CAIncompatibleAllEnchant(@NotNull Enchantment enchantment, @Nullable EnchantmentRarity rarity) {
|
||||||
|
super(enchantment, rarity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CAIncompatibleAllEnchant(@NotNull Enchantment enchantment) {
|
||||||
|
super(enchantment);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
||||||
|
return !enchantments.isEmpty() && !(enchantments.size() == 1 && enchantments.containsKey(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,18 +10,18 @@ import java.util.List;
|
||||||
public class UpdateUtils {
|
public class UpdateUtils {
|
||||||
public static final String MINECRAFT_VERSION_PATH = "lowMinecraftVersion";
|
public static final String MINECRAFT_VERSION_PATH = "lowMinecraftVersion";
|
||||||
|
|
||||||
public static Version currentMinecraftVersion(){
|
public static Version currentMinecraftVersion() {
|
||||||
String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0];
|
String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0];
|
||||||
return Version.fromString(versionString);
|
return Version.fromString(versionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static int[] currentMinecraftVersionArray(){
|
public static int[] currentMinecraftVersionArray() {
|
||||||
String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0];
|
String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0];
|
||||||
return UpdateUtils.readVersionFromString(versionString);
|
return UpdateUtils.readVersionFromString(versionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] readVersionFromString(String versionString){
|
public static int[] readVersionFromString(String versionString) {
|
||||||
String[] partialVersion = versionString.split("\\.");
|
String[] partialVersion = versionString.split("\\.");
|
||||||
int[] versionParts = new int[]{0, 0, 0};
|
int[] versionParts = new int[]{0, 0, 0};
|
||||||
|
|
||||||
|
|
@ -31,11 +31,22 @@ public class UpdateUtils {
|
||||||
return versionParts;
|
return versionParts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addToStringList(FileConfiguration config, String path, String... toAdd){
|
public static void addToStringList(FileConfiguration config, String path, String... toAdd) {
|
||||||
List<String> groups = new ArrayList<>(config.getStringList(path));
|
List<String> groups = new ArrayList<>(config.getStringList(path));
|
||||||
groups.addAll(Arrays.asList(toAdd));
|
groups.addAll(Arrays.asList(toAdd));
|
||||||
config.set(path, groups);
|
config.set(path, groups);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void addAbsentToList(FileConfiguration config, String path, String... toAdd) {
|
||||||
|
List<String> groups = new ArrayList<>(config.getStringList(path));
|
||||||
|
for (String val : toAdd) {
|
||||||
|
if (groups.contains(val)) continue;
|
||||||
|
|
||||||
|
groups.add(val);
|
||||||
|
}
|
||||||
|
config.set(path, groups);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import io.delilaheve.CustomAnvil;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||||
|
|
||||||
import static xyz.alexcrea.cuanvil.update.UpdateUtils.addToStringList;
|
import static xyz.alexcrea.cuanvil.update.UpdateUtils.addAbsentToList;
|
||||||
|
|
||||||
// This is a temporary class that aim to handle 1.21 update.
|
// This is a temporary class that aim to handle 1.21 update.
|
||||||
// It will be replaced by a better system later.
|
// It will be replaced by a better system later.
|
||||||
|
|
@ -40,28 +40,27 @@ public class Update_1_21 {
|
||||||
|
|
||||||
// Add mace to groups
|
// Add mace to groups
|
||||||
groupConfig.set("mace.type", "include");
|
groupConfig.set("mace.type", "include");
|
||||||
addToStringList(groupConfig, "mace.items", "mace");
|
addAbsentToList(groupConfig, "mace.items", "mace");
|
||||||
|
|
||||||
addToStringList(groupConfig, "can_unbreak.groups", "mace");
|
addAbsentToList(groupConfig, "can_unbreak.groups", "mace");
|
||||||
|
|
||||||
// Add new enchant conflicts
|
// Add new enchant conflicts
|
||||||
addToStringList(conflictConfig, "restriction_density.enchantments", "minecraft:density");
|
addAbsentToList(conflictConfig, "restriction_density.enchantments", "minecraft:density");
|
||||||
addToStringList(conflictConfig, "restriction_density.notAffectedGroups", "mace", "enchanted_book");
|
addAbsentToList(conflictConfig, "restriction_density.notAffectedGroups", "mace", "enchanted_book");
|
||||||
|
|
||||||
addToStringList(conflictConfig, "restriction_breach.enchantments", "minecraft:breach");
|
addAbsentToList(conflictConfig, "restriction_breach.enchantments", "minecraft:breach");
|
||||||
addToStringList(conflictConfig, "restriction_breach.notAffectedGroups", "mace", "enchanted_book");
|
addAbsentToList(conflictConfig, "restriction_breach.notAffectedGroups", "mace", "enchanted_book");
|
||||||
|
|
||||||
addToStringList(conflictConfig, "restriction_wind_burst.enchantments", "minecraft:wind_burst");
|
addAbsentToList(conflictConfig, "restriction_wind_burst.enchantments", "minecraft:wind_burst");
|
||||||
addToStringList(conflictConfig, "restriction_wind_burst.notAffectedGroups", "mace", "enchanted_book");
|
addAbsentToList(conflictConfig, "restriction_wind_burst.notAffectedGroups", "mace", "enchanted_book");
|
||||||
|
|
||||||
// Add mace to conflicts
|
// Add mace to conflicts
|
||||||
addToStringList(conflictConfig, "restriction_fire_aspect.notAffectedGroups", "mace");
|
addAbsentToList(conflictConfig, "restriction_fire_aspect.notAffectedGroups", "mace");
|
||||||
addToStringList(conflictConfig, "restriction_smite.notAffectedGroups", "mace");
|
addAbsentToList(conflictConfig, "restriction_smite.notAffectedGroups", "mace");
|
||||||
addToStringList(conflictConfig, "restriction_bane_of_arthropods.notAffectedGroups", "mace");
|
addAbsentToList(conflictConfig, "restriction_bane_of_arthropods.notAffectedGroups", "mace");
|
||||||
|
|
||||||
addToStringList(conflictConfig, "mace_enchant_conflict.enchantments",
|
addAbsentToList(conflictConfig, "sword_enchant_conflict.enchantments",
|
||||||
"minecraft:density", "minecraft:breach", "minecraft:smite", "minecraft:bane_of_arthropods");
|
"minecraft:density", "minecraft:breach");
|
||||||
conflictConfig.set("mace_enchant_conflict.maxEnchantmentBeforeConflict", 1);
|
|
||||||
|
|
||||||
// Add level limit
|
// Add level limit
|
||||||
baseConfig.set("enchant_limits.minecraft:density", 5);
|
baseConfig.set("enchant_limits.minecraft:density", 5);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package xyz.alexcrea.cuanvil.update;
|
package xyz.alexcrea.cuanvil.update;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public record Version(int major, int minor, int patch) {
|
public record Version(int major, int minor, int patch) {
|
||||||
|
|
||||||
|
|
@ -11,7 +12,9 @@ public record Version(int major, int minor, int patch) {
|
||||||
this(major, 0, 0);
|
this(major, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Version fromString(@Nonnull String versionString){
|
public static Version fromString(@Nullable String versionString){
|
||||||
|
if(versionString == null) return new Version(0, 0, 0);
|
||||||
|
|
||||||
String[] partialVersion = versionString.split("\\.");
|
String[] partialVersion = versionString.split("\\.");
|
||||||
int[] versionParts = new int[]{0, 0, 0};
|
int[] versionParts = new int[]{0, 0, 0};
|
||||||
|
|
||||||
|
|
@ -45,4 +48,8 @@ public record Version(int major, int minor, int patch) {
|
||||||
this.patch <= other.patch)));
|
this.patch <= other.patch)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return major + "." + minor + "." + patch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
package xyz.alexcrea.cuanvil.update.plugin;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import xyz.alexcrea.cuanvil.api.MaterialGroupApi;
|
||||||
|
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||||
|
import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup;
|
||||||
|
import xyz.alexcrea.cuanvil.group.IncludeGroup;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static xyz.alexcrea.cuanvil.update.UpdateUtils.addAbsentToList;
|
||||||
|
|
||||||
|
public class PUpdate_1_11_0 {
|
||||||
|
|
||||||
|
private static final List<String> mace_expected = List.of(
|
||||||
|
"density",
|
||||||
|
"breach",
|
||||||
|
"smite",
|
||||||
|
"bane_of_arthropods"
|
||||||
|
);
|
||||||
|
private static final List<String> sword_expected = List.of(
|
||||||
|
"sharpness",
|
||||||
|
"smite",
|
||||||
|
"bane_of_arthropods"
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Material[] PICKAXES = new Material[]{
|
||||||
|
Material.WOODEN_PICKAXE, Material.STONE_PICKAXE,
|
||||||
|
Material.IRON_PICKAXE, Material.DIAMOND_PICKAXE,
|
||||||
|
Material.GOLDEN_PICKAXE, Material.NETHERITE_PICKAXE
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Material[] SHOVELS = new Material[]{
|
||||||
|
Material.WOODEN_SHOVEL, Material.STONE_SHOVEL,
|
||||||
|
Material.IRON_SHOVEL, Material.DIAMOND_SHOVEL,
|
||||||
|
Material.GOLDEN_SHOVEL, Material.NETHERITE_SHOVEL
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Material[] HOES = new Material[]{
|
||||||
|
Material.WOODEN_HOE, Material.STONE_HOE,
|
||||||
|
Material.IRON_HOE, Material.DIAMOND_HOE,
|
||||||
|
Material.GOLDEN_HOE, Material.NETHERITE_HOE
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void handleUpdate(@Nonnull Set<ConfigHolder> toSave) {
|
||||||
|
handleToolsMigration();
|
||||||
|
handleMaceMigration(toSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleToolsMigration() {
|
||||||
|
// We migrate the mace conflict if exist and unmodified
|
||||||
|
AbstractMaterialGroup tools = MaterialGroupApi.getGroup("tools");
|
||||||
|
|
||||||
|
migrateTools(tools, "pickaxes", PICKAXES);
|
||||||
|
migrateTools(tools, "shovels", SHOVELS);
|
||||||
|
migrateTools(tools, "hoes", HOES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void migrateTools(
|
||||||
|
@Nullable AbstractMaterialGroup tools,
|
||||||
|
@NotNull String toolset,
|
||||||
|
@NotNull Material[] toolMats) {
|
||||||
|
|
||||||
|
// Create new group
|
||||||
|
IncludeGroup group = new IncludeGroup(toolset);
|
||||||
|
group.addAll(toolMats);
|
||||||
|
|
||||||
|
MaterialGroupApi.addMaterialGroup(group, true);
|
||||||
|
|
||||||
|
// Try to see if all the materials was in the tools group. and if so, replace it with the new group
|
||||||
|
if (tools == null) return;
|
||||||
|
if (!(tools instanceof IncludeGroup include)) return;
|
||||||
|
|
||||||
|
List<Material> mats = List.of(toolMats);
|
||||||
|
Set<Material> matSet = include.getNonGroupInheritedMaterials();
|
||||||
|
if (!matSet.containsAll(mats)) return;
|
||||||
|
|
||||||
|
mats.forEach(matSet::remove);
|
||||||
|
tools.addToPolicy(group);
|
||||||
|
MaterialGroupApi.writeMaterialGroup(tools);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleMaceMigration(@Nonnull Set<ConfigHolder> toSave) {
|
||||||
|
// We migrate the mace conflict if exist and unmodified
|
||||||
|
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig();
|
||||||
|
|
||||||
|
if (!config.isConfigurationSection("sword_enchant_conflict")) return;
|
||||||
|
if (!config.isConfigurationSection("mace_enchant_conflict")) return;
|
||||||
|
|
||||||
|
ConfigurationSection mace_conflict = config.getConfigurationSection("mace_enchant_conflict");
|
||||||
|
// Test mace conflict if default
|
||||||
|
if (mace_conflict == null) return;
|
||||||
|
if (mace_conflict.getInt("maxEnchantmentBeforeConflict", 0) != 1) return;
|
||||||
|
|
||||||
|
if (mace_conflict.isList("notAffectedGroups") && !mace_conflict.getList("notAffectedGroups").isEmpty()) return;
|
||||||
|
|
||||||
|
List<String> enchantments = mace_conflict.getStringList("enchantments");
|
||||||
|
if (enchantments.size() != 4) return;
|
||||||
|
for (String ench : mace_expected) {
|
||||||
|
if (!enchantments.contains(ench) && !enchantments.contains("minecraft:" + ench)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test sword_enchant_conflict is default
|
||||||
|
ConfigurationSection sword_conflict = config.getConfigurationSection("sword_enchant_conflict");
|
||||||
|
if (sword_conflict.getInt("maxEnchantmentBeforeConflict", 0) != 1) return;
|
||||||
|
|
||||||
|
if (sword_conflict.isList("notAffectedGroups") && !sword_conflict.getList("notAffectedGroups").isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
enchantments = sword_conflict.getStringList("enchantments");
|
||||||
|
if (enchantments.size() != 3) return;
|
||||||
|
for (String ench : sword_expected) {
|
||||||
|
if (!enchantments.contains(ench) && !enchantments.contains("minecraft:" + ench)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally we know both conflict are default. so we fix
|
||||||
|
addAbsentToList(config, "sword_enchant_conflict.enchantments",
|
||||||
|
"minecraft:density", "minecraft:breach");
|
||||||
|
|
||||||
|
config.set("mace_enchant_conflict", null);
|
||||||
|
toSave.add(ConfigHolder.CONFLICT_HOLDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
package xyz.alexcrea.cuanvil.update.plugin;
|
package xyz.alexcrea.cuanvil.update.plugin;
|
||||||
|
|
||||||
import io.delilaheve.CustomAnvil;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static xyz.alexcrea.cuanvil.update.UpdateUtils.addToStringList;
|
import static xyz.alexcrea.cuanvil.update.UpdateUtils.addAbsentToList;
|
||||||
|
|
||||||
public class PUpdate_1_6_2 {
|
public class PUpdate_1_6_2 {
|
||||||
|
|
||||||
|
|
@ -30,7 +29,7 @@ public class PUpdate_1_6_2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!contained){
|
if(!contained){
|
||||||
addToStringList(config, path, "enchanted_book");
|
addAbsentToList(config, path, "enchanted_book");
|
||||||
conflictUpdated = true;
|
conflictUpdated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,21 @@ public class PluginUpdates {
|
||||||
|
|
||||||
if (new Version(1, 6, 2).greaterThan(current)) {
|
if (new Version(1, 6, 2).greaterThan(current)) {
|
||||||
PUpdate_1_6_2.handleUpdate(toSave);
|
PUpdate_1_6_2.handleUpdate(toSave);
|
||||||
|
|
||||||
// We assume 1.6.7 will run. TODO a better system instead of that I guess
|
// We assume 1.6.7 will run. TODO a better system instead of that I guess
|
||||||
}
|
}
|
||||||
if (new Version(1, 6, 7).greaterThan(current)) {
|
if (new Version(1, 6, 7).greaterThan(current)) {
|
||||||
PUpdate_1_6_7.handleUpdate(toSave);
|
PUpdate_1_6_7.handleUpdate(toSave);
|
||||||
|
|
||||||
// We assume 1.8.0 will run.
|
// We assume 1.8.0 will run.
|
||||||
}
|
}
|
||||||
if (new Version(1, 8, 0).greaterThan(current)) {
|
if (new Version(1, 8, 0).greaterThan(current)) {
|
||||||
PUpdate_1_8_0.handleUpdate(toSave);
|
PUpdate_1_8_0.handleUpdate(toSave);
|
||||||
|
// We assume 1.11.0 will run.
|
||||||
|
}
|
||||||
|
|
||||||
finishConfiguration("1.8.0", toSave);
|
if (new Version(1, 11, 0).greaterThan(current)) {
|
||||||
|
PUpdate_1_11_0.handleUpdate(toSave);
|
||||||
|
|
||||||
|
finishConfiguration("1.11.0", toSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package io.delilaheve.util
|
||||||
|
|
||||||
import io.delilaheve.CustomAnvil
|
import io.delilaheve.CustomAnvil
|
||||||
import io.delilaheve.util.EnchantmentUtil.enchantmentName
|
import io.delilaheve.util.EnchantmentUtil.enchantmentName
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType
|
import xyz.alexcrea.cuanvil.config.WorkPenaltyType
|
||||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart
|
import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart
|
||||||
|
|
@ -51,6 +52,8 @@ object ConfigOptions {
|
||||||
|
|
||||||
const val DISABLE_MERGE_OVER_ROOT = "disable-merge-over"
|
const val DISABLE_MERGE_OVER_ROOT = "disable-merge-over"
|
||||||
|
|
||||||
|
const val IMMUTABLE_ENCHANTMENT_LIST = "immutable_enchantments"
|
||||||
|
|
||||||
// Keys for specific enchantment values
|
// Keys for specific enchantment values
|
||||||
private const val KEY_BOOK = "book"
|
private const val KEY_BOOK = "book"
|
||||||
private const val KEY_ITEM = "item"
|
private const val KEY_ITEM = "item"
|
||||||
|
|
@ -478,4 +481,17 @@ object ConfigOptions {
|
||||||
.takeIf { it in ENCHANT_LIMIT_RANGE }
|
.takeIf { it in ENCHANT_LIMIT_RANGE }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isImmutable(key: NamespacedKey): Boolean {
|
||||||
|
val immutables = ConfigHolder.DEFAULT_CONFIG.config.getStringList(IMMUTABLE_ENCHANTMENT_LIST)
|
||||||
|
|
||||||
|
// We need to ignore case so can't just check "contain"
|
||||||
|
for (ench in immutables) {
|
||||||
|
if (ench.equals(key.toString(), ignoreCase = true) ||
|
||||||
|
ench.equals(key.key, ignoreCase = true)
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||||
import org.bukkit.inventory.AnvilInventory
|
import org.bukkit.inventory.AnvilInventory
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||||
|
import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.GuiTesterSelector
|
import xyz.alexcrea.cuanvil.dependency.gui.GuiTesterSelector
|
||||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
||||||
|
|
@ -78,12 +79,13 @@ object DependencyManager {
|
||||||
havenBagsCompatibility = HavenBagsDependency()
|
havenBagsCompatibility = HavenBagsDependency()
|
||||||
havenBagsCompatibility!!.redirectListeners()
|
havenBagsCompatibility!!.redirectListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleCompatibilityConfig() {
|
fun handleCompatibilityConfig() {
|
||||||
enchantmentSquaredCompatibility?.registerPluginConfiguration()
|
enchantmentSquaredCompatibility?.registerPluginConfiguration()
|
||||||
|
|
||||||
|
// datapacks
|
||||||
|
DataPackDependency.handleDatapackConfigs()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerEnchantments() {
|
fun registerEnchantments() {
|
||||||
|
|
@ -100,6 +102,35 @@ object DependencyManager {
|
||||||
// Then handle plugin reload
|
// Then handle plugin reload
|
||||||
ecoEnchantCompatibility?.handleConfigReload()
|
ecoEnchantCompatibility?.handleConfigReload()
|
||||||
}
|
}
|
||||||
|
// Return true if should bypass (either by a dependency or error)
|
||||||
|
// called before immutability test
|
||||||
|
fun earlyTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||||
|
try {
|
||||||
|
return earlyUnsafeTryEventPreAnvilBypass(event, player)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
CustomAnvil.instance.logger.log(
|
||||||
|
Level.SEVERE,
|
||||||
|
"Error while trying to handle custom anvil supported plugin: ",
|
||||||
|
e
|
||||||
|
)
|
||||||
|
|
||||||
|
// Just in case to avoid illegal items
|
||||||
|
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||||
|
|
||||||
|
// Finally, warn the player, maybe a lot of time but better warn than do nothing
|
||||||
|
event.view.player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun earlyUnsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||||
|
var bypass = false
|
||||||
|
|
||||||
|
// Test if the inventory is a gui(version specific)
|
||||||
|
if (externGuiTester?.testIfGui(event.view) == true) bypass = true
|
||||||
|
|
||||||
|
return bypass
|
||||||
|
}
|
||||||
|
|
||||||
// Return true if should bypass (either by a dependency or error)
|
// Return true if should bypass (either by a dependency or error)
|
||||||
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||||
|
|
@ -133,10 +164,6 @@ object DependencyManager {
|
||||||
// Test excellent enchantments used prepare anvil
|
// Test excellent enchantments used prepare anvil
|
||||||
if (!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true
|
if (!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true
|
||||||
|
|
||||||
// Test if the inventory is a gui(version specific)
|
|
||||||
if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true
|
|
||||||
|
|
||||||
|
|
||||||
return bypass
|
return bypass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,19 +101,6 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
|
||||||
|
|
||||||
private fun writeMissingGroups(){
|
private fun writeMissingGroups(){
|
||||||
// Write group that do not exist on custom anvil.
|
// Write group that do not exist on custom anvil.
|
||||||
// (Tools group regroup most of the tool items. I did not create a seperated group for theses)
|
|
||||||
val pickaxes = IncludeGroup("pickaxes")
|
|
||||||
pickaxes.addAll(Material.WOODEN_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.DIAMOND_PICKAXE, Material.GOLDEN_PICKAXE, Material.NETHERITE_PICKAXE)
|
|
||||||
MaterialGroupApi.addMaterialGroup(pickaxes)
|
|
||||||
|
|
||||||
val shovels = IncludeGroup("shovels")
|
|
||||||
shovels.addAll(Material.WOODEN_SHOVEL, Material.STONE_SHOVEL, Material.IRON_SHOVEL, Material.DIAMOND_SHOVEL, Material.GOLDEN_SHOVEL, Material.NETHERITE_SHOVEL)
|
|
||||||
MaterialGroupApi.addMaterialGroup(shovels)
|
|
||||||
|
|
||||||
val hoes = IncludeGroup("hoes")
|
|
||||||
hoes.addAll(Material.WOODEN_HOE, Material.STONE_HOE, Material.IRON_HOE, Material.DIAMOND_HOE, Material.GOLDEN_HOE, Material.NETHERITE_HOE)
|
|
||||||
MaterialGroupApi.addMaterialGroup(hoes)
|
|
||||||
|
|
||||||
val shield = IncludeGroup("shield")
|
val shield = IncludeGroup("shield")
|
||||||
shield.addToPolicy(Material.SHIELD)
|
shield.addToPolicy(Material.SHIELD)
|
||||||
MaterialGroupApi.addMaterialGroup(shield)
|
MaterialGroupApi.addMaterialGroup(shield)
|
||||||
|
|
@ -125,7 +112,6 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
|
||||||
val trinkets = IncludeGroup("trinkets")
|
val trinkets = IncludeGroup("trinkets")
|
||||||
trinkets.addToPolicy(Material.ROTTEN_FLESH)
|
trinkets.addToPolicy(Material.ROTTEN_FLESH)
|
||||||
MaterialGroupApi.addMaterialGroup(trinkets)
|
MaterialGroupApi.addMaterialGroup(trinkets)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeMaterialRestriction(esEnchantments: List<CAEnchantSquaredEnchantment>){
|
private fun writeMaterialRestriction(esEnchantments: List<CAEnchantSquaredEnchantment>){
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,290 @@
|
||||||
|
package xyz.alexcrea.cuanvil.dependency.datapack
|
||||||
|
|
||||||
|
import io.delilaheve.CustomAnvil
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
|
import xyz.alexcrea.cuanvil.api.ConflictBuilder
|
||||||
|
import xyz.alexcrea.cuanvil.api.EnchantmentApi
|
||||||
|
import xyz.alexcrea.cuanvil.api.MaterialGroupApi
|
||||||
|
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.wrapped.CABukkitEnchantment
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.wrapped.CAIncompatibleAllEnchant
|
||||||
|
import xyz.alexcrea.cuanvil.group.IncludeGroup
|
||||||
|
import xyz.alexcrea.cuanvil.update.UpdateUtils
|
||||||
|
import xyz.alexcrea.cuanvil.update.Version
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
|
object DataPackDependency {
|
||||||
|
private val START_DETECT_VERSION = Version(1, 19, 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of the latest CustomAnvil update related to the pack
|
||||||
|
*/
|
||||||
|
private val LASTEST_VERSION = mapOf(
|
||||||
|
Pair("bracken", Version(1, 11, 0))
|
||||||
|
)
|
||||||
|
|
||||||
|
val enabledDatapacks: List<String>
|
||||||
|
get() {
|
||||||
|
val version: Version = UpdateUtils.currentMinecraftVersion()
|
||||||
|
if (version.lesserThan(START_DETECT_VERSION)) return emptyList()
|
||||||
|
|
||||||
|
return DataPackTester.enabledPacks
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleDatapackConfigs() {
|
||||||
|
val enabledDatapack = enabledDatapacks
|
||||||
|
for (packName in enabledDatapack) {
|
||||||
|
// Handling of pack name is horrible: it is based on file name
|
||||||
|
// So if someone rename a datapack it will make me sad
|
||||||
|
if(!packName.startsWith("file/")) continue
|
||||||
|
|
||||||
|
if (packName.contains("bp_post_scarcity", ignoreCase = true)
|
||||||
|
|| packName.contains("bracken", ignoreCase = true)) {
|
||||||
|
handlePack("bracken")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePack(pack: String){
|
||||||
|
CustomAnvil.instance.logger.info("trying to handle datapack $pack")
|
||||||
|
handlePackInitialConfig(pack)
|
||||||
|
writeDefaultByNamespace(pack)
|
||||||
|
CustomAnvil.instance.logger.info("configuration done for $pack")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePackInitialConfig(pack: String) {
|
||||||
|
val defConfig = ConfigHolder.DEFAULT_CONFIG
|
||||||
|
val version = LASTEST_VERSION[pack]
|
||||||
|
|
||||||
|
val currentVersion = Version.fromString(defConfig.config.getString("datapack.$pack"))
|
||||||
|
if (currentVersion.greaterEqual(version!!)) {
|
||||||
|
handleEnchantAllConflict(pack)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add pack value or do update from previous version
|
||||||
|
// note: update thingy is not yet implemented
|
||||||
|
configureDatapack(pack)
|
||||||
|
|
||||||
|
// Finally, set current pack version to config
|
||||||
|
defConfig.config.set("datapack.$pack", version.toString())
|
||||||
|
defConfig.saveToDisk(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun configureDatapack(pack: String) {
|
||||||
|
val itemGroups = javaClass.getResource("/datapack/$pack/item_groups.yml")
|
||||||
|
val itemConflict = javaClass.getResource("/datapack/$pack/item_conflict.yml")
|
||||||
|
val enchantConflict = javaClass.getResource("/datapack/$pack/enchant_conflict.yml")
|
||||||
|
|
||||||
|
if (itemGroups != null) {
|
||||||
|
val reader = InputStreamReader(itemGroups.openStream())
|
||||||
|
val yml = YamlConfiguration.loadConfiguration(reader)
|
||||||
|
|
||||||
|
handleItemGroups(yml)
|
||||||
|
}
|
||||||
|
|
||||||
|
val newConflictList = ArrayList<ConflictBuilder>()
|
||||||
|
var needSave = false
|
||||||
|
if (itemConflict != null) {
|
||||||
|
val reader = InputStreamReader(itemConflict.openStream())
|
||||||
|
val yml = YamlConfiguration.loadConfiguration(reader)
|
||||||
|
|
||||||
|
addItemConflicts(yml, newConflictList)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enchantConflict != null) {
|
||||||
|
val reader = InputStreamReader(enchantConflict.openStream())
|
||||||
|
val yml = YamlConfiguration.loadConfiguration(reader)
|
||||||
|
|
||||||
|
needSave = addEnchantConflict(yml, newConflictList)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (conflict in newConflictList) {
|
||||||
|
needSave = !conflict.registerIfAbsent() && needSave
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needSave) {
|
||||||
|
ConfigHolder.CONFLICT_HOLDER.saveToDisk(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order matter for this file
|
||||||
|
// Could rewrite to not matter but not really important, so I keep it like that
|
||||||
|
private fun handleItemGroups(yml: YamlConfiguration) {
|
||||||
|
for (groupName in yml.getKeys(false)) {
|
||||||
|
val section = yml.getConfigurationSection(groupName) ?: continue
|
||||||
|
|
||||||
|
var group = MaterialGroupApi.getGroup(groupName)
|
||||||
|
val exist = group != null
|
||||||
|
|
||||||
|
if (group == null) group = IncludeGroup(groupName)
|
||||||
|
|
||||||
|
for (name in section.getStringList("items")) {
|
||||||
|
val mat = Material.getMaterial(name.uppercase())
|
||||||
|
if (mat == null) {
|
||||||
|
CustomAnvil.instance.logger.warning("Could not find material $name for item group $groupName")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
group.addToPolicy(mat)
|
||||||
|
}
|
||||||
|
for (name in section.getStringList("groups")) {
|
||||||
|
val otherGroup = MaterialGroupApi.getGroup(name)
|
||||||
|
if (otherGroup == null) {
|
||||||
|
CustomAnvil.instance.logger.warning("Could not find sub group $name for group $groupName")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
group.addToPolicy(otherGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
group.updateMaterials()
|
||||||
|
|
||||||
|
if (exist) {
|
||||||
|
MaterialGroupApi.writeMaterialGroup(group)
|
||||||
|
} else {
|
||||||
|
MaterialGroupApi.addMaterialGroup(group, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addItemConflicts(yml: FileConfiguration, conflictList: MutableList<ConflictBuilder>) {
|
||||||
|
for (ench in yml.getKeys(false)) {
|
||||||
|
val groups = yml.getStringList(ench)
|
||||||
|
|
||||||
|
val conflict = ConflictBuilder(
|
||||||
|
"restriction_${ench.replace(":", "_")}",
|
||||||
|
CustomAnvil.instance
|
||||||
|
)
|
||||||
|
conflict.addEnchantment(NamespacedKey.fromString(ench)!!)
|
||||||
|
for (group in groups) {
|
||||||
|
conflict.addExcludedGroup(group)
|
||||||
|
}
|
||||||
|
conflict.addExcludedGroup("enchanted_book")
|
||||||
|
|
||||||
|
conflictList.add(conflict)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addEnchantConflict(yml: YamlConfiguration, conflictList: MutableList<ConflictBuilder>): Boolean {
|
||||||
|
var needSave = false
|
||||||
|
|
||||||
|
val conflicts = HashMap<String, ConflictBuilder>()
|
||||||
|
for (ench in yml.getKeys(false)) {
|
||||||
|
val groups = yml.getStringList(ench)
|
||||||
|
|
||||||
|
for (group in groups) {
|
||||||
|
if (group.startsWith('#')) {
|
||||||
|
needSave = joinGroup(conflicts, group.substring(1), ench) || needSave
|
||||||
|
} else {
|
||||||
|
createConflict(conflictList, ench, group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conflictList.addAll(conflicts.values)
|
||||||
|
return needSave
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createConflict(conflictList: MutableList<ConflictBuilder>, ench: String, other: String) {
|
||||||
|
|
||||||
|
val conflict = ConflictBuilder(
|
||||||
|
"conflict_" +
|
||||||
|
"${ench.replace(":", "_")}_" +
|
||||||
|
other.replace(":", "_"),
|
||||||
|
CustomAnvil.instance
|
||||||
|
)
|
||||||
|
conflict.addEnchantment(NamespacedKey.fromString(ench)!!)
|
||||||
|
conflict.addEnchantment(NamespacedKey.fromString(other)!!)
|
||||||
|
|
||||||
|
conflict.setMaxBeforeConflict(1)
|
||||||
|
|
||||||
|
conflictList.add(conflict)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setEnchantAsAll(ench: String) {
|
||||||
|
// We assume current is not null and of type CABukkitEnchantment
|
||||||
|
val current = EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!) as CABukkitEnchantment
|
||||||
|
|
||||||
|
// We need to replace current wrapped enchantment with the all conflict wrapper
|
||||||
|
EnchantmentApi.unregisterEnchantment(current)
|
||||||
|
EnchantmentApi.registerEnchantment(CAIncompatibleAllEnchant(current.bukkit, current.defaultRarity()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun joinGroup(conflicts: HashMap<String, ConflictBuilder>, group: String, ench: String): Boolean {
|
||||||
|
if ("all".equals(group, ignoreCase = true)) {
|
||||||
|
setEnchantAsAll(ench)
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
val config = ConfigHolder.CONFLICT_HOLDER.config
|
||||||
|
|
||||||
|
// If conflict do not yet exist
|
||||||
|
if (!config.isConfigurationSection(group)) {
|
||||||
|
val conflict = conflicts.getOrPut(group) {
|
||||||
|
val conflict = ConflictBuilder(group, CustomAnvil.instance)
|
||||||
|
conflict.setMaxBeforeConflict(1)
|
||||||
|
conflict
|
||||||
|
}
|
||||||
|
|
||||||
|
conflict.addEnchantment(NamespacedKey.fromString(ench)!!)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Find current conflict
|
||||||
|
val manager = ConfigHolder.CONFLICT_HOLDER.conflictManager
|
||||||
|
|
||||||
|
// This assumes that:
|
||||||
|
// - the conflict existing in the config exist in the runtime config (as configuration section exist)
|
||||||
|
// - the enchantment exist and is provided correctly
|
||||||
|
val conflict = manager.conflictList.find {
|
||||||
|
it.name.equals(group, ignoreCase = true)
|
||||||
|
}
|
||||||
|
if(conflict == null) {
|
||||||
|
// This should not happen as configuration section
|
||||||
|
CustomAnvil.instance.logger.severe("Could not find $group while its configuration section exist... this should NOT happen")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val key = NamespacedKey.fromString(ench)!!
|
||||||
|
val enchant = EnchantmentApi.getByKey(key)
|
||||||
|
if (enchant == null){
|
||||||
|
CustomAnvil.instance.logger.severe("Could not find enchantment $ench while configuring pack a datapack")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
conflict.addEnchantment(enchant)
|
||||||
|
|
||||||
|
UpdateUtils.addAbsentToList(config, "$group.enchantments", ench)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleEnchantAllConflict(pack: String) {
|
||||||
|
val enchantConflict = javaClass.getResource("/datapack/$pack/enchant_conflict.yml") ?: return
|
||||||
|
|
||||||
|
val reader = InputStreamReader(enchantConflict.openStream())
|
||||||
|
val yml = YamlConfiguration.loadConfiguration(reader)
|
||||||
|
|
||||||
|
for (ench in yml.getKeys(false)) {
|
||||||
|
val groups = yml.getStringList(ench)
|
||||||
|
|
||||||
|
if (groups.contains("#all")) {
|
||||||
|
setEnchantAsAll(ench)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun writeDefaultByNamespace(namespace: String) {
|
||||||
|
for (enchantment in EnchantmentApi.getRegisteredEnchantments().values) {
|
||||||
|
if(!enchantment.key.namespace.equals(namespace, ignoreCase = true)) continue
|
||||||
|
|
||||||
|
CustomAnvil.log("Writing default for $enchantment")
|
||||||
|
EnchantmentApi.writeDefaultConfig(enchantment, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -31,8 +31,9 @@ class EnchantConflictManager {
|
||||||
|
|
||||||
// 1.20.5 compatibility TODO better update system
|
// 1.20.5 compatibility TODO better update system
|
||||||
private val SWEEPING_EDGE_ENCHANT = Collections.singletonList<CAEnchantment>(
|
private val SWEEPING_EDGE_ENCHANT = Collections.singletonList<CAEnchantment>(
|
||||||
CAEnchantment.getByKey(NamespacedKey.minecraft("sweeping_edge")) ?:
|
CAEnchantment.getByKey(NamespacedKey.minecraft("sweeping_edge"))
|
||||||
CAEnchantment.getByKey(Enchantment.SWEEPING_EDGE.key))
|
?: CAEnchantment.getByKey(Enchantment.SWEEPING_EDGE.key)
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,12 +58,12 @@ class EnchantConflictManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addConflict(conflict: EnchantConflictGroup){
|
fun addConflict(conflict: EnchantConflictGroup) {
|
||||||
addConflictToEnchantments(conflict)
|
addConflictToEnchantments(conflict)
|
||||||
conflictList.add(conflict)
|
conflictList.add(conflict)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeConflict(conflict: EnchantConflictGroup){
|
fun removeConflict(conflict: EnchantConflictGroup) {
|
||||||
removeConflictFromEnchantments(conflict)
|
removeConflictFromEnchantments(conflict)
|
||||||
conflictList.remove(conflict)
|
conflictList.remove(conflict)
|
||||||
}
|
}
|
||||||
|
|
@ -114,14 +115,14 @@ class EnchantConflictManager {
|
||||||
|
|
||||||
private fun getEnchantByIdentifier(enchantName: String): List<CAEnchantment> {
|
private fun getEnchantByIdentifier(enchantName: String): List<CAEnchantment> {
|
||||||
val key = NamespacedKey.fromString(enchantName)
|
val key = NamespacedKey.fromString(enchantName)
|
||||||
if(key != null){
|
if (key != null) {
|
||||||
val enchantment = CAEnchantment.getByKey(key)
|
val enchantment = CAEnchantment.getByKey(key)
|
||||||
if(enchantment != null) return Collections.singletonList(enchantment)
|
if (enchantment != null) return Collections.singletonList(enchantment)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary solution for 1.20.5
|
// Temporary solution for 1.20.5
|
||||||
when(enchantName){
|
when (enchantName) {
|
||||||
"minecraft:sweeping", "sweeping",
|
"minecraft:sweeping", "sweeping",
|
||||||
"minecraft:sweeping_edge", "sweeping_edge" -> {
|
"minecraft:sweeping_edge", "sweeping_edge" -> {
|
||||||
return SWEEPING_EDGE_ENCHANT
|
return SWEEPING_EDGE_ENCHANT
|
||||||
|
|
@ -169,22 +170,31 @@ class EnchantConflictManager {
|
||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isConflicting(appliedEnchants: Map<CAEnchantment, Int>, item: ItemStack, newEnchant: CAEnchantment): ConflictType {
|
fun isConflicting(
|
||||||
|
appliedEnchants: Map<CAEnchantment, Int>,
|
||||||
|
item: ItemStack,
|
||||||
|
newEnchant: CAEnchantment
|
||||||
|
): ConflictType {
|
||||||
val mat = item.type
|
val mat = item.type
|
||||||
CustomAnvil.verboseLog("Testing conflict for ${newEnchant.key} on ${mat.key}")
|
CustomAnvil.verboseLog("Testing conflict for ${newEnchant.key} on ${mat.key}")
|
||||||
val conflictList = newEnchant.conflicts
|
val conflictList = newEnchant.conflicts
|
||||||
|
|
||||||
var result = ConflictType.NO_CONFLICT
|
var result = ConflictType.NO_CONFLICT
|
||||||
for (conflict in conflictList) {
|
for (conflict in conflictList) {
|
||||||
CustomAnvil.verboseLog("Is against $conflict")
|
val isBigConflict = conflict.getEnchants().size > 1
|
||||||
|
if (result == ConflictType.ITEM_CONFLICT && !isBigConflict) {
|
||||||
|
CustomAnvil.verboseLog("skipping small conflict ${conflict.name}")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
val allowed = conflict.allowed(appliedEnchants.keys, mat)
|
val allowed = conflict.allowed(appliedEnchants.keys, mat)
|
||||||
CustomAnvil.verboseLog("Was against $conflict and conflicting: ${!allowed} ")
|
CustomAnvil.verboseLog("Was against $conflict and conflicting: ${!allowed} ")
|
||||||
if (!allowed) {
|
if (!allowed) {
|
||||||
if (conflict.getEnchants().size <= 1) {
|
if (conflict.getEnchants().size <= 1) {
|
||||||
result = ConflictType.ITEM_CONFLICT
|
result = ConflictType.ITEM_CONFLICT
|
||||||
CustomAnvil.verboseLog("Small conflict, continuing")
|
CustomAnvil.verboseLog("Small conflict (${conflict.name}), continuing")
|
||||||
} else {
|
} else {
|
||||||
CustomAnvil.verboseLog("Big conflict, probably stoping")
|
CustomAnvil.verboseLog("Big conflict (${conflict.name}), stopping")
|
||||||
return ConflictType.ENCHANTMENT_CONFLICT
|
return ConflictType.ENCHANTMENT_CONFLICT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -192,19 +202,20 @@ class EnchantConflictManager {
|
||||||
|
|
||||||
val immutableEnchants = Collections.unmodifiableMap(appliedEnchants)
|
val immutableEnchants = Collections.unmodifiableMap(appliedEnchants)
|
||||||
for (appliedEnchant in appliedEnchants.keys) {
|
for (appliedEnchant in appliedEnchants.keys) {
|
||||||
if(appliedEnchant is AdditionalTestEnchantment){
|
if (appliedEnchant is AdditionalTestEnchantment) {
|
||||||
val doConflict = appliedEnchant.isEnchantConflict(immutableEnchants, mat)
|
val doConflict = appliedEnchant.isEnchantConflict(immutableEnchants, mat)
|
||||||
if(doConflict){
|
if (doConflict) {
|
||||||
|
CustomAnvil.verboseLog("Big conflict by additional test, stopping")
|
||||||
return ConflictType.ENCHANTMENT_CONFLICT
|
return ConflictType.ENCHANTMENT_CONFLICT
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((result != ConflictType.ITEM_CONFLICT) && (newEnchant is AdditionalTestEnchantment)){
|
if ((result != ConflictType.ITEM_CONFLICT) && (newEnchant is AdditionalTestEnchantment)) {
|
||||||
val partialItem = createPartialResult(item, immutableEnchants)
|
val partialItem = createPartialResult(item, immutableEnchants)
|
||||||
|
|
||||||
if(newEnchant.isItemConflict(immutableEnchants, mat, partialItem)){
|
if (newEnchant.isItemConflict(immutableEnchants, mat, partialItem)) {
|
||||||
return ConflictType.ITEM_CONFLICT
|
return ConflictType.ITEM_CONFLICT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,8 +228,8 @@ class EnchantConflictManager {
|
||||||
val newItem = item.clone()
|
val newItem = item.clone()
|
||||||
|
|
||||||
CAEnchantment.clearEnchants(newItem)
|
CAEnchantment.clearEnchants(newItem)
|
||||||
enchantments.forEach{
|
enchantments.forEach { enchantment ->
|
||||||
enchantment -> enchantment.key.addEnchantmentUnsafe(newItem, enchantment.value)
|
enchantment.key.addEnchantmentUnsafe(newItem, enchantment.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newItem
|
return newItem
|
||||||
|
|
@ -247,7 +258,7 @@ enum class ConflictType(private val importance: Int) {
|
||||||
ENCHANTMENT_CONFLICT(2);
|
ENCHANTMENT_CONFLICT(2);
|
||||||
|
|
||||||
fun getWorstConflict(otherConflict: ConflictType): ConflictType {
|
fun getWorstConflict(otherConflict: ConflictType): ConflictType {
|
||||||
return if(this.importance > otherConflict.importance) this
|
return if (this.importance > otherConflict.importance) this
|
||||||
else otherConflict
|
else otherConflict
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ import org.bukkit.event.Listener
|
||||||
import org.bukkit.event.inventory.PrepareAnvilEvent
|
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||||
import org.bukkit.inventory.AnvilInventory
|
import org.bukkit.inventory.AnvilInventory
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.inventory.meta.EnchantmentStorageMeta
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta
|
||||||
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||||
import xyz.alexcrea.cuanvil.util.*
|
import xyz.alexcrea.cuanvil.util.*
|
||||||
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
||||||
|
|
@ -45,20 +47,30 @@ class PrepareAnvilListener : Listener {
|
||||||
// Should find player
|
// Should find player
|
||||||
val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view)
|
val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view)
|
||||||
|
|
||||||
// Test if the event should bypass custom anvil.
|
// Test if custom anvil is bypassed before immutability test
|
||||||
if (DependencyManager.tryEventPreAnvilBypass(event, player)) return
|
if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) return
|
||||||
|
|
||||||
val inventory = event.inventory
|
val inventory = event.inventory
|
||||||
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
||||||
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
|
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
|
||||||
|
|
||||||
|
if (isImmutable(first) || isImmutable(second)) {
|
||||||
|
CustomAnvil.verboseLog("Skipping anvil process as one of the two item is immutable")
|
||||||
|
|
||||||
|
event.result = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test if the event should bypass custom anvil.
|
||||||
|
if (DependencyManager.tryEventPreAnvilBypass(event, player)) return
|
||||||
|
|
||||||
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
||||||
|
|
||||||
// Test custom recipe
|
// Test custom recipe
|
||||||
if(testCustomRecipe(event, inventory, player, first, second)) return
|
if (testCustomRecipe(event, inventory, player, first, second)) return
|
||||||
|
|
||||||
// Test rename lonely item
|
// Test rename lonely item
|
||||||
if(second == null) {
|
if (second == null) {
|
||||||
doRenaming(event, inventory, player, first)
|
doRenaming(event, inventory, player, first)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -70,23 +82,51 @@ class PrepareAnvilListener : Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for unit repair
|
// Test for unit repair
|
||||||
if(testUnitRepair(event, inventory, player, first, second)) return
|
if (testUnitRepair(event, inventory, player, first, second)) return
|
||||||
|
|
||||||
// Test for lore edit
|
// Test for lore edit
|
||||||
if(testLoreEdit(event, inventory, player, first, second)) return
|
if (testLoreEdit(event, inventory, player, first, second)) return
|
||||||
|
|
||||||
CustomAnvil.log("no anvil fuse type found")
|
CustomAnvil.log("no anvil fuse type found")
|
||||||
event.result = null
|
event.result = null
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isImmutable(item: ItemStack?): Boolean {
|
||||||
|
if (item == null) return false
|
||||||
|
|
||||||
|
val meta = item.itemMeta
|
||||||
|
return meta != null &&
|
||||||
|
(hasImmutableEnchants(meta) || hasImmutableStoredEnchants(meta))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasImmutableEnchants(meta: ItemMeta): Boolean {
|
||||||
|
if (!meta.hasEnchants()) return false
|
||||||
|
|
||||||
|
for (enchant in meta.enchants.keys) {
|
||||||
|
if (ConfigOptions.isImmutable(enchant.key)) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasImmutableStoredEnchants(meta: ItemMeta): Boolean {
|
||||||
|
if (meta !is EnchantmentStorageMeta || !meta.hasStoredEnchants()) return false
|
||||||
|
|
||||||
|
for (enchant in meta.storedEnchants.keys) {
|
||||||
|
if (ConfigOptions.isImmutable(enchant.key)) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// return true if a custom recipe exist with these ingredients
|
// return true if a custom recipe exist with these ingredients
|
||||||
private fun testCustomRecipe(event: PrepareAnvilEvent, inventory: AnvilInventory,
|
private fun testCustomRecipe(
|
||||||
|
event: PrepareAnvilEvent, inventory: AnvilInventory,
|
||||||
player: HumanEntity,
|
player: HumanEntity,
|
||||||
first: ItemStack, second: ItemStack?): Boolean {
|
first: ItemStack, second: ItemStack?
|
||||||
|
): Boolean {
|
||||||
val recipe = CustomRecipeUtil.getCustomRecipe(first, second)
|
val recipe = CustomRecipeUtil.getCustomRecipe(first, second)
|
||||||
CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}")
|
CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}")
|
||||||
if(recipe == null) return false
|
if (recipe == null) return false
|
||||||
|
|
||||||
val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, first, second)
|
val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, first, second)
|
||||||
|
|
||||||
|
|
@ -94,7 +134,7 @@ class PrepareAnvilListener : Listener {
|
||||||
resultItem.amount *= amount
|
resultItem.amount *= amount
|
||||||
|
|
||||||
event.result = resultItem
|
event.result = resultItem
|
||||||
if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return true
|
if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return true
|
||||||
|
|
||||||
// Maybe add an option on custom craft to ignore/not ignore penalty ??
|
// Maybe add an option on custom craft to ignore/not ignore penalty ??
|
||||||
var xpCost = recipe.xpCostPerCraft * amount
|
var xpCost = recipe.xpCostPerCraft * amount
|
||||||
|
|
@ -105,8 +145,10 @@ class PrepareAnvilListener : Listener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doRenaming(event: PrepareAnvilEvent, inventory: AnvilInventory,
|
private fun doRenaming(
|
||||||
player: HumanEntity, first: ItemStack) {
|
event: PrepareAnvilEvent, inventory: AnvilInventory,
|
||||||
|
player: HumanEntity, first: ItemStack
|
||||||
|
) {
|
||||||
val resultItem = first.clone()
|
val resultItem = first.clone()
|
||||||
var anvilCost = handleRename(resultItem, inventory, player)
|
var anvilCost = handleRename(resultItem, inventory, player)
|
||||||
|
|
||||||
|
|
@ -118,7 +160,7 @@ class PrepareAnvilListener : Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
event.result = resultItem
|
event.result = resultItem
|
||||||
if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return
|
if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return
|
||||||
|
|
||||||
anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
|
anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
|
||||||
|
|
||||||
|
|
@ -131,18 +173,20 @@ class PrepareAnvilListener : Listener {
|
||||||
|
|
||||||
var sumCost = 0
|
var sumCost = 0
|
||||||
var useColor = false
|
var useColor = false
|
||||||
if(ConfigOptions.renameColorPossible && inventoryName != null){
|
if (ConfigOptions.renameColorPossible && inventoryName != null) {
|
||||||
val resultString = StringBuilder(inventoryName)
|
val resultString = StringBuilder(inventoryName)
|
||||||
|
|
||||||
useColor = AnvilColorUtil.handleColor(resultString, player,
|
useColor = AnvilColorUtil.handleColor(
|
||||||
|
resultString, player,
|
||||||
ConfigOptions.permissionNeededForColor,
|
ConfigOptions.permissionNeededForColor,
|
||||||
ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor,
|
ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor,
|
||||||
AnvilColorUtil.ColorUseType.RENAME)
|
AnvilColorUtil.ColorUseType.RENAME
|
||||||
|
)
|
||||||
|
|
||||||
if(useColor) {
|
if (useColor) {
|
||||||
inventoryName = resultString.toString()
|
inventoryName = resultString.toString()
|
||||||
|
|
||||||
sumCost+= ConfigOptions.useOfColorCost
|
sumCost += ConfigOptions.useOfColorCost
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,9 +209,11 @@ class PrepareAnvilListener : Listener {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doMerge(event: PrepareAnvilEvent, inventory: AnvilInventory,
|
private fun doMerge(
|
||||||
|
event: PrepareAnvilEvent, inventory: AnvilInventory,
|
||||||
player: HumanEntity,
|
player: HumanEntity,
|
||||||
first: ItemStack, second: ItemStack) {
|
first: ItemStack, second: ItemStack
|
||||||
|
) {
|
||||||
val newEnchants = first.findEnchantments()
|
val newEnchants = first.findEnchantments()
|
||||||
.combineWith(second.findEnchantments(), first, player)
|
.combineWith(second.findEnchantments(), first, player)
|
||||||
val resultItem = first.clone()
|
val resultItem = first.clone()
|
||||||
|
|
@ -195,14 +241,16 @@ class PrepareAnvilListener : Listener {
|
||||||
|
|
||||||
// Finally, we set result
|
// Finally, we set result
|
||||||
event.result = resultItem
|
event.result = resultItem
|
||||||
if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return
|
if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return
|
||||||
|
|
||||||
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if there is a valid unit repair with these ingredients
|
// return true if there is a valid unit repair with these ingredients
|
||||||
private fun testUnitRepair(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
|
private fun testUnitRepair(
|
||||||
first: ItemStack, second: ItemStack): Boolean {
|
event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
|
||||||
|
first: ItemStack, second: ItemStack
|
||||||
|
): Boolean {
|
||||||
val unitRepairAmount = first.getRepair(second) ?: return false
|
val unitRepairAmount = first.getRepair(second) ?: return false
|
||||||
|
|
||||||
val resultItem = first.clone()
|
val resultItem = first.clone()
|
||||||
|
|
@ -222,26 +270,27 @@ class PrepareAnvilListener : Listener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
event.result = resultItem
|
event.result = resultItem
|
||||||
if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return true
|
if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return true
|
||||||
|
|
||||||
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testLoreEdit(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
|
private fun testLoreEdit(
|
||||||
first: ItemStack, second: ItemStack): Boolean {
|
event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
|
||||||
|
first: ItemStack, second: ItemStack
|
||||||
|
): Boolean {
|
||||||
val type = second.type
|
val type = second.type
|
||||||
var result: ItemStack? = null
|
var result: ItemStack? = null
|
||||||
|
|
||||||
val xpCost = AtomicInteger()
|
val xpCost = AtomicInteger()
|
||||||
if(Material.WRITABLE_BOOK == type) {
|
if (Material.WRITABLE_BOOK == type) {
|
||||||
result = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second, xpCost)
|
result = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second, xpCost)
|
||||||
}
|
} else if (Material.PAPER == type) {
|
||||||
else if(Material.PAPER == type) {
|
|
||||||
result = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second, xpCost)
|
result = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second, xpCost)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result == null || first == result) {
|
if (result == null || first == result) {
|
||||||
CustomAnvil.log("lore edit, But input is same as output")
|
CustomAnvil.log("lore edit, But input is same as output")
|
||||||
event.result = null
|
event.result = null
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -367,4 +367,4 @@ debug_log_verbose: false
|
||||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
||||||
force_protocolib: false
|
force_protocolib: false
|
||||||
|
|
||||||
configVersion: 1.8.0
|
configVersion: 1.11.0
|
||||||
|
|
|
||||||
35
src/main/resources/datapack/bracken/enchant_conflict.yml
Normal file
35
src/main/resources/datapack/bracken/enchant_conflict.yml
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
"bracken:abstraction": ['#sword_enchant_conflict']
|
||||||
|
"bracken:antivenom": ['#protection_enchant_conflict']
|
||||||
|
"bracken:blinding_fix": ['minecraft:fire_aspect']
|
||||||
|
"bracken:boldness": ['#protection_enchant_conflict']
|
||||||
|
"bracken:butchering": ['#sword_enchant_conflict']
|
||||||
|
"bracken:defusing": ['#sword_enchant_conflict']
|
||||||
|
"bracken:dentine_touch": ['#tool_conflict']
|
||||||
|
"bracken:dullness_curse": ['minecraft:sharpness']
|
||||||
|
"bracken:famine_walker": ['#boot_conflict']
|
||||||
|
"bracken:ferocity": ['#sword_enchant_conflict']
|
||||||
|
"bracken:flame_walker": ['#boot_conflict']
|
||||||
|
"bracken:float_walker": ['#boot_conflict']
|
||||||
|
"bracken:flood_walker": ['#boot_conflict']
|
||||||
|
"bracken:fragility_curse": ['minecraft:unbreaking']
|
||||||
|
"bracken:freezing_fix": ['minecraft:fire_aspect']
|
||||||
|
"bracken:guarding": ['#sword_enchant_conflict']
|
||||||
|
"bracken:huskiness": ['#bracken_pet_armor']
|
||||||
|
"bracken:infused_fire_aspect_fix": ['minecraft:fire_aspect']
|
||||||
|
"bracken:infused_frost_walker_fix": ['#boot_conflict']
|
||||||
|
"bracken:infused_mending_fix": ['minecraft:mending']
|
||||||
|
"bracken:infused_thorns_fix": ['minecraft:thorns']
|
||||||
|
"bracken:lethargy_curse": ['bracken:ferocity']
|
||||||
|
"bracken:lifesteal": ['#bow_conflict']
|
||||||
|
"bracken:litheness": ['#bracken_pet_armor']
|
||||||
|
"bracken:lunar_concordance_armor": ['#bracken_lunarite_armor']
|
||||||
|
"bracken:lunar_concordance_weapon": ['#bracken_lunarite_weapons']
|
||||||
|
"bracken:maiming_curse": ['bracken:vitality_fix']
|
||||||
|
"bracken:mortality": ['#sword_enchant_conflict']
|
||||||
|
"bracken:poisoning_fix": ['minecraft:fire_aspect']
|
||||||
|
"bracken:pugnacity": ['#bracken_pet_armor']
|
||||||
|
"bracken:rending": ['#crossbow_conflict']
|
||||||
|
"bracken:silvered_fix": ['#all']
|
||||||
|
"bracken:vitality_fix": ['bracken:maiming_curse']
|
||||||
|
"bracken:weakening_fix": ['minecraft:fire_aspect']
|
||||||
|
"bracken:withering_fix": ['minecraft:fire_aspect']
|
||||||
54
src/main/resources/datapack/bracken/item_conflict.yml
Normal file
54
src/main/resources/datapack/bracken/item_conflict.yml
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
"bracken:abstraction": ['melee_weapons', 'mace']
|
||||||
|
"bracken:antivenom": ['armors']
|
||||||
|
"bracken:astuteness_fix": ['armors']
|
||||||
|
"bracken:blinding_fix": ['can_unbreak']
|
||||||
|
"bracken:boldness": ['armors']
|
||||||
|
"bracken:butchering": ['melee_weapons', 'mace']
|
||||||
|
"bracken:chiseling_fix": ['axes', 'pickaxes', 'shovels', 'hoes']
|
||||||
|
"bracken:decaying_fix": ['can_unbreak']
|
||||||
|
"bracken:defusing": ['melee_weapons', 'mace']
|
||||||
|
"bracken:dentine_touch": ['axes', 'pickaxes', 'shovels', 'hoes']
|
||||||
|
"bracken:devouring_curse": ['melee_weapons', 'mace']
|
||||||
|
"bracken:dullness_curse": ['melee_weapons', 'mace']
|
||||||
|
"bracken:famine_walker": ['boots']
|
||||||
|
"bracken:ferocity": ['melee_weapons', 'mace']
|
||||||
|
"bracken:flame_walker": ['boots']
|
||||||
|
"bracken:float_walker": ['boots']
|
||||||
|
"bracken:flood_walker": ['boots']
|
||||||
|
"bracken:fragility_curse": ['can_unbreak']
|
||||||
|
"bracken:freezing_fix": ['can_unbreak']
|
||||||
|
"bracken:guarding": ['melee_weapons', 'mace']
|
||||||
|
"bracken:huskiness": ['pet_armor']
|
||||||
|
"bracken:infused_fire_aspect_fix": ['melee_weapons', 'mace']
|
||||||
|
"bracken:infused_frost_walker_fix": ['boots']
|
||||||
|
"bracken:infused_mending_fix": ['can_unbreak']
|
||||||
|
"bracken:infused_thorns_fix": ['armors']
|
||||||
|
"bracken:integrity_fix": ['armors']
|
||||||
|
"bracken:lethargy_curse": ['melee_weapons', 'mace']
|
||||||
|
"bracken:lifesteal": ['bow']
|
||||||
|
"bracken:litheness": ['pet_armor']
|
||||||
|
"bracken:maiming_curse": ['armors']
|
||||||
|
"bracken:mortality": ['melee_weapons', 'mace']
|
||||||
|
"bracken:poisoning_fix": ['can_unbreak']
|
||||||
|
"bracken:pugnacity": ['wolf_armor']
|
||||||
|
"bracken:pushback": ['armors']
|
||||||
|
"bracken:quenching_fix": ['armors']
|
||||||
|
"bracken:rending": ['crossbow']
|
||||||
|
"bracken:reverse_thorns": ['axes']
|
||||||
|
"bracken:searing_surface": ['armors']
|
||||||
|
"bracken:sentience_curse_1": ['can_unbreak']
|
||||||
|
"bracken:sentience_curse_2": ['can_unbreak']
|
||||||
|
"bracken:sentience_curse_3": ['can_unbreak']
|
||||||
|
"bracken:sentience_curse_4": ['can_unbreak']
|
||||||
|
"bracken:sentience_curse_5": ['can_unbreak']
|
||||||
|
"bracken:sentience_curse_6": ['can_unbreak']
|
||||||
|
"bracken:sentience_curse_7": ['can_unbreak']
|
||||||
|
"bracken:shrewdness": ['swords']
|
||||||
|
"bracken:silvered_fix": ['can_unbreak']
|
||||||
|
"bracken:spectrality_fix": ['melee_weapons', 'mace']
|
||||||
|
"bracken:splintering": ['bow']
|
||||||
|
"bracken:trampling": ['horse_armor']
|
||||||
|
"bracken:vitality_fix": ['armors']
|
||||||
|
"bracken:weakening_fix": ['can_unbreak']
|
||||||
|
"bracken:wisdom": ['tools']
|
||||||
|
"bracken:withering_fix": ['can_unbreak']
|
||||||
15
src/main/resources/datapack/bracken/item_groups.yml
Normal file
15
src/main/resources/datapack/bracken/item_groups.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
horse_armor:
|
||||||
|
items:
|
||||||
|
- leather_horse_armor
|
||||||
|
- iron_horse_armor
|
||||||
|
- golden_horse_armor
|
||||||
|
- diamond_horse_armor
|
||||||
|
|
||||||
|
wolf_armor:
|
||||||
|
items:
|
||||||
|
- wolf_armor
|
||||||
|
|
||||||
|
pet_armor:
|
||||||
|
groups:
|
||||||
|
- wolf_armor
|
||||||
|
- horse_armor
|
||||||
|
|
@ -126,7 +126,7 @@ wearable:
|
||||||
groups:
|
groups:
|
||||||
- armors
|
- armors
|
||||||
|
|
||||||
tools:
|
pickaxes:
|
||||||
type: include
|
type: include
|
||||||
items:
|
items:
|
||||||
- wooden_pickaxe
|
- wooden_pickaxe
|
||||||
|
|
@ -135,19 +135,33 @@ tools:
|
||||||
- diamond_pickaxe
|
- diamond_pickaxe
|
||||||
- golden_pickaxe
|
- golden_pickaxe
|
||||||
- netherite_pickaxe
|
- netherite_pickaxe
|
||||||
|
|
||||||
|
shovels:
|
||||||
|
type: include
|
||||||
|
items:
|
||||||
- wooden_shovel
|
- wooden_shovel
|
||||||
- stone_shovel
|
- stone_shovel
|
||||||
- iron_shovel
|
- iron_shovel
|
||||||
- diamond_shovel
|
- diamond_shovel
|
||||||
- golden_shovel
|
- golden_shovel
|
||||||
- netherite_shovel
|
- netherite_shovel
|
||||||
|
|
||||||
|
hoes:
|
||||||
|
type: include
|
||||||
|
items:
|
||||||
- wooden_hoe
|
- wooden_hoe
|
||||||
- stone_hoe
|
- stone_hoe
|
||||||
- iron_hoe
|
- iron_hoe
|
||||||
- diamond_hoe
|
- diamond_hoe
|
||||||
- golden_hoe
|
- golden_hoe
|
||||||
- netherite_hoe
|
- netherite_hoe
|
||||||
|
|
||||||
|
tools:
|
||||||
|
type: include
|
||||||
groups:
|
groups:
|
||||||
|
- pickaxes
|
||||||
|
- shovels
|
||||||
|
- hoes
|
||||||
- axes
|
- axes
|
||||||
|
|
||||||
enchanted_book:
|
enchanted_book:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue