mirror of
https://github.com/plexusorg/ItemizerX.git
synced 2026-06-04 03:36:54 +00:00
Updated ItemizerX to the latest stable Paper version (1.21.8)
Given the complexity of the NMS update (including data components), I have decided to omit the support of older MC versions and maintain multiversion compatibility from 1.21.8 onwards from v2.4. I suspect this may not change much in the future, making it easier to maintain. In the future, I may look into moving away from NMS provided Paper is now exposing them in Paper API via Data Components This also closes #1
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
dependencies {
|
||||
paperweight.paperDevBundle("1.21-R0.1-SNAPSHOT")
|
||||
paperweight.paperDevBundle("1.21.8-R0.1-SNAPSHOT")
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package dev.plex.itemizerx.v1_21_R1;
|
||||
|
||||
import dev.plex.itemizerx.Attributes;
|
||||
import dev.plex.itemizerx.IAttributeManager;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
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.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;
|
||||
|
||||
public class AttributeManager implements IAttributeManager {
|
||||
|
||||
private final MiniMessage mm = MiniMessage.miniMessage();
|
||||
|
||||
@Override
|
||||
public void addAttr(Player player, String[] args) {
|
||||
if (args.length < 4)
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<aqua>/itemizer attr add <<white>name<aqua>> <<white>strength<aqua>>" +
|
||||
"[<white>slot<aqua>] <red>- <gold>Add an attribute"));
|
||||
return;
|
||||
}
|
||||
|
||||
Attributes a = Attributes.get(args[2]);
|
||||
if (a == null)
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_red>\"" + args[2] + "\" is not a valid attribute type."));
|
||||
return;
|
||||
}
|
||||
|
||||
double amount;
|
||||
try
|
||||
{
|
||||
amount = Double.parseDouble(args[3]);
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_red>\"" + args[3] + "\" is not a valid number."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Double.isNaN(amount))
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_red>Please do not use <white>'NaN (Not a Number)'"));
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand());
|
||||
final List<Entry> entries = nms.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY).modifiers();
|
||||
for (Entry entry : entries)
|
||||
{
|
||||
if (entry.attribute().getRegisteredName().equalsIgnoreCase(args[2]))
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_red>An attribute with the name \"<white>" + args[2] + "<dark_red>\" already exists!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AtomicReference<EquipmentSlotGroup> group = new AtomicReference<>(EquipmentSlotGroup.ANY);
|
||||
if (args.length == 5)
|
||||
{
|
||||
EquipmentSlot slot;
|
||||
try
|
||||
{
|
||||
slot = EquipmentSlot.byName(args[4].toLowerCase());
|
||||
}
|
||||
catch (IllegalArgumentException ignored)
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_green>Supported options:"));
|
||||
player.sendMessage(mm.deserialize("<yellow>" + StringUtils.join(
|
||||
Arrays.stream(EquipmentSlot.values()).map(s -> s.getName().toLowerCase()).toArray(), ", ")));
|
||||
return;
|
||||
}
|
||||
|
||||
group.set(EquipmentSlotGroup.bySlot(slot));
|
||||
}
|
||||
|
||||
final ResourceLocation locationID = ResourceLocation.fromNamespaceAndPath("itemizerx", String.format("modifier_%s", a.mcName));
|
||||
final AttributeModifier modifier = new AttributeModifier(locationID, amount, Operation.BY_ID.apply(a.op));
|
||||
nms.update(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY, x ->
|
||||
x.withModifierAdded(a.attributeHolder, modifier, group.get()));
|
||||
final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms);
|
||||
player.getInventory().setItemInMainHand(is);
|
||||
player.sendMessage(mm.deserialize("<dark_aqua>Attribute added!"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttr(Player player, String string) {
|
||||
Attributes a = Attributes.get(string);
|
||||
if (a == null)
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_red>\"" + string + "\" is not a valid attribute type."));
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand());
|
||||
ItemAttributeModifiers attrModifiers = nms.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY);
|
||||
final List<Entry> entries = attrModifiers.modifiers();
|
||||
Optional<Entry> optionalEntry = entries.stream().filter(e -> e.attribute().equals(a.attributeHolder)).findFirst();
|
||||
|
||||
ItemAttributeModifiers.Builder builder = ItemAttributeModifiers.builder();
|
||||
optionalEntry.ifPresentOrElse(entry -> {
|
||||
entries.forEach(e -> {
|
||||
if (e.attribute().equals(a.attributeHolder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
builder.add(entry.attribute(), entry.modifier(), entry.slot(), entry.display());
|
||||
});
|
||||
|
||||
nms.set(DataComponents.ATTRIBUTE_MODIFIERS, builder.build());
|
||||
final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms);
|
||||
player.getInventory().setItemInMainHand(is);
|
||||
player.sendMessage(mm.deserialize("<dark_aqua>Attribute removed!"));
|
||||
}, () -> player.sendMessage(mm.deserialize("<dark_red>The attribute \"" + string + "\" doesn't exist!")));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listAttr(Player player) {
|
||||
final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand());
|
||||
|
||||
List<Entry> entries = nms.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY).modifiers();
|
||||
if (entries.isEmpty()) {
|
||||
player.sendMessage(mm.deserialize("<yellow>This item has no attributes."));
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendMessage(mm.deserialize("<dark_green>Item attributes: "));
|
||||
entries.forEach(entry -> {
|
||||
player.sendMessage(mm.deserialize("<yellow>" + entry.attribute().getRegisteredName() + ", " + entry.modifier().amount() + ", " + entry.slot()));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package dev.plex.itemizerx.v1_21_R1;
|
||||
|
||||
import dev.plex.itemizerx.IEnchantmentManager;
|
||||
import java.util.Objects;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class EnchantmentManager implements IEnchantmentManager {
|
||||
|
||||
private final MiniMessage mm = MiniMessage.miniMessage();
|
||||
|
||||
@Override
|
||||
public void addEnchantment(Player player, ItemStack item, String[] args) {
|
||||
if (args.length < 4)
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_aqua>===============<white>[<light_purple>Enchant Commands<white>]<dark_aqua>==============="));
|
||||
player.sendMessage(mm.deserialize("<aqua>/itemizer enchant add <<white>name<aqua>> <<white>level<aqua>> <red>- <gold>Add an enchantment"));
|
||||
return;
|
||||
}
|
||||
|
||||
EnchantmentMap map = EnchantmentMap.fromName(args[2]);
|
||||
if (map == null) {
|
||||
player.sendMessage(mm.deserialize("<dark_red>The <white>'" + args[2] + "<white>' <dark_red>enchantment does not exist!"));
|
||||
return;
|
||||
}
|
||||
|
||||
Enchantment enchantment = map.asEnchantment();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
assert meta != null;
|
||||
if (meta.getEnchants().containsKey(enchantment))
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_red>This item already have the <white>'" + enchantment.getKey().getKey() + "' <dark_red>enchantment!"));
|
||||
return;
|
||||
}
|
||||
|
||||
int level;
|
||||
try
|
||||
{
|
||||
level = Integer.parseInt(args[3]);
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<white>\"" + args[3] + "<white>\"<dark_red> is not a valid number!"));
|
||||
return;
|
||||
}
|
||||
|
||||
item.addUnsafeEnchantment(enchantment, level);
|
||||
player.sendMessage(mm.deserialize("<dark_green>The enchant <white>'" + enchantment.getKey().getKey() + "' <dark_green>has been added to your item"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEnchantment(Player player, ItemStack item, String[] args) {
|
||||
if (args.length == 2)
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_aqua>===============<white>[<light_purple>Enchant Commands<white>]<dark_aqua>==============="));
|
||||
player.sendMessage(mm.deserialize("<aqua>/itemizer enchant remove <<white>name<aqua>> <red>- <gold>Remove an enchantment"));
|
||||
return;
|
||||
}
|
||||
|
||||
EnchantmentMap map = EnchantmentMap.fromName(args[2]);
|
||||
if (map == null) {
|
||||
player.sendMessage(mm.deserialize("<dark_red>The <white>'" + args[2] + "<white>' <dark_red> enchantment does not exist!"));
|
||||
return;
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
assert meta != null;
|
||||
if (Objects.requireNonNull(meta.getEnchants()).isEmpty())
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_red>This item doesn't hold any enchants"));
|
||||
return;
|
||||
}
|
||||
|
||||
Enchantment enchantment = map.asEnchantment();
|
||||
if (!meta.getEnchants().containsKey(enchantment))
|
||||
{
|
||||
player.sendMessage(mm.deserialize("<dark_red>This item doesn't have the <white>'" + enchantment.getKey().getKey() + "' <dark_red>enchantment!"));
|
||||
return;
|
||||
}
|
||||
item.removeEnchantment(enchantment);
|
||||
player.sendMessage(mm.deserialize("<dark_green>The <white>'" + enchantment.getKey().getKey() + "' <dark_green>enchantment has been removed from your item"));
|
||||
}
|
||||
|
||||
private enum EnchantmentMap {
|
||||
PROTECTION(Enchantment.PROTECTION),
|
||||
FIRE_PROTECTION(Enchantment.FIRE_PROTECTION),
|
||||
FEATHER_FALLING(Enchantment.FEATHER_FALLING),
|
||||
BLAST_PROTECTION(Enchantment.BLAST_PROTECTION),
|
||||
PROJECTILE_PROTECTION(Enchantment.PROJECTILE_PROTECTION),
|
||||
RESPIRATION(Enchantment.RESPIRATION),
|
||||
AQUA_AFFINITY(Enchantment.AQUA_AFFINITY),
|
||||
THORNS(Enchantment.THORNS),
|
||||
DEPTH_STRIDER(Enchantment.DEPTH_STRIDER),
|
||||
FROST_WALKER(Enchantment.FROST_WALKER),
|
||||
BINDING_CURSE(Enchantment.BINDING_CURSE),
|
||||
SHARPNESS(Enchantment.SHARPNESS),
|
||||
SMITE(Enchantment.SMITE),
|
||||
BANE_OF_ARTHROPODS(Enchantment.BANE_OF_ARTHROPODS),
|
||||
KNOCKBACK(Enchantment.KNOCKBACK),
|
||||
FIRE_ASPECT(Enchantment.FIRE_ASPECT),
|
||||
LOOTING(Enchantment.LOOTING),
|
||||
SWEEPING_EDGE(Enchantment.SWEEPING_EDGE),
|
||||
EFFICIENCY(Enchantment.EFFICIENCY),
|
||||
SILK_TOUCH(Enchantment.SILK_TOUCH),
|
||||
UNBREAKING(Enchantment.UNBREAKING),
|
||||
FORTUNE(Enchantment.FORTUNE),
|
||||
POWER(Enchantment.POWER),
|
||||
PUNCH(Enchantment.PUNCH),
|
||||
FLAME(Enchantment.FLAME),
|
||||
INFINITY(Enchantment.INFINITY),
|
||||
LUCK_OF_THE_SEA(Enchantment.LUCK_OF_THE_SEA),
|
||||
LURE(Enchantment.LURE),
|
||||
LOYALTY(Enchantment.LOYALTY),
|
||||
IMPALING(Enchantment.IMPALING),
|
||||
RIPTIDE(Enchantment.RIPTIDE),
|
||||
CHANNELING(Enchantment.CHANNELING),
|
||||
MULTISHOT(Enchantment.MULTISHOT),
|
||||
QUICK_CHARGE(Enchantment.QUICK_CHARGE),
|
||||
PIERCING(Enchantment.PIERCING),
|
||||
DENSITY(Enchantment.DENSITY),
|
||||
BREACH(Enchantment.BREACH),
|
||||
WIND_BURST(Enchantment.WIND_BURST),
|
||||
MENDING(Enchantment.MENDING),
|
||||
VANISHING_CURSE(Enchantment.VANISHING_CURSE),
|
||||
SOUL_SPEED(Enchantment.SOUL_SPEED),
|
||||
SWIFT_SNEAK(Enchantment.SWIFT_SNEAK);
|
||||
|
||||
private final Enchantment enchantment;
|
||||
|
||||
EnchantmentMap(Enchantment enchantment) {
|
||||
this.enchantment = enchantment;
|
||||
}
|
||||
|
||||
public static EnchantmentMap fromName(String name) {
|
||||
for (EnchantmentMap map : values()) {
|
||||
if (map.name().equalsIgnoreCase(name)) {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Enchantment asEnchantment() {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package dev.plex.itemizerx.v1_21_R1;
|
||||
|
||||
public class Main
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user