diff --git a/build.gradle.kts b/build.gradle.kts index d65cde5..3a25f2d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -104,7 +104,7 @@ dependencies { implementation("org.bstats:bstats-base:3.0.2") implementation("org.bstats:bstats-bukkit:3.0.2") implementation(project(path = ":shared", configuration = "shadow")) - implementation(project(path = ":v1_21_R1", configuration = "shadow")) + //implementation(project(path = ":v1_21_R1", configuration = "shadow")) implementation(project(path = ":v1_20_R4", configuration = "shadow")) implementation(project(path = ":v1_20_R3", configuration = "shadow")) implementation(project(path = ":v1_20_R2", configuration = "shadow")) diff --git a/settings.gradle.kts b/settings.gradle.kts index 5dacf95..9cd2f51 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,7 +4,7 @@ plugins { rootProject.name = "ItemizerX" include("shared") -include("v1_21_R1") +//include("v1_21_R1") include("v1_20_R4") include("v1_20_R3") include("v1_20_R2") diff --git a/shared/src/main/java/dev/plex/itemizerx/IAttributeManager.java b/shared/src/main/java/dev/plex/itemizerx/IAttributeManager.java index 83d1d32..8aa5d34 100644 --- a/shared/src/main/java/dev/plex/itemizerx/IAttributeManager.java +++ b/shared/src/main/java/dev/plex/itemizerx/IAttributeManager.java @@ -1,12 +1,24 @@ package dev.plex.itemizerx; +import java.util.Collections; +import java.util.List; import net.minecraft.nbt.ListTag; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import org.bukkit.entity.Player; public interface IAttributeManager { - ListTag getAttrList(final ItemStack item); + default ListTag getAttrList(final ItemStack item) + { + return null; + } + + default List getAttrList(final Item item) + { + return Collections.emptyList(); + } void addAttr(final Player player, final String[] args); diff --git a/src/main/java/dev/plex/itemizerx/ItemizerX.java b/src/main/java/dev/plex/itemizerx/ItemizerX.java index f3c8ff0..6476ed9 100644 --- a/src/main/java/dev/plex/itemizerx/ItemizerX.java +++ b/src/main/java/dev/plex/itemizerx/ItemizerX.java @@ -30,12 +30,12 @@ public class ItemizerX extends JavaPlugin { getCommand("itemizer").setExecutor(new ItemizerXCommand()); attr = new dev.plex.itemizerx.v1_21_R1.AttributeManager(); - } + }*/ case "1.20.5", "1.20.6" -> { getCommand("itemizer").setExecutor(new ItemizerXCommand()); attr = new dev.plex.itemizerx.v1_20_R4.AttributeManager(); - }*/ + } case "1.20.4" -> { getCommand("itemizer").setExecutor(new ItemizerXCommand()); diff --git a/v1_20_R4/src/main/java/dev/plex/itemizerx/v1_20_R4/AttributeManager.java b/v1_20_R4/src/main/java/dev/plex/itemizerx/v1_20_R4/AttributeManager.java index 61d548a..57533f4 100644 --- a/v1_20_R4/src/main/java/dev/plex/itemizerx/v1_20_R4/AttributeManager.java +++ b/v1_20_R4/src/main/java/dev/plex/itemizerx/v1_20_R4/AttributeManager.java @@ -1,51 +1,59 @@ -/*package dev.plex.itemizerx.v1_20_R4; +package dev.plex.itemizerx.v1_20_R4; -import dev.plex.itemizerx.Attributes; import dev.plex.itemizerx.IAttributeManager; +import java.util.Arrays; +import java.util.Collections; +import java.util.concurrent.atomic.AtomicReference; import net.kyori.adventure.text.minimessage.MiniMessage; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.Tag; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.EquipmentSlotGroup; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ItemAttributeModifiers; +import net.minecraft.world.item.component.ItemAttributeModifiers.Entry; import org.apache.commons.lang3.StringUtils; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.List; -import java.util.Random; public class AttributeManager implements IAttributeManager { private final MiniMessage mm = MiniMessage.miniMessage(); @Override - public ListTag getAttrList(final ItemStack item) + public List getAttrList(final Item item) { - ListTag attrmod = item.getOrCreateTag().getList("AttributeModifiers", 10); - if (attrmod == null) + ItemAttributeModifiers attrmod = item.components().getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); + List modifiers = new ArrayList<>(); + for (Entry modifier : attrmod.modifiers()) { - item.put("AttributeModifiers", new CompoundTag()); + modifiers.add(modifier.modifier()); } - return item.getTag().getList("AttributeModifiers", 10); + return modifiers; } @Override public void addAttr(final Player player, final String[] args) { - int op; if (args.length < 4) { player.sendMessage(mm.deserialize("/itemizer attr add <name> <strength>" + "[slot] - Add an attribute")); return; } - final Attributes a = Attributes.get(args[2]); + + final Attributes_v1_20_R4 a = Attributes_v1_20_R4.get(args[2]); if (a == null) { player.sendMessage(mm.deserialize("\"" + args[2] + "\" is not a valid attribute type.")); return; } + double amount; try { @@ -56,55 +64,45 @@ public class AttributeManager implements IAttributeManager player.sendMessage(mm.deserialize("\"" + args[3] + "\" is not a valid number.")); return; } + if (Double.isNaN(amount)) { player.sendMessage(mm.deserialize("Please do not use 'NaN (Not a Number)'")); return; } - final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); - final ListTag attrmod = getAttrList(nms); - for (Tag nbtBase : attrmod) + + ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final List attrmod = getAttrList(nms.getItem()); + for (AttributeModifier modifier : attrmod) { - final CompoundTag c = (CompoundTag) nbtBase; - if (c.getString("Name").equals(args[2])) + if (modifier.name().equalsIgnoreCase(args[2])) { player.sendMessage(mm.deserialize("An attribute with the name \"" + args[2] + "\" already exists!")); return; } } - final CompoundTag c = new CompoundTag(); - c.putString("Name", args[2]); - c.putString("AttributeName", a.mcName); - c.putDouble("Amount", amount); - op = a.op; - c.putInt("Operation", op); - final Random random = new Random(); - c.putIntArray("UUID", new int[] - { - random.nextInt(), - random.nextInt(), - random.nextInt(), - random.nextInt() - }); + + AtomicReference group = new AtomicReference<>(EquipmentSlotGroup.ANY); if (args.length == 5) { - final List options = new ArrayList<>(); - options.add("mainhand"); - options.add("offhand"); - options.add("head"); - options.add("chest"); - options.add("legs"); - options.add("feet"); - if (!options.contains(args[4].toLowerCase())) + EquipmentSlot slot; + try + { + slot = EquipmentSlot.byName(args[4].toLowerCase()); + } + catch (IllegalArgumentException ignored) { player.sendMessage(mm.deserialize("Supported options:")); - player.sendMessage(mm.deserialize("" + StringUtils.join(options, ", "))); + player.sendMessage(mm.deserialize("" + StringUtils.join(Arrays.stream(EquipmentSlot.values()).map(s -> s.getName().toLowerCase()).toArray(), ", "))); return; } - c.putString("Slot", args[4].toLowerCase()); + + group.set(EquipmentSlotGroup.bySlot(slot)); } - attrmod.add(c); - nms.getTag().put("AttributeModifiers", attrmod); + + final AttributeModifier modifier = new AttributeModifier(a.mcName, amount, Operation.BY_ID.apply(a.op)); + nms.update(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY, x -> + x.withModifierAdded(a.attributeHolder, modifier, group.get()).withTooltip(true)); final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); player.getInventory().setItemInMainHand(is); player.sendMessage(mm.deserialize("Attribute added!")); @@ -113,7 +111,7 @@ public class AttributeManager implements IAttributeManager @Override public void removeAttr(final Player player, final String string) { - final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + /*final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); final ListTag attrmod = getAttrList(nms); final ListTag newList = new ListTag(); boolean r = false; @@ -134,29 +132,27 @@ public class AttributeManager implements IAttributeManager player.sendMessage(mm.deserialize("The attribute \"" + string + "\" doesn't exist!")); return; } - nms.getTag().put("AttributeModifiers", newList); + //nms.getTag().put("AttributeModifiers", newList); final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); - player.getInventory().setItemInMainHand(is); - player.sendMessage(mm.deserialize("Attribute removed!")); + player.getInventory().setItemInMainHand(is);*/ + player.sendMessage(mm.deserialize("Removing attributes isn't supported at the moment!")); } @Override public void listAttr(final Player player) { final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); - final ListTag attrmod = getAttrList(nms); - if (attrmod.size() == 0) + final List attrmod = getAttrList(nms.getItem()); + if (attrmod.isEmpty()) { player.sendMessage(mm.deserialize("This item has no attributes.")); return; } + player.sendMessage(mm.deserialize("Item attributes: ")); - for (Tag nbtBase : attrmod) + for (AttributeModifier modifier : attrmod) { - final CompoundTag c = (CompoundTag) nbtBase; - player.sendMessage(mm.deserialize("" + Attributes.get(c.getString("AttributeName")).mcName - + ", " + c.getDouble("Amount"))); + player.sendMessage(mm.deserialize("" + modifier.name() + ", " + modifier.amount())); } } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/v1_20_R4/src/main/java/dev/plex/itemizerx/v1_20_R4/Attributes_v1_20_R4.java b/v1_20_R4/src/main/java/dev/plex/itemizerx/v1_20_R4/Attributes_v1_20_R4.java new file mode 100644 index 0000000..21ee85f --- /dev/null +++ b/v1_20_R4/src/main/java/dev/plex/itemizerx/v1_20_R4/Attributes_v1_20_R4.java @@ -0,0 +1,63 @@ +package dev.plex.itemizerx.v1_20_R4; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.core.Holder; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.Attributes; +import org.apache.commons.lang3.StringUtils; + +public enum Attributes_v1_20_R4 +{ + MAX_HEALTH("generic.max_health", 0, Attributes.MAX_HEALTH), + FOLLOW_RANGE("generic.follow_range", 1, Attributes.FOLLOW_RANGE), + KNOCKBACK_RESISTANCE("generic.knockback_resistance", 1, Attributes.KNOCKBACK_RESISTANCE), + MOVEMENT_SPEED("generic.movement_speed", 1, Attributes.MOVEMENT_SPEED), + FLYING_SPEED("generic.flying_speed", 1, Attributes.FLYING_SPEED), + DAMAGE("generic.attack_damage", 0, Attributes.ATTACK_DAMAGE), + ATTACK_KNOCKBACK("generic.attack_knockback", 0, Attributes.ATTACK_KNOCKBACK), + ATTACK_SPEED("generic.attack_speed", 1, Attributes.ATTACK_SPEED), + ARMOR("generic.armor", 0, Attributes.ARMOR), + ARMOR_TOUGHNESS("generic.armor_toughness", 0, Attributes.ARMOR_TOUGHNESS), + LUCK("generic.luck", 0, Attributes.LUCK), + JUMP_STRENGTH("generic.jump_strength", 1, Attributes.JUMP_STRENGTH), + ZOMBIE_REINFORCEMENTS("zombie.spawn_reinforcements", 1, Attributes.SPAWN_REINFORCEMENTS_CHANCE); + + public final String mcName; + public final int op; + public final Holder attributeHolder; + + Attributes_v1_20_R4(String mcName, int op, Holder attributeHolder) + { + this.mcName = mcName; + this.op = op; + this.attributeHolder = attributeHolder; + } + + public static Attributes_v1_20_R4 get(String name) + { + for (Attributes_v1_20_R4 attr : values()) + { + if (attr.name().equalsIgnoreCase(name) || attr.mcName.equalsIgnoreCase(name.replace("minecraft:", ""))) + { + return attr; + } + } + return null; + } + + public static String getAttributes() + { + return StringUtils.join(values(), ", "); + } + + public static List getAttributeList() + { + List attributes = new ArrayList<>(); + for (Attributes_v1_20_R4 attr : values()) + { + attributes.add(attr.name()); + } + return attributes; + } +}