mirror of
https://github.com/PaperMC/Paper.git
synced 2025-05-19 13:40:24 -07:00
Add ItemStack#copyDataFrom (#12224)
This commit is contained in:
parent
5a6ab97be6
commit
c467df95a2
@ -79,7 +79,7 @@ public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
|
|||||||
RegistryKey<BlockType> BLOCK = create("block");
|
RegistryKey<BlockType> BLOCK = create("block");
|
||||||
/**
|
/**
|
||||||
* @apiNote use preferably only in the context of registry entries.
|
* @apiNote use preferably only in the context of registry entries.
|
||||||
* @see io.papermc.paper.registry.data
|
* @see io.papermc.paper.registry.keys.ItemTypeKeys
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Experimental // Paper - already required for registry builders
|
@ApiStatus.Experimental // Paper - already required for registry builders
|
||||||
RegistryKey<ItemType> ITEM = create("item");
|
RegistryKey<ItemType> ITEM = create("item");
|
||||||
|
@ -6,6 +6,7 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -1306,6 +1307,31 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
|||||||
this.craftDelegate.resetData(type);
|
this.craftDelegate.resetData(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies component values and component removals from the provided ItemStack.
|
||||||
|
* <p>
|
||||||
|
* Example:
|
||||||
|
* <pre>{@code
|
||||||
|
* Set<DataComponentType> types = Set.of(
|
||||||
|
* DataComponentTypes.CONSUMABLE,
|
||||||
|
* DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE,
|
||||||
|
* DataComponentTypes.RARITY
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* ItemStack source = ItemStack.of(Material.ENCHANTED_GOLDEN_APPLE);
|
||||||
|
* ItemStack target = ItemStack.of(Material.GOLDEN_CARROT);
|
||||||
|
*
|
||||||
|
* target.copyDataFrom(source, types::contains);
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param source the item stack to copy from
|
||||||
|
* @param filter predicate for which components to copy
|
||||||
|
*/
|
||||||
|
@org.jetbrains.annotations.ApiStatus.Experimental
|
||||||
|
public void copyDataFrom(final @NotNull ItemStack source, final @NotNull Predicate<io.papermc.paper.datacomponent.@NotNull DataComponentType> filter) {
|
||||||
|
this.craftDelegate.copyDataFrom(source, filter);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the data component type is overridden from the default for the
|
* Checks if the data component type is overridden from the default for the
|
||||||
* item type.
|
* item type.
|
||||||
|
@ -7,6 +7,7 @@ import java.util.Collections;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||||
import net.minecraft.advancements.critereon.MinMaxBounds;
|
import net.minecraft.advancements.critereon.MinMaxBounds;
|
||||||
@ -15,6 +16,7 @@ import net.minecraft.core.HolderSet;
|
|||||||
import net.minecraft.core.component.DataComponentMap;
|
import net.minecraft.core.component.DataComponentMap;
|
||||||
import net.minecraft.core.component.DataComponentPatch;
|
import net.minecraft.core.component.DataComponentPatch;
|
||||||
import net.minecraft.core.component.DataComponentPredicate;
|
import net.minecraft.core.component.DataComponentPredicate;
|
||||||
|
import net.minecraft.core.component.DataComponentType;
|
||||||
import net.minecraft.core.component.DataComponents;
|
import net.minecraft.core.component.DataComponents;
|
||||||
import net.minecraft.core.component.PatchedDataComponentMap;
|
import net.minecraft.core.component.PatchedDataComponentMap;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
@ -54,7 +56,7 @@ public final class CraftItemStack extends ItemStack {
|
|||||||
if (bukkit instanceof final CraftItemStack craftItemStack) {
|
if (bukkit instanceof final CraftItemStack craftItemStack) {
|
||||||
return craftItemStack;
|
return craftItemStack;
|
||||||
} else {
|
} else {
|
||||||
return (CraftItemStack) API_ITEM_STACK_CRAFT_DELEGATE_FIELD.get(bukkit);
|
return (CraftItemStack) API_ITEM_STACK_CRAFT_DELEGATE_FIELD.get(bukkit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,12 +73,12 @@ public final class CraftItemStack extends ItemStack {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public boolean equals(final Object obj) {
|
||||||
if (!(obj instanceof final org.bukkit.inventory.ItemStack bukkit)) return false;
|
if (!(obj instanceof final ItemStack bukkit)) return false;
|
||||||
final CraftItemStack craftStack = getCraftStack(bukkit);
|
final CraftItemStack craftStack = getCraftStack(bukkit);
|
||||||
if (this.handle == craftStack.handle) return true;
|
if (this.handle == craftStack.handle) return true;
|
||||||
else if (this.handle == null || craftStack.handle == null) return false;
|
if (this.handle == null || craftStack.handle == null) return false;
|
||||||
else if (this.handle.isEmpty() && craftStack.handle.isEmpty()) return true;
|
if (this.handle.isEmpty() && craftStack.handle.isEmpty()) return true;
|
||||||
else return net.minecraft.world.item.ItemStack.matches(this.handle, craftStack.handle);
|
return net.minecraft.world.item.ItemStack.matches(this.handle, craftStack.handle);
|
||||||
}
|
}
|
||||||
// Paper end
|
// Paper end
|
||||||
|
|
||||||
@ -648,14 +650,32 @@ public final class CraftItemStack extends ItemStack {
|
|||||||
this.handle.set(nms, nmsValue);
|
this.handle.set(nms, nmsValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copyDataFrom(final ItemStack source, final Predicate<io.papermc.paper.datacomponent.DataComponentType> filter) {
|
||||||
|
Preconditions.checkArgument(source != null, "source cannot be null");
|
||||||
|
Preconditions.checkArgument(filter != null, "filter cannot be null");
|
||||||
|
if (this.isEmpty() || source.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Predicate<DataComponentType<?>> nmsFilter = nms -> filter.test(io.papermc.paper.datacomponent.PaperDataComponentType.minecraftToBukkit(nms));
|
||||||
|
net.minecraft.world.item.ItemStack sourceNmsStack = getCraftStack(source).handle;
|
||||||
|
this.handle.applyComponents(sourceNmsStack.getPrototype().filter(nmsType -> {
|
||||||
|
return !sourceNmsStack.hasNonDefault(nmsType) && nmsFilter.test(nmsType);
|
||||||
|
}));
|
||||||
|
|
||||||
|
final DataComponentPatch.SplitResult split = sourceNmsStack.getComponentsPatch().split();
|
||||||
|
this.handle.applyComponents(split.added().filter(nmsFilter));
|
||||||
|
split.removed().stream().filter(nmsFilter).forEach(this.handle::remove);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDataOverridden(final io.papermc.paper.datacomponent.DataComponentType type) {
|
public boolean isDataOverridden(final io.papermc.paper.datacomponent.DataComponentType type) {
|
||||||
if (this.isEmpty()) {
|
if (this.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final net.minecraft.core.component.DataComponentType<?> nms = io.papermc.paper.datacomponent.PaperDataComponentType.bukkitToMinecraft(type);
|
final net.minecraft.core.component.DataComponentType<?> nms = io.papermc.paper.datacomponent.PaperDataComponentType.bukkitToMinecraft(type);
|
||||||
// maybe a more efficient way is to expose the "patch" map in PatchedDataComponentMap and just check if the type exists as a key
|
return this.handle.hasNonDefault(nms);
|
||||||
return !java.util.Objects.equals(this.handle.get(nms), this.handle.getPrototype().get(nms));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user