recoded the anvil code...

it now fully works with EnchantmentWrappers
This commit is contained in:
XTerPL 2025-01-25 18:52:09 +01:00
parent e6b2008618
commit 20cc493196
10 changed files with 157 additions and 84 deletions

View file

@ -76,9 +76,4 @@ public class PatternEnchantment extends CustomEnchantment {
public boolean conflictsWith(@NotNull CustomEnchantment enchantment) {
return enchantment == CustomEnchantments.TREE_FELLER;
}
@Override
public boolean canUpgradeLevel(int currentLevel) {
return false;
}
}

View file

@ -15,6 +15,7 @@
*/
package de.blazemcworld.blazinggames.enchantments.sys;
import de.blazemcworld.blazinggames.items.CustomItem;
import de.blazemcworld.blazinggames.items.predicates.ItemPredicate;
import de.blazemcworld.blazinggames.utils.NumberUtils;
import net.kyori.adventure.text.Component;
@ -47,12 +48,16 @@ public abstract class CustomEnchantment implements EnchantmentWrapper {
@Override
public boolean canGoOnItem(ItemStack tool) {
return getItemTarget().matchItem(tool) || tool.getType() == Material.BOOK
|| tool.getType() == Material.ENCHANTED_BOOK;
}
if(getItemTarget().matchItem(tool)) {
return true;
}
public boolean canUpgradeLevel(int currentLevel) {
return true;
if(CustomItem.isCustomItem(tool)) {
return false;
}
return tool.getType() == Material.BOOK
|| tool.getType() == Material.ENCHANTED_BOOK;
}
public @NotNull CustomEnchantmentType getEnchantmentType() {

View file

@ -248,20 +248,23 @@ public class EnchantmentHelper implements ItemChangeProvider {
return null;
}
public static ItemStack enchantFromItem(ItemStack in, ItemStack enchantingItem) {
public static Pair<ItemStack, Integer> enchantFromItem(ItemStack in, ItemStack enchantingItem) {
ItemStack result = in.clone();
if(!canEnchantItem(result)) {
return result;
return new Pair<>(result, 0);
}
int cost = 0;
Map<EnchantmentWrapper, Integer> enchantmentLevels = getEnchantmentWrappers(enchantingItem);
for(Map.Entry<EnchantmentWrapper, Integer> enchantment : enchantmentLevels.entrySet()) {
result = enchantTool(result, enchantment.getKey(), enchantment.getValue());
cost++;
}
return ItemChangeProviders.update(result);
return new Pair<>(ItemChangeProviders.update(result), cost);
}
public static boolean hasCustomEnchantments(ItemStack stack) {

View file

@ -115,7 +115,8 @@ public class EnchantmentWrappers {
);
public static VanillaEnchantmentWrapper MENDING =
new OverridableVanillaEnchantmentWrapper(Enchantment.MENDING, () -> new ItemStack(Material.SHULKER_SHELL),
new OverridableVanillaEnchantmentWrapper.VanillaEnchantmentOverrides().conflicts(),
new OverridableVanillaEnchantmentWrapper.VanillaEnchantmentOverrides().target(BreakableItemPredicate.instance)
.conflicts(),
new AltarRecipe(4,10, 15, CustomItems.NETHER_STAR_CHUNK)
);
public static VanillaEnchantmentWrapper LOYALTY =
@ -297,7 +298,7 @@ public class EnchantmentWrappers {
private static Set<VanillaEnchantmentWrapper> vanilla() {
return Set.of(
MULTISHOT, PIERCING, SILK_TOUCH, VANISHING_CURSE, FROST_WALKER, FORTUNE, BINDING_CURSE, SHARPNESS, SWEEPING_EDGE,
RIPTIDE, QUICK_CHARGE, IMPALING, FIRE_PROTECTION, LOYALTY, LUCK_OF_THE_SEA, RESPIRATION, FLAME, PUNCH,
RIPTIDE, QUICK_CHARGE, IMPALING, FIRE_PROTECTION, MENDING, LOYALTY, LUCK_OF_THE_SEA, RESPIRATION, FLAME, PUNCH,
BLAST_PROTECTION, PROJECTILE_PROTECTION, PROTECTION, AQUA_AFFINITY, SMITE, POWER, THORNS, LOOTING,
FEATHER_FALLING, FIRE_ASPECT, UNBREAKING, CHANNELING, LURE, INFINITY, EFFICIENCY, DEPTH_STRIDER, KNOCKBACK,
SOUL_SPEED, SWIFT_SNEAK, BANE_OF_ARTHROPODS, WIND_BURST, BREACH, DENSITY

View file

@ -15,7 +15,6 @@
*/
package de.blazemcworld.blazinggames.enchantments.sys;
import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.enchantments.sys.altar.AltarRecipe;
import de.blazemcworld.blazinggames.items.predicates.ItemPredicate;
import org.bukkit.enchantments.Enchantment;
@ -68,8 +67,6 @@ public class OverridableVanillaEnchantmentWrapper extends VanillaEnchantmentWrap
@Override
public boolean conflictsWith(Enchantment other) {
BlazingGames.get().log(overrides.conflicts);
if(overrides.conflicts != null) {
return overrides.conflicts.contains(other);
}

View file

@ -16,6 +16,8 @@
package de.blazemcworld.blazinggames.enchantments.sys;
import de.blazemcworld.blazinggames.enchantments.sys.altar.AltarRecipe;
import de.blazemcworld.blazinggames.items.CustomItem;
import io.papermc.paper.datacomponent.DataComponentTypes;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
@ -55,6 +57,10 @@ public class VanillaEnchantmentWrapper implements EnchantmentWrapper {
public ItemStack apply(ItemStack tool, int level) {
ItemStack result = tool.clone();
if(!CustomItem.isCustomItem(result) && result.getType() == Material.BOOK) {
result = result.withType(Material.ENCHANTED_BOOK);
}
result.addUnsafeEnchantment(enchantment, level);
return result;
@ -62,11 +68,19 @@ public class VanillaEnchantmentWrapper implements EnchantmentWrapper {
@Override
public int getLevel(ItemStack tool) {
if(tool.hasData(DataComponentTypes.STORED_ENCHANTMENTS)) {
return tool.getData(DataComponentTypes.STORED_ENCHANTMENTS).enchantments().getOrDefault(enchantment, 0);
}
return tool.getEnchantmentLevel(enchantment);
}
@Override
public boolean canGoOnItem(ItemStack tool) {
if(CustomItem.isCustomItem(tool)) {
return false;
}
return enchantment.canEnchantItem(tool) || tool.getType() == Material.BOOK
|| tool.getType() == Material.ENCHANTED_BOOK;
}

View file

@ -16,6 +16,7 @@
package de.blazemcworld.blazinggames.enchantments.sys.altar;
import de.blazemcworld.blazinggames.enchantments.sys.EnchantmentWrapper;
import de.blazemcworld.blazinggames.items.change.ItemChangeProviders;
import de.blazemcworld.blazinggames.userinterfaces.UserInterface;
import de.blazemcworld.blazinggames.userinterfaces.UserInterfaceSlot;
@ -94,7 +95,10 @@ public class EnchantmentSlot implements UserInterfaceSlot {
if(lapis.getAmount() >= recipe.lapisAmount()) {
if(recipe.matchMaterial(material)) {
if(player.getLevel() >= recipe.expAmount()) {
altarInterface.setItem(1, 1, wrapper.apply(tool, level+1));
ItemStack result = wrapper.apply(tool, level+1);
result = ItemChangeProviders.update(result);
altarInterface.setItem(1, 1, result);
lapis.subtract(recipe.lapisAmount());
material.subtract(recipe.itemAmount());
player.setLevel(player.getLevel() - recipe.expAmount());

View file

@ -1,12 +1,12 @@
/*
* Copyright 2025 The Blazing Games Maintainers
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -24,16 +24,12 @@ import de.blazemcworld.blazinggames.utils.InventoryUtils;
import de.blazemcworld.blazinggames.utils.Pair;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.HumanEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.*;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
@ -184,32 +180,6 @@ public class ClickInventorySlotEventListener implements Listener {
}
}
}
if(inventory instanceof AnvilInventory anvil) {
if(event.getSlotType() == InventoryType.SlotType.RESULT) {
ItemStack result = anvil.getResult();
ItemStack book = anvil.getSecondItem();
if(book != null && book.getType() == Material.ENCHANTED_BOOK) {
if(book.getItemMeta() instanceof EnchantmentStorageMeta esm) {
if(esm.hasStoredEnchant(Enchantment.INFINITY)) {
if(result != null && result.getType() == Material.FIREWORK_ROCKET
&& result.getEnchantmentLevel(Enchantment.INFINITY) > 0) {
if(giveItemStack(event, result)) {
anvil.setFirstItem(ItemStack.empty());
anvil.setSecondItem(ItemStack.empty());
anvil.setResult(ItemStack.empty());
HumanEntity p = event.getWhoClicked();
p.getWorld().playSound(p, Sound.BLOCK_ANVIL_USE, SoundCategory.BLOCKS, 1, 1);
}
}
}
}
}
}
}
}
private ItemStack scrubResultClick(ItemStack up, ItemStack down) {

View file

@ -17,13 +17,14 @@ package de.blazemcworld.blazinggames.events;
import de.blazemcworld.blazinggames.enchantments.sys.EnchantmentHelper;
import de.blazemcworld.blazinggames.items.CustomItem;
import de.blazemcworld.blazinggames.utils.Pair;
import de.blazemcworld.blazinggames.utils.TextUtils;
import io.papermc.paper.datacomponent.DataComponentTypes;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
public class PrepareAnvilEventListener implements Listener {
@EventHandler
@ -35,54 +36,129 @@ public class PrepareAnvilEventListener implements Listener {
ItemStack in = event.getInventory().getFirstItem();
ItemStack enchantingItem = event.getInventory().getSecondItem();
ItemStack result = event.getInventory().getResult();
if(in == null || in.isEmpty() || enchantingItem == null || enchantingItem.isEmpty()) {
return;
}
if ((in.getType() == Material.BOOK || in.getType() == Material.ENCHANTED_BOOK) &&
(enchantingItem.getType() == Material.BOOK || enchantingItem.getType() == Material.ENCHANTED_BOOK)) {
if(in == null || in.isEmpty()) {
event.setResult(null);
return;
}
if(in.getType() == Material.FIREWORK_ROCKET) {
if(enchantingItem.getType() == Material.ENCHANTED_BOOK) {
if(enchantingItem.hasItemMeta() && enchantingItem.getItemMeta() instanceof EnchantmentStorageMeta esm) {
if(esm.hasStoredEnchant(Enchantment.INFINITY)) {
result = in.clone();
result.addUnsafeEnchantment(Enchantment.INFINITY, 1);
event.setResult(result);
return;
ItemStack result = in.clone();
event.getView().setRepairItemCountCost(0);
int repairCost = result.getDataOrDefault(DataComponentTypes.REPAIR_COST, 0);
if(enchantingItem != null && !enchantingItem.isEmpty()) {
repairCost += enchantingItem.getDataOrDefault(DataComponentTypes.REPAIR_COST, 0);
if(CustomItem.isCustomItem(enchantingItem))
{
if(EnchantmentHelper.canEnchantItem(result)) {
CustomItem<?> item = CustomItem.getCustomItem(enchantingItem);
if(item != null && item.matchItem(result)) {
Pair<ItemStack, Integer> enchantResult = EnchantmentHelper.enchantFromItem(result, enchantingItem);
result = enchantResult.left;
repairCost += repairByCombination(result, enchantingItem) + enchantResult.right;
}
}
}
else
{
if(result.isRepairableBy(enchantingItem)) {
if(result.hasData(DataComponentTypes.MAX_DAMAGE) &&
result.hasData(DataComponentTypes.DAMAGE) &&
!result.hasData(DataComponentTypes.UNBREAKABLE))
{
int damage = result.getData(DataComponentTypes.DAMAGE);
int maxDamage = result.getData(DataComponentTypes.MAX_DAMAGE);
int damageReduced = maxDamage / 4;
int count = 0;
while(count * damageReduced < damage) {
if(count >= enchantingItem.getAmount()) {
break;
}
count++;
}
damage -= count * damageReduced;
if(damage < 0) damage = 0;
result.setData(DataComponentTypes.DAMAGE, damage);
event.getView().setRepairItemCountCost(count);
repairCost += count;
}
}
else {
if(EnchantmentHelper.canEnchantItem(result)) {
if(enchantingItem.getType() == Material.ENCHANTED_BOOK) {
Pair<ItemStack, Integer> enchantResult = EnchantmentHelper.enchantFromItem(result, enchantingItem);
result = enchantResult.left;
repairCost += enchantResult.right;
}
else if(!CustomItem.isCustomItem(result) && enchantingItem.getType() == result.getType()) {
Pair<ItemStack, Integer> enchantResult = EnchantmentHelper.enchantFromItem(result, enchantingItem);
result = enchantResult.left;
repairCost += repairByCombination(result, enchantingItem) + enchantResult.right;
}
}
}
}
}
if(in.getAmount() != 1 || enchantingItem.getAmount() != 1) {
return;
}
String renameText = event.getView().getRenameText();
if(result == null || result.isEmpty()) {
result = in.clone();
if(renameText == null || renameText.isBlank()) {
if(result.hasData(DataComponentTypes.CUSTOM_NAME)) {
repairCost++;
result.resetData(DataComponentTypes.CUSTOM_NAME);
}
}
if(!EnchantmentHelper.canEnchantItem(result)) {
return;
else {
if(!TextUtils.componentToAmpersandString(result.displayName()).equals(renameText)) {
repairCost++;
result.setData(DataComponentTypes.CUSTOM_NAME, TextUtils.ampersandStringToComponent(renameText));
}
}
if(CustomItem.isCustomItem(enchantingItem) || enchantingItem.getType() != Material.ENCHANTED_BOOK
&& enchantingItem.getType() != result.getType()) {
return;
}
result = EnchantmentHelper.enchantFromItem(result, enchantingItem);
if(result.equals(in)) {
event.setResult(null);
return;
}
event.setResult(result);
event.getView().setRepairCost(repairCost);
}
private static int repairByCombination(ItemStack in, ItemStack repairer) {
if(!in.hasData(DataComponentTypes.MAX_DAMAGE) ||
!in.hasData(DataComponentTypes.DAMAGE) ||
in.hasData(DataComponentTypes.UNBREAKABLE))
{
return 0;
}
int inDamage = in.getDataOrDefault(DataComponentTypes.DAMAGE, 0);
int repairerDamage = repairer.getDataOrDefault(DataComponentTypes.DAMAGE, 0);
int inMaxDamage = in.getDataOrDefault(DataComponentTypes.MAX_DAMAGE, 0);
int repairerMaxDamage = repairer.getDataOrDefault(DataComponentTypes.MAX_DAMAGE, 0);
int inDurability = inMaxDamage - inDamage;
int repairerDurability = repairerMaxDamage - repairerDamage;
int extraDurability = inMaxDamage * 12 / 100;
int totalDurability = inDurability + repairerDurability + extraDurability;
int newDamage = inMaxDamage - totalDurability;
if(newDamage < 0) newDamage = 0;
if(newDamage > inMaxDamage) newDamage = inMaxDamage;
in.setData(DataComponentTypes.DAMAGE, newDamage);
return 2;
}
}

View file

@ -23,10 +23,18 @@ public class TextUtils {
return LegacyComponentSerializer.legacySection().serialize(component);
}
public static String componentToAmpersandString(Component component) {
return LegacyComponentSerializer.legacyAmpersand().serialize(component);
}
public static Component stringToComponent(String string) {
return Component.text(string);
}
public static Component ampersandStringToComponent(String string) {
return LegacyComponentSerializer.legacyAmpersand().deserialize(string);
}
public static Component colorCodeParser(Component message) {
String text = componentToString(message)
.replaceAll("&([a-fk-or0-9])", "§$1");