HyCodeYourTale

Item Stacks

Item Stacks

Detailní dokumentace k ItemStack a item systému v Hytale.

---

Přehled Architektury

Item System

├── Item (Asset definition)
│ ├── Id, Icon, Model
│ ├── MaxStack, Durability
│ └── Tool, Weapon, Armor configs

├── ItemStack (Runtime instance)
│ ├── itemId
│ ├── quantity
│ ├── durability/maxDurability
│ └── metadata (BsonDocument)

└── Inventory Events
├── LivingEntityInventoryChangeEvent
├── CraftRecipeEvent
├── InteractivelyPickupItemEvent
└── DropItemEvent

---

ItemStack

Runtime reprezentace itemu v inventáři:

public class ItemStack implements NetworkSerializable {
// Konstanty
public static final ItemStack[] EMPTY_ARRAY = new ItemStack[0];
public static final ItemStack EMPTY = new ItemStack() { { this.itemId = "Empty"; } };

// CODEC pro serializaci
public static final BuilderCodec CODEC = BuilderCodec.builder(ItemStack.class, ItemStack::new)
.append(new KeyedCodec<>("Id", Codec.STRING), ...)
.append(new KeyedCodec<>("Quantity", Codec.INTEGER), ...)
.append(new KeyedCodec<>("Durability", Codec.DOUBLE), ...)
.append(new KeyedCodec<>("MaxDurability", Codec.DOUBLE), ...)
.append(new KeyedCodec<>("Metadata", Codec.BSON_DOCUMENT), ...)
.build();

// Properties
protected String itemId;
protected int quantity = 1;
protected double durability;
protected double maxDurability;
protected boolean overrideDroppedItemAnimation;
@Nullable protected BsonDocument metadata;
}

---

Vytvoření ItemStack

Konstruktory

// Základní - 1 kus
ItemStack sword = new ItemStack("DiamondSword");

// S množstvím
ItemStack arrows = new ItemStack("Arrow", 64);

// S množstvím a metadaty
BsonDocument meta = new BsonDocument();
meta.put("enchant", new BsonString("sharpness"));
ItemStack enchantedSword = new ItemStack("DiamondSword", 1, meta);

// S durability
ItemStack usedSword = new ItemStack("DiamondSword", 1, 500.0, 1000.0, null);

Empty ItemStack

// Prázdný stack
ItemStack empty = ItemStack.EMPTY;

// Kontrola prázdnosti
if (itemStack.isEmpty()) { ... }
if (ItemStack.isEmpty(itemStack)) { ... } // Null-safe

---

Vlastnosti ItemStack

Základní Gettery

// ID itemu
String itemId = itemStack.getItemId();

// Množství
int count = itemStack.getQuantity();

// Durability
double durability = itemStack.getDurability();
double maxDurability = itemStack.getMaxDurability();
boolean isUnbreakable = itemStack.isUnbreakable();
boolean isBroken = itemStack.isBroken();

// Metadata
BsonDocument metadata = itemStack.getMetadata();

// Asset reference
Item item = itemStack.getItem();

// Validita
boolean valid = itemStack.isValid();

Block Key

// Pokud item reprezentuje blok
String blockKey = itemStack.getBlockKey();

// Kontrola
if (blockKey != null) {
// Item lze položit jako blok
}

---

Immutabilita a With Metody

ItemStack je immutable - změny vrací novou instanci:

Quantity

// Změna množství
ItemStack halfStack = itemStack.withQuantity(32);

// Vrátí null pokud quantity == 0
ItemStack maybeNull = itemStack.withQuantity(0); // null!

Durability

// Nastavení durability
ItemStack repaired = itemStack.withDurability(1000.0);

// Zvýšení durability
ItemStack healed = itemStack.withIncreasedDurability(50.0);

// Obnovení na max
ItemStack full = itemStack.withRestoredDurability(1000.0);

// Změna max durability
ItemStack stronger = itemStack.withMaxDurability(2000.0);

Metadata

// Nastavení celého metadata dokumentu
ItemStack withMeta = itemStack.withMetadata(bsonDocument);

// Nastavení jednotlivého klíče
ItemStack tagged = itemStack.withMetadata("CustomTag", new BsonString("value"));

// S typovaným codecem
ItemStack typed = itemStack.withMetadata(new KeyedCodec<>("Level", Codec.INTEGER), 5);

State

// Změna stavu itemu (např. nabitý/vybitý luk)
ItemStack charged = itemStack.withState("Charged");

---

Metadata

ItemStack může obsahovat custom data v BsonDocument:

Čtení Metadata

// Přímý přístup (deprecated)
BsonDocument meta = itemStack.getMetadata();

// Typované čtení
Integer level = itemStack.getFromMetadataOrNull("Level", Codec.INTEGER);

// S KeyedCodec
KeyedCodec levelCodec = new KeyedCodec<>("Level", Codec.INTEGER);
Integer level = itemStack.getFromMetadataOrNull(levelCodec);

// S default hodnotou (pro BuilderCodec)
MyData data = itemStack.getFromMetadataOrDefault("CustomData", MyData.CODEC);

Zápis Metadata

// Přidání hodnoty
ItemStack updated = itemStack.withMetadata("Owner", new BsonString(uuid.toString()));

// Odebrání hodnoty
ItemStack removed = itemStack.withMetadata("Owner", (BsonValue) null);

// S typem
ItemStack typed = itemStack.withMetadata("Count", Codec.INTEGER, 42);

Vestavěné Metadata Klíče

public static class Metadata {
public static final String BLOCK_STATE = "BlockState";
}

---

Porovnávání ItemStack

Stackability

// Lze složit do jednoho stacku?
boolean canStack = itemStack.isStackableWith(other);

// Statická verze (null-safe)
boolean canStack = ItemStack.isStackableWith(a, b);

// Stackable = stejné ID, durability, metadata

Ekvivalence

// Stejný typ (ignoring quantity)
boolean sameType = itemStack.isEquivalentType(other);
boolean sameType = ItemStack.isEquivalentType(a, b);

// Pouze stejné ID
boolean sameItem = ItemStack.isSameItemType(a, b);

Equals

// Plná rovnost (včetně quantity)
boolean equal = itemStack.equals(other);

---

Item Asset

Definice itemu z assets:

public class Item implements JsonAssetWithMap>,
NetworkSerializable {
// Základní properties
protected String id;
protected String icon;
protected int maxStack = -1; // -1 = default (64)
protected double maxDurability;

// Typy
protected ItemTool tool; // Pro nástroje
protected ItemWeapon weapon; // Pro zbraně
protected ItemArmor armor; // Pro brnění
protected ItemGlider glider; // Pro glider
protected ItemUtility utility; // Pro utility itemy

// Block reference
protected String blockId;
protected boolean hasBlockType;

// Vizuální
protected String model;
protected String texture;
protected float scale = 1.0F;

// Zvuky
protected String soundEventId;
protected String itemSoundSetId = "ISS_Default";
}

Získání Item Asset

// Z ItemStack
Item item = itemStack.getItem();

// Přímý přístup
Item item = Item.getAssetMap().getAsset("DiamondSword");

// Unknown item
if (item == Item.UNKNOWN) {
// Item neexistuje
}

---

Inventory Eventy

LivingEntityInventoryChangeEvent

getEventRegistry().register(LivingEntityInventoryChangeEvent.class, event -> {
// Inventář entity se změnil
getLogger().atInfo().log("Inventory changed");
});

CraftRecipeEvent

getEventRegistry().register(CraftRecipeEvent.class, event -> {
// Hráč craftí
// Můžeš zrušit
// event.cancel();
});

InteractivelyPickupItemEvent

getEventRegistry().register(InteractivelyPickupItemEvent.class, event -> {
// Hráč sebral item ze země
});

DropItemEvent

getEventRegistry().register(DropItemEvent.class, event -> {
// Hráč zahodil item
// Můžeš zrušit
// event.cancel();
});

---

Network Serialization

ItemStack lze serializovat pro síťovou komunikaci:

// Převod na packet
ItemWithAllMetadata packet = itemStack.toPacket();

// Packet obsahuje:
// - itemId
// - quantity
// - durability
// - maxDurability
// - overrideDroppedItemAnimation
// - metadata (jako JSON string)

// Vytvoření z packetu (zjednodušená verze)
ItemStack stack = ItemStack.fromPacket(itemQuantityPacket);

---

BSON Serializace

Pro ukládání do databáze:

// Serializace
BsonValue bson = ItemStack.CODEC.encode(itemStack);

// Deserializace
ItemStack loaded = ItemStack.CODEC.decode(bsonValue);

---

Item JSON Asset

{
"Id": "DiamondSword",
"Icon": "Items/DiamondSword.png",
"Model": "Models/Items/DiamondSword.fbx",
"MaxStack": 1,
"MaxDurability": 1561,
"Weapon": {
"Damage": 7,
"AttackSpeed": 1.6
},
"ItemSoundSetId": "ISS_Sword"
}

Tool Item

{
"Id": "DiamondPickaxe",
"MaxStack": 1,
"MaxDurability": 1561,
"Tool": {
"Type": "Pickaxe",
"MiningSpeed": 8.0,
"MiningLevel": 3
}
}

Block Item

{
"Id": "Stone",
"BlockId": "Stone",
"HasBlockType": true,
"MaxStack": 64
}

Consumable

{
"Id": "Apple",
"MaxStack": 64,
"Consumable": true,
"Utility": {
"OnConsume": {
"Type": "Heal",
"Amount": 4
}
}
}

---

Příklady

Vytvoření Custom Itemu

// Vytvoření stacku s custom metadata
BsonDocument customData = new BsonDocument();
customData.put("CraftedBy", new BsonString(player.getUuid().toString()));
customData.put("CraftTime", new BsonInt64(System.currentTimeMillis()));

ItemStack customItem = new ItemStack("DiamondSword", 1, customData);

Kontrola Durability

public boolean needsRepair(ItemStack item) {
if (item.isUnbreakable()) return false;
return item.getDurability() < item.getMaxDurability() * 0.1; // Pod 10%
}

Damage Item

public ItemStack damageItem(ItemStack item, double damage) {
if (item.isUnbreakable()) return item;

double newDurability = item.getDurability() - damage;
if (newDurability <= 0) {
return null; // Item zničen
}

return item.withDurability(newDurability);
}

---

Shrnutí

| Třída | Účel |
|-------|------|
| ItemStack | Runtime instance itemu |
| Item | Asset definice itemu |
| ItemStack.CODEC | BSON serializace |
| ItemStack.EMPTY | Prázdný stack |

| Metoda | Účel |
|--------|------|
| getItemId() | ID itemu |
| getQuantity() | Množství |
| getDurability() | Aktuální durability |
| getItem() | Asset reference |
| withQuantity() | Nový stack s jiným množstvím |
| withDurability() | Nový stack s jinou durability |
| withMetadata() | Nový stack s metadaty |
| isStackableWith() | Kontrola stackability |

| Event | Popis |
|-------|-------|
| LivingEntityInventoryChangeEvent | Změna inventáře |
| CraftRecipeEvent | Crafting |
| InteractivelyPickupItemEvent | Sebrání itemu |
| DropItemEvent | Zahození itemu |

Last updated: 20. ledna 2026