10 KiB
10 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| ItemStacks | docs | 1 |
ItemStack represents a stack of items in Hytale with quantity, durability, and metadata.
Creating ItemStacks
ItemStacks are created using constructors with an item ID:
// Create by item ID
ItemStack sword = new ItemStack("iron_sword");
// Create with quantity
ItemStack materials = new ItemStack("wood_plank", 64);
// Create with quantity and metadata
BsonDocument metadata = new BsonDocument();
ItemStack customItem = new ItemStack("iron_sword", 1, metadata);
// Create with full parameters (durability)
ItemStack damagedSword = new ItemStack("iron_sword", 1, 50.0, 100.0, null);
// Parameters: itemId, quantity, durability, maxDurability, metadata
ItemStack Properties
ItemStack stack = new ItemStack("iron_sword", 1);
// Get the item ID
String itemId = stack.getItemId(); // "iron_sword"
// Get the Item asset
Item item = stack.getItem();
// Get quantity (NOT getCount!)
int quantity = stack.getQuantity();
// Check if empty
boolean empty = stack.isEmpty();
// Check validity
boolean valid = stack.isValid();
// Durability
double durability = stack.getDurability();
double maxDurability = stack.getMaxDurability();
boolean unbreakable = stack.isUnbreakable(); // true if maxDurability <= 0
boolean broken = stack.isBroken(); // true if durability == 0
Modifying ItemStacks
ItemStack uses a with* pattern that returns NEW instances:
ItemStack stack = new ItemStack("iron_sword", 1);
// Change quantity - returns NEW ItemStack or null if quantity is 0
ItemStack moreItems = stack.withQuantity(32);
// Change durability
ItemStack damaged = stack.withDurability(50.0);
// Increase durability
ItemStack repaired = stack.withIncreasedDurability(25.0);
// Restore full durability
ItemStack fullyRepaired = stack.withRestoredDurability(100.0);
// Change max durability
ItemStack stronger = stack.withMaxDurability(200.0);
// Change state (for items with states)
ItemStack newState = stack.withState("activated");
// Add/modify metadata
ItemStack withMeta = stack.withMetadata(metadataDocument);
// Add specific metadata value
ItemStack tagged = stack.withMetadata("CustomKey", Codec.STRING, "CustomValue");
{{< callout type="warning" >}}
Important: withQuantity(0) returns null, not an empty ItemStack. Always check for null when decreasing quantity!
{{< /callout >}}
The EMPTY Constant
Use ItemStack.EMPTY for empty stacks:
// Static empty instance (singleton)
ItemStack empty = ItemStack.EMPTY;
// Check for empty
if (stack.isEmpty()) {
// Stack is empty
}
// Static helper method
if (ItemStack.isEmpty(stack)) {
// Handles null and empty stacks
}
Comparing ItemStacks
ItemStack a = new ItemStack("iron_sword", 1);
ItemStack b = new ItemStack("iron_sword", 5);
ItemStack c = new ItemStack("diamond_sword", 1);
// Check if stackable (same itemId, durability, maxDurability, AND metadata)
// Note: Different quantities can stack, but durability values must match exactly
boolean canStack = a.isStackableWith(b);
// Check equivalent type (same itemId and metadata, ignores durability values)
boolean sameType = a.isEquivalentType(b);
// Check same item type only (just itemId comparison)
boolean sameItem = ItemStack.isSameItemType(a, c); // false
// Static helpers (handle nulls safely)
ItemStack.isStackableWith(a, b);
ItemStack.isEquivalentType(a, b);
Working with Metadata
ItemStack supports BSON metadata for custom data:
// Create metadata codec
KeyedCodec<String> OWNER_KEY = new KeyedCodec<>("Owner", Codec.STRING);
// Add metadata
ItemStack withOwner = stack.withMetadata(OWNER_KEY, "PlayerName");
// Read metadata
String owner = stack.getFromMetadataOrNull(OWNER_KEY);
// Read with key and codec
Integer level = stack.getFromMetadataOrNull("Level", Codec.INTEGER);
// Read with default from BuilderCodec
MyData data = stack.getFromMetadataOrDefault("Data", MyData.CODEC);
Block Items
Check if an item can be placed as a block:
ItemStack stack = new ItemStack("stone", 1);
// Get associated block key (null if not a block item)
String blockKey = stack.getBlockKey();
if (blockKey != null) {
// This item can be placed as a block
}
// Check via Item asset
Item item = stack.getItem();
if (item.hasBlockType()) {
String blockId = item.getBlockId();
}
Common Patterns
Consuming Items
public ItemStack consumeOne(ItemStack stack) {
if (stack == null || stack.isEmpty()) {
return null;
}
int newQuantity = stack.getQuantity() - 1;
// withQuantity returns null if quantity is 0
return stack.withQuantity(newQuantity);
}
// Usage with container
public void useItem(ItemContainer container, short slot) {
ItemStack current = container.getItemStack(slot);
ItemStack remaining = consumeOne(current);
// remaining may be null if stack was depleted
container.setItemStackForSlot(slot, remaining);
}
Checking Item Type
public boolean isHoldingSword(ItemStack hand) {
if (hand == null || hand.isEmpty()) {
return false;
}
// Check item type by ID
return hand.getItemId().contains("sword");
// Or check via Item asset
// return hand.getItem().getCategory().equals("weapon");
}
Splitting Stacks
public ItemStack[] splitStack(ItemStack stack, int splitAmount) {
if (stack == null || stack.isEmpty()) {
return null;
}
int currentQuantity = stack.getQuantity();
if (splitAmount >= currentQuantity) {
return new ItemStack[] { stack, null };
}
// Create two stacks
ItemStack remaining = stack.withQuantity(currentQuantity - splitAmount);
ItemStack split = stack.withQuantity(splitAmount);
return new ItemStack[] { remaining, split };
}
Merging Stacks
public ItemStack[] mergeStacks(ItemStack target, ItemStack source) {
if (!target.isStackableWith(source)) {
return new ItemStack[] { target, source }; // Can't merge
}
int maxStack = target.getItem().getMaxStack();
int totalQuantity = target.getQuantity() + source.getQuantity();
if (totalQuantity <= maxStack) {
// Full merge
return new ItemStack[] {
target.withQuantity(totalQuantity),
null
};
}
// Partial merge
return new ItemStack[] {
target.withQuantity(maxStack),
source.withQuantity(totalQuantity - maxStack)
};
}
Best Practices
{{< callout type="info" >}} Remember:
- Use
getQuantity()notgetCount()- Hytale uses "quantity" withQuantity(0)returnsnull- check for this!- Use
ItemStack.isEmpty(stack)to handle both null and empty - ItemStacks are mostly immutable -
with*methods return new instances - Use
isStackableWith()before attempting to merge stacks ResourceType.Idmust not be null when creating items via codecs {{< /callout >}}
// Good: Handle null from withQuantity
ItemStack result = stack.withQuantity(newQuantity);
if (result == null) {
// Stack depleted, handle appropriately
}
// Good: Safe empty check
if (ItemStack.isEmpty(stack)) {
// Handles both null and empty ItemStack.EMPTY
}
// Bad: Ignoring the returned value
stack.withQuantity(10); // Returns new stack, original unchanged!
ItemStack API Reference
Instance Methods
| Method | Returns | Description |
|---|---|---|
getItemId() |
String |
The item type identifier |
getItem() |
Item |
The Item asset (returns Item.UNKNOWN if not found) |
getQuantity() |
int |
Stack size |
getDurability() |
double |
Current durability |
getMaxDurability() |
double |
Maximum durability |
isEmpty() |
boolean |
True if itemId equals "Empty" |
isUnbreakable() |
boolean |
True if maxDurability <= 0 |
isBroken() |
boolean |
True if NOT unbreakable AND durability == 0 |
isValid() |
boolean |
True if empty OR item asset exists |
isStackableWith(ItemStack) |
boolean |
Same itemId, durability, maxDurability, metadata |
isEquivalentType(ItemStack) |
boolean |
Same itemId and metadata (ignores durability) |
getBlockKey() |
String? |
Block ID if item is placeable, null otherwise |
getOverrideDroppedItemAnimation() |
boolean |
Animation override flag |
getMetadata() |
BsonDocument? |
Deprecated - Returns cloned metadata |
getFromMetadataOrNull(KeyedCodec) |
T? |
Get typed metadata value |
getFromMetadataOrNull(String, Codec) |
T? |
Get typed metadata by key |
getFromMetadataOrDefault(String, BuilderCodec) |
T |
Get metadata with default |
Modifier Methods (return new ItemStack)
| Method | Returns | Description |
|---|---|---|
withQuantity(int) |
ItemStack? |
Returns null if quantity is 0 |
withDurability(double) |
ItemStack |
Clamped to [0, maxDurability] |
withMaxDurability(double) |
ItemStack |
Also clamps current durability |
withIncreasedDurability(double) |
ItemStack |
Add to current durability |
withRestoredDurability(double) |
ItemStack |
Set both durability and max |
withState(String) |
ItemStack |
Change item state |
withMetadata(BsonDocument) |
ItemStack |
Replace all metadata |
withMetadata(KeyedCodec, T) |
ItemStack |
Set typed metadata |
withMetadata(String, Codec, T) |
ItemStack |
Set metadata by key |
withMetadata(String, BsonValue) |
ItemStack |
Set raw BSON value |
setOverrideDroppedItemAnimation(boolean) |
void |
Mutates in place |
Static Fields
| Field | Type | Description |
|---|---|---|
EMPTY |
ItemStack |
Singleton empty stack (itemId = "Empty") |
EMPTY_ARRAY |
ItemStack[] |
Empty array constant |
CODEC |
BuilderCodec<ItemStack> |
Serialization codec |
Static Methods
| Method | Returns | Description |
|---|---|---|
isEmpty(ItemStack) |
boolean |
Null-safe empty check |
isStackableWith(ItemStack, ItemStack) |
boolean |
Null-safe stackable check |
isEquivalentType(ItemStack, ItemStack) |
boolean |
Null-safe type check |
isSameItemType(ItemStack, ItemStack) |
boolean |
Compare itemId only |
fromPacket(ItemQuantity) |
ItemStack? |
Create from network packet |
Nested Classes
| Class | Description |
|---|---|
ItemStack.Metadata |
Contains BLOCK_STATE constant for block state metadata key |