-
Notifications
You must be signed in to change notification settings - Fork 1
ItemStacks
Scafall distinguishes between ItemStack (mutable) and ItemStackSnapshot (immutable) that are both a ItemStackLike.
This is mostly done to make it easier to understand which references can be mutated to apply changes.
ItemStacks are mutable, so it can be assumed that changes to the stack are reflected where ever else the stack is used (like an inventory)
import com.wolfyscript.scafall.wrappers.world.items.ItemStack
import com.wolfyscript.scafall.identifier.Key
val stack = ItemStack.of(Key.key(Key.MINECRAFT_NAMESPACE, "stick"))Tip
When modifying the unwrapped ItemStack value, changes to it are reflected in the wrapper, so rewrapping is not necessary.
val immutableStack = stack.snapshot()ItemStackSnapshots are immutable, meaning changes to the stack are not applied.
Note
Keep in mind when unwrapping it, you are modifying a copy of the original stack!
Changes to the value will not be reflected in the wrapper.
val mutableStack = snapshot.createStack()Caution
This part of the API is currently discontinued.
Instead unwrap the ItemStack/ItemStackSnapshot and work with the platform specific features!
The API is very similar to the vanilla Data Component system. In fact, it tries to mirror the vanilla structure of data components as best as possible.
Since it is cross-platform, the provided data is converted and applied to the ItemStacks on their native platform (or fallback to Minecraft itself).
[!note] When you get the data from a ItemStackLike (mutable/immutable) then changes to that data are not reflected on the ItemStackLike.
For changes to be applied, the data needs to be set to the ItemStack again.
import com.wolfyscript.scafall.data.ItemStackDataKeys
import com.wolfyscript.scafall.deserialize
// Specify a custom name for the item using the MiniMessage extension function
stack.set(ItemStackDataKeys.CUSTOM_NAME, "<purple><b>Special Stick".deserialize())import com.wolfyscript.scafall.data.ItemStackDataKeys
stack.remove(ItemStackDataKeys.CUSTOM_NAME)[!note] The data returned is always Nullable. It's non-null when that data is present, otherwise null.
This is the same for all data components, including simple numbers, so no default values (e.g. Int? instead of Int).
import com.wolfyscript.scafall.data.ItemStackDataKeys
import net.kyori.adventure.text.Component
val data: Component? = stack.get(ItemStackDataKeys.CUSTOM_NAME)Not all Data Components have a converter implemented on each platform, due to limitations, or simply because they are still WIP.
The following table lists the current implementation status of the Data Component Converters:
⚫ — Not implemented
🟢 — Implemented
🔵 — Partly implemented / WIP / Untested
🟠 — Implemented with limitations (e.g. loss of information)
🔴 — Implementation not possible / Requires modding using NMS
| Data Component | Spigot | Paper | Sponge | Notes |
|---|---|---|---|---|
| attribute_modifiers | 🔵 | 🔵 | 🔵 | ----- |
| banner_patterns | 🟢 | 🟢 | 🟢 | ----- |
| base_color | 🟢 | 🟢 | 🟢 | ----- |
| bees | ⚫ | ⚫ | ⚫ | ----- |
| block_entity_data | ⚫ | ⚫ | ⚫ | ----- |
| block_state | ⚫ | ⚫ | ⚫ | ----- |
| blocks_attacks | ⚫ | 🟠 | ⚫ | Papers API is still EXPERIMENTAL (missing damage reduction, item damage) |
| break_sound | ⚫ | 🟠 | ⚫ | Paper only supports existing Sound Events. Custom radius is ignored |
| bucket_entity_data | ⚫ | ⚫ | ⚫ | ----- |
| bundle_contents | 🟢 | 🟢 | ⚫ | ----- |
| can_break | 🟠 | ⚫ | 🟠 | Block preconditions are missing |
| can_place_on | 🟠 | ⚫ | 🟠 | Block preconditions are missing |
| charged_projectiles | 🟢 | 🟢 | 🟢 | ----- |
| consumable | ⚫ | 🟢 | ⚫ | ----- |
| container | ⚫ | 🟢 | ⚫ | ----- |
| container_loot | ⚫ | 🟢 | ⚫ | ----- |
| custom_data | ⚫ | ⚫ | ⚫ | ----- |
| custom_model_data | 🟠 | 🟢 | 🟠 | Changed in upcoming 1.21.4 |
| custom_name | 🟢 | 🟢 | 🟢 | ----- |
| damage | 🟢 | 🟢 | 🟢 | ----- |
| damage_resistant | ⚫ | 🟢 | ⚫ | ----- |
| debug_stick_state | ⚫ | ⚫ | ⚫ | ----- |
| death_protection | ⚫ | 🟢 | ⚫ | ----- |
| dyed_color | 🟢 | ⚫ | 🟢 | ----- |
| enchantable | 🟢 | 🟢 | ⚫ | ----- |
| enchantment_glint_override | 🟢 | 🟢 | 🟢 | ----- |
| enchantments | 🟢 | 🟢 | 🟢 | ----- |
| entity_data | ⚫ | ⚫ | ⚫ | ----- |
| equippable | 🔵 | ⚫ | ⚫ | ----- |
| firework_explosion | 🔵 | ⚫ | ⚫ | ----- |
| fireworks | 🔵 | ⚫ | ⚫ | ----- |
| food | 🟢 | 🟢 | ⚫ | ----- |
| glider | 🟢 | 🟢 | ⚫ | ----- |
| instrument | 🟢 | 🟢 | 🟢 | ----- |
| intangible_projectile | 🟢 | 🟢 | 🟢 | ----- |
| item_model | 🟢 | 🟢 | 🟢 | ----- |
| item_name | 🟢 | 🟢 | 🟢 | ----- |
| jukebox_playable | ⚫ | ⚫ | ⚫ | ----- |
| lock | ⚫ | ⚫ | ⚫ | ----- |
| lodestone_tracker | ⚫ | ⚫ | ⚫ | ----- |
| lore | 🟢 | 🟢 | 🟢 | ----- |
| map_color | ⚫ | 🟢 | ⚫ | ----- |
| map_decorations | ⚫ | ⚫ | ⚫ | ----- |
| map_id | 🟢 | 🟢 | ⚫ | ----- |
| max_damage | 🟢 | 🟢 | ⚫ | ----- |
| max_stack_size | 🟢 | 🟢 | ⚫ | ----- |
| note_block_sound | 🟢 | 🟢 | 🟢 | ----- |
| ominous_bottle_amplifier | ⚫ | 🟢 | ⚫ | ----- |
| pot_decorations | 🔵 | 🟢 | 🟢 | ----- |
| potion_contents | ⚫ | ⚫ | ⚫ | ----- |
| profile | 🔵 | ⚫ | 🔵 | ----- |
| provides_banner_patterns | ⚫ | 🟢 | ⚫ | ----- |
| provides_trim_material | ⚫ | ⚫ | ⚫ | ----- |
| rarity | ⚫ | 🟢 | ⚫ | ----- |
| recipes | 🟢 | 🟢 | 🔴 | Couldn't find API in Sponge to get recipes |
| repairable | ⚫ | 🟢 | ⚫ | ----- |
| repair_cost | 🟢 | 🟢 | 🟢 | ----- |
| stored_enchantments | 🟢 | 🟢 | 🟢 | ----- |
| suspicious_stew_effects | ⚫ | 🟢 | ⚫ | ----- |
| tool | 🟢 | 🟢 | ⚫ | ----- |
| tooltip_display | ⚫ | 🟢 | ⚫ | ----- |
| tooltip_style | 🟢 | 🟢 | ⚫ | ----- |
| trim | ⚫ | 🟢 | ⚫ | ----- |
| unbreakable | 🟢 | 🟢 | 🟢 | ----- |
| use_cooldown | ⚫ | 🟢 | ⚫ | ----- |
| use_remainder | ⚫ | 🟢 | ⚫ | ----- |
| weapon | ⚫ | 🟢 | ⚫ | ----- |
| writable_book_content | ⚫ | ⚫ | ⚫ | ----- |
| written_book_content | ⚫ | ⚫ | ⚫ | ----- |
ItemStackConfigs wrap an ItemStack and provide additional configuration options, such as overrides. These overrides are able to modify the data of the wrapped ItemStack. They are only applied when required and can take context into account, such as the player, world, scoreboard, etc.
When saved to a config, the ItemStack is saved as is with its full data (SNBT), and the overrides are saved in a separate list.
When loaded from config both are loaded separately, meaning overrides are not directly applied.